Merge branch 'apache-3.2' into apache-3.3
# Conflicts: # dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/ReferenceBean.java # dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationPostProcessor.java # dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/reference/ReferenceBeanSupport.java
This commit is contained in:
commit
642f741dba
|
|
@ -21,6 +21,7 @@ import org.apache.dubbo.common.URL;
|
|||
import org.apache.dubbo.common.extension.SPI;
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.rpc.AsyncRpcResult;
|
||||
import org.apache.dubbo.rpc.BaseFilter;
|
||||
import org.apache.dubbo.rpc.Filter;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
|
|
@ -36,6 +37,7 @@ import java.util.List;
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_EXECUTE_FILTER_EXCEPTION;
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.INTERNAL_ERROR;
|
||||
import static org.apache.dubbo.common.extension.ExtensionScope.APPLICATION;
|
||||
|
||||
@SPI(value = "default", scope = APPLICATION)
|
||||
|
|
@ -294,6 +296,7 @@ public interface FilterChainBuilder {
|
|||
|
||||
@Experimental("Works for the same purpose as FilterChainNode, replace FilterChainNode with this one when proved stable enough")
|
||||
class CopyOfFilterChainNode<T, TYPE extends Invoker<T>, FILTER extends BaseFilter> implements Invoker<T> {
|
||||
private static final ErrorTypeAwareLogger LOGGER = LoggerFactory.getErrorTypeAwareLogger(CopyOfFilterChainNode.class);
|
||||
TYPE originalInvoker;
|
||||
Invoker<T> nextNode;
|
||||
FILTER filter;
|
||||
|
|
@ -329,6 +332,12 @@ public interface FilterChainBuilder {
|
|||
try {
|
||||
InvocationProfilerUtils.enterDetailProfiler(invocation, () -> "Filter " + filter.getClass().getName() + " invoke.");
|
||||
asyncResult = filter.invoke(nextNode, invocation);
|
||||
if (!(asyncResult instanceof AsyncRpcResult)) {
|
||||
String msg = "The result of filter invocation must be AsyncRpcResult. (If you want to recreate a result, please use AsyncRpcResult.newDefaultAsyncResult.) " +
|
||||
"Filter class: " + filter.getClass().getName() + ". Result class: " + asyncResult.getClass().getName() + ".";
|
||||
LOGGER.error(INTERNAL_ERROR, "", "", msg);
|
||||
throw new RpcException(msg);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
InvocationProfilerUtils.releaseDetailProfiler(invocation);
|
||||
if (filter instanceof ListenableFilter) {
|
||||
|
|
|
|||
|
|
@ -16,11 +16,6 @@
|
|||
*/
|
||||
package org.apache.dubbo.rpc.cluster.support;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.Version;
|
||||
import org.apache.dubbo.common.config.Configuration;
|
||||
|
|
@ -37,6 +32,7 @@ import org.apache.dubbo.rpc.Invoker;
|
|||
import org.apache.dubbo.rpc.Result;
|
||||
import org.apache.dubbo.rpc.RpcContext;
|
||||
import org.apache.dubbo.rpc.RpcException;
|
||||
import org.apache.dubbo.rpc.RpcServiceContext;
|
||||
import org.apache.dubbo.rpc.cluster.ClusterInvoker;
|
||||
import org.apache.dubbo.rpc.cluster.Directory;
|
||||
import org.apache.dubbo.rpc.cluster.LoadBalance;
|
||||
|
|
@ -44,6 +40,11 @@ import org.apache.dubbo.rpc.model.ApplicationModel;
|
|||
import org.apache.dubbo.rpc.model.ScopeModelUtil;
|
||||
import org.apache.dubbo.rpc.support.RpcUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_LOADBALANCE;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_RESELECT_COUNT;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.ENABLE_CONNECTIVITY_VALIDATION;
|
||||
|
|
@ -372,7 +373,7 @@ public abstract class AbstractClusterInvoker<T> implements ClusterInvoker<T> {
|
|||
}
|
||||
|
||||
protected Result invokeWithContext(Invoker<T> invoker, Invocation invocation) {
|
||||
setContext(invoker);
|
||||
Invoker<T> originInvoker = setContext(invoker);
|
||||
Result result;
|
||||
try {
|
||||
if (ProfilerSwitch.isEnableSimpleProfiler()) {
|
||||
|
|
@ -381,7 +382,7 @@ public abstract class AbstractClusterInvoker<T> implements ClusterInvoker<T> {
|
|||
invocation.addInvokedInvoker(invoker);
|
||||
result = invoker.invoke(invocation);
|
||||
} finally {
|
||||
clearContext(invoker);
|
||||
clearContext(originInvoker);
|
||||
InvocationProfilerUtils.releaseSimpleProfiler(invocation);
|
||||
}
|
||||
return result;
|
||||
|
|
@ -394,12 +395,12 @@ public abstract class AbstractClusterInvoker<T> implements ClusterInvoker<T> {
|
|||
* @return
|
||||
*/
|
||||
protected Result invokeWithContextAsync(Invoker<T> invoker, Invocation invocation, URL consumerUrl) {
|
||||
setContext(invoker, consumerUrl);
|
||||
Invoker<T> originInvoker = setContext(invoker, consumerUrl);
|
||||
Result result;
|
||||
try {
|
||||
result = invoker.invoke(invocation);
|
||||
} finally {
|
||||
clearContext(invoker);
|
||||
clearContext(originInvoker);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -436,19 +437,21 @@ public abstract class AbstractClusterInvoker<T> implements ClusterInvoker<T> {
|
|||
}
|
||||
|
||||
|
||||
private void setContext(Invoker<T> invoker) {
|
||||
setContext(invoker, null);
|
||||
private Invoker<T> setContext(Invoker<T> invoker) {
|
||||
return setContext(invoker, null);
|
||||
}
|
||||
|
||||
private void setContext(Invoker<T> invoker, URL consumerUrl) {
|
||||
RpcContext context = RpcContext.getServiceContext();
|
||||
private Invoker<T> setContext(Invoker<T> invoker, URL consumerUrl) {
|
||||
RpcServiceContext context = RpcContext.getServiceContext();
|
||||
Invoker<?> originInvoker = context.getInvoker();
|
||||
context.setInvoker(invoker)
|
||||
.setConsumerUrl(null != consumerUrl ? consumerUrl : RpcContext.getServiceContext().getConsumerUrl());
|
||||
return (Invoker<T>) originInvoker;
|
||||
}
|
||||
|
||||
private void clearContext(Invoker<T> invoker) {
|
||||
// do nothing
|
||||
RpcContext context = RpcContext.getServiceContext();
|
||||
context.setInvoker(null);
|
||||
context.setInvoker(invoker);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,12 @@ import java.util.List;
|
|||
|
||||
public interface ReferenceCache {
|
||||
@SuppressWarnings("unchecked")
|
||||
<T> T get(ReferenceConfigBase<T> referenceConfig);
|
||||
default <T> T get(ReferenceConfigBase<T> referenceConfig) {
|
||||
return get(referenceConfig, true);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
<T> T get(ReferenceConfigBase<T> referenceConfig, boolean check);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
<T> T get(String key, Class<T> type);
|
||||
|
|
@ -36,6 +41,11 @@ public interface ReferenceCache {
|
|||
@SuppressWarnings("unchecked")
|
||||
<T> T get(Class<T> type);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
<T> void check(ReferenceConfigBase<T> referenceConfig, long timeout);
|
||||
|
||||
void check(String key, Class<?> type, long timeout);
|
||||
|
||||
void destroy(String key, Class<?> type);
|
||||
|
||||
void destroy(Class<?> type);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,243 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.common.convert;
|
||||
|
||||
import org.apache.dubbo.common.utils.Assert;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.apache.dubbo.common.utils.StringUtils.isNotEmpty;
|
||||
|
||||
public class StringToDurationConverter implements StringConverter<Duration> {
|
||||
|
||||
@Override
|
||||
public Duration convert(String source) {
|
||||
return isNotEmpty(source) ? DurationStyle.detectAndParse(source) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPriority() {
|
||||
return NORMAL_PRIORITY + 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Phillip Webb
|
||||
* @author Valentine Wu
|
||||
* @link {org.springframework.boot.convert.DurationStyle}
|
||||
*/
|
||||
enum DurationStyle {
|
||||
|
||||
/**
|
||||
* Simple formatting, for example '1s'.
|
||||
*/
|
||||
SIMPLE("^([+-]?\\d+)([a-zA-Z]{0,2})$") {
|
||||
@Override
|
||||
public Duration parse(String value, ChronoUnit unit) {
|
||||
try {
|
||||
Matcher matcher = matcher(value);
|
||||
Assert.assertTrue(matcher.matches(), "Does not match simple duration pattern");
|
||||
String suffix = matcher.group(2);
|
||||
return (StringUtils.isNotBlank(suffix) ? TimeUnit.fromSuffix(suffix) : TimeUnit.fromChronoUnit(unit))
|
||||
.parse(matcher.group(1));
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalArgumentException("'" + value + "' is not a valid simple duration", ex);
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* ISO-8601 formatting.
|
||||
*/
|
||||
ISO8601("^[+-]?[pP].*$") {
|
||||
@Override
|
||||
public Duration parse(String value, ChronoUnit unit) {
|
||||
try {
|
||||
return Duration.parse(value);
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalArgumentException("'" + value + "' is not a valid ISO-8601 duration", ex);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
private final Pattern pattern;
|
||||
|
||||
DurationStyle(String pattern) {
|
||||
this.pattern = Pattern.compile(pattern);
|
||||
}
|
||||
|
||||
protected final boolean matches(String value) {
|
||||
return this.pattern.matcher(value).matches();
|
||||
}
|
||||
|
||||
protected final Matcher matcher(String value) {
|
||||
return this.pattern.matcher(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given value to a duration.
|
||||
*
|
||||
* @param value the value to parse
|
||||
* @return a duration
|
||||
*/
|
||||
public Duration parse(String value) {
|
||||
return parse(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given value to a duration.
|
||||
*
|
||||
* @param value the value to parse
|
||||
* @param unit the duration unit to use if the value doesn't specify one ({@code null}
|
||||
* will default to ms)
|
||||
* @return a duration
|
||||
*/
|
||||
public abstract Duration parse(String value, ChronoUnit unit);
|
||||
|
||||
/**
|
||||
* Detect the style then parse the value to return a duration.
|
||||
*
|
||||
* @param value the value to parse
|
||||
* @return the parsed duration
|
||||
* @throws IllegalArgumentException if the value is not a known style or cannot be
|
||||
* parsed
|
||||
*/
|
||||
public static Duration detectAndParse(String value) {
|
||||
return detectAndParse(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect the style then parse the value to return a duration.
|
||||
*
|
||||
* @param value the value to parse
|
||||
* @param unit the duration unit to use if the value doesn't specify one ({@code null}
|
||||
* will default to ms)
|
||||
* @return the parsed duration
|
||||
* @throws IllegalArgumentException if the value is not a known style or cannot be
|
||||
* parsed
|
||||
*/
|
||||
public static Duration detectAndParse(String value, ChronoUnit unit) {
|
||||
return detect(value).parse(value, unit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect the style from the given source value.
|
||||
*
|
||||
* @param value the source value
|
||||
* @return the duration style
|
||||
* @throws IllegalArgumentException if the value is not a known style
|
||||
*/
|
||||
public static DurationStyle detect(String value) {
|
||||
Assert.notNull(value, "Value must not be null");
|
||||
for (DurationStyle candidate : values()) {
|
||||
if (candidate.matches(value)) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("'" + value + "' is not a valid duration");
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Unit that support.
|
||||
*/
|
||||
enum TimeUnit {
|
||||
|
||||
/**
|
||||
* Nanoseconds.
|
||||
*/
|
||||
NANOS(ChronoUnit.NANOS, "ns", Duration::toNanos),
|
||||
|
||||
/**
|
||||
* Microseconds.
|
||||
*/
|
||||
MICROS(ChronoUnit.MICROS, "us", (duration) -> duration.toNanos() / 1000L),
|
||||
|
||||
/**
|
||||
* Milliseconds.
|
||||
*/
|
||||
MILLIS(ChronoUnit.MILLIS, "ms", Duration::toMillis),
|
||||
|
||||
/**
|
||||
* Seconds.
|
||||
*/
|
||||
SECONDS(ChronoUnit.SECONDS, "s", Duration::getSeconds),
|
||||
|
||||
/**
|
||||
* Minutes.
|
||||
*/
|
||||
MINUTES(ChronoUnit.MINUTES, "m", Duration::toMinutes),
|
||||
|
||||
/**
|
||||
* Hours.
|
||||
*/
|
||||
HOURS(ChronoUnit.HOURS, "h", Duration::toHours),
|
||||
|
||||
/**
|
||||
* Days.
|
||||
*/
|
||||
DAYS(ChronoUnit.DAYS, "d", Duration::toDays);
|
||||
|
||||
private final ChronoUnit chronoUnit;
|
||||
|
||||
private final String suffix;
|
||||
|
||||
private final Function<Duration, Long> longValue;
|
||||
|
||||
TimeUnit(ChronoUnit chronoUnit, String suffix, Function<Duration, Long> toUnit) {
|
||||
this.chronoUnit = chronoUnit;
|
||||
this.suffix = suffix;
|
||||
this.longValue = toUnit;
|
||||
}
|
||||
|
||||
public Duration parse(String value) {
|
||||
return Duration.of(Long.parseLong(value), this.chronoUnit);
|
||||
}
|
||||
|
||||
public long longValue(Duration value) {
|
||||
return this.longValue.apply(value);
|
||||
}
|
||||
|
||||
public static TimeUnit fromChronoUnit(ChronoUnit chronoUnit) {
|
||||
if (chronoUnit == null) {
|
||||
return TimeUnit.MILLIS;
|
||||
}
|
||||
for (TimeUnit candidate : values()) {
|
||||
if (candidate.chronoUnit == chronoUnit) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Unknown unit " + chronoUnit);
|
||||
}
|
||||
|
||||
public static TimeUnit fromSuffix(String suffix) {
|
||||
for (TimeUnit candidate : values()) {
|
||||
if (candidate.suffix.equalsIgnoreCase(suffix)) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Unknown unit '" + suffix + "'");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -89,6 +89,11 @@ public interface ApplicationDeployer extends Deployer<ApplicationModel> {
|
|||
*/
|
||||
void notifyModuleChanged(ModuleModel moduleModel, DeployState state);
|
||||
|
||||
/**
|
||||
* refresh service instance
|
||||
*/
|
||||
void refreshServiceInstance();
|
||||
|
||||
/**
|
||||
* Increase the count of service update threads.
|
||||
* NOTE: should call ${@link ApplicationDeployer#decreaseServiceRefreshCount()} after update finished
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import java.lang.reflect.Array;
|
|||
import java.lang.reflect.Method;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
|
@ -87,7 +88,8 @@ public class ClassUtils {
|
|||
BigDecimal.class,
|
||||
BigInteger.class,
|
||||
Date.class,
|
||||
Object.class
|
||||
Object.class,
|
||||
Duration.class
|
||||
);
|
||||
/**
|
||||
* Prefix for internal array class names: "[L"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.common.utils;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class ToStringUtils {
|
||||
|
||||
private ToStringUtils() {
|
||||
}
|
||||
|
||||
public static String printToString(Object obj) {
|
||||
if (obj == null) {
|
||||
return "null";
|
||||
}
|
||||
try {
|
||||
return JsonUtils.toJson(obj);
|
||||
} catch (Throwable throwable) {
|
||||
if (obj instanceof Object[]) {
|
||||
return Arrays.toString((Object[]) obj);
|
||||
}
|
||||
return obj.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -277,9 +277,10 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
protected void appendMetricsCompatible(Map<String, String> map) {
|
||||
MetricsConfig metricsConfig = getConfigManager().getMetrics().orElse(null);
|
||||
if (metricsConfig != null) {
|
||||
if (metricsConfig.getProtocol() != null && !StringUtils.isEquals(metricsConfig.getProtocol(), PROTOCOL_PROMETHEUS)) {
|
||||
String protocol = Optional.ofNullable(metricsConfig.getProtocol()).orElse(PROTOCOL_PROMETHEUS);
|
||||
if (!StringUtils.isEquals(protocol, PROTOCOL_PROMETHEUS)) {
|
||||
Assert.notEmptyString(metricsConfig.getPort(), "Metrics port cannot be null");
|
||||
map.put("metrics.protocol", metricsConfig.getProtocol());
|
||||
map.put("metrics.protocol", protocol);
|
||||
map.put("metrics.port", metricsConfig.getPort());
|
||||
}
|
||||
}
|
||||
|
|
@ -375,8 +376,9 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
}
|
||||
|
||||
/**
|
||||
* it is used for skipping the check of interface since dubbo 3.2
|
||||
* rest protocol allow the service is implement class
|
||||
* it is used for skipping the check of interface since dubbo 3.2
|
||||
* rest protocol allow the service is implement class
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected boolean canSkipInterfaceCheck() {
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ public class MetricsConfig extends AbstractConfig {
|
|||
*/
|
||||
private Boolean useGlobalRegistry;
|
||||
|
||||
private Boolean enableRpc;
|
||||
|
||||
public MetricsConfig() {
|
||||
}
|
||||
|
|
@ -214,4 +215,12 @@ public class MetricsConfig extends AbstractConfig {
|
|||
public void setUseGlobalRegistry(Boolean useGlobalRegistry) {
|
||||
this.useGlobalRegistry = useGlobalRegistry;
|
||||
}
|
||||
|
||||
public Boolean getEnableRpc() {
|
||||
return enableRpc;
|
||||
}
|
||||
|
||||
public void setEnableRpc(Boolean enableRpc) {
|
||||
this.enableRpc = enableRpc;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -368,7 +368,15 @@ public abstract class ReferenceConfigBase<T> extends AbstractReferenceConfig {
|
|||
}
|
||||
|
||||
@Transient
|
||||
public abstract T get();
|
||||
public abstract T get(boolean check);
|
||||
|
||||
@Transient
|
||||
public abstract void checkOrDestroy(long timeout);
|
||||
|
||||
@Transient
|
||||
public final T get() {
|
||||
return get(true);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
getModuleConfigManager().removeConfig(this);
|
||||
|
|
|
|||
|
|
@ -415,7 +415,9 @@ public abstract class ServiceConfigBase<T> extends AbstractServiceConfig {
|
|||
/**
|
||||
* export service and auto start application instance
|
||||
*/
|
||||
public abstract void export();
|
||||
public final void export() {
|
||||
export(true);
|
||||
}
|
||||
|
||||
public abstract void unexport();
|
||||
|
||||
|
|
@ -423,4 +425,7 @@ public abstract class ServiceConfigBase<T> extends AbstractServiceConfig {
|
|||
|
||||
public abstract boolean isUnexported();
|
||||
|
||||
public abstract void export(boolean register);
|
||||
|
||||
public abstract void register();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -254,6 +254,7 @@ public class ConfigManager extends AbstractConfigManager implements ApplicationE
|
|||
// load dubbo.metrics.xxx
|
||||
loadConfigsOfTypeFromProps(MetricsConfig.class);
|
||||
|
||||
//load dubbo.tracing.xxx
|
||||
loadConfigsOfTypeFromProps(TracingConfig.class);
|
||||
|
||||
// load multiple config types:
|
||||
|
|
|
|||
|
|
@ -9,4 +9,5 @@ string-to-long=org.apache.dubbo.common.convert.StringToLongConverter
|
|||
string-to-optional=org.apache.dubbo.common.convert.StringToOptionalConverter
|
||||
string-to-short=org.apache.dubbo.common.convert.StringToShortConverter
|
||||
string-to-string=org.apache.dubbo.common.convert.StringToStringConverter
|
||||
string-to-byte=org.apache.dubbo.common.convert.StringToByteConverter
|
||||
string-to-byte=org.apache.dubbo.common.convert.StringToByteConverter
|
||||
string-to-duration=org.apache.dubbo.common.convert.StringToDurationConverter
|
||||
|
|
@ -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.common.convert;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* {@link StringToDurationConverter} Test
|
||||
*
|
||||
* @since 3.2.3
|
||||
*/
|
||||
class StringToDurationConverterTest {
|
||||
|
||||
private StringToDurationConverter converter;
|
||||
|
||||
@BeforeEach
|
||||
public void init() {
|
||||
converter = (StringToDurationConverter) getExtensionLoader(Converter.class).getExtension("string-to-duration");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAccept() {
|
||||
assertTrue(converter.accept(String.class, Duration.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConvert() {
|
||||
assertEquals(Duration.ofMillis(1000), converter.convert("1000ms"));
|
||||
assertEquals(Duration.ofSeconds(1), converter.convert("1s"));
|
||||
assertEquals(Duration.ofMinutes(1), converter.convert("1m"));
|
||||
assertEquals(Duration.ofHours(1), converter.convert("1h"));
|
||||
assertEquals(Duration.ofDays(1), converter.convert("1d"));
|
||||
|
||||
assertNull(converter.convert(null));
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
converter.convert("ttt");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package com.alibaba.dubbo.cache;
|
||||
|
||||
import com.alibaba.dubbo.common.DelegateURL;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.rpc.Invocation;
|
||||
|
||||
|
|
@ -26,6 +27,6 @@ public interface CacheFactory extends org.apache.dubbo.cache.CacheFactory {
|
|||
Cache getCache(URL url, Invocation invocation);
|
||||
|
||||
default org.apache.dubbo.cache.Cache getCache(org.apache.dubbo.common.URL url, org.apache.dubbo.rpc.Invocation invocation) {
|
||||
return this.getCache(new URL(url), new Invocation.CompatibleInvocation(invocation));
|
||||
return this.getCache(new DelegateURL(url), new Invocation.CompatibleInvocation(invocation));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package com.alibaba.dubbo.cache.support;
|
|||
|
||||
import com.alibaba.dubbo.cache.Cache;
|
||||
import com.alibaba.dubbo.cache.CacheFactory;
|
||||
import com.alibaba.dubbo.common.DelegateURL;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.rpc.Invocation;
|
||||
|
||||
|
|
@ -48,6 +49,6 @@ public abstract class AbstractCacheFactory implements CacheFactory {
|
|||
|
||||
@Override
|
||||
public org.apache.dubbo.cache.Cache getCache(org.apache.dubbo.common.URL url, org.apache.dubbo.rpc.Invocation invocation) {
|
||||
return getCache(new URL(url), new Invocation.CompatibleInvocation(invocation));
|
||||
return getCache(new DelegateURL(url), new Invocation.CompatibleInvocation(invocation));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -73,7 +73,7 @@ public class URL extends org.apache.dubbo.common.URL {
|
|||
|
||||
public static URL valueOf(String url) {
|
||||
org.apache.dubbo.common.URL result = org.apache.dubbo.common.URL.valueOf(url);
|
||||
return new URL(result);
|
||||
return new DelegateURL(result);
|
||||
}
|
||||
|
||||
public static String encode(String value) {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package com.alibaba.dubbo.common.serialize;
|
||||
|
||||
import com.alibaba.dubbo.common.DelegateURL;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
@ -32,11 +33,11 @@ public interface Serialization extends org.apache.dubbo.common.serialize.Seriali
|
|||
|
||||
@Override
|
||||
default org.apache.dubbo.common.serialize.ObjectOutput serialize(org.apache.dubbo.common.URL url, OutputStream output) throws IOException {
|
||||
return this.serialize(new URL(url), output);
|
||||
return this.serialize(new DelegateURL(url), output);
|
||||
}
|
||||
|
||||
@Override
|
||||
default org.apache.dubbo.common.serialize.ObjectInput deserialize(org.apache.dubbo.common.URL url, InputStream input) throws IOException {
|
||||
return this.deserialize(new URL(url), input);
|
||||
return this.deserialize(new DelegateURL(url), input);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,6 @@ public interface ThreadPool extends org.apache.dubbo.common.threadpool.ThreadPoo
|
|||
|
||||
@Override
|
||||
default Executor getExecutor(URL url) {
|
||||
return getExecutor(new com.alibaba.dubbo.common.URL(url));
|
||||
return getExecutor(new com.alibaba.dubbo.common.DelegateURL(url));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
package com.alibaba.dubbo.common.utils;
|
||||
|
||||
import com.alibaba.dubbo.common.DelegateURL;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
|
||||
import java.util.List;
|
||||
|
|
@ -30,11 +31,11 @@ import java.util.stream.Collectors;
|
|||
public class UrlUtils {
|
||||
|
||||
public static URL parseURL(String address, Map<String, String> defaults) {
|
||||
return new URL(org.apache.dubbo.common.utils.UrlUtils.parseURL(address, defaults));
|
||||
return new DelegateURL(org.apache.dubbo.common.utils.UrlUtils.parseURL(address, defaults));
|
||||
}
|
||||
|
||||
public static List<URL> parseURLs(String address, Map<String, String> defaults) {
|
||||
return org.apache.dubbo.common.utils.UrlUtils.parseURLs(address, defaults).stream().map(e -> new URL(e)).collect(Collectors.toList());
|
||||
return org.apache.dubbo.common.utils.UrlUtils.parseURLs(address, defaults).stream().map(e -> new DelegateURL(e)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static Map<String, Map<String, String>> convertRegister(Map<String, Map<String, String>> register) {
|
||||
|
|
@ -64,7 +65,7 @@ public class UrlUtils {
|
|||
}
|
||||
|
||||
public static URL getEmptyUrl(String service, String category) {
|
||||
return new URL(org.apache.dubbo.common.utils.UrlUtils.getEmptyUrl(service, category));
|
||||
return new DelegateURL(org.apache.dubbo.common.utils.UrlUtils.getEmptyUrl(service, category));
|
||||
}
|
||||
|
||||
public static boolean isMatchCategory(String category, String categories) {
|
||||
|
|
|
|||
|
|
@ -34,11 +34,11 @@ public interface Monitor extends org.apache.dubbo.monitor.Monitor {
|
|||
|
||||
@Override
|
||||
default void collect(URL statistics) {
|
||||
this.collect(new com.alibaba.dubbo.common.URL(statistics));
|
||||
this.collect(new com.alibaba.dubbo.common.DelegateURL(statistics));
|
||||
}
|
||||
|
||||
@Override
|
||||
default List<URL> lookup(URL query) {
|
||||
return this.lookup(new com.alibaba.dubbo.common.URL(query)).stream().map(url -> url.getOriginalURL()).collect(Collectors.toList());
|
||||
return this.lookup(new com.alibaba.dubbo.common.DelegateURL(query)).stream().map(url -> url.getOriginalURL()).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,6 @@ public interface MonitorFactory extends org.apache.dubbo.monitor.MonitorFactory
|
|||
|
||||
@Override
|
||||
default Monitor getMonitor(URL url) {
|
||||
return this.getMonitor(new com.alibaba.dubbo.common.URL(url));
|
||||
return this.getMonitor(new com.alibaba.dubbo.common.DelegateURL(url));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package com.alibaba.dubbo.registry;
|
||||
|
||||
import com.alibaba.dubbo.common.DelegateURL;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
|
||||
import java.util.List;
|
||||
|
|
@ -54,7 +55,7 @@ public interface NotifyListener {
|
|||
@Override
|
||||
public void notify(List<org.apache.dubbo.common.URL> urls) {
|
||||
if (listener != null) {
|
||||
listener.notify(urls.stream().map(url -> new URL(url)).collect(Collectors.toList()));
|
||||
listener.notify(urls.stream().map(url -> new DelegateURL(url)).collect(Collectors.toList()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,29 +41,29 @@ public interface Registry extends org.apache.dubbo.registry.Registry {
|
|||
|
||||
@Override
|
||||
default void register(URL url) {
|
||||
this.register(new com.alibaba.dubbo.common.URL(url));
|
||||
this.register(new com.alibaba.dubbo.common.DelegateURL(url));
|
||||
}
|
||||
|
||||
@Override
|
||||
default void unregister(URL url) {
|
||||
this.unregister(new com.alibaba.dubbo.common.URL(url));
|
||||
this.unregister(new com.alibaba.dubbo.common.DelegateURL(url));
|
||||
}
|
||||
|
||||
@Override
|
||||
default void subscribe(URL url, NotifyListener listener) {
|
||||
this.subscribe(new com.alibaba.dubbo.common.URL(url),
|
||||
this.subscribe(new com.alibaba.dubbo.common.DelegateURL(url),
|
||||
new com.alibaba.dubbo.registry.NotifyListener.CompatibleNotifyListener(listener));
|
||||
}
|
||||
|
||||
@Override
|
||||
default void unsubscribe(URL url, NotifyListener listener) {
|
||||
this.unsubscribe(new com.alibaba.dubbo.common.URL(url),
|
||||
this.unsubscribe(new com.alibaba.dubbo.common.DelegateURL(url),
|
||||
new com.alibaba.dubbo.registry.NotifyListener.CompatibleNotifyListener(listener));
|
||||
}
|
||||
|
||||
@Override
|
||||
default List<URL> lookup(URL url) {
|
||||
return this.lookup(new com.alibaba.dubbo.common.URL(url)).stream().map(u -> u.getOriginalURL()).
|
||||
return this.lookup(new com.alibaba.dubbo.common.DelegateURL(url)).stream().map(u -> u.getOriginalURL()).
|
||||
collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,6 @@ public interface RegistryFactory extends org.apache.dubbo.registry.RegistryFacto
|
|||
|
||||
@Override
|
||||
default Registry getRegistry(URL url) {
|
||||
return this.getRegistry(new com.alibaba.dubbo.common.URL(url));
|
||||
return this.getRegistry(new com.alibaba.dubbo.common.DelegateURL(url));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ public abstract class AbstractRegistry implements Registry {
|
|||
|
||||
@Override
|
||||
public com.alibaba.dubbo.common.URL getUrl() {
|
||||
return new com.alibaba.dubbo.common.URL(abstractRegistry.getUrl());
|
||||
return new com.alibaba.dubbo.common.DelegateURL(abstractRegistry.getUrl());
|
||||
}
|
||||
|
||||
protected void setUrl(com.alibaba.dubbo.common.URL url) {
|
||||
|
|
@ -47,35 +47,35 @@ public abstract class AbstractRegistry implements Registry {
|
|||
}
|
||||
|
||||
public Set<com.alibaba.dubbo.common.URL> getRegistered() {
|
||||
return abstractRegistry.getRegistered().stream().map(url -> new com.alibaba.dubbo.common.URL(url)).collect(Collectors.toSet());
|
||||
return abstractRegistry.getRegistered().stream().map(url -> new com.alibaba.dubbo.common.DelegateURL(url)).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public Map<com.alibaba.dubbo.common.URL, Set<com.alibaba.dubbo.registry.NotifyListener>> getSubscribed() {
|
||||
return abstractRegistry.getSubscribed().entrySet()
|
||||
.stream()
|
||||
.collect(Collectors.toMap(entry -> new com.alibaba.dubbo.common.URL(entry.getKey()),
|
||||
.collect(Collectors.toMap(entry -> new com.alibaba.dubbo.common.DelegateURL(entry.getKey()),
|
||||
entry -> convertToNotifyListeners(entry.getValue())));
|
||||
}
|
||||
|
||||
public Map<com.alibaba.dubbo.common.URL, Map<String, List<com.alibaba.dubbo.common.URL>>> getNotified() {
|
||||
return abstractRegistry.getNotified().entrySet().stream()
|
||||
.collect(Collectors.toMap(entry -> new com.alibaba.dubbo.common.URL(entry.getKey()),
|
||||
.collect(Collectors.toMap(entry -> new com.alibaba.dubbo.common.DelegateURL(entry.getKey()),
|
||||
entry -> {
|
||||
return entry.getValue().entrySet()
|
||||
.stream()
|
||||
.collect(Collectors.toMap(e -> e.getKey(), e -> {
|
||||
return e.getValue().stream().map(url -> new com.alibaba.dubbo.common.URL(url)).collect(Collectors.toList());
|
||||
return e.getValue().stream().map(url -> new com.alibaba.dubbo.common.DelegateURL(url)).collect(Collectors.toList());
|
||||
}));
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
public List<com.alibaba.dubbo.common.URL> getCacheUrls(com.alibaba.dubbo.common.URL url) {
|
||||
return abstractRegistry.lookup(url.getOriginalURL()).stream().map(tmpUrl -> new com.alibaba.dubbo.common.URL(tmpUrl)).collect(Collectors.toList());
|
||||
return abstractRegistry.lookup(url.getOriginalURL()).stream().map(tmpUrl -> new com.alibaba.dubbo.common.DelegateURL(tmpUrl)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<com.alibaba.dubbo.common.URL> lookup(com.alibaba.dubbo.common.URL url) {
|
||||
return abstractRegistry.lookup(url.getOriginalURL()).stream().map(tmpUrl -> new com.alibaba.dubbo.common.URL(tmpUrl)).collect(Collectors.toList());
|
||||
return abstractRegistry.lookup(url.getOriginalURL()).stream().map(tmpUrl -> new com.alibaba.dubbo.common.DelegateURL(tmpUrl)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
protected void notify(com.alibaba.dubbo.common.URL url, com.alibaba.dubbo.registry.NotifyListener listener, List<com.alibaba.dubbo.common.URL> urls) {
|
||||
|
|
@ -101,22 +101,22 @@ public abstract class AbstractRegistry implements Registry {
|
|||
|
||||
@Override
|
||||
public void register(URL url) {
|
||||
this.register(new com.alibaba.dubbo.common.URL(url));
|
||||
this.register(new com.alibaba.dubbo.common.DelegateURL(url));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregister(URL url) {
|
||||
this.unregister(new com.alibaba.dubbo.common.URL(url));
|
||||
this.unregister(new com.alibaba.dubbo.common.DelegateURL(url));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribe(URL url, NotifyListener listener) {
|
||||
this.subscribe(new com.alibaba.dubbo.common.URL(url), new com.alibaba.dubbo.registry.NotifyListener.CompatibleNotifyListener(listener));
|
||||
this.subscribe(new com.alibaba.dubbo.common.DelegateURL(url), new com.alibaba.dubbo.registry.NotifyListener.CompatibleNotifyListener(listener));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsubscribe(URL url, NotifyListener listener) {
|
||||
this.unsubscribe(new com.alibaba.dubbo.common.URL(url), new com.alibaba.dubbo.registry.NotifyListener.CompatibleNotifyListener(listener));
|
||||
this.unsubscribe(new com.alibaba.dubbo.common.DelegateURL(url), new com.alibaba.dubbo.registry.NotifyListener.CompatibleNotifyListener(listener));
|
||||
}
|
||||
|
||||
final Set<com.alibaba.dubbo.registry.NotifyListener> convertToNotifyListeners(Set<NotifyListener> notifyListeners) {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,6 @@ public abstract class AbstractRegistryFactory extends org.apache.dubbo.registry.
|
|||
|
||||
@Override
|
||||
protected Registry createRegistry(URL url) {
|
||||
return createRegistry(new com.alibaba.dubbo.common.URL(url));
|
||||
return createRegistry(new com.alibaba.dubbo.common.DelegateURL(url));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
package com.alibaba.dubbo.registry.support;
|
||||
|
||||
import com.alibaba.dubbo.common.DelegateURL;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.registry.NotifyListener;
|
||||
import com.alibaba.dubbo.registry.Registry;
|
||||
|
|
@ -87,12 +88,12 @@ public abstract class FailbackRegistry implements org.apache.dubbo.registry.Regi
|
|||
|
||||
@Override
|
||||
public List<URL> lookup(URL url) {
|
||||
return failbackRegistry.lookup(url.getOriginalURL()).stream().map(e -> new URL(e)).collect(Collectors.toList());
|
||||
return failbackRegistry.lookup(url.getOriginalURL()).stream().map(e -> new DelegateURL(e)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getUrl() {
|
||||
return new URL(failbackRegistry.getUrl());
|
||||
return new DelegateURL(failbackRegistry.getUrl());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -112,22 +113,22 @@ public abstract class FailbackRegistry implements org.apache.dubbo.registry.Regi
|
|||
|
||||
@Override
|
||||
public void register(org.apache.dubbo.common.URL url) {
|
||||
this.register(new URL(url));
|
||||
this.register(new DelegateURL(url));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregister(org.apache.dubbo.common.URL url) {
|
||||
this.unregister(new URL(url));
|
||||
this.unregister(new DelegateURL(url));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribe(org.apache.dubbo.common.URL url, org.apache.dubbo.registry.NotifyListener listener) {
|
||||
this.subscribe(new URL(url), new NotifyListener.CompatibleNotifyListener(listener));
|
||||
this.subscribe(new DelegateURL(url), new NotifyListener.CompatibleNotifyListener(listener));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsubscribe(org.apache.dubbo.common.URL url, org.apache.dubbo.registry.NotifyListener listener) {
|
||||
this.unsubscribe(new URL(url), new NotifyListener.CompatibleNotifyListener(listener));
|
||||
this.unsubscribe(new DelegateURL(url), new NotifyListener.CompatibleNotifyListener(listener));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -147,22 +148,22 @@ public abstract class FailbackRegistry implements org.apache.dubbo.registry.Regi
|
|||
|
||||
@Override
|
||||
public void doRegister(org.apache.dubbo.common.URL url) {
|
||||
this.compatibleFailbackRegistry.doRegister(new URL(url));
|
||||
this.compatibleFailbackRegistry.doRegister(new DelegateURL(url));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doUnregister(org.apache.dubbo.common.URL url) {
|
||||
this.compatibleFailbackRegistry.doUnregister(new URL(url));
|
||||
this.compatibleFailbackRegistry.doUnregister(new DelegateURL(url));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doSubscribe(org.apache.dubbo.common.URL url, org.apache.dubbo.registry.NotifyListener listener) {
|
||||
this.compatibleFailbackRegistry.doSubscribe(new URL(url), new NotifyListener.CompatibleNotifyListener(listener));
|
||||
this.compatibleFailbackRegistry.doSubscribe(new DelegateURL(url), new NotifyListener.CompatibleNotifyListener(listener));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doUnsubscribe(org.apache.dubbo.common.URL url, org.apache.dubbo.registry.NotifyListener listener) {
|
||||
this.compatibleFailbackRegistry.doUnsubscribe(new URL(url), new NotifyListener.CompatibleNotifyListener(listener));
|
||||
this.compatibleFailbackRegistry.doUnsubscribe(new DelegateURL(url), new NotifyListener.CompatibleNotifyListener(listener));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import org.apache.dubbo.common.extension.Adaptive;
|
|||
import org.apache.dubbo.remoting.Constants;
|
||||
import org.apache.dubbo.remoting.RemotingServer;
|
||||
|
||||
import com.alibaba.dubbo.common.DelegateURL;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
|
||||
@Deprecated
|
||||
|
|
@ -32,7 +33,7 @@ public interface Transporter extends org.apache.dubbo.remoting.Transporter {
|
|||
@Override
|
||||
default RemotingServer bind(org.apache.dubbo.common.URL url, org.apache.dubbo.remoting.ChannelHandler handler)
|
||||
throws org.apache.dubbo.remoting.RemotingException {
|
||||
return bind(new URL(url), new ChannelHandler() {
|
||||
return bind(new DelegateURL(url), new ChannelHandler() {
|
||||
@Override
|
||||
public void connected(Channel channel) throws RemotingException {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ public interface Exporter<T> extends org.apache.dubbo.rpc.Exporter<T> {
|
|||
@Override
|
||||
Invoker<T> getInvoker();
|
||||
|
||||
default void register() {}
|
||||
|
||||
default void unregister() {}
|
||||
|
||||
class CompatibleExporter<T> implements Exporter<T> {
|
||||
|
|
@ -43,6 +45,11 @@ public interface Exporter<T> extends org.apache.dubbo.rpc.Exporter<T> {
|
|||
delegate.unexport();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register() {
|
||||
delegate.register();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregister() {
|
||||
delegate.unregister();
|
||||
|
|
|
|||
|
|
@ -18,6 +18,9 @@
|
|||
package com.alibaba.dubbo.rpc;
|
||||
|
||||
import org.apache.dubbo.rpc.AsyncRpcResult;
|
||||
import org.apache.dubbo.rpc.AttachmentsAdapter;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Deprecated
|
||||
public interface Filter extends org.apache.dubbo.rpc.Filter {
|
||||
|
|
@ -27,17 +30,21 @@ public interface Filter extends org.apache.dubbo.rpc.Filter {
|
|||
@Override
|
||||
default org.apache.dubbo.rpc.Result invoke(org.apache.dubbo.rpc.Invoker<?> invoker,
|
||||
org.apache.dubbo.rpc.Invocation invocation)
|
||||
throws org.apache.dubbo.rpc.RpcException {
|
||||
throws org.apache.dubbo.rpc.RpcException {
|
||||
Result invokeResult = invoke(new Invoker.CompatibleInvoker<>(invoker),
|
||||
new Invocation.CompatibleInvocation(invocation));
|
||||
|
||||
if (invokeResult instanceof Result.CompatibleResult) {
|
||||
return invokeResult;
|
||||
return ((Result.CompatibleResult) invokeResult).getDelegate();
|
||||
}
|
||||
|
||||
AsyncRpcResult asyncRpcResult = AsyncRpcResult.newDefaultAsyncResult(invocation);
|
||||
asyncRpcResult.setValue(invokeResult.getValue());
|
||||
asyncRpcResult.setException(invokeResult.getException());
|
||||
Map<String, String> attachments = invokeResult.getAttachments();
|
||||
if (!(attachments instanceof AttachmentsAdapter.ObjectToStringMap)) {
|
||||
asyncRpcResult.setAttachments(attachments);
|
||||
}
|
||||
asyncRpcResult.setObjectAttachments(invokeResult.getObjectAttachments());
|
||||
|
||||
return asyncRpcResult;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package com.alibaba.dubbo.rpc;
|
|||
|
||||
import org.apache.dubbo.rpc.AsyncRpcResult;
|
||||
|
||||
import com.alibaba.dubbo.common.DelegateURL;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
|
||||
@Deprecated
|
||||
|
|
@ -77,7 +78,7 @@ public interface Invoker<T> extends org.apache.dubbo.rpc.Invoker<T> {
|
|||
|
||||
@Override
|
||||
public URL getUrl() {
|
||||
return new URL(invoker.getUrl());
|
||||
return new DelegateURL(invoker.getUrl());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package com.alibaba.dubbo.rpc;
|
|||
|
||||
import org.apache.dubbo.rpc.ProtocolServer;
|
||||
|
||||
import com.alibaba.dubbo.common.DelegateURL;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
|
||||
import java.util.Collections;
|
||||
|
|
@ -38,7 +39,7 @@ public interface Protocol extends org.apache.dubbo.rpc.Protocol {
|
|||
|
||||
@Override
|
||||
default <T> org.apache.dubbo.rpc.Invoker<T> refer(Class<T> aClass, org.apache.dubbo.common.URL url) throws RpcException {
|
||||
return this.refer(aClass, new URL(url));
|
||||
return this.refer(aClass, new DelegateURL(url));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -42,6 +42,6 @@ public interface ProxyFactory extends org.apache.dubbo.rpc.ProxyFactory {
|
|||
|
||||
@Override
|
||||
default <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) throws RpcException {
|
||||
return getInvoker(proxy, type, new com.alibaba.dubbo.common.URL(url));
|
||||
return getInvoker(proxy, type, new com.alibaba.dubbo.common.DelegateURL(url));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,6 +64,16 @@ public interface Result extends org.apache.dubbo.rpc.Result {
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see com.alibaba.dubbo.rpc.Result#getValue()
|
||||
* @deprecated Replace to getValue()
|
||||
*/
|
||||
@Deprecated
|
||||
default Object getResult() {
|
||||
return getValue();
|
||||
}
|
||||
|
||||
class CompatibleResult implements Result {
|
||||
private org.apache.dubbo.rpc.Result delegate;
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import org.apache.dubbo.common.utils.CollectionUtils;
|
|||
import org.apache.dubbo.rpc.FutureContext;
|
||||
|
||||
import com.alibaba.dubbo.common.Constants;
|
||||
import com.alibaba.dubbo.common.DelegateURL;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.rpc.protocol.dubbo.FutureAdapter;
|
||||
|
||||
|
|
@ -134,7 +135,7 @@ public class RpcContext {
|
|||
if (CollectionUtils.isNotEmpty(newUrls)) {
|
||||
List<URL> urls = new ArrayList<>(newUrls.size());
|
||||
for (org.apache.dubbo.common.URL newUrl : newUrls) {
|
||||
urls.add(new URL(newUrl));
|
||||
urls.add(new DelegateURL(newUrl));
|
||||
}
|
||||
return urls;
|
||||
}
|
||||
|
|
@ -152,7 +153,7 @@ public class RpcContext {
|
|||
}
|
||||
|
||||
public URL getUrl() {
|
||||
return new URL(newRpcContext.getUrl());
|
||||
return new DelegateURL(newRpcContext.getUrl());
|
||||
}
|
||||
|
||||
public void setUrl(URL url) {
|
||||
|
|
|
|||
|
|
@ -37,6 +37,6 @@ public interface Configurator extends org.apache.dubbo.rpc.cluster.Configurator
|
|||
|
||||
@Override
|
||||
default URL configure(URL url) {
|
||||
return this.configure(new com.alibaba.dubbo.common.URL(url));
|
||||
return this.configure(new com.alibaba.dubbo.common.DelegateURL(url));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,6 @@ public interface ConfiguratorFactory extends org.apache.dubbo.rpc.cluster.Config
|
|||
|
||||
@Override
|
||||
default Configurator getConfigurator(URL url) {
|
||||
return this.getConfigurator(new com.alibaba.dubbo.common.URL(url));
|
||||
return this.getConfigurator(new com.alibaba.dubbo.common.DelegateURL(url));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ import org.apache.dubbo.rpc.Invocation;
|
|||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.RpcException;
|
||||
|
||||
import com.alibaba.dubbo.common.DelegateURL;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
|
@ -38,7 +40,9 @@ public interface LoadBalance extends org.apache.dubbo.rpc.cluster.LoadBalance {
|
|||
map(invoker -> new com.alibaba.dubbo.rpc.Invoker.CompatibleInvoker<T>(invoker)).
|
||||
collect(Collectors.toList());
|
||||
|
||||
return select(invs, new com.alibaba.dubbo.common.URL(url),
|
||||
new com.alibaba.dubbo.rpc.Invocation.CompatibleInvocation(invocation));
|
||||
com.alibaba.dubbo.rpc.Invoker<T> selected = select(invs, new DelegateURL(url),
|
||||
new com.alibaba.dubbo.rpc.Invocation.CompatibleInvocation(invocation));
|
||||
|
||||
return selected == null ? null : selected.getOriginal();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import org.apache.dubbo.rpc.Invoker;
|
|||
import org.apache.dubbo.rpc.RpcException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Deprecated
|
||||
|
|
@ -44,9 +45,9 @@ public interface Router extends org.apache.dubbo.rpc.cluster.Router{
|
|||
List<com.alibaba.dubbo.rpc.Invoker<T>> invs = invokers.stream().map(invoker -> new com.alibaba.dubbo.rpc.Invoker.CompatibleInvoker<T>(invoker)).
|
||||
collect(Collectors.toList());
|
||||
|
||||
List<com.alibaba.dubbo.rpc.Invoker<T>> res = this.route(invs, new com.alibaba.dubbo.common.URL(url), new com.alibaba.dubbo.rpc.Invocation.CompatibleInvocation(invocation));
|
||||
List<com.alibaba.dubbo.rpc.Invoker<T>> res = this.route(invs, new com.alibaba.dubbo.common.DelegateURL(url), new com.alibaba.dubbo.rpc.Invocation.CompatibleInvocation(invocation));
|
||||
|
||||
return res.stream().map(inv -> inv.getOriginal()).collect(Collectors.toList());
|
||||
return res.stream().map(inv -> inv.getOriginal()).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -27,6 +27,6 @@ public interface RouterFactory extends org.apache.dubbo.rpc.cluster.RouterFactor
|
|||
|
||||
@Override
|
||||
default Router getRouter(URL url) {
|
||||
return this.getRouter(new com.alibaba.dubbo.common.URL(url));
|
||||
return this.getRouter(new com.alibaba.dubbo.common.DelegateURL(url));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ public interface RuleConverter extends org.apache.dubbo.rpc.cluster.RuleConverte
|
|||
|
||||
@Override
|
||||
default List<URL> convert(URL subscribeUrl, Object source) {
|
||||
return this.convert(new com.alibaba.dubbo.common.URL(subscribeUrl), source).
|
||||
return this.convert(new com.alibaba.dubbo.common.DelegateURL(subscribeUrl), source).
|
||||
stream().map(url -> url.getOriginalURL()).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@
|
|||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>testcontainers</artifactId>
|
||||
<version>1.18.1</version>
|
||||
<version>1.18.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package org.apache.dubbo.config;
|
|||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.Version;
|
||||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
import org.apache.dubbo.common.constants.LoggerCodeConstants;
|
||||
import org.apache.dubbo.common.constants.RegistryConstants;
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
|
|
@ -220,7 +221,7 @@ public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
|
|||
|
||||
@Override
|
||||
@Transient
|
||||
public T get() {
|
||||
public T get(boolean check) {
|
||||
if (destroyed) {
|
||||
throw new IllegalStateException("The invoker of ReferenceConfig(" + url + ") has already destroyed!");
|
||||
}
|
||||
|
|
@ -229,12 +230,53 @@ public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
|
|||
// ensure start module, compatible with old api usage
|
||||
getScopeModel().getDeployer().start();
|
||||
|
||||
init();
|
||||
init(check);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkOrDestroy(long timeout) {
|
||||
if (!initialized || ref == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
checkInvokerAvailable(timeout);
|
||||
} catch (Throwable t) {
|
||||
logAndCleanup(t);
|
||||
throw t;
|
||||
}
|
||||
}
|
||||
|
||||
private void logAndCleanup(Throwable t) {
|
||||
try {
|
||||
if (invoker != null) {
|
||||
invoker.destroy();
|
||||
}
|
||||
} catch (Throwable destroy) {
|
||||
logger.warn(CONFIG_FAILED_DESTROY_INVOKER, "", "", "Unexpected error occurred when destroy invoker of ReferenceConfig(" + url + ").", t);
|
||||
}
|
||||
if (consumerModel != null) {
|
||||
ModuleServiceRepository repository = getScopeModel().getServiceRepository();
|
||||
repository.unregisterConsumer(consumerModel);
|
||||
}
|
||||
initialized = false;
|
||||
invoker = null;
|
||||
ref = null;
|
||||
consumerModel = null;
|
||||
serviceMetadata.setTarget(null);
|
||||
serviceMetadata.getAttributeMap().remove(PROXY_CLASS_REF);
|
||||
|
||||
// Thrown by checkInvokerAvailable().
|
||||
if (t.getClass() == IllegalStateException.class &&
|
||||
t.getMessage().contains("No provider available for the service")) {
|
||||
|
||||
// 2-2 - No provider available.
|
||||
logger.error(CLUSTER_NO_VALID_PROVIDER, "server crashed", "", "No provider available.", t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void destroy() {
|
||||
super.destroy();
|
||||
|
|
@ -258,6 +300,10 @@ public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
|
|||
}
|
||||
|
||||
protected synchronized void init() {
|
||||
init(true);
|
||||
}
|
||||
|
||||
protected synchronized void init(boolean check) {
|
||||
if (initialized && ref != null) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -308,33 +354,11 @@ public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
|
|||
consumerModel.setProxyObject(ref);
|
||||
consumerModel.initMethodModels();
|
||||
|
||||
checkInvokerAvailable();
|
||||
if (check) {
|
||||
checkInvokerAvailable(0);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
try {
|
||||
if (invoker != null) {
|
||||
invoker.destroy();
|
||||
}
|
||||
} catch (Throwable destroy) {
|
||||
logger.warn(CONFIG_FAILED_DESTROY_INVOKER, "", "", "Unexpected error occurred when destroy invoker of ReferenceConfig(" + url + ").", t);
|
||||
}
|
||||
if (consumerModel != null) {
|
||||
ModuleServiceRepository repository = getScopeModel().getServiceRepository();
|
||||
repository.unregisterConsumer(consumerModel);
|
||||
}
|
||||
initialized = false;
|
||||
invoker = null;
|
||||
ref = null;
|
||||
consumerModel = null;
|
||||
serviceMetadata.setTarget(null);
|
||||
serviceMetadata.getAttributeMap().remove(PROXY_CLASS_REF);
|
||||
|
||||
// Thrown by checkInvokerAvailable().
|
||||
if (t.getClass() == IllegalStateException.class &&
|
||||
t.getMessage().contains("No provider available for the service")) {
|
||||
|
||||
// 2-2 - No provider available.
|
||||
logger.error(CLUSTER_NO_VALID_PROVIDER, "server crashed", "", "No provider available.", t);
|
||||
}
|
||||
logAndCleanup(t);
|
||||
|
||||
throw t;
|
||||
}
|
||||
|
|
@ -631,8 +655,31 @@ public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
|
|||
}
|
||||
}
|
||||
|
||||
private void checkInvokerAvailable() throws IllegalStateException {
|
||||
if (shouldCheck() && !invoker.isAvailable()) {
|
||||
private void checkInvokerAvailable(long timeout) throws IllegalStateException {
|
||||
if (!shouldCheck()) {
|
||||
return;
|
||||
}
|
||||
boolean available = invoker.isAvailable();
|
||||
if (available) {
|
||||
return;
|
||||
}
|
||||
|
||||
long startTime = System.currentTimeMillis();
|
||||
long checkDeadline = startTime + timeout;
|
||||
do {
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
break;
|
||||
}
|
||||
available = invoker.isAvailable();
|
||||
} while (!available && checkDeadline > System.currentTimeMillis());
|
||||
logger.warn(LoggerCodeConstants.REGISTRY_EMPTY_ADDRESS, "", "",
|
||||
"Check reference of [" + getUniqueServiceName() + "] failed very beginning. " +
|
||||
"After " + (System.currentTimeMillis() - startTime) + "ms reties, finally " +
|
||||
(available ? "succeed" : "failed") + ".");
|
||||
if (!available) {
|
||||
// 2-2 - No provider available.
|
||||
|
||||
IllegalStateException illegalStateException = new IllegalStateException("Failed to check the status of the service "
|
||||
|
|
|
|||
|
|
@ -280,7 +280,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void export() {
|
||||
public void export(boolean register) {
|
||||
if (this.exported) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -300,19 +300,37 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
this.init();
|
||||
|
||||
if (shouldDelay()) {
|
||||
doDelayExport();
|
||||
// should register if delay export
|
||||
doDelayExport(true);
|
||||
} else {
|
||||
doExport();
|
||||
doExport(register);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void doDelayExport() {
|
||||
@Override
|
||||
public void register() {
|
||||
if (!this.exported) {
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (this) {
|
||||
if (!this.exported) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Exporter<?> exporter : exporters) {
|
||||
exporter.register();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void doDelayExport(boolean register) {
|
||||
ExecutorRepository.getInstance(getScopeModel().getApplicationModel()).getServiceExportExecutor()
|
||||
.schedule(() -> {
|
||||
try {
|
||||
doExport();
|
||||
doExport(register);
|
||||
} catch (Exception e) {
|
||||
logger.error(CONFIG_FAILED_EXPORT_SERVICE, "configuration server disconnected", "", "Failed to (async)export service config: " + interfaceName, e);
|
||||
}
|
||||
|
|
@ -439,7 +457,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
checkAndUpdateSubConfigs();
|
||||
}
|
||||
|
||||
protected synchronized void doExport() {
|
||||
protected synchronized void doExport(boolean register) {
|
||||
if (unexported) {
|
||||
throw new IllegalStateException("The service " + interfaceClass.getName() + " has already unexported!");
|
||||
}
|
||||
|
|
@ -450,12 +468,12 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
if (StringUtils.isEmpty(path)) {
|
||||
path = interfaceName;
|
||||
}
|
||||
doExportUrls();
|
||||
doExportUrls(register);
|
||||
exported();
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
private void doExportUrls() {
|
||||
private void doExportUrls(boolean register) {
|
||||
ModuleServiceRepository repository = getScopeModel().getServiceRepository();
|
||||
ServiceDescriptor serviceDescriptor;
|
||||
final boolean serverService = ref instanceof ServerService;
|
||||
|
|
@ -490,7 +508,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
// In case user specified path, register service one more time to map it to path.
|
||||
repository.registerService(pathKey, interfaceClass);
|
||||
}
|
||||
doExportUrlsFor1Protocol(protocolConfig, registryURLs);
|
||||
doExportUrlsFor1Protocol(protocolConfig, registryURLs, register);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
@ -499,7 +517,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
providerModel.setServiceUrls(urls);
|
||||
}
|
||||
|
||||
private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs) {
|
||||
private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs, boolean register) {
|
||||
Map<String, String> map = buildAttributes(protocolConfig);
|
||||
|
||||
// remove null key and null value
|
||||
|
|
@ -511,7 +529,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
|
||||
processServiceExecutor(url);
|
||||
|
||||
exportUrl(url, registryURLs);
|
||||
exportUrl(url, registryURLs, register);
|
||||
}
|
||||
|
||||
private void processServiceExecutor(URL url) {
|
||||
|
|
@ -695,7 +713,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
return url;
|
||||
}
|
||||
|
||||
private void exportUrl(URL url, List<URL> registryURLs) {
|
||||
private void exportUrl(URL url, List<URL> registryURLs, boolean register) {
|
||||
String scope = url.getParameter(SCOPE_KEY);
|
||||
// don't export when none is configured
|
||||
if (!SCOPE_NONE.equalsIgnoreCase(scope)) {
|
||||
|
|
@ -719,7 +737,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
build();
|
||||
}
|
||||
|
||||
url = exportRemote(url, registryURLs);
|
||||
url = exportRemote(url, registryURLs, register);
|
||||
if (!isGeneric(generic) && !getScopeModel().isInternal()) {
|
||||
MetadataUtils.publishServiceDefinition(url, providerModel.getServiceModel(), getApplicationModel());
|
||||
}
|
||||
|
|
@ -734,7 +752,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
URL localUrl = URLBuilder.from(url).
|
||||
setProtocol(protocol).
|
||||
build();
|
||||
localUrl = exportRemote(localUrl, registryURLs);
|
||||
localUrl = exportRemote(localUrl, registryURLs, register);
|
||||
if (!isGeneric(generic) && !getScopeModel().isInternal()) {
|
||||
MetadataUtils.publishServiceDefinition(localUrl, providerModel.getServiceModel(), getApplicationModel());
|
||||
}
|
||||
|
|
@ -746,7 +764,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
this.urls.add(url);
|
||||
}
|
||||
|
||||
private URL exportRemote(URL url, List<URL> registryURLs) {
|
||||
private URL exportRemote(URL url, List<URL> registryURLs, boolean register) {
|
||||
if (CollectionUtils.isNotEmpty(registryURLs)) {
|
||||
for (URL registryURL : registryURLs) {
|
||||
if (SERVICE_REGISTRY_PROTOCOL.equals(registryURL.getProtocol())) {
|
||||
|
|
@ -778,7 +796,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
}
|
||||
}
|
||||
|
||||
doExportUrl(registryURL.putAttribute(EXPORT_KEY, url), true);
|
||||
doExportUrl(registryURL.putAttribute(EXPORT_KEY, url), true, register);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -787,7 +805,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
logger.info("Export dubbo service " + interfaceClass.getName() + " to url " + url);
|
||||
}
|
||||
|
||||
doExportUrl(url, true);
|
||||
doExportUrl(url, true, register);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -795,7 +813,10 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
private void doExportUrl(URL url, boolean withMetaData) {
|
||||
private void doExportUrl(URL url, boolean withMetaData, boolean register) {
|
||||
if (!register) {
|
||||
url = url.addParameter(REGISTER_KEY, false);
|
||||
}
|
||||
Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, url);
|
||||
if (withMetaData) {
|
||||
invoker = new DelegateProviderMetaDataInvoker(invoker, this);
|
||||
|
|
@ -817,7 +838,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
local = local.setScopeModel(getScopeModel())
|
||||
.setServiceModel(providerModel);
|
||||
local = local.addParameter(EXPORTER_LISTENER_KEY, LOCAL_PROTOCOL);
|
||||
doExportUrl(local, false);
|
||||
doExportUrl(local, false, true);
|
||||
logger.info("Export dubbo service " + interfaceClass.getName() + " to local registry url : " + local);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -936,6 +936,17 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshServiceInstance() {
|
||||
if (registered) {
|
||||
try {
|
||||
ServiceInstanceMetadataUtils.refreshMetadataAndInstance(applicationModel);
|
||||
} catch (Exception e) {
|
||||
logger.error(CONFIG_REFRESH_INSTANCE_ERROR, "", "", "Refresh instance and metadata error.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void increaseServiceRefreshCount() {
|
||||
serviceRefreshState.incrementAndGet();
|
||||
|
|
|
|||
|
|
@ -54,10 +54,11 @@ public class DefaultMetricsServiceExporter implements MetricsServiceExporter, Sc
|
|||
MetricsConfig metricsConfig = applicationModel.getApplicationConfigManager().getMetrics().orElse(null);
|
||||
// TODO compatible with old usage of metrics, remove protocol check after new metrics is ready for use.
|
||||
if (metricsConfig != null && metricsService == null) {
|
||||
if (PROTOCOL_PROMETHEUS.equals(metricsConfig.getProtocol()) ) {
|
||||
String protocol = Optional.ofNullable(metricsConfig.getProtocol()).orElse(PROTOCOL_PROMETHEUS);
|
||||
if (PROTOCOL_PROMETHEUS.equals(protocol) ) {
|
||||
this.metricsService = applicationModel.getExtensionLoader(MetricsService.class).getDefaultExtension();
|
||||
} else {
|
||||
logger.warn(COMMON_METRICS_COLLECTOR_EXCEPTION, "", "", "Protocol " + metricsConfig.getProtocol() + " not support for new metrics mechanism. " +
|
||||
logger.warn(COMMON_METRICS_COLLECTOR_EXCEPTION, "", "", "Protocol " + protocol + " not support for new metrics mechanism. " +
|
||||
"Using old metrics mechanism instead.");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import org.apache.dubbo.config.ConsumerConfig;
|
|||
import org.apache.dubbo.config.ModuleConfig;
|
||||
import org.apache.dubbo.config.ProviderConfig;
|
||||
import org.apache.dubbo.config.ReferenceConfig;
|
||||
import org.apache.dubbo.config.ReferenceConfigBase;
|
||||
import org.apache.dubbo.config.ServiceConfig;
|
||||
import org.apache.dubbo.config.ServiceConfigBase;
|
||||
import org.apache.dubbo.config.context.ModuleConfigManager;
|
||||
|
|
@ -174,7 +175,17 @@ public class DefaultModuleDeployer extends AbstractDeployer<ModuleModel> impleme
|
|||
|
||||
// if no async export/refer services, just set started
|
||||
if (asyncExportingFutures.isEmpty() && asyncReferringFutures.isEmpty()) {
|
||||
// publish module started event
|
||||
onModuleStarted();
|
||||
|
||||
// register services to registry
|
||||
registerServices();
|
||||
|
||||
// check reference config
|
||||
checkReferences();
|
||||
|
||||
// complete module start future after application state changed
|
||||
completeStartFuture(true);
|
||||
} else {
|
||||
frameworkExecutorRepository.getSharedExecutor().submit(() -> {
|
||||
try {
|
||||
|
|
@ -182,17 +193,30 @@ public class DefaultModuleDeployer extends AbstractDeployer<ModuleModel> impleme
|
|||
waitExportFinish();
|
||||
// wait for refer finish
|
||||
waitReferFinish();
|
||||
|
||||
// publish module started event
|
||||
onModuleStarted();
|
||||
|
||||
// register services to registry
|
||||
registerServices();
|
||||
|
||||
// check reference config
|
||||
checkReferences();
|
||||
} catch (Throwable e) {
|
||||
logger.warn(CONFIG_FAILED_WAIT_EXPORT_REFER, "", "", "wait for export/refer services occurred an exception", e);
|
||||
onModuleFailed(getIdentifier() + " start failed: " + e, e);
|
||||
} finally {
|
||||
onModuleStarted();
|
||||
// complete module start future after application state changed
|
||||
completeStartFuture(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
} catch (Throwable e) {
|
||||
onModuleFailed(getIdentifier() + " start failed: " + e, e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
return startFuture;
|
||||
}
|
||||
|
||||
|
|
@ -300,16 +324,11 @@ public class DefaultModuleDeployer extends AbstractDeployer<ModuleModel> impleme
|
|||
}
|
||||
|
||||
private void onModuleStarted() {
|
||||
try {
|
||||
if (isStarting()) {
|
||||
setStarted();
|
||||
logger.info(getIdentifier() + " has started.");
|
||||
applicationDeployer.notifyModuleChanged(moduleModel, DeployState.STARTED);
|
||||
}
|
||||
} finally {
|
||||
// complete module start future after application state changed
|
||||
completeStartFuture(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void onModuleFailed(String msg, Throwable ex) {
|
||||
|
|
@ -366,6 +385,21 @@ public class DefaultModuleDeployer extends AbstractDeployer<ModuleModel> impleme
|
|||
}
|
||||
}
|
||||
|
||||
private void registerServices() {
|
||||
for (ServiceConfigBase sc : configManager.getServices()) {
|
||||
if (!Boolean.FALSE.equals(sc.isRegister())) {
|
||||
registerServiceInternal(sc);
|
||||
}
|
||||
}
|
||||
applicationDeployer.refreshServiceInstance();
|
||||
}
|
||||
|
||||
private void checkReferences() {
|
||||
for (ReferenceConfigBase<?> rc : configManager.getReferences()) {
|
||||
referenceCache.check(rc, 3000);
|
||||
}
|
||||
}
|
||||
|
||||
private void exportServiceInternal(ServiceConfigBase sc) {
|
||||
ServiceConfig<?> serviceConfig = (ServiceConfig<?>) sc;
|
||||
if (!serviceConfig.isRefreshed()) {
|
||||
|
|
@ -390,12 +424,23 @@ public class DefaultModuleDeployer extends AbstractDeployer<ModuleModel> impleme
|
|||
asyncExportingFutures.add(future);
|
||||
} else {
|
||||
if (!sc.isExported()) {
|
||||
sc.export();
|
||||
sc.export(false);
|
||||
exportedServices.add(sc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void registerServiceInternal(ServiceConfigBase sc) {
|
||||
ServiceConfig<?> serviceConfig = (ServiceConfig<?>) sc;
|
||||
if (!serviceConfig.isRefreshed()) {
|
||||
serviceConfig.refresh();
|
||||
}
|
||||
if (!sc.isExported()) {
|
||||
return;
|
||||
}
|
||||
sc.register();
|
||||
}
|
||||
|
||||
private void unexportServices() {
|
||||
exportedServices.forEach(sc -> {
|
||||
try {
|
||||
|
|
@ -428,7 +473,7 @@ public class DefaultModuleDeployer extends AbstractDeployer<ModuleModel> impleme
|
|||
ExecutorService executor = executorRepository.getServiceReferExecutor();
|
||||
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
referenceCache.get(rc);
|
||||
referenceCache.get(rc, false);
|
||||
} catch (Throwable t) {
|
||||
logger.error(CONFIG_FAILED_EXPORT_SERVICE, "", "", "Failed to async export service config: " + getIdentifier() + " , catch error : " + t.getMessage(), t);
|
||||
}
|
||||
|
|
@ -436,7 +481,7 @@ public class DefaultModuleDeployer extends AbstractDeployer<ModuleModel> impleme
|
|||
|
||||
asyncReferringFutures.add(future);
|
||||
} else {
|
||||
referenceCache.get(rc);
|
||||
referenceCache.get(rc, false);
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
|
|
@ -456,6 +501,9 @@ public class DefaultModuleDeployer extends AbstractDeployer<ModuleModel> impleme
|
|||
});
|
||||
asyncReferringFutures.clear();
|
||||
referenceCache.destroyAll();
|
||||
for (ReferenceConfigBase<?> rc : configManager.getReferences()) {
|
||||
rc.destroy();
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ public class CompositeReferenceCache implements ReferenceCache {
|
|||
}
|
||||
|
||||
@Override
|
||||
public <T> T get(ReferenceConfigBase<T> referenceConfig) {
|
||||
public <T> T get(ReferenceConfigBase<T> referenceConfig, boolean check) {
|
||||
|
||||
Class<?> type = referenceConfig.getInterfaceClass();
|
||||
String key = BaseServiceMetadata.buildServiceKey(type.getName(), referenceConfig.getGroup(), referenceConfig.getVersion());
|
||||
|
|
@ -57,7 +57,7 @@ public class CompositeReferenceCache implements ReferenceCache {
|
|||
"Call ReferenceConfig#get() directly for non-singleton ReferenceConfig instead of using ReferenceCache#get(ReferenceConfig)");
|
||||
}
|
||||
if (proxy == null) {
|
||||
proxy = referenceConfig.get();
|
||||
proxy = referenceConfig.get(check);
|
||||
}
|
||||
return proxy;
|
||||
}
|
||||
|
|
@ -111,6 +111,20 @@ public class CompositeReferenceCache implements ReferenceCache {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check(String key, Class<?> type, long timeout) {
|
||||
for (ModuleModel moduleModel : applicationModel.getModuleModels()) {
|
||||
moduleModel.getDeployer().getReferenceCache().check(key, type, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void check(ReferenceConfigBase<T> referenceConfig, long timeout) {
|
||||
for (ModuleModel moduleModel : applicationModel.getModuleModels()) {
|
||||
moduleModel.getDeployer().getReferenceCache().check(referenceConfig, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy(Class<?> type) {
|
||||
for (ModuleModel moduleModel : applicationModel.getModuleModels()) {
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ public class SimpleReferenceCache implements ReferenceCache {
|
|||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T get(ReferenceConfigBase<T> rc) {
|
||||
public <T> T get(ReferenceConfigBase<T> rc, boolean check) {
|
||||
String key = generator.generateKey(rc);
|
||||
Class<?> type = rc.getInterfaceClass();
|
||||
|
||||
|
|
@ -129,7 +129,7 @@ public class SimpleReferenceCache implements ReferenceCache {
|
|||
referencesOfType.add(rc);
|
||||
List<ReferenceConfigBase<?>> referenceConfigList = ConcurrentHashMapUtils.computeIfAbsent(referenceKeyMap, key, _k -> Collections.synchronizedList(new ArrayList<>()));
|
||||
referenceConfigList.add(rc);
|
||||
proxy = rc.get();
|
||||
proxy = rc.get(check);
|
||||
}
|
||||
|
||||
return proxy;
|
||||
|
|
@ -203,6 +203,29 @@ public class SimpleReferenceCache implements ReferenceCache {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check(String key, Class<?> type, long timeout) {
|
||||
List<ReferenceConfigBase<?>> referencesOfKey = referenceKeyMap.get(key);
|
||||
if (CollectionUtils.isEmpty(referencesOfKey)) {
|
||||
return;
|
||||
}
|
||||
List<ReferenceConfigBase<?>> referencesOfType = referenceTypeMap.get(type);
|
||||
if (CollectionUtils.isEmpty(referencesOfType)) {
|
||||
return;
|
||||
}
|
||||
for (ReferenceConfigBase<?> rc : referencesOfKey) {
|
||||
rc.checkOrDestroy(timeout);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void check(ReferenceConfigBase<T> referenceConfig, long timeout) {
|
||||
String key = generator.generateKey(referenceConfig);
|
||||
Class<?> type = referenceConfig.getInterfaceClass();
|
||||
check(key, type, timeout);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy(String key, Class<?> type) {
|
||||
List<ReferenceConfigBase<?>> referencesOfKey = referenceKeyMap.remove(key);
|
||||
|
|
|
|||
|
|
@ -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(), 3);
|
||||
Assertions.assertEquals(exporterListener.getExportedExporters().size(), 5);
|
||||
// The exported exporter contains MultipleRegistryCenterExportProviderFilter
|
||||
Assertions.assertTrue(exporterListener.getFilters().contains(filter));
|
||||
|
||||
|
|
@ -244,4 +244,4 @@ class MultipleRegistryCenterExportProviderIntegrationTest implements Integration
|
|||
logger.info(getClass().getSimpleName() + " testcase is ending...");
|
||||
registryProtocolListener = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,11 +40,11 @@ public class MockReferenceConfig extends ReferenceConfig<FooService> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public synchronized FooService get() {
|
||||
public synchronized FooService get(boolean check) {
|
||||
if (value != null) return value;
|
||||
|
||||
counter.getAndIncrement();
|
||||
value = super.get();
|
||||
value = super.get(check);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,11 +40,11 @@ public class XxxMockReferenceConfig extends ReferenceConfig<XxxService> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public synchronized XxxService get() {
|
||||
public synchronized XxxService get(boolean check) {
|
||||
if (value != null) return value;
|
||||
|
||||
counter.getAndIncrement();
|
||||
value = super.get();
|
||||
value = super.get(check);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,10 @@
|
|||
*/
|
||||
package org.apache.dubbo.config.spring;
|
||||
|
||||
import org.apache.dubbo.common.bytecode.Proxy;
|
||||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.utils.Assert;
|
||||
import org.apache.dubbo.common.utils.ClassUtils;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
|
|
@ -26,11 +30,11 @@ import org.apache.dubbo.config.spring.reference.ReferenceAttributes;
|
|||
import org.apache.dubbo.config.spring.reference.ReferenceBeanManager;
|
||||
import org.apache.dubbo.config.spring.reference.ReferenceBeanSupport;
|
||||
import org.apache.dubbo.config.spring.schema.DubboBeanDefinitionParser;
|
||||
import org.apache.dubbo.config.spring.util.LazyTargetInvocationHandler;
|
||||
import org.apache.dubbo.config.spring.util.LazyTargetSource;
|
||||
import org.apache.dubbo.config.support.Parameter;
|
||||
import org.apache.dubbo.rpc.proxy.AbstractProxyFactory;
|
||||
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.aop.target.AbstractLazyCreationTargetSource;
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
|
|
@ -45,10 +49,13 @@ import org.springframework.context.ApplicationContext;
|
|||
import org.springframework.context.ApplicationContextAware;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROXY_FAILED;
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
|
|
@ -99,7 +106,7 @@ import java.util.Map;
|
|||
*/
|
||||
public class ReferenceBean<T> implements FactoryBean<T>,
|
||||
ApplicationContextAware, BeanClassLoaderAware, BeanNameAware, InitializingBean, DisposableBean {
|
||||
|
||||
private final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(getClass());
|
||||
private transient ApplicationContext applicationContext;
|
||||
|
||||
private ClassLoader beanClassLoader;
|
||||
|
|
@ -124,6 +131,9 @@ public class ReferenceBean<T> implements FactoryBean<T>,
|
|||
// 'interfaceName' field for compatible with seata-1.4.0: io.seata.rm.tcc.remoting.parser.DubboRemotingParser#getServiceDesc()
|
||||
private String interfaceName;
|
||||
|
||||
// proxy style
|
||||
private String proxy;
|
||||
|
||||
//from annotation attributes
|
||||
private Map<String, Object> referenceProps;
|
||||
|
||||
|
|
@ -240,6 +250,10 @@ public class ReferenceBean<T> implements FactoryBean<T>,
|
|||
propertyValues = beanDefinition.getPropertyValues();
|
||||
}
|
||||
}
|
||||
|
||||
if (referenceProps != null) {
|
||||
this.proxy = (String) referenceProps.get(ReferenceAttributes.PROXY);
|
||||
}
|
||||
Assert.notNull(this.interfaceName, "The interface name of ReferenceBean is not initialized");
|
||||
|
||||
ReferenceBeanManager referenceBeanManager = beanFactory.getBean(ReferenceBeanManager.BEAN_NAME, ReferenceBeanManager.class);
|
||||
|
|
@ -325,24 +339,56 @@ public class ReferenceBean<T> implements FactoryBean<T>,
|
|||
|
||||
//set proxy interfaces
|
||||
//see also: org.apache.dubbo.rpc.proxy.AbstractProxyFactory.getProxy(org.apache.dubbo.rpc.Invoker<T>, boolean)
|
||||
ProxyFactory proxyFactory = new ProxyFactory();
|
||||
proxyFactory.setTargetSource(new DubboReferenceLazyInitTargetSource());
|
||||
proxyFactory.addInterface(interfaceClass);
|
||||
List<Class<?>> interfaces = new ArrayList<>();
|
||||
interfaces.add(interfaceClass);
|
||||
Class<?>[] internalInterfaces = AbstractProxyFactory.getInternalInterfaces();
|
||||
for (Class<?> anInterface : internalInterfaces) {
|
||||
proxyFactory.addInterface(anInterface);
|
||||
}
|
||||
Collections.addAll(interfaces, internalInterfaces);
|
||||
if (!StringUtils.isEquals(interfaceClass.getName(), interfaceName)) {
|
||||
//add service interface
|
||||
try {
|
||||
Class<?> serviceInterface = ClassUtils.forName(interfaceName, beanClassLoader);
|
||||
proxyFactory.addInterface(serviceInterface);
|
||||
interfaces.add(serviceInterface);
|
||||
} catch (ClassNotFoundException e) {
|
||||
// generic call maybe without service interface class locally
|
||||
}
|
||||
}
|
||||
|
||||
this.lazyProxy = proxyFactory.getProxy(this.beanClassLoader);
|
||||
if (StringUtils.isEmpty(this.proxy) || CommonConstants.DEFAULT_PROXY.equalsIgnoreCase(this.proxy)) {
|
||||
generateFromJavassistFirst(interfaces);
|
||||
}
|
||||
|
||||
if (this.lazyProxy == null) {
|
||||
generateFromJdk(interfaces);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateFromJavassistFirst(List<Class<?>> interfaces) {
|
||||
try {
|
||||
this.lazyProxy = Proxy.getProxy(interfaces.toArray(new Class[0])).newInstance(new LazyTargetInvocationHandler(new DubboReferenceLazyInitTargetSource()));
|
||||
} catch (Throwable fromJavassist) {
|
||||
// try fall back to JDK proxy factory
|
||||
try {
|
||||
this.lazyProxy = java.lang.reflect.Proxy.newProxyInstance(beanClassLoader, interfaces.toArray(new Class[0]), new LazyTargetInvocationHandler(new DubboReferenceLazyInitTargetSource()));
|
||||
logger.error(PROXY_FAILED, "", "", "Failed to generate proxy by Javassist failed. Fallback to use JDK proxy success. " +
|
||||
"Interfaces: " + interfaces, fromJavassist);
|
||||
} catch (Throwable fromJdk) {
|
||||
logger.error(PROXY_FAILED, "", "", "Failed to generate proxy by Javassist failed. Fallback to use JDK proxy is also failed. " +
|
||||
"Interfaces: " + interfaces + " Javassist Error.", fromJavassist);
|
||||
logger.error(PROXY_FAILED, "", "", "Failed to generate proxy by Javassist failed. Fallback to use JDK proxy is also failed. " +
|
||||
"Interfaces: " + interfaces + " JDK Error.", fromJdk);
|
||||
throw fromJavassist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void generateFromJdk(List<Class<?>> interfaces) {
|
||||
try {
|
||||
this.lazyProxy = java.lang.reflect.Proxy.newProxyInstance(beanClassLoader, interfaces.toArray(new Class[0]), new LazyTargetInvocationHandler(new DubboReferenceLazyInitTargetSource()));
|
||||
} catch (Throwable fromJdk) {
|
||||
logger.error(PROXY_FAILED, "", "", "Failed to generate proxy by Javassist failed. Fallback to use JDK proxy is also failed. " +
|
||||
"Interfaces: " + interfaces + " JDK Error.", fromJdk);
|
||||
throw fromJdk;
|
||||
}
|
||||
}
|
||||
|
||||
private Object getCallProxy() throws Exception {
|
||||
|
|
@ -350,7 +396,7 @@ public class ReferenceBean<T> implements FactoryBean<T>,
|
|||
throw new IllegalStateException("ReferenceBean is not ready yet, please make sure to call reference interface method after dubbo is started.");
|
||||
}
|
||||
//get reference proxy
|
||||
//Subclasses should synchronize on the given Object if they perform any sort of extended singleton creation phase.
|
||||
//Subclasses should synchronize on the given Object if they perform any sort of extended singleton creation phase.
|
||||
// In particular, subclasses should not have their own mutexes involved in singleton creation, to avoid the potential for deadlocks in lazy-init situations.
|
||||
//The redundant type cast is to be compatible with earlier than spring-4.2
|
||||
synchronized (((DefaultSingletonBeanRegistry) getBeanFactory()).getSingletonMutex()) {
|
||||
|
|
@ -358,17 +404,11 @@ public class ReferenceBean<T> implements FactoryBean<T>,
|
|||
}
|
||||
}
|
||||
|
||||
private class DubboReferenceLazyInitTargetSource extends AbstractLazyCreationTargetSource {
|
||||
|
||||
private class DubboReferenceLazyInitTargetSource implements LazyTargetSource {
|
||||
@Override
|
||||
protected Object createObject() throws Exception {
|
||||
public Object getTarget() throws Exception {
|
||||
return getCallProxy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Class<?> getTargetClass() {
|
||||
return getInterfaceClass();
|
||||
}
|
||||
}
|
||||
|
||||
public void setInterfaceClass(Class<?> interfaceClass) {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ package org.apache.dubbo.config.spring.beans.factory.annotation;
|
|||
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.config.spring.util.AnnotationUtils;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.PropertyValues;
|
||||
|
|
@ -53,7 +55,6 @@ import java.util.List;
|
|||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import static com.alibaba.spring.util.AnnotationUtils.getAnnotationAttributes;
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_DUBBO_BEAN_INITIALIZER;
|
||||
import static org.springframework.core.BridgeMethodResolver.findBridgedMethod;
|
||||
import static org.springframework.core.BridgeMethodResolver.isVisibilityBridgeMethodPair;
|
||||
|
|
@ -135,7 +136,7 @@ public abstract class AbstractAnnotationBeanPostProcessor implements
|
|||
|
||||
for (Class<? extends Annotation> annotationType : getAnnotationTypes()) {
|
||||
|
||||
AnnotationAttributes attributes = getAnnotationAttributes(field, annotationType, getEnvironment(), true, true);
|
||||
AnnotationAttributes attributes = AnnotationUtils.getAnnotationAttributes(field, annotationType, getEnvironment(), true, true);
|
||||
|
||||
if (attributes != null) {
|
||||
|
||||
|
|
@ -180,7 +181,7 @@ public abstract class AbstractAnnotationBeanPostProcessor implements
|
|||
|
||||
for (Class<? extends Annotation> annotationType : getAnnotationTypes()) {
|
||||
|
||||
AnnotationAttributes attributes = getAnnotationAttributes(bridgedMethod, annotationType, getEnvironment(), true, true);
|
||||
AnnotationAttributes attributes = AnnotationUtils.getAnnotationAttributes(bridgedMethod, annotationType, getEnvironment(), true, true);
|
||||
|
||||
if (attributes != null && method.equals(ClassUtils.getMostSpecificMethod(method, beanClass))) {
|
||||
if (Modifier.isStatic(method.getModifiers())) {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
*/
|
||||
package org.apache.dubbo.config.spring.beans.factory.annotation;
|
||||
|
||||
import org.apache.dubbo.config.spring.util.AnnotationUtils;
|
||||
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.beans.PropertyValue;
|
||||
import org.springframework.beans.PropertyValues;
|
||||
|
|
@ -24,8 +26,6 @@ import org.springframework.core.env.PropertyResolver;
|
|||
import java.lang.annotation.Annotation;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.alibaba.spring.util.AnnotationUtils.getAttributes;
|
||||
|
||||
/**
|
||||
* {@link Annotation} {@link PropertyValues} Adapter
|
||||
*
|
||||
|
|
@ -45,12 +45,12 @@ public class AnnotationPropertyValuesAdapter implements PropertyValues {
|
|||
*/
|
||||
public AnnotationPropertyValuesAdapter(Map<String, Object> attributes, PropertyResolver propertyResolver,
|
||||
String... ignoreAttributeNames) {
|
||||
this.delegate = new MutablePropertyValues(getAttributes(attributes, propertyResolver, ignoreAttributeNames));
|
||||
this.delegate = new MutablePropertyValues(AnnotationUtils.getAttributes(attributes, propertyResolver, ignoreAttributeNames));
|
||||
}
|
||||
|
||||
public AnnotationPropertyValuesAdapter(Annotation annotation, PropertyResolver propertyResolver,
|
||||
boolean ignoreDefaultValue, String... ignoreAttributeNames) {
|
||||
this.delegate = new MutablePropertyValues(getAttributes(annotation, propertyResolver, ignoreDefaultValue, ignoreAttributeNames));
|
||||
this.delegate = new MutablePropertyValues(AnnotationUtils.getAttributes(annotation, propertyResolver, ignoreDefaultValue, ignoreAttributeNames));
|
||||
}
|
||||
|
||||
public AnnotationPropertyValuesAdapter(Annotation annotation, PropertyResolver propertyResolver, String... ignoreAttributeNames) {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package org.apache.dubbo.config.spring.beans.factory.annotation;
|
|||
|
||||
import org.apache.dubbo.config.AbstractConfig;
|
||||
import org.apache.dubbo.config.spring.context.annotation.DubboConfigConfigurationRegistrar;
|
||||
import org.apache.dubbo.config.spring.util.BeanRegistrar;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
|
|
@ -25,7 +26,6 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
|||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
|
||||
|
||||
import static com.alibaba.spring.util.BeanRegistrar.hasAlias;
|
||||
import static org.springframework.util.ObjectUtils.nullSafeEquals;
|
||||
import static org.springframework.util.StringUtils.hasText;
|
||||
|
||||
|
|
@ -65,7 +65,7 @@ public class DubboConfigAliasPostProcessor implements BeanDefinitionRegistryPost
|
|||
String id = ((AbstractConfig) bean).getId();
|
||||
if (hasText(id) // id MUST be present in AbstractConfig
|
||||
&& !nullSafeEquals(id, beanName) // id MUST NOT be equal to bean name
|
||||
&& !hasAlias(registry, beanName, id)) { // id MUST NOT be present in AliasRegistry
|
||||
&& !BeanRegistrar.hasAlias(registry, beanName, id)) { // id MUST NOT be present in AliasRegistry
|
||||
registry.registerAlias(beanName, id);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,8 +31,10 @@ import org.apache.dubbo.config.spring.context.event.DubboConfigInitEvent;
|
|||
import org.apache.dubbo.config.spring.reference.ReferenceAttributes;
|
||||
import org.apache.dubbo.config.spring.reference.ReferenceBeanManager;
|
||||
import org.apache.dubbo.config.spring.reference.ReferenceBeanSupport;
|
||||
import org.apache.dubbo.config.spring.util.AnnotationUtils;
|
||||
import org.apache.dubbo.config.spring.util.SpringCompatUtils;
|
||||
import org.apache.dubbo.rpc.service.GenericService;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.PropertyValue;
|
||||
import org.springframework.beans.PropertyValues;
|
||||
|
|
@ -65,7 +67,6 @@ import java.util.Map;
|
|||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import static com.alibaba.spring.util.AnnotationUtils.getAttribute;
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_DUBBO_BEAN_INITIALIZER;
|
||||
import static org.apache.dubbo.common.utils.AnnotationUtils.filterDefaultValues;
|
||||
import static org.springframework.util.StringUtils.hasText;
|
||||
|
|
@ -385,7 +386,7 @@ public class ReferenceAnnotationBeanPostProcessor extends AbstractAnnotationBean
|
|||
|
||||
boolean renameable = true;
|
||||
// referenceBeanName
|
||||
String referenceBeanName = getAttribute(attributes, ReferenceAttributes.ID);
|
||||
String referenceBeanName = AnnotationUtils.getAttribute(attributes, ReferenceAttributes.ID);
|
||||
if (hasText(referenceBeanName)) {
|
||||
renameable = false;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -16,9 +16,9 @@
|
|||
*/
|
||||
package org.apache.dubbo.config.spring.beans.factory.annotation;
|
||||
|
||||
import com.alibaba.spring.util.AnnotationUtils;
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.utils.AnnotationUtils;
|
||||
import org.apache.dubbo.common.utils.ClassUtils;
|
||||
import org.apache.dubbo.common.utils.ReflectUtils;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
|
|
@ -32,7 +32,9 @@ import org.apache.dubbo.config.spring.aot.AotWithSpringDetector;
|
|||
import org.apache.dubbo.config.spring.context.annotation.DubboClassPathBeanDefinitionScanner;
|
||||
import org.apache.dubbo.config.spring.schema.AnnotationBeanDefinitionParser;
|
||||
import org.apache.dubbo.config.spring.util.DubboAnnotationUtils;
|
||||
import org.apache.dubbo.config.spring.util.ObjectUtils;
|
||||
import org.apache.dubbo.config.spring.util.SpringCompatUtils;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
|
|
@ -80,7 +82,6 @@ import java.util.Objects;
|
|||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.alibaba.spring.util.ObjectUtils.of;
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_DUPLICATED_BEAN_DEFINITION;
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_NO_ANNOTATIONS_FOUND;
|
||||
|
|
@ -431,7 +432,7 @@ public class ServiceAnnotationPostProcessor implements BeanDefinitionRegistryPos
|
|||
|
||||
MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();
|
||||
|
||||
String[] ignoreAttributeNames = of("provider", "monitor", "application", "module", "registry", "protocol",
|
||||
String[] ignoreAttributeNames = ObjectUtils.of("provider", "monitor", "application", "module", "registry", "protocol",
|
||||
"methods", "interfaceName", "parameters", "executor");
|
||||
|
||||
propertyValues.addPropertyValues(new AnnotationPropertyValuesAdapter(serviceAnnotationAttributes, environment, ignoreAttributeNames));
|
||||
|
|
|
|||
|
|
@ -20,12 +20,12 @@ import org.apache.dubbo.config.annotation.Reference;
|
|||
import org.apache.dubbo.config.annotation.Service;
|
||||
import org.apache.dubbo.config.spring.ReferenceBean;
|
||||
import org.apache.dubbo.config.spring.ServiceBean;
|
||||
import org.apache.dubbo.config.spring.util.AnnotationUtils;
|
||||
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static com.alibaba.spring.util.AnnotationUtils.getAttribute;
|
||||
import static org.apache.dubbo.config.spring.util.DubboAnnotationUtils.resolveInterfaceName;
|
||||
import static org.springframework.core.annotation.AnnotationUtils.getAnnotationAttributes;
|
||||
|
||||
|
|
@ -63,8 +63,8 @@ public class ServiceBeanNameBuilder {
|
|||
|
||||
private ServiceBeanNameBuilder(AnnotationAttributes attributes, Class<?> defaultInterfaceClass, Environment environment) {
|
||||
this(resolveInterfaceName(attributes, defaultInterfaceClass), environment);
|
||||
this.group(getAttribute(attributes,"group"));
|
||||
this.version(getAttribute(attributes,"version"));
|
||||
this.group(AnnotationUtils.getAttribute(attributes,"group"));
|
||||
this.version(AnnotationUtils.getAttribute(attributes,"version"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -18,8 +18,9 @@ package org.apache.dubbo.config.spring.beans.factory.config;
|
|||
|
||||
import org.apache.dubbo.config.AbstractConfig;
|
||||
import org.apache.dubbo.config.Constants;
|
||||
import org.apache.dubbo.config.spring.util.GenericBeanPostProcessorAdapter;
|
||||
import org.apache.dubbo.config.spring.util.ObjectUtils;
|
||||
|
||||
import com.alibaba.spring.beans.factory.config.GenericBeanPostProcessorAdapter;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
|
|
@ -34,7 +35,6 @@ import java.beans.PropertyDescriptor;
|
|||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static com.alibaba.spring.util.ObjectUtils.of;
|
||||
import static org.springframework.aop.support.AopUtils.getTargetClass;
|
||||
import static org.springframework.beans.BeanUtils.getPropertyDescriptor;
|
||||
import static org.springframework.util.ReflectionUtils.invokeMethod;
|
||||
|
|
@ -91,7 +91,7 @@ public class DubboConfigDefaultPropertyValueBeanPostProcessor extends GenericBea
|
|||
|
||||
Method setterMethod = propertyDescriptor.getWriteMethod();
|
||||
if (setterMethod != null) { // the getter and setter methods are present
|
||||
if (Arrays.equals(of(String.class), setterMethod.getParameterTypes())) { // the param type is String
|
||||
if (Arrays.equals(ObjectUtils.of(String.class), setterMethod.getParameterTypes())) { // the param type is String
|
||||
// set bean name to the value of the property
|
||||
invokeMethod(setterMethod, bean, beanName);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,11 +16,6 @@
|
|||
*/
|
||||
package org.apache.dubbo.config.spring.context;
|
||||
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_STOP_DUBBO_ERROR;
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_FAILED_START_MODEL;
|
||||
import static org.springframework.util.ObjectUtils.nullSafeEquals;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
import org.apache.dubbo.common.deploy.DeployListenerAdapter;
|
||||
import org.apache.dubbo.common.deploy.DeployState;
|
||||
import org.apache.dubbo.common.deploy.ModuleDeployer;
|
||||
|
|
@ -28,10 +23,12 @@ import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
|||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.utils.Assert;
|
||||
import org.apache.dubbo.config.spring.context.event.DubboApplicationStateEvent;
|
||||
import org.apache.dubbo.config.spring.context.event.DubboModuleStateEvent;
|
||||
import org.apache.dubbo.config.spring.util.DubboBeanUtils;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ModelConstants;
|
||||
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
|
|
@ -41,6 +38,12 @@ import org.springframework.context.event.ContextClosedEvent;
|
|||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_FAILED_START_MODEL;
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_STOP_DUBBO_ERROR;
|
||||
import static org.springframework.util.ObjectUtils.nullSafeEquals;
|
||||
|
||||
/**
|
||||
* An ApplicationListener to control Dubbo application.
|
||||
*/
|
||||
|
|
@ -62,39 +65,73 @@ public class DubboDeployApplicationListener implements ApplicationListener<Appli
|
|||
applicationModel.getDeployer().addDeployListener(new DeployListenerAdapter<ApplicationModel>(){
|
||||
@Override
|
||||
public void onStarting(ApplicationModel scopeModel) {
|
||||
publishEvent(DeployState.STARTING);
|
||||
publishApplicationEvent(DeployState.STARTING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStarted(ApplicationModel scopeModel) {
|
||||
publishEvent(DeployState.STARTED);
|
||||
publishApplicationEvent(DeployState.STARTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopping(ApplicationModel scopeModel) {
|
||||
publishEvent(DeployState.STOPPING);
|
||||
publishApplicationEvent(DeployState.STOPPING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopped(ApplicationModel scopeModel) {
|
||||
publishEvent(DeployState.STOPPED);
|
||||
publishApplicationEvent(DeployState.STOPPED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(ApplicationModel scopeModel, Throwable cause) {
|
||||
publishEvent(DeployState.FAILED, cause);
|
||||
publishApplicationEvent(DeployState.FAILED, cause);
|
||||
}
|
||||
});
|
||||
moduleModel.getDeployer().addDeployListener(new DeployListenerAdapter<ModuleModel>(){
|
||||
@Override
|
||||
public void onStarting(ModuleModel scopeModel) {
|
||||
publishModuleEvent(DeployState.STARTING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStarted(ModuleModel scopeModel) {
|
||||
publishModuleEvent(DeployState.STARTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopping(ModuleModel scopeModel) {
|
||||
publishModuleEvent(DeployState.STOPPING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopped(ModuleModel scopeModel) {
|
||||
publishModuleEvent(DeployState.STOPPED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(ModuleModel scopeModel, Throwable cause) {
|
||||
publishModuleEvent(DeployState.FAILED, cause);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void publishEvent(DeployState state) {
|
||||
private void publishApplicationEvent(DeployState state) {
|
||||
applicationContext.publishEvent(new DubboApplicationStateEvent(applicationModel, state));
|
||||
}
|
||||
|
||||
private void publishEvent(DeployState state, Throwable cause) {
|
||||
private void publishApplicationEvent(DeployState state, Throwable cause) {
|
||||
applicationContext.publishEvent(new DubboApplicationStateEvent(applicationModel, state, cause));
|
||||
}
|
||||
|
||||
private void publishModuleEvent(DeployState state) {
|
||||
applicationContext.publishEvent(new DubboModuleStateEvent(moduleModel, state));
|
||||
}
|
||||
|
||||
private void publishModuleEvent(DeployState state, Throwable cause) {
|
||||
applicationContext.publishEvent(new DubboModuleStateEvent(moduleModel, state, cause));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationContextEvent event) {
|
||||
if (nullSafeEquals(applicationContext, event.getSource())) {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package org.apache.dubbo.config.spring.context.config;
|
|||
|
||||
import org.apache.dubbo.config.AbstractConfig;
|
||||
import org.apache.dubbo.config.spring.beans.factory.config.DubboConfigDefaultPropertyValueBeanPostProcessor;
|
||||
import org.apache.dubbo.config.spring.util.ObjectUtils;
|
||||
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
|
|
@ -25,7 +26,6 @@ import java.beans.PropertyDescriptor;
|
|||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static com.alibaba.spring.util.ObjectUtils.of;
|
||||
import static org.springframework.beans.BeanUtils.getPropertyDescriptor;
|
||||
|
||||
/**
|
||||
|
|
@ -71,7 +71,7 @@ public class NamePropertyDefaultValueDubboConfigBeanCustomizer implements DubboC
|
|||
|
||||
Method setNameMethod = propertyDescriptor.getWriteMethod();
|
||||
if (setNameMethod != null) { // "setName" and "getName" methods are present
|
||||
if (Arrays.equals(of(String.class), setNameMethod.getParameterTypes())) { // the param type is String
|
||||
if (Arrays.equals(ObjectUtils.of(String.class), setNameMethod.getParameterTypes())) { // the param type is String
|
||||
// set bean name to the value of the "name" property
|
||||
ReflectionUtils.invokeMethod(setNameMethod, dubboConfigBean, beanName);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.config.spring.context.event;
|
||||
|
||||
import org.apache.dubbo.common.deploy.DeployState;
|
||||
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
/**
|
||||
* Dubbo's module state event on starting/started/stopping/stopped
|
||||
*/
|
||||
public class DubboModuleStateEvent extends ApplicationEvent {
|
||||
|
||||
private final DeployState state;
|
||||
|
||||
private Throwable cause;
|
||||
|
||||
public DubboModuleStateEvent(ModuleModel applicationModel, DeployState state) {
|
||||
super(applicationModel);
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public DubboModuleStateEvent(ModuleModel applicationModel, DeployState state, Throwable cause) {
|
||||
super(applicationModel);
|
||||
this.state = state;
|
||||
this.cause = cause;
|
||||
}
|
||||
|
||||
public ModuleModel getModule() {
|
||||
return (ModuleModel) getSource();
|
||||
}
|
||||
|
||||
public DeployState getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public Throwable getCause() {
|
||||
return cause;
|
||||
}
|
||||
}
|
||||
|
|
@ -17,6 +17,7 @@
|
|||
package org.apache.dubbo.config.spring.context.properties;
|
||||
|
||||
import org.apache.dubbo.config.AbstractConfig;
|
||||
import org.apache.dubbo.config.spring.util.PropertySourcesUtils;
|
||||
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.validation.BindingResult;
|
||||
|
|
@ -27,8 +28,6 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import static com.alibaba.spring.util.PropertySourcesUtils.getSubProperties;
|
||||
|
||||
/**
|
||||
* Default {@link DubboConfigBinder} implementation based on Spring {@link DataBinder}
|
||||
*/
|
||||
|
|
@ -41,7 +40,7 @@ public class DefaultDubboConfigBinder extends AbstractDubboConfigBinder {
|
|||
dataBinder.setIgnoreInvalidFields(isIgnoreInvalidFields());
|
||||
dataBinder.setIgnoreUnknownFields(isIgnoreUnknownFields());
|
||||
// Get properties under specified prefix from PropertySources
|
||||
Map<String, Object> properties = getSubProperties(getPropertySources(), prefix);
|
||||
Map<String, Object> properties = PropertySourcesUtils.getSubProperties(getPropertySources(), prefix);
|
||||
// Convert Map to MutablePropertyValues
|
||||
MutablePropertyValues propertyValues = new MutablePropertyValues(properties);
|
||||
// Bind
|
||||
|
|
|
|||
|
|
@ -16,15 +16,16 @@
|
|||
*/
|
||||
package org.apache.dubbo.config.spring.reference;
|
||||
|
||||
import com.alibaba.spring.util.AnnotationUtils;
|
||||
import org.apache.dubbo.common.utils.Assert;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.config.annotation.ProvidedBy;
|
||||
import org.apache.dubbo.config.spring.Constants;
|
||||
import org.apache.dubbo.config.spring.ReferenceBean;
|
||||
import org.apache.dubbo.config.spring.aot.AotWithSpringDetector;
|
||||
import org.apache.dubbo.config.spring.util.AnnotationUtils;
|
||||
import org.apache.dubbo.config.spring.util.DubboAnnotationUtils;
|
||||
import org.apache.dubbo.rpc.service.GenericService;
|
||||
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.beans.PropertyValue;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
|
|
|
|||
|
|
@ -29,11 +29,12 @@ import org.apache.dubbo.config.annotation.Argument;
|
|||
import org.apache.dubbo.config.annotation.DubboReference;
|
||||
import org.apache.dubbo.config.annotation.Method;
|
||||
import org.apache.dubbo.config.spring.beans.factory.annotation.AnnotationPropertyValuesAdapter;
|
||||
import org.apache.dubbo.config.spring.util.AnnotationUtils;
|
||||
import org.apache.dubbo.config.spring.util.DubboAnnotationUtils;
|
||||
import org.apache.dubbo.config.spring.util.DubboBeanUtils;
|
||||
import org.apache.dubbo.config.spring.util.ObjectUtils;
|
||||
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
|
||||
import com.alibaba.spring.util.AnnotationUtils;
|
||||
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
|
|
@ -43,9 +44,6 @@ import org.springframework.validation.DataBinder;
|
|||
|
||||
import java.util.Map;
|
||||
|
||||
import static com.alibaba.spring.util.AnnotationUtils.getAttribute;
|
||||
import static com.alibaba.spring.util.ObjectUtils.of;
|
||||
|
||||
/**
|
||||
* {@link ReferenceConfig} Creator for @{@link DubboReference}
|
||||
*
|
||||
|
|
@ -54,7 +52,7 @@ import static com.alibaba.spring.util.ObjectUtils.of;
|
|||
public class ReferenceCreator {
|
||||
|
||||
// Ignore those fields
|
||||
static final String[] IGNORE_FIELD_NAMES = of("application", "module", "consumer", "monitor", "registry", "interfaceClass");
|
||||
static final String[] IGNORE_FIELD_NAMES = ObjectUtils.of("application", "module", "consumer", "monitor", "registry", "interfaceClass");
|
||||
|
||||
private static final String ONRETURN = "onreturn";
|
||||
|
||||
|
|
@ -117,7 +115,7 @@ public class ReferenceCreator {
|
|||
}
|
||||
|
||||
private void configureMonitorConfig(ReferenceConfig configBean) {
|
||||
String monitorConfigId = getAttribute(attributes, "monitor");
|
||||
String monitorConfigId = AnnotationUtils.getAttribute(attributes, "monitor");
|
||||
if (StringUtils.hasText(monitorConfigId)) {
|
||||
MonitorConfig monitorConfig = getConfig(monitorConfigId, MonitorConfig.class);
|
||||
configBean.setMonitor(monitorConfig);
|
||||
|
|
@ -125,7 +123,7 @@ public class ReferenceCreator {
|
|||
}
|
||||
|
||||
private void configureModuleConfig(ReferenceConfig configBean) {
|
||||
String moduleConfigId = getAttribute(attributes, "module");
|
||||
String moduleConfigId = AnnotationUtils.getAttribute(attributes, "module");
|
||||
if (StringUtils.hasText(moduleConfigId)) {
|
||||
ModuleConfig moduleConfig = getConfig(moduleConfigId, ModuleConfig.class);
|
||||
configBean.setModule(moduleConfig);
|
||||
|
|
@ -134,7 +132,7 @@ public class ReferenceCreator {
|
|||
|
||||
private void configureConsumerConfig(ReferenceConfig<?> referenceBean) {
|
||||
ConsumerConfig consumerConfig = null;
|
||||
Object consumer = getAttribute(attributes, "consumer");
|
||||
Object consumer = AnnotationUtils.getAttribute(attributes, "consumer");
|
||||
if (consumer != null) {
|
||||
if (consumer instanceof String) {
|
||||
consumerConfig = getConfig((String) consumer, ConsumerConfig.class);
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ import org.apache.dubbo.config.ProviderConfig;
|
|||
import org.apache.dubbo.config.ReferenceConfig;
|
||||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.config.nested.AggregationConfig;
|
||||
import org.apache.dubbo.config.nested.PrometheusConfig;
|
||||
import org.apache.dubbo.config.nested.HistogramConfig;
|
||||
import org.apache.dubbo.config.nested.PrometheusConfig;
|
||||
import org.apache.dubbo.config.spring.Constants;
|
||||
import org.apache.dubbo.config.spring.ReferenceBean;
|
||||
import org.apache.dubbo.config.spring.ServiceBean;
|
||||
|
|
@ -103,9 +103,11 @@ public class DubboBeanDefinitionParser implements BeanDefinitionParser {
|
|||
if (StringUtils.isNotEmpty(configId)) {
|
||||
beanDefinition.getPropertyValues().addPropertyValue("id", configId);
|
||||
}
|
||||
// get id from name
|
||||
|
||||
String configName = "";
|
||||
// get configName from name
|
||||
if (StringUtils.isEmpty(configId)) {
|
||||
configId = resolveAttribute(element, "name", parserContext);
|
||||
configName = resolveAttribute(element, "name", parserContext);
|
||||
}
|
||||
|
||||
String beanName = configId;
|
||||
|
|
@ -113,13 +115,14 @@ public class DubboBeanDefinitionParser implements BeanDefinitionParser {
|
|||
// generate bean name
|
||||
String prefix = beanClass.getName();
|
||||
int counter = 0;
|
||||
beanName = prefix + "#" + counter;
|
||||
beanName = prefix + (StringUtils.isEmpty(configName) ? "#" : ("#" + configName + "#")) + counter;
|
||||
while (parserContext.getRegistry().containsBeanDefinition(beanName)) {
|
||||
beanName = prefix + "#" + (counter++);
|
||||
beanName = prefix + (StringUtils.isEmpty(configName) ? "#" : ("#" + configName + "#")) + (counter++);
|
||||
}
|
||||
}
|
||||
beanDefinition.setAttribute(BEAN_NAME, beanName);
|
||||
|
||||
|
||||
if (ProtocolConfig.class.equals(beanClass)) {
|
||||
// for (String name : parserContext.getRegistry().getBeanDefinitionNames()) {
|
||||
// BeanDefinition definition = parserContext.getRegistry().getBeanDefinition(name);
|
||||
|
|
@ -184,7 +187,7 @@ public class DubboBeanDefinitionParser implements BeanDefinitionParser {
|
|||
* For 'provider' 'protocol' 'registry', keep literal value (should be id/name) and set the value to 'registryIds' 'providerIds' protocolIds'
|
||||
* The following process should make sure each id refers to the corresponding instance, here's how to find the instance for different use cases:
|
||||
* 1. Spring, check existing bean by id, see{@link ServiceBean#afterPropertiesSet()}; then try to use id to find configs defined in remote Config Center
|
||||
* 2. API, directly use id to find configs defined in remote Config Center; if all config instances are defined locally, please use {@link ServiceConfig#setRegistries(List)}
|
||||
* 2. API, directly use id to find configs defined in remote Config Center; if all config instances are defined locally, please use {@link org.apache.dubbo.config.ServiceConfig#setRegistries(List)}
|
||||
*/
|
||||
beanDefinition.getPropertyValues().addPropertyValue(beanProperty + "Ids", value);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,437 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.config.spring.util;
|
||||
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.PropertyResolver;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static java.lang.String.valueOf;
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.springframework.core.annotation.AnnotationAttributes.fromMap;
|
||||
import static org.springframework.core.annotation.AnnotationUtils.getDefaultValue;
|
||||
import static org.springframework.util.ClassUtils.resolveClassName;
|
||||
import static org.springframework.util.CollectionUtils.isEmpty;
|
||||
import static org.springframework.util.ObjectUtils.nullSafeEquals;
|
||||
import static org.springframework.util.ReflectionUtils.findMethod;
|
||||
import static org.springframework.util.ReflectionUtils.invokeMethod;
|
||||
import static org.springframework.util.StringUtils.trimWhitespace;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public abstract class AnnotationUtils {
|
||||
|
||||
/**
|
||||
* The class name of AnnotatedElementUtils that is introduced since Spring Framework 4
|
||||
*/
|
||||
public static final String ANNOTATED_ELEMENT_UTILS_CLASS_NAME = "org.springframework.core.annotation.AnnotatedElementUtils";
|
||||
|
||||
private static final Map<Integer, Boolean> annotatedElementUtilsPresentCache = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Get the {@link Annotation} attributes
|
||||
*
|
||||
* @param annotation specified {@link Annotation}
|
||||
* @param propertyResolver {@link PropertyResolver} instance, e.g {@link Environment}
|
||||
* @param ignoreDefaultValue whether ignore default value or not
|
||||
* @param ignoreAttributeNames the attribute names of annotation should be ignored
|
||||
* @return non-null
|
||||
*/
|
||||
public static Map<String, Object> getAttributes(Annotation annotation, PropertyResolver propertyResolver,
|
||||
boolean ignoreDefaultValue, String... ignoreAttributeNames) {
|
||||
return getAttributes(annotation, propertyResolver, false, false, ignoreDefaultValue, ignoreAttributeNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link Annotation} attributes
|
||||
*
|
||||
* @param annotationAttributes the attributes of specified {@link Annotation}
|
||||
* @param propertyResolver {@link PropertyResolver} instance, e.g {@link Environment}
|
||||
* @param ignoreAttributeNames the attribute names of annotation should be ignored
|
||||
* @return non-null
|
||||
*/
|
||||
public static Map<String, Object> getAttributes(Map<String, Object> annotationAttributes,
|
||||
PropertyResolver propertyResolver, String... ignoreAttributeNames) {
|
||||
|
||||
Set<String> ignoreAttributeNamesSet = new HashSet<>(Arrays.asList(ignoreAttributeNames));
|
||||
|
||||
Map<String, Object> actualAttributes = new LinkedHashMap<String, Object>();
|
||||
|
||||
for (Map.Entry<String, Object> annotationAttribute : annotationAttributes.entrySet()) {
|
||||
|
||||
String attributeName = annotationAttribute.getKey();
|
||||
Object attributeValue = annotationAttribute.getValue();
|
||||
|
||||
// ignore attribute name
|
||||
if (ignoreAttributeNamesSet.contains(attributeName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (attributeValue instanceof String) {
|
||||
attributeValue = resolvePlaceholders(valueOf(attributeValue), propertyResolver);
|
||||
} else if (attributeValue instanceof String[]) {
|
||||
String[] values = (String[]) attributeValue;
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
values[i] = resolvePlaceholders(values[i], propertyResolver);
|
||||
}
|
||||
attributeValue = values;
|
||||
}
|
||||
actualAttributes.put(attributeName, attributeValue);
|
||||
}
|
||||
return actualAttributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param annotation specified {@link Annotation}
|
||||
* @param propertyResolver {@link PropertyResolver} instance, e.g {@link Environment}
|
||||
* @param classValuesAsString whether to turn Class references into Strings (for
|
||||
* compatibility with {@link org.springframework.core.type.AnnotationMetadata} or to
|
||||
* preserve them as Class references
|
||||
* @param nestedAnnotationsAsMap whether to turn nested Annotation instances into
|
||||
* {@link AnnotationAttributes} maps (for compatibility with
|
||||
* {@link org.springframework.core.type.AnnotationMetadata} or to preserve them as
|
||||
* Annotation instances
|
||||
* @param ignoreDefaultValue whether ignore default value or not
|
||||
* @param ignoreAttributeNames the attribute names of annotation should be ignored
|
||||
* @return
|
||||
*/
|
||||
public static Map<String, Object> getAttributes(Annotation annotation,
|
||||
PropertyResolver propertyResolver,
|
||||
boolean classValuesAsString,
|
||||
boolean nestedAnnotationsAsMap,
|
||||
boolean ignoreDefaultValue,
|
||||
String... ignoreAttributeNames) {
|
||||
|
||||
Map<String, Object> annotationAttributes = org.springframework.core.annotation.AnnotationUtils.getAnnotationAttributes(annotation, classValuesAsString, nestedAnnotationsAsMap);
|
||||
|
||||
String[] actualIgnoreAttributeNames = ignoreAttributeNames;
|
||||
|
||||
if (ignoreDefaultValue && !isEmpty(annotationAttributes)) {
|
||||
|
||||
List<String> attributeNamesToIgnore = new LinkedList<String>(asList(ignoreAttributeNames));
|
||||
|
||||
for (Map.Entry<String, Object> annotationAttribute : annotationAttributes.entrySet()) {
|
||||
String attributeName = annotationAttribute.getKey();
|
||||
Object attributeValue = annotationAttribute.getValue();
|
||||
if (nullSafeEquals(attributeValue, getDefaultValue(annotation, attributeName))) {
|
||||
attributeNamesToIgnore.add(attributeName);
|
||||
}
|
||||
}
|
||||
// extends the ignored list
|
||||
actualIgnoreAttributeNames = attributeNamesToIgnore.toArray(new String[attributeNamesToIgnore.size()]);
|
||||
}
|
||||
|
||||
return getAttributes(annotationAttributes, propertyResolver, actualIgnoreAttributeNames);
|
||||
}
|
||||
|
||||
private static String resolvePlaceholders(String attributeValue, PropertyResolver propertyResolver) {
|
||||
String resolvedValue = attributeValue;
|
||||
if (propertyResolver != null) {
|
||||
resolvedValue = propertyResolver.resolvePlaceholders(resolvedValue);
|
||||
resolvedValue = trimWhitespace(resolvedValue);
|
||||
}
|
||||
return resolvedValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value
|
||||
*
|
||||
* @param attributes {@link Map the annotation attributes} or {@link AnnotationAttributes}
|
||||
* @param attributeName the name of attribute
|
||||
* @param <T> the type of attribute value
|
||||
* @return the attribute value if found
|
||||
*/
|
||||
public static <T> T getAttribute(Map<String, Object> attributes, String attributeName) {
|
||||
return getAttribute(attributes, attributeName, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value the will
|
||||
*
|
||||
* @param attributes {@link Map the annotation attributes} or {@link AnnotationAttributes}
|
||||
* @param attributeName the name of attribute
|
||||
* @param required the required attribute or not
|
||||
* @param <T> the type of attribute value
|
||||
* @return the attribute value if found
|
||||
* @throws IllegalStateException if attribute value can't be found
|
||||
*/
|
||||
public static <T> T getAttribute(Map<String, Object> attributes, String attributeName, boolean required) {
|
||||
T value = getAttribute(attributes, attributeName, null);
|
||||
if (required && value == null) {
|
||||
throw new IllegalStateException("The attribute['" + attributeName + "] is required!");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value with default value
|
||||
*
|
||||
* @param attributes {@link Map the annotation attributes} or {@link AnnotationAttributes}
|
||||
* @param attributeName the name of attribute
|
||||
* @param defaultValue the default value of attribute
|
||||
* @param <T> the type of attribute value
|
||||
* @return the attribute value if found
|
||||
*/
|
||||
public static <T> T getAttribute(Map<String, Object> attributes, String attributeName, T defaultValue) {
|
||||
T value = (T) attributes.get(attributeName);
|
||||
return value == null ? defaultValue : value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required attribute value
|
||||
*
|
||||
* @param attributes {@link Map the annotation attributes} or {@link AnnotationAttributes}
|
||||
* @param attributeName the name of attribute
|
||||
* @param <T> the type of attribute value
|
||||
* @return the attribute value if found
|
||||
* @throws IllegalStateException if attribute value can't be found
|
||||
*/
|
||||
public static <T> T getRequiredAttribute(Map<String, Object> attributes, String attributeName) {
|
||||
return getAttribute(attributes, attributeName, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link AnnotationAttributes}
|
||||
*
|
||||
* @param annotation specified {@link Annotation}
|
||||
* @param ignoreDefaultValue whether ignore default value or not
|
||||
* @param ignoreAttributeNames the attribute names of annotation should be ignored
|
||||
* @return non-null
|
||||
* @see #getAnnotationAttributes(Annotation, PropertyResolver, boolean, String...)
|
||||
*/
|
||||
public static AnnotationAttributes getAnnotationAttributes(Annotation annotation, boolean ignoreDefaultValue,
|
||||
String... ignoreAttributeNames) {
|
||||
return getAnnotationAttributes(annotation, null, ignoreDefaultValue, ignoreAttributeNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link AnnotationAttributes}
|
||||
*
|
||||
* @param annotation specified {@link Annotation}
|
||||
* @param propertyResolver {@link PropertyResolver} instance, e.g {@link Environment}
|
||||
* @param classValuesAsString whether to turn Class references into Strings (for
|
||||
* compatibility with {@link org.springframework.core.type.AnnotationMetadata} or to
|
||||
* preserve them as Class references
|
||||
* @param nestedAnnotationsAsMap whether to turn nested Annotation instances into
|
||||
* {@link AnnotationAttributes} maps (for compatibility with
|
||||
* {@link org.springframework.core.type.AnnotationMetadata} or to preserve them as
|
||||
* Annotation instances
|
||||
* @param ignoreAttributeNames the attribute names of annotation should be ignored
|
||||
* @param ignoreDefaultValue whether ignore default value or not
|
||||
* @return non-null
|
||||
* @see #getAttributes(Annotation, PropertyResolver, boolean, String...)
|
||||
* @see #getAnnotationAttributes(AnnotatedElement, Class, PropertyResolver, boolean, String...)
|
||||
*/
|
||||
public static AnnotationAttributes getAnnotationAttributes(Annotation annotation,
|
||||
PropertyResolver propertyResolver,
|
||||
boolean classValuesAsString,
|
||||
boolean nestedAnnotationsAsMap,
|
||||
boolean ignoreDefaultValue,
|
||||
String... ignoreAttributeNames) {
|
||||
return fromMap(getAttributes(annotation, propertyResolver, classValuesAsString, nestedAnnotationsAsMap,
|
||||
ignoreDefaultValue, ignoreAttributeNames));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link AnnotationAttributes}
|
||||
*
|
||||
* @param annotation specified {@link Annotation}
|
||||
* @param propertyResolver {@link PropertyResolver} instance, e.g {@link Environment}
|
||||
* @param ignoreDefaultValue whether ignore default value or not
|
||||
* @param ignoreAttributeNames the attribute names of annotation should be ignored
|
||||
* @return non-null
|
||||
* @see #getAttributes(Annotation, PropertyResolver, boolean, String...)
|
||||
* @see #getAnnotationAttributes(AnnotatedElement, Class, PropertyResolver, boolean, String...)
|
||||
*/
|
||||
public static AnnotationAttributes getAnnotationAttributes(Annotation annotation, PropertyResolver propertyResolver,
|
||||
boolean ignoreDefaultValue, String... ignoreAttributeNames) {
|
||||
return getAnnotationAttributes(annotation, propertyResolver, false, false, ignoreDefaultValue, ignoreAttributeNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link AnnotationAttributes}
|
||||
*
|
||||
* @param annotatedElement {@link AnnotatedElement the annotated element}
|
||||
* @param annotationType the {@link Class tyoe} pf {@link Annotation annotation}
|
||||
* @param propertyResolver {@link PropertyResolver} instance, e.g {@link Environment}
|
||||
* @param ignoreDefaultValue whether ignore default value or not
|
||||
* @param ignoreAttributeNames the attribute names of annotation should be ignored
|
||||
* @return if <code>annotatedElement</code> can't be found in <code>annotatedElement</code>, return <code>null</code>
|
||||
*/
|
||||
public static AnnotationAttributes getAnnotationAttributes(AnnotatedElement annotatedElement,
|
||||
Class<? extends Annotation> annotationType,
|
||||
PropertyResolver propertyResolver,
|
||||
boolean classValuesAsString,
|
||||
boolean nestedAnnotationsAsMap,
|
||||
boolean ignoreDefaultValue,
|
||||
String... ignoreAttributeNames) {
|
||||
Annotation annotation = annotatedElement.getAnnotation(annotationType);
|
||||
return annotation == null ? null : getAnnotationAttributes(annotation, propertyResolver,
|
||||
classValuesAsString, nestedAnnotationsAsMap, ignoreDefaultValue, ignoreAttributeNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link AnnotationAttributes}, if the argument <code>tryMergedAnnotation</code> is <code>true</code>,
|
||||
* the {@link AnnotationAttributes} will be got from
|
||||
* {@link #tryGetMergedAnnotationAttributes(AnnotatedElement, Class, PropertyResolver, boolean, String...) merged annotation} first,
|
||||
* if failed, and then to get from
|
||||
* {@link #getAnnotationAttributes(AnnotatedElement, Class, PropertyResolver, boolean, boolean, String...) normal one}
|
||||
*
|
||||
* @param annotatedElement {@link AnnotatedElement the annotated element}
|
||||
* @param annotationType the {@link Class tyoe} pf {@link Annotation annotation}
|
||||
* @param propertyResolver {@link PropertyResolver} instance, e.g {@link Environment}
|
||||
* @param ignoreDefaultValue whether ignore default value or not
|
||||
* @param tryMergedAnnotation whether try merged annotation or not
|
||||
* @param ignoreAttributeNames the attribute names of annotation should be ignored
|
||||
* @return if <code>annotatedElement</code> can't be found in <code>annotatedElement</code>, return <code>null</code>
|
||||
*/
|
||||
public static AnnotationAttributes getAnnotationAttributes(AnnotatedElement annotatedElement,
|
||||
Class<? extends Annotation> annotationType,
|
||||
PropertyResolver propertyResolver,
|
||||
boolean ignoreDefaultValue,
|
||||
boolean tryMergedAnnotation,
|
||||
String... ignoreAttributeNames) {
|
||||
return getAnnotationAttributes(annotatedElement, annotationType, propertyResolver,
|
||||
false, false, ignoreDefaultValue, tryMergedAnnotation, ignoreAttributeNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link AnnotationAttributes}, if the argument <code>tryMergedAnnotation</code> is <code>true</code>,
|
||||
* the {@link AnnotationAttributes} will be got from
|
||||
* {@link #tryGetMergedAnnotationAttributes(AnnotatedElement, Class, PropertyResolver, boolean, String...) merged annotation} first,
|
||||
* if failed, and then to get from
|
||||
* {@link #getAnnotationAttributes(AnnotatedElement, Class, PropertyResolver, boolean, boolean, String...) normal one}
|
||||
*
|
||||
* @param annotatedElement {@link AnnotatedElement the annotated element}
|
||||
* @param annotationType the {@link Class tyoe} pf {@link Annotation annotation}
|
||||
* @param propertyResolver {@link PropertyResolver} instance, e.g {@link Environment}
|
||||
* @param classValuesAsString whether to turn Class references into Strings (for
|
||||
* compatibility with {@link org.springframework.core.type.AnnotationMetadata} or to
|
||||
* preserve them as Class references
|
||||
* @param nestedAnnotationsAsMap whether to turn nested Annotation instances into
|
||||
* {@link AnnotationAttributes} maps (for compatibility with
|
||||
* {@link org.springframework.core.type.AnnotationMetadata} or to preserve them as
|
||||
* Annotation instances
|
||||
* @param ignoreDefaultValue whether ignore default value or not
|
||||
* @param tryMergedAnnotation whether try merged annotation or not
|
||||
* @param ignoreAttributeNames the attribute names of annotation should be ignored
|
||||
* @return if <code>annotatedElement</code> can't be found in <code>annotatedElement</code>, return <code>null</code>
|
||||
*/
|
||||
public static AnnotationAttributes getAnnotationAttributes(AnnotatedElement annotatedElement,
|
||||
Class<? extends Annotation> annotationType,
|
||||
PropertyResolver propertyResolver,
|
||||
boolean classValuesAsString,
|
||||
boolean nestedAnnotationsAsMap,
|
||||
boolean ignoreDefaultValue,
|
||||
boolean tryMergedAnnotation,
|
||||
String... ignoreAttributeNames) {
|
||||
|
||||
AnnotationAttributes attributes = null;
|
||||
|
||||
if (tryMergedAnnotation) {
|
||||
attributes = tryGetMergedAnnotationAttributes(annotatedElement, annotationType, propertyResolver,
|
||||
classValuesAsString, nestedAnnotationsAsMap, ignoreDefaultValue, ignoreAttributeNames);
|
||||
}
|
||||
|
||||
if (attributes == null) {
|
||||
attributes = getAnnotationAttributes(annotatedElement, annotationType, propertyResolver,
|
||||
classValuesAsString, nestedAnnotationsAsMap, ignoreDefaultValue, ignoreAttributeNames);
|
||||
}
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to get the merged {@link Annotation annotation}
|
||||
*
|
||||
* @param annotatedElement {@link AnnotatedElement the annotated element}
|
||||
* @param annotationType the {@link Class tyoe} pf {@link Annotation annotation}
|
||||
* @param classValuesAsString whether to turn Class references into Strings (for
|
||||
* compatibility with {@link org.springframework.core.type.AnnotationMetadata} or to
|
||||
* preserve them as Class references
|
||||
* @param nestedAnnotationsAsMap whether to turn nested Annotation instances into
|
||||
* {@link AnnotationAttributes} maps (for compatibility with
|
||||
* {@link org.springframework.core.type.AnnotationMetadata} or to preserve them as
|
||||
* Annotation instances
|
||||
* @return If current version of Spring Framework is below 4.2, return <code>null</code>
|
||||
*/
|
||||
public static Annotation tryGetMergedAnnotation(AnnotatedElement annotatedElement,
|
||||
Class<? extends Annotation> annotationType,
|
||||
boolean classValuesAsString,
|
||||
boolean nestedAnnotationsAsMap) {
|
||||
|
||||
Annotation mergedAnnotation = null;
|
||||
|
||||
ClassLoader classLoader = annotationType.getClassLoader();
|
||||
|
||||
if (annotatedElementUtilsPresentCache.computeIfAbsent(System.identityHashCode(classLoader),
|
||||
(_k) -> ClassUtils.isPresent(ANNOTATED_ELEMENT_UTILS_CLASS_NAME, classLoader))) {
|
||||
Class<?> annotatedElementUtilsClass = resolveClassName(ANNOTATED_ELEMENT_UTILS_CLASS_NAME, classLoader);
|
||||
// getMergedAnnotation method appears in the Spring Framework 4.2
|
||||
Method getMergedAnnotationMethod = findMethod(annotatedElementUtilsClass, "getMergedAnnotation",
|
||||
AnnotatedElement.class, Class.class, boolean.class, boolean.class);
|
||||
if (getMergedAnnotationMethod != null) {
|
||||
mergedAnnotation = (Annotation) invokeMethod(getMergedAnnotationMethod, null,
|
||||
annotatedElement, annotationType, classValuesAsString, nestedAnnotationsAsMap);
|
||||
}
|
||||
}
|
||||
|
||||
return mergedAnnotation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to get {@link AnnotationAttributes the annotation attributes} after merging and resolving the placeholders
|
||||
*
|
||||
* @param annotatedElement {@link AnnotatedElement the annotated element}
|
||||
* @param annotationType the {@link Class tyoe} pf {@link Annotation annotation}
|
||||
* @param propertyResolver {@link PropertyResolver} instance, e.g {@link Environment}
|
||||
* @param classValuesAsString whether to turn Class references into Strings (for
|
||||
* compatibility with {@link org.springframework.core.type.AnnotationMetadata} or to
|
||||
* preserve them as Class references
|
||||
* @param nestedAnnotationsAsMap whether to turn nested Annotation instances into
|
||||
* {@link AnnotationAttributes} maps (for compatibility with
|
||||
* {@link org.springframework.core.type.AnnotationMetadata} or to preserve them as
|
||||
* Annotation instances
|
||||
* @param ignoreDefaultValue whether ignore default value or not
|
||||
* @param ignoreAttributeNames the attribute names of annotation should be ignored
|
||||
* @return If the specified annotation type is not found, return <code>null</code>
|
||||
*/
|
||||
public static AnnotationAttributes tryGetMergedAnnotationAttributes(AnnotatedElement annotatedElement,
|
||||
Class<? extends Annotation> annotationType,
|
||||
PropertyResolver propertyResolver,
|
||||
boolean classValuesAsString,
|
||||
boolean nestedAnnotationsAsMap,
|
||||
boolean ignoreDefaultValue,
|
||||
String... ignoreAttributeNames) {
|
||||
Annotation annotation = tryGetMergedAnnotation(annotatedElement, annotationType, classValuesAsString, nestedAnnotationsAsMap);
|
||||
return annotation == null ? null : getAnnotationAttributes(annotation, propertyResolver,
|
||||
classValuesAsString, nestedAnnotationsAsMap, ignoreDefaultValue, ignoreAttributeNames);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.config.spring.util;
|
||||
|
||||
import org.springframework.core.AliasRegistry;
|
||||
|
||||
import static org.springframework.util.ObjectUtils.containsElement;
|
||||
import static org.springframework.util.StringUtils.hasText;
|
||||
|
||||
/**
|
||||
* Bean Registrar
|
||||
*/
|
||||
public abstract class BeanRegistrar {
|
||||
|
||||
/**
|
||||
* Detect the alias is present or not in the given bean name from {@link AliasRegistry}
|
||||
*
|
||||
* @param registry {@link AliasRegistry}
|
||||
* @param beanName the bean name
|
||||
* @param alias alias to test
|
||||
* @return if present, return <code>true</code>, or <code>false</code>
|
||||
*/
|
||||
public static boolean hasAlias(AliasRegistry registry, String beanName, String alias) {
|
||||
return hasText(beanName) && hasText(alias) && containsElement(registry.getAliases(beanName), alias);
|
||||
}
|
||||
}
|
||||
|
|
@ -32,7 +32,6 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.alibaba.spring.util.AnnotationUtils.getAttribute;
|
||||
import static org.springframework.util.ClassUtils.getAllInterfacesForClass;
|
||||
import static org.springframework.util.StringUtils.hasText;
|
||||
|
||||
|
|
@ -78,7 +77,7 @@ public class DubboAnnotationUtils {
|
|||
*/
|
||||
public static String resolveInterfaceName(Map<String, Object> attributes, Class<?> defaultInterfaceClass) {
|
||||
// 1. get from DubboService.interfaceName()
|
||||
String interfaceClassName = getAttribute(attributes, "interfaceName");
|
||||
String interfaceClassName = AnnotationUtils.getAttribute(attributes, "interfaceName");
|
||||
if (StringUtils.hasText(interfaceClassName)) {
|
||||
if (GenericService.class.getName().equals(interfaceClassName) ||
|
||||
com.alibaba.dubbo.rpc.service.GenericService.class.getName().equals(interfaceClassName)) {
|
||||
|
|
@ -88,7 +87,7 @@ public class DubboAnnotationUtils {
|
|||
}
|
||||
|
||||
// 2. get from DubboService.interfaceClass()
|
||||
Class<?> interfaceClass = getAttribute(attributes, "interfaceClass");
|
||||
Class<?> interfaceClass = AnnotationUtils.getAttribute(attributes, "interfaceClass");
|
||||
if (interfaceClass == null || void.class.equals(interfaceClass)) { // default or set void.class for purpose.
|
||||
interfaceClass = null;
|
||||
} else if (GenericService.class.isAssignableFrom(interfaceClass)) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.config.spring.util;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* Generic {@link BeanPostProcessor} Adapter
|
||||
*
|
||||
* @see BeanPostProcessor
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public abstract class GenericBeanPostProcessorAdapter<T> implements BeanPostProcessor {
|
||||
|
||||
private final Class<T> beanType;
|
||||
|
||||
public GenericBeanPostProcessorAdapter() {
|
||||
ParameterizedType parameterizedType = (ParameterizedType) getClass().getGenericSuperclass();
|
||||
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
|
||||
this.beanType = (Class<T>) actualTypeArguments[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
if (ClassUtils.isAssignableValue(beanType, bean)) {
|
||||
return doPostProcessBeforeInitialization((T) bean, beanName);
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
if (ClassUtils.isAssignableValue(beanType, bean)) {
|
||||
return doPostProcessAfterInitialization((T) bean, beanName);
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bean Type
|
||||
*
|
||||
* @return Bean Type
|
||||
*/
|
||||
public final Class<T> getBeanType() {
|
||||
return beanType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapter BeanPostProcessor#postProcessBeforeInitialization(Object, String) method , sub-type
|
||||
* could override this method.
|
||||
*
|
||||
* @param bean Bean Object
|
||||
* @param beanName Bean Name
|
||||
* @return Bean Object
|
||||
* @see BeanPostProcessor#postProcessBeforeInitialization(Object, String)
|
||||
*/
|
||||
protected T doPostProcessBeforeInitialization(T bean, String beanName) throws BeansException {
|
||||
|
||||
processBeforeInitialization(bean, beanName);
|
||||
|
||||
return bean;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapter BeanPostProcessor#postProcessAfterInitialization(Object, String) method , sub-type
|
||||
* could override this method.
|
||||
*
|
||||
* @param bean Bean Object
|
||||
* @param beanName Bean Name
|
||||
* @return Bean Object
|
||||
* @see BeanPostProcessor#postProcessAfterInitialization(Object, String)
|
||||
*/
|
||||
protected T doPostProcessAfterInitialization(T bean, String beanName) throws BeansException {
|
||||
|
||||
processAfterInitialization(bean, beanName);
|
||||
|
||||
return bean;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Process {@link T Bean} with name without return value before initialization,
|
||||
* <p>
|
||||
* This method will be invoked by BeanPostProcessor#postProcessBeforeInitialization(Object, String)
|
||||
*
|
||||
* @param bean Bean Object
|
||||
* @param beanName Bean Name
|
||||
* @throws BeansException in case of errors
|
||||
*/
|
||||
protected void processBeforeInitialization(T bean, String beanName) throws BeansException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Process {@link T Bean} with name without return value after initialization,
|
||||
* <p>
|
||||
* This method will be invoked by BeanPostProcessor#postProcessAfterInitialization(Object, String)
|
||||
*
|
||||
* @param bean Bean Object
|
||||
* @param beanName Bean Name
|
||||
* @throws BeansException in case of errors
|
||||
*/
|
||||
protected void processAfterInitialization(T bean, String beanName) throws BeansException {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.config.spring.util;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class LazyTargetInvocationHandler implements InvocationHandler {
|
||||
private final LazyTargetSource lazyTargetSource;
|
||||
private volatile Object target;
|
||||
|
||||
public LazyTargetInvocationHandler(LazyTargetSource lazyTargetSource) {
|
||||
this.lazyTargetSource = lazyTargetSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
String methodName = method.getName();
|
||||
Class<?>[] parameterTypes = method.getParameterTypes();
|
||||
if (parameterTypes.length == 0) {
|
||||
if ("toString".equals(methodName)) {
|
||||
if (target != null) {
|
||||
return target.toString();
|
||||
} else {
|
||||
return this.toString();
|
||||
}
|
||||
} else if ("hashCode".equals(methodName)) {
|
||||
return this.hashCode();
|
||||
}
|
||||
} else if (parameterTypes.length == 1 && "equals".equals(methodName)) {
|
||||
return this.equals(args[0]);
|
||||
}
|
||||
|
||||
if (target == null) {
|
||||
synchronized (this) {
|
||||
if (target == null) {
|
||||
target = lazyTargetSource.getTarget();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (method.getDeclaringClass().isInstance(target)) {
|
||||
try {
|
||||
return method.invoke(target, args);
|
||||
} catch (InvocationTargetException exception) {
|
||||
Throwable targetException = exception.getTargetException();
|
||||
if (targetException != null) {
|
||||
throw targetException;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("The proxied interface [" + method.getDeclaringClass() +
|
||||
"] contains a method [" + method + "] that is not implemented by the proxy class [" + target.getClass() + "]");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.config.spring.util;
|
||||
|
||||
public interface LazyTargetSource {
|
||||
Object getTarget() throws Exception;
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.config.spring.util;
|
||||
|
||||
/**
|
||||
* Object Utilities
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public abstract class ObjectUtils {
|
||||
|
||||
/**
|
||||
* Empty String array
|
||||
*/
|
||||
public static final String[] EMPTY_STRING_ARRAY = {};
|
||||
|
||||
/**
|
||||
* Convert from variable arguments to array
|
||||
*
|
||||
* @param values variable arguments
|
||||
* @param <T> The class
|
||||
* @return array
|
||||
*/
|
||||
public static <T> T[] of(T... values) {
|
||||
return values;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.config.spring.util;
|
||||
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.EnumerablePropertySource;
|
||||
import org.springframework.core.env.MutablePropertySources;
|
||||
import org.springframework.core.env.PropertyResolver;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.core.env.PropertySources;
|
||||
import org.springframework.core.env.PropertySourcesPropertyResolver;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import static java.util.Collections.unmodifiableMap;
|
||||
|
||||
/**
|
||||
* {@link PropertySources} Utilities
|
||||
*
|
||||
* @see PropertySources
|
||||
*/
|
||||
public abstract class PropertySourcesUtils {
|
||||
|
||||
/**
|
||||
* Get Sub {@link Properties}
|
||||
*
|
||||
* @param propertySources {@link PropertySource} Iterable
|
||||
* @param prefix the prefix of property name
|
||||
* @return Map
|
||||
* @see Properties
|
||||
*/
|
||||
public static Map<String, Object> getSubProperties(Iterable<PropertySource<?>> propertySources, String prefix) {
|
||||
|
||||
MutablePropertySources mutablePropertySources = new MutablePropertySources();
|
||||
|
||||
for (PropertySource<?> source : propertySources) {
|
||||
mutablePropertySources.addLast(source);
|
||||
}
|
||||
|
||||
return getSubProperties(mutablePropertySources, prefix);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Sub {@link Properties}
|
||||
*
|
||||
* @param environment {@link ConfigurableEnvironment}
|
||||
* @param prefix the prefix of property name
|
||||
* @return Map
|
||||
* @see Properties
|
||||
*/
|
||||
public static Map<String, Object> getSubProperties(ConfigurableEnvironment environment, String prefix) {
|
||||
return getSubProperties(environment.getPropertySources(), environment, prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize the prefix
|
||||
*
|
||||
* @param prefix the prefix
|
||||
* @return the prefix
|
||||
*/
|
||||
public static String normalizePrefix(String prefix) {
|
||||
return prefix.endsWith(".") ? prefix : prefix + ".";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get prefixed {@link Properties}
|
||||
*
|
||||
* @param propertySources {@link PropertySources}
|
||||
* @param prefix the prefix of property name
|
||||
* @return Map
|
||||
* @see Properties
|
||||
*/
|
||||
public static Map<String, Object> getSubProperties(PropertySources propertySources, String prefix) {
|
||||
return getSubProperties(propertySources, new PropertySourcesPropertyResolver(propertySources), prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get prefixed {@link Properties}
|
||||
*
|
||||
* @param propertySources {@link PropertySources}
|
||||
* @param propertyResolver {@link PropertyResolver} to resolve the placeholder if present
|
||||
* @param prefix the prefix of property name
|
||||
* @return Map
|
||||
* @see Properties
|
||||
*/
|
||||
public static Map<String, Object> getSubProperties(PropertySources propertySources, PropertyResolver propertyResolver, String prefix) {
|
||||
|
||||
Map<String, Object> subProperties = new LinkedHashMap<String, Object>();
|
||||
|
||||
String normalizedPrefix = normalizePrefix(prefix);
|
||||
|
||||
Iterator<PropertySource<?>> iterator = propertySources.iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
PropertySource<?> source = iterator.next();
|
||||
for (String name : getPropertyNames(source)) {
|
||||
if (!subProperties.containsKey(name) && name.startsWith(normalizedPrefix)) {
|
||||
String subName = name.substring(normalizedPrefix.length());
|
||||
if (!subProperties.containsKey(subName)) { // take first one
|
||||
Object value = source.getProperty(name);
|
||||
if (value instanceof String) {
|
||||
// Resolve placeholder
|
||||
value = propertyResolver.resolvePlaceholders((String) value);
|
||||
}
|
||||
subProperties.put(subName, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return unmodifiableMap(subProperties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the property names as the array from the specified {@link PropertySource} instance.
|
||||
*
|
||||
* @param propertySource {@link PropertySource} instance
|
||||
* @return non-null
|
||||
*/
|
||||
public static String[] getPropertyNames(PropertySource propertySource) {
|
||||
String[] propertyNames = propertySource instanceof EnumerablePropertySource ?
|
||||
((EnumerablePropertySource) propertySource).getPropertyNames() : null;
|
||||
|
||||
if (propertyNames == null) {
|
||||
propertyNames = ObjectUtils.EMPTY_STRING_ARRAY;
|
||||
}
|
||||
|
||||
return propertyNames;
|
||||
}
|
||||
}
|
||||
|
|
@ -1098,6 +1098,12 @@
|
|||
<xsd:documentation><![CDATA[ Deprecated. No longer use. ]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
|
||||
<xsd:attribute name="enable-rpc" type="xsd:boolean" default="true">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[ Enable record rpc metrics. ]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="tracingType">
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ import org.springframework.context.annotation.PropertySource;
|
|||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
|
@ -97,6 +98,63 @@ class JavaConfigReferenceBeanTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLazyProxy1() {
|
||||
AnnotationConfigApplicationContext context = null;
|
||||
try {
|
||||
context = new AnnotationConfigApplicationContext(CommonConfig.class,
|
||||
LazyProxyConfiguration1.class);
|
||||
HelloService helloServiceClient = context.getBean("helloServiceClient", HelloService.class);
|
||||
Assertions.assertNotNull(helloServiceClient);
|
||||
Assertions.assertInstanceOf(HelloService.class, helloServiceClient);
|
||||
Class<? extends HelloService> clientClass = helloServiceClient.getClass();
|
||||
Assertions.assertFalse(Modifier.isFinal(clientClass.getModifiers()));
|
||||
Assertions.assertEquals("Hello, dubbo", helloServiceClient.sayHello("dubbo"));
|
||||
} finally {
|
||||
if (context != null) {
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLazyProxy2() {
|
||||
AnnotationConfigApplicationContext context = null;
|
||||
try {
|
||||
context = new AnnotationConfigApplicationContext(CommonConfig.class,
|
||||
LazyProxyConfiguration2.class);
|
||||
HelloService helloServiceClient = context.getBean("helloServiceClient", HelloService.class);
|
||||
Assertions.assertNotNull(helloServiceClient);
|
||||
Assertions.assertInstanceOf(HelloService.class, helloServiceClient);
|
||||
Class<? extends HelloService> clientClass = helloServiceClient.getClass();
|
||||
Assertions.assertFalse(Modifier.isFinal(clientClass.getModifiers()));
|
||||
Assertions.assertEquals("Hello, dubbo", helloServiceClient.sayHello("dubbo"));
|
||||
} finally {
|
||||
if (context != null) {
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLazyProxy3() {
|
||||
AnnotationConfigApplicationContext context = null;
|
||||
try {
|
||||
context = new AnnotationConfigApplicationContext(CommonConfig.class,
|
||||
LazyProxyConfiguration3.class);
|
||||
HelloService helloServiceClient = context.getBean("helloServiceClient", HelloService.class);
|
||||
Assertions.assertNotNull(helloServiceClient);
|
||||
Assertions.assertInstanceOf(HelloService.class, helloServiceClient);
|
||||
Class<? extends HelloService> clientClass = helloServiceClient.getClass();
|
||||
Assertions.assertTrue(Modifier.isFinal(clientClass.getModifiers()));
|
||||
Assertions.assertEquals("Hello, dubbo", helloServiceClient.sayHello("dubbo"));
|
||||
} finally {
|
||||
if (context != null) {
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getStackTrace(Throwable ex) {
|
||||
StringWriter stringWriter = new StringWriter();
|
||||
ex.printStackTrace(new PrintWriter(stringWriter));
|
||||
|
|
@ -106,7 +164,7 @@ class JavaConfigReferenceBeanTest {
|
|||
@Test
|
||||
void testAnnotationBean() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(CommonConfig.class,
|
||||
AnnotationBeanConfiguration.class);
|
||||
AnnotationBeanConfiguration.class);
|
||||
|
||||
try {
|
||||
Map<String, HelloService> helloServiceMap = context.getBeansOfType(HelloService.class);
|
||||
|
|
@ -165,7 +223,7 @@ class JavaConfigReferenceBeanTest {
|
|||
@Test
|
||||
void testReferenceBean() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(CommonConfig.class,
|
||||
ReferenceBeanConfiguration.class);
|
||||
ReferenceBeanConfiguration.class);
|
||||
|
||||
try {
|
||||
Map<String, HelloService> helloServiceMap = context.getBeansOfType(HelloService.class);
|
||||
|
|
@ -316,6 +374,42 @@ class JavaConfigReferenceBeanTest {
|
|||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
public static class LazyProxyConfiguration1 {
|
||||
|
||||
@DubboReference(group = "${myapp.group}")
|
||||
private HelloService helloService;
|
||||
|
||||
@Bean(name = "helloServiceClient")
|
||||
public HelloService helloService() {
|
||||
return helloService;
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class LazyProxyConfiguration2 {
|
||||
|
||||
@DubboReference(group = "${myapp.group}", proxy = "javassist")
|
||||
private HelloService helloService;
|
||||
|
||||
@Bean(name = "helloServiceClient")
|
||||
public HelloService helloService() {
|
||||
return helloService;
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class LazyProxyConfiguration3 {
|
||||
|
||||
@DubboReference(group = "${myapp.group}", proxy = "jdk")
|
||||
private HelloService helloService;
|
||||
|
||||
@Bean(name = "helloServiceClient")
|
||||
public HelloService helloService() {
|
||||
return helloService;
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class AnnotationAtFieldConfiguration {
|
||||
|
||||
|
|
@ -353,7 +447,7 @@ class JavaConfigReferenceBeanTest {
|
|||
}
|
||||
|
||||
@Bean
|
||||
@Reference(group = "${myapp.group}", interfaceName = "org.apache.dubbo.config.spring.api.LocalMissClass")
|
||||
@DubboReference(group = "${myapp.group}", interfaceName = "org.apache.dubbo.config.spring.api.LocalMissClass", scope = "local")
|
||||
public ReferenceBean<GenericService> genericServiceWithoutInterface() {
|
||||
return new ReferenceBean();
|
||||
}
|
||||
|
|
@ -365,8 +459,8 @@ class JavaConfigReferenceBeanTest {
|
|||
@Bean
|
||||
public ReferenceBean<HelloService> helloService() {
|
||||
return new ReferenceBeanBuilder()
|
||||
.setGroup("${myapp.group}")
|
||||
.build();
|
||||
.setGroup("${myapp.group}")
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
|
@ -394,9 +488,9 @@ class JavaConfigReferenceBeanTest {
|
|||
@Bean
|
||||
public ReferenceBean helloService() {
|
||||
return new ReferenceBeanBuilder()
|
||||
.setGroup("${myapp.group}")
|
||||
.setInterface(HelloService.class)
|
||||
.build();
|
||||
.setGroup("${myapp.group}")
|
||||
.setInterface(HelloService.class)
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -435,4 +529,4 @@ class JavaConfigReferenceBeanTest {
|
|||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,11 +99,12 @@ class DubboNamespaceHandlerTest {
|
|||
private void testProviderXml(ApplicationContext context) {
|
||||
|
||||
String appName = "demo-provider";
|
||||
String configId = ApplicationConfig.class.getName() + "#" + appName + "#0";
|
||||
Map<String, ApplicationConfig> applicationConfigMap = context.getBeansOfType(ApplicationConfig.class);
|
||||
ApplicationConfig providerAppConfig = context.getBean(appName, ApplicationConfig.class);
|
||||
ApplicationConfig providerAppConfig = context.getBean(configId, ApplicationConfig.class);
|
||||
assertNotNull(providerAppConfig);
|
||||
assertEquals(appName, providerAppConfig.getName());
|
||||
assertEquals(appName, providerAppConfig.getId());
|
||||
// assertEquals(configId, providerAppConfig.getId());
|
||||
|
||||
ProtocolConfig protocolConfig = context.getBean(ProtocolConfig.class);
|
||||
assertThat(protocolConfig, not(nullValue()));
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@
|
|||
<spring_version>5.3.25</spring_version>
|
||||
<spring_security_version>5.8.3</spring_security_version>
|
||||
<javassist_version>3.29.2-GA</javassist_version>
|
||||
<bytebuddy.version>1.14.4</bytebuddy.version>
|
||||
<bytebuddy.version>1.14.5</bytebuddy.version>
|
||||
<netty_version>3.2.10.Final</netty_version>
|
||||
<netty4_version>4.1.92.Final</netty4_version>
|
||||
<mina_version>2.2.1</mina_version>
|
||||
|
|
@ -102,7 +102,7 @@
|
|||
<httpclient_version>4.5.14</httpclient_version>
|
||||
<httpcore_version>4.4.16</httpcore_version>
|
||||
<fastjson_version>1.2.83</fastjson_version>
|
||||
<fastjson2_version>2.0.32</fastjson2_version>
|
||||
<fastjson2_version>2.0.33</fastjson2_version>
|
||||
<zookeeper_version>3.4.14</zookeeper_version>
|
||||
<curator_version>4.3.0</curator_version>
|
||||
<curator_test_version>2.12.0</curator_test_version>
|
||||
|
|
@ -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.1</protobuf-java_version>
|
||||
<protobuf-java_version>3.23.2</protobuf-java_version>
|
||||
<javax_annotation-api_version>1.3.2</javax_annotation-api_version>
|
||||
<servlet_version>3.1.0</servlet_version>
|
||||
<jetty_version>9.4.51.v20230217</jetty_version>
|
||||
|
|
@ -148,7 +148,7 @@
|
|||
<codehaus-jackson_version>1.9.13</codehaus-jackson_version>
|
||||
<tomcat_embed_version>8.5.87</tomcat_embed_version>
|
||||
<jetcd_version>0.7.5</jetcd_version>
|
||||
<nacos_version>2.2.2</nacos_version>
|
||||
<nacos_version>2.2.3</nacos_version>
|
||||
<grpc.version>1.55.1</grpc.version>
|
||||
<grpc_contrib_verdion>0.8.1</grpc_contrib_verdion>
|
||||
<jprotoc_version>1.2.2</jprotoc_version>
|
||||
|
|
@ -174,17 +174,17 @@
|
|||
|
||||
<jaxb_version>2.2.7</jaxb_version>
|
||||
<activation_version>1.2.0</activation_version>
|
||||
<test_container_version>1.18.1</test_container_version>
|
||||
<test_container_version>1.18.3</test_container_version>
|
||||
<etcd_launcher_version>0.7.5</etcd_launcher_version>
|
||||
<hessian_lite_version>3.2.13</hessian_lite_version>
|
||||
<swagger_version>1.6.11</swagger_version>
|
||||
|
||||
<snappy_java_version>1.1.9.1</snappy_java_version>
|
||||
<snappy_java_version>1.1.10.0</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>
|
||||
<gson_version>2.10.1</gson_version>
|
||||
<jackson_version>2.15.1</jackson_version>
|
||||
<jackson_version>2.15.2</jackson_version>
|
||||
<jsonrpc_version>1.6</jsonrpc_version>
|
||||
<mortbay_jetty_version>6.1.26</mortbay_jetty_version>
|
||||
<portlet_version>2.0</portlet_version>
|
||||
|
|
|
|||
|
|
@ -94,7 +94,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.getServiceName() + "_" + invocation.getMethodName(), container.getInitFunc());
|
||||
Number current = (Number) ConcurrentHashMapUtils.computeIfAbsent(container, invocation.getTargetServiceUniqueName() + "_" + invocation.getMethodName(), container.getInitFunc());
|
||||
container.getConsumerFunc().accept(responseTime, current);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ public enum MetricsKey {
|
|||
METRIC_REQUESTS_SUCCEED("dubbo.%s.requests.succeed.total", "Total Succeed Requests"),
|
||||
METRIC_REQUEST_BUSINESS_FAILED("dubbo.%s.requests.business.failed.total", "Total Failed Business Requests"),
|
||||
|
||||
METRIC_REQUESTS_PROCESSING("dubbo.%s.requests.processing", "Processing Requests"),
|
||||
METRIC_REQUESTS_PROCESSING("dubbo.%s.requests.processing.total", "Processing Requests"),
|
||||
METRIC_REQUESTS_TIMEOUT("dubbo.%s.requests.timeout.total", "Total Timeout Failed Requests"),
|
||||
METRIC_REQUESTS_LIMIT("dubbo.%s.requests.limit.total", "Total Limit Failed Requests"),
|
||||
METRIC_REQUESTS_FAILED("dubbo.%s.requests.unknown.failed.total", "Total Unknown Failed Requests"),
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@ public class TimeWindowAggregatorTest {
|
|||
public void testTimeWindowAggregator() {
|
||||
TimeWindowAggregator aggregator = new TimeWindowAggregator(5, 5);
|
||||
|
||||
// 第一个时间窗口,时间范围:0秒 - 5秒
|
||||
//First time window, time range: 0 - 5 seconds
|
||||
|
||||
aggregator.add(10);
|
||||
aggregator.add(20);
|
||||
aggregator.add(30);
|
||||
|
|
@ -39,7 +40,7 @@ public class TimeWindowAggregatorTest {
|
|||
Assertions.assertEquals(30, entry1.getMax());
|
||||
Assertions.assertEquals(10, entry1.getMin());
|
||||
|
||||
// 第二个时间窗口,时间范围:5秒 - 10秒
|
||||
//Second time window, time range: 5 - 10 seconds
|
||||
try {
|
||||
TimeUnit.SECONDS.sleep(5);
|
||||
} catch (InterruptedException e) {
|
||||
|
|
@ -57,7 +58,9 @@ public class TimeWindowAggregatorTest {
|
|||
Assertions.assertEquals(35, entry2.getMax());
|
||||
Assertions.assertEquals(15, entry2.getMin());
|
||||
|
||||
// 第三个时间窗口,时间范围:10秒 - 15秒
|
||||
|
||||
//Third time window, time range: 10 - 15 seconds
|
||||
|
||||
try {
|
||||
TimeUnit.SECONDS.sleep(5);
|
||||
} catch (InterruptedException e) {
|
||||
|
|
|
|||
|
|
@ -53,10 +53,16 @@ public class HistogramMetricsCollector extends AbstractMetricsListener<RequestEv
|
|||
|
||||
ConfigManager configManager = applicationModel.getApplicationConfigManager();
|
||||
MetricsConfig config = configManager.getMetrics().orElse(null);
|
||||
if (config != null && config.getHistogram() != null && Boolean.TRUE.equals(config.getHistogram().getEnabled())) {
|
||||
if (config == null || config.getHistogram() == null || config.getHistogram().getEnabled() == null || Boolean.TRUE.equals(config.getHistogram().getEnabled())) {
|
||||
registerListener();
|
||||
|
||||
HistogramConfig histogram = config.getHistogram();
|
||||
HistogramConfig histogram;
|
||||
if (config == null || config.getHistogram() == null) {
|
||||
histogram = new HistogramConfig();
|
||||
} else {
|
||||
histogram = config.getHistogram();
|
||||
}
|
||||
|
||||
if (!Boolean.TRUE.equals(histogram.getEnabledPercentiles()) && histogram.getBucketsMs() == null) {
|
||||
histogram.setBucketsMs(DEFAULT_BUCKETS_MS);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package org.apache.dubbo.metrics.filter;
|
|||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.config.MetricsConfig;
|
||||
import org.apache.dubbo.metrics.event.MetricsEventBus;
|
||||
import org.apache.dubbo.metrics.event.RequestEvent;
|
||||
import org.apache.dubbo.rpc.BaseFilter;
|
||||
|
|
@ -40,20 +41,24 @@ import static org.apache.dubbo.metrics.DefaultConstants.METRIC_THROWABLE;
|
|||
public class MetricsFilter implements Filter, BaseFilter.Listener, ScopeModelAware {
|
||||
|
||||
private ApplicationModel applicationModel;
|
||||
private final static ErrorTypeAwareLogger LOGGER = LoggerFactory.getErrorTypeAwareLogger(MetricsFilter.class);
|
||||
private static final ErrorTypeAwareLogger LOGGER = LoggerFactory.getErrorTypeAwareLogger(MetricsFilter.class);
|
||||
private boolean rpcMetricsEnable;
|
||||
|
||||
@Override
|
||||
public void setApplicationModel(ApplicationModel applicationModel) {
|
||||
this.applicationModel = applicationModel;
|
||||
this.rpcMetricsEnable = applicationModel.getApplicationConfigManager().getMetrics().map(MetricsConfig::getEnableRpc).orElse(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
|
||||
try {
|
||||
RequestEvent requestEvent = RequestEvent.toRequestEvent(applicationModel, invocation);
|
||||
MetricsEventBus.before(requestEvent, () -> invocation.put(METRIC_FILTER_EVENT, requestEvent));
|
||||
} catch (Throwable t) {
|
||||
LOGGER.warn(INTERNAL_ERROR, "", "", "Error occurred when invoke.", t);
|
||||
if (rpcMetricsEnable) {
|
||||
try {
|
||||
RequestEvent requestEvent = RequestEvent.toRequestEvent(applicationModel, invocation);
|
||||
MetricsEventBus.before(requestEvent, () -> invocation.put(METRIC_FILTER_EVENT, requestEvent));
|
||||
} catch (Throwable t) {
|
||||
LOGGER.warn(INTERNAL_ERROR, "", "", "Error occurred when invoke.", t);
|
||||
}
|
||||
}
|
||||
return invoker.invoke(invocation);
|
||||
}
|
||||
|
|
@ -84,6 +89,4 @@ public class MetricsFilter implements Filter, BaseFilter.Listener, ScopeModelAwa
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,6 @@ class MetricsFilterTest {
|
|||
config.setName("MockMetrics");
|
||||
applicationModel = ApplicationModel.defaultModel();
|
||||
applicationModel.getApplicationConfigManager().setApplication(config);
|
||||
|
||||
invocation = new RpcInvocation();
|
||||
filter = new MetricsFilter();
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
<properties>
|
||||
<skip_maven_deploy>false</skip_maven_deploy>
|
||||
<protobuf-java.version>3.22.2</protobuf-java.version>
|
||||
<grpc.version>1.41.0</grpc.version>
|
||||
<grpc.version>1.55.1</grpc.version>
|
||||
</properties>
|
||||
|
||||
<artifactId>dubbo-security</artifactId>
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ import java.util.concurrent.ConcurrentMap;
|
|||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
|
||||
|
|
@ -162,8 +163,8 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
|
|||
|
||||
private final Map<String, ServiceConfigurationListener> serviceConfigurationListeners = new ConcurrentHashMap<>();
|
||||
//To solve the problem of RMI repeated exposure port conflicts, the services that have been exposed are no longer exposed.
|
||||
//provider url <--> exporter
|
||||
private final ConcurrentMap<String, ExporterChangeableWrapper<?>> bounds = new ConcurrentHashMap<>();
|
||||
//provider url <--> registry url <--> exporter
|
||||
private final Map<String, Map<String, ExporterChangeableWrapper<?>>> bounds = new ConcurrentHashMap<>();
|
||||
protected Protocol protocol;
|
||||
protected ProxyFactory proxyFactory;
|
||||
|
||||
|
|
@ -217,7 +218,7 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
|
|||
return map;
|
||||
}
|
||||
|
||||
private void register(Registry registry, URL registeredProviderUrl) {
|
||||
private static void register(Registry registry, URL registeredProviderUrl) {
|
||||
ApplicationDeployer deployer = registeredProviderUrl.getOrDefaultApplicationModel().getDeployer();
|
||||
try {
|
||||
deployer.increaseServiceRefreshCount();
|
||||
|
|
@ -272,6 +273,7 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
|
|||
exporter.setRegisterUrl(registeredProviderUrl);
|
||||
exporter.setSubscribeUrl(overrideSubscribeUrl);
|
||||
exporter.setNotifyListener(overrideSubscribeListener);
|
||||
exporter.setRegistered(register);
|
||||
|
||||
ApplicationModel applicationModel = getApplicationModel(providerUrl.getScopeModel());
|
||||
if (applicationModel.getModelEnvironment().getConfiguration().convert(Boolean.class, ENABLE_26X_CONFIGURATION_LISTEN, true)) {
|
||||
|
|
@ -308,12 +310,14 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> ExporterChangeableWrapper<T> doLocalExport(final Invoker<T> originInvoker, URL providerUrl) {
|
||||
String key = getCacheKey(originInvoker);
|
||||
String providerUrlKey = getProviderUrlKey(originInvoker);
|
||||
String registryUrlKey = getRegistryUrlKey(originInvoker);
|
||||
|
||||
return (ExporterChangeableWrapper<T>) bounds.computeIfAbsent(key, s -> {
|
||||
Invoker<?> invokerDelegate = new InvokerDelegate<>(originInvoker, providerUrl);
|
||||
return new ExporterChangeableWrapper<>((Exporter<T>) protocol.export(invokerDelegate), originInvoker);
|
||||
});
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
public <T> void reExport(Exporter<T> exporter, URL newInvokerUrl) {
|
||||
|
|
@ -333,8 +337,18 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
|
|||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> void reExport(final Invoker<T> originInvoker, URL newInvokerUrl) {
|
||||
String key = getCacheKey(originInvoker);
|
||||
ExporterChangeableWrapper<T> exporter = (ExporterChangeableWrapper<T>) bounds.get(key);
|
||||
String providerUrlKey = getProviderUrlKey(originInvoker);
|
||||
String registryUrlKey = getRegistryUrlKey(originInvoker);
|
||||
Map<String, ExporterChangeableWrapper<?>> registryMap = bounds.get(providerUrlKey);
|
||||
if (registryMap == null) {
|
||||
logger.warn(INTERNAL_ERROR, "error state, exporterMap can not be null", "", "error state, exporterMap can not be null", new IllegalStateException("error state, exporterMap can not be null"));
|
||||
return;
|
||||
}
|
||||
ExporterChangeableWrapper<T> exporter = (ExporterChangeableWrapper<T>) registryMap.get(registryUrlKey);
|
||||
if (exporter == null) {
|
||||
logger.warn(INTERNAL_ERROR, "error state, exporterMap can not be null", "", "error state, exporterMap can not be null", new IllegalStateException("error state, exporterMap can not be null"));
|
||||
return;
|
||||
}
|
||||
URL registeredUrl = exporter.getRegisterUrl();
|
||||
|
||||
URL registryUrl = getRegistryUrl(originInvoker);
|
||||
|
|
@ -369,7 +383,7 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
|
|||
|
||||
private <T> void doReExport(final Invoker<T> originInvoker, ExporterChangeableWrapper<T> exporter,
|
||||
URL registryUrl, URL oldProviderUrl, URL newProviderUrl) {
|
||||
if (getProviderUrl(originInvoker).getParameter(REGISTER_KEY, true)) {
|
||||
if (exporter.isRegistered()) {
|
||||
Registry registry;
|
||||
try {
|
||||
registry = getRegistry(getRegistryUrl(originInvoker));
|
||||
|
|
@ -480,12 +494,18 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
|
|||
* @param originInvoker
|
||||
* @return
|
||||
*/
|
||||
private String getCacheKey(final Invoker<?> originInvoker) {
|
||||
private String getProviderUrlKey(final Invoker<?> originInvoker) {
|
||||
URL providerUrl = getProviderUrl(originInvoker);
|
||||
String key = providerUrl.removeParameters(DYNAMIC_KEY, ENABLED_KEY).toFullString();
|
||||
return key;
|
||||
}
|
||||
|
||||
private String getRegistryUrlKey(final Invoker<?> originInvoker) {
|
||||
URL registryUrl = getRegistryUrl(originInvoker);
|
||||
String key = registryUrl.removeParameters(DYNAMIC_KEY, ENABLED_KEY).toFullString();
|
||||
return key;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
|
||||
|
|
@ -653,7 +673,7 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
|
|||
}
|
||||
}
|
||||
|
||||
List<Exporter<?>> exporters = new ArrayList<>(bounds.values());
|
||||
List<Exporter<?>> exporters = bounds.values().stream().flatMap(e -> e.values().stream()).collect(Collectors.toList());
|
||||
for (Exporter<?> exporter : exporters) {
|
||||
exporter.unexport();
|
||||
}
|
||||
|
|
@ -712,6 +732,11 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
|
|||
exporter.unexport();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register() {
|
||||
exporter.register();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregister() {
|
||||
exporter.unregister();
|
||||
|
|
@ -777,8 +802,14 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
|
|||
}
|
||||
//The origin invoker
|
||||
URL originUrl = RegistryProtocol.this.getProviderUrl(invoker);
|
||||
String key = getCacheKey(originInvoker);
|
||||
ExporterChangeableWrapper<?> exporter = bounds.get(key);
|
||||
String providerUrlKey = getProviderUrlKey(originInvoker);
|
||||
String registryUrlKey = getRegistryUrlKey(originInvoker);
|
||||
Map<String, ExporterChangeableWrapper<?>> exporterMap = bounds.get(providerUrlKey);
|
||||
if (exporterMap == null) {
|
||||
logger.warn(INTERNAL_ERROR, "error state, exporterMap can not be null", "", "error state, exporterMap can not be null", new IllegalStateException("error state, exporterMap can not be null"));
|
||||
return;
|
||||
}
|
||||
ExporterChangeableWrapper<?> exporter = exporterMap.get(registryUrlKey);
|
||||
if (exporter == null) {
|
||||
logger.warn(INTERNAL_ERROR, "unknown error in registry module", "", "error state, exporter should not be null", new IllegalStateException("error state, exporter should not be null"));
|
||||
return;
|
||||
|
|
@ -920,7 +951,7 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
|
|||
private URL registerUrl;
|
||||
|
||||
private NotifyListener notifyListener;
|
||||
private final AtomicBoolean unregistered = new AtomicBoolean(false);
|
||||
private final AtomicBoolean registered = new AtomicBoolean(false);
|
||||
|
||||
public ExporterChangeableWrapper(Exporter<T> exporter, Invoker<T> originInvoker) {
|
||||
this.exporter = exporter;
|
||||
|
|
@ -943,9 +974,28 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
|
|||
this.exporter = exporter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register() {
|
||||
if (registered.compareAndSet(false, true)) {
|
||||
URL registryUrl = getRegistryUrl(originInvoker);
|
||||
Registry registry = getRegistry(registryUrl);
|
||||
RegistryProtocol.register(registry, getRegisterUrl());
|
||||
|
||||
ProviderModel providerModel = frameworkModel.getServiceRepository()
|
||||
.lookupExportedService(getRegisterUrl().getServiceKey());
|
||||
|
||||
List<ProviderModel.RegisterStatedURL> statedUrls = providerModel.getStatedUrl();
|
||||
statedUrls.stream()
|
||||
.filter(u -> u.getRegistryUrl().equals(registryUrl)
|
||||
&& u.getProviderUrl().getProtocol().equals(getRegisterUrl().getProtocol()))
|
||||
.forEach(u -> u.setRegistered(true));
|
||||
logger.info("Registered dubbo service " + getRegisterUrl().getServiceKey() + " url " + getRegisterUrl() + " to registry " + registryUrl);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void unregister() {
|
||||
if (unregistered.compareAndSet(false, true)) {
|
||||
if (registered.compareAndSet(true, false)) {
|
||||
Registry registry = RegistryProtocol.this.getRegistry(getRegistryUrl(originInvoker));
|
||||
try {
|
||||
registry.unregister(registerUrl);
|
||||
|
|
@ -987,13 +1037,25 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
|
|||
|
||||
@Override
|
||||
public synchronized void unexport() {
|
||||
String key = getCacheKey(this.originInvoker);
|
||||
bounds.remove(key);
|
||||
String providerUrlKey = getProviderUrlKey(this.originInvoker);
|
||||
String registryUrlKey = getRegistryUrlKey(this.originInvoker);
|
||||
Map<String, ExporterChangeableWrapper<?>> exporterMap = bounds.remove(providerUrlKey);
|
||||
if (exporterMap != null) {
|
||||
exporterMap.remove(registryUrlKey);
|
||||
}
|
||||
|
||||
unregister();
|
||||
doUnExport();
|
||||
}
|
||||
|
||||
public void setRegistered(boolean registered) {
|
||||
this.registered.set(registered);
|
||||
}
|
||||
|
||||
public boolean isRegistered() {
|
||||
return registered.get();
|
||||
}
|
||||
|
||||
private void doUnExport() {
|
||||
try {
|
||||
exporter.unexport();
|
||||
|
|
|
|||
|
|
@ -28,6 +28,11 @@ public class Response {
|
|||
*/
|
||||
public static final byte OK = 20;
|
||||
|
||||
/**
|
||||
* serialization error
|
||||
*/
|
||||
public static final byte SERIALIZATION_ERROR = 25;
|
||||
|
||||
/**
|
||||
* client side timeout.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -360,6 +360,7 @@ public class ExchangeCodec extends TelnetCodec {
|
|||
logger.warn(TRANSPORT_EXCEED_PAYLOAD_LIMIT, "", "", t.getMessage(), t);
|
||||
try {
|
||||
r.setErrorMessage(t.getMessage());
|
||||
r.setStatus(Response.SERIALIZATION_ERROR);
|
||||
channel.send(r);
|
||||
return;
|
||||
} catch (RemotingException e) {
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import org.apache.dubbo.common.timer.TimerTask;
|
|||
import org.apache.dubbo.common.utils.NamedThreadFactory;
|
||||
import org.apache.dubbo.remoting.Channel;
|
||||
import org.apache.dubbo.remoting.RemotingException;
|
||||
import org.apache.dubbo.common.serialize.SerializationException;
|
||||
import org.apache.dubbo.remoting.TimeoutException;
|
||||
import org.apache.dubbo.remoting.exchange.Request;
|
||||
import org.apache.dubbo.remoting.exchange.Response;
|
||||
|
|
@ -215,7 +216,9 @@ public class DefaultFuture extends CompletableFuture<Object> {
|
|||
this.complete(res.getResult());
|
||||
} else if (res.getStatus() == Response.CLIENT_TIMEOUT || res.getStatus() == Response.SERVER_TIMEOUT) {
|
||||
this.completeExceptionally(new TimeoutException(res.getStatus() == Response.SERVER_TIMEOUT, channel, res.getErrorMessage()));
|
||||
} else {
|
||||
} else if(res.getStatus() == Response.SERIALIZATION_ERROR){
|
||||
this.completeExceptionally(new SerializationException(res.getErrorMessage()));
|
||||
}else {
|
||||
this.completeExceptionally(new RemotingException(channel, res.getErrorMessage()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -282,7 +282,11 @@ final class DeprecatedExchangeCodec extends DeprecatedTelnetCodec implements Cod
|
|||
logger.warn(TRANSPORT_FAILED_RESPONSE, "", "", "Fail to encode response: " + res + ", send bad_response info instead, cause: " + t.getMessage(), t);
|
||||
|
||||
Response r = new Response(res.getId(), res.getVersion());
|
||||
r.setStatus(Response.BAD_RESPONSE);
|
||||
if (t instanceof IOException) {
|
||||
r.setStatus(Response.SERIALIZATION_ERROR);
|
||||
} else {
|
||||
r.setStatus(Response.BAD_RESPONSE);
|
||||
}
|
||||
r.setErrorMessage("Failed to send response: " + res + ", cause: " + StringUtils.toString(t));
|
||||
channel.send(r);
|
||||
|
||||
|
|
|
|||
|
|
@ -512,7 +512,7 @@ class ExchangeCodecTest extends TelnetCodecTest {
|
|||
codec.encode(channel, encodeBuffer, response);
|
||||
Assertions.assertTrue(channel.getReceivedMessage() instanceof Response);
|
||||
Response receiveMessage = (Response) channel.getReceivedMessage();
|
||||
Assertions.assertEquals(Response.BAD_RESPONSE, receiveMessage.getStatus());
|
||||
Assertions.assertEquals(Response.SERIALIZATION_ERROR, receiveMessage.getStatus());
|
||||
Assertions.assertTrue(receiveMessage.getErrorMessage().contains("Data length too large: "));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,10 @@
|
|||
package org.apache.dubbo.remoting.transport.netty4;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.handler.codec.EncoderException;
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
|
|
@ -33,9 +36,6 @@ import org.apache.dubbo.remoting.exchange.Response;
|
|||
import org.apache.dubbo.remoting.transport.AbstractChannel;
|
||||
import org.apache.dubbo.remoting.transport.codec.CodecAdapter;
|
||||
import org.apache.dubbo.remoting.utils.PayloadDropper;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
|
@ -344,7 +344,11 @@ final class NettyChannel extends AbstractChannel {
|
|||
*/
|
||||
private static Response buildErrorResponse(Request request, Throwable t) {
|
||||
Response response = new Response(request.getId(), request.getVersion());
|
||||
response.setStatus(Response.BAD_REQUEST);
|
||||
if(t instanceof EncoderException){
|
||||
response.setStatus(Response.SERIALIZATION_ERROR);
|
||||
}else{
|
||||
response.setStatus(Response.BAD_REQUEST);
|
||||
}
|
||||
response.setErrorMessage(StringUtils.toString(t));
|
||||
return response;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,11 @@ public interface Exporter<T> {
|
|||
*/
|
||||
void unexport();
|
||||
|
||||
/**
|
||||
* register to registry
|
||||
*/
|
||||
void register();
|
||||
|
||||
/**
|
||||
* unregister from registry
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -62,6 +62,11 @@ public class ListenerExporterWrapper<T> implements Exporter<T> {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register() {
|
||||
exporter.register();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregister() {
|
||||
exporter.unregister();
|
||||
|
|
|
|||
|
|
@ -60,6 +60,11 @@ public abstract class AbstractExporter<T> implements Exporter<T> {
|
|||
afterUnExport();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregister() {
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import org.apache.dubbo.common.utils.ArrayUtils;
|
|||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
import org.apache.dubbo.common.utils.NetUtils;
|
||||
import org.apache.dubbo.remoting.RemotingException;
|
||||
import org.apache.dubbo.common.serialize.SerializationException;
|
||||
import org.apache.dubbo.remoting.TimeoutException;
|
||||
import org.apache.dubbo.remoting.utils.UrlUtils;
|
||||
import org.apache.dubbo.rpc.AsyncRpcResult;
|
||||
|
|
@ -112,7 +113,7 @@ public abstract class AbstractInvoker<T> implements Invoker<T> {
|
|||
}
|
||||
this.type = type;
|
||||
this.url = url;
|
||||
|
||||
|
||||
this.attachment = attachment == null
|
||||
? null
|
||||
: Collections.unmodifiableMap(attachment);
|
||||
|
|
@ -293,6 +294,9 @@ public abstract class AbstractInvoker<T> implements Invoker<T> {
|
|||
throw new RpcException(RpcException.TIMEOUT_EXCEPTION, "Invoke remote method timeout. method: " + invocation.getMethodName() + ", provider: " + getUrl() + ", cause: " + e.getMessage(), e);
|
||||
} else if (rootCause instanceof RemotingException) {
|
||||
throw new RpcException(RpcException.NETWORK_EXCEPTION, "Failed to invoke remote method: " + invocation.getMethodName() + ", provider: " + getUrl() + ", cause: " + e.getMessage(), e);
|
||||
} else if (rootCause instanceof SerializationException) {
|
||||
throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, "Invoke remote method failed cause by serialization error. remote method: " +
|
||||
invocation.getMethodName() + ", provider: " + getUrl() + ", cause: " + e.getMessage(), e);
|
||||
} else {
|
||||
throw new RpcException(RpcException.UNKNOWN_EXCEPTION, "Fail to invoke remote method: " + invocation.getMethodName() + ", provider: " + getUrl() + ", cause: " + e.getMessage(), e);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@
|
|||
package org.apache.dubbo.rpc.support;
|
||||
|
||||
|
||||
import org.apache.dubbo.common.utils.JsonUtils;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.common.utils.ToStringUtils;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.RpcContext;
|
||||
|
|
@ -248,7 +248,7 @@ public final class AccessLogData {
|
|||
|
||||
Object[] args = get(ARGUMENTS) != null ? (Object[]) get(ARGUMENTS) : null;
|
||||
if (args != null && args.length > 0) {
|
||||
sn.append(JsonUtils.toJson(args));
|
||||
sn.append(ToStringUtils.printToString(args));
|
||||
}
|
||||
|
||||
return sn.toString();
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue