Annotation activate compatible (#2152)

* support @Activate for compatible

* add testcase for @Activate compatible

* add LICENSE for test class

* import format
This commit is contained in:
Jerrick Zhu 2018-08-02 14:08:49 +08:00 committed by GitHub
parent d62e15d95d
commit 7cb044ca07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 239 additions and 35 deletions

View File

@ -148,12 +148,12 @@ Please follow the [template](https://github.com/apache/incubator-dubbo/issues/ne
Please report security vulnerability to security@dubbo.incubator.apache.org (private mailing list).
## Ecosystem
## [Ecosystem](https://github.com/dubbo)
* [Dubbo website](https://github.com/apache/incubator-dubbo-website) - Apache Dubbo (incubating) official website
* [Dubbo samples](https://github.com/dubbo/dubbo-samples) - samples for Apache Dubbo (incubating)
* [Dubbo Website](https://github.com/apache/incubator-dubbo-website) - Apache Dubbo (incubating) official website
* [Dubbo Samples](https://github.com/dubbo/dubbo-samples) - samples for Apache Dubbo (incubating)
* [Dubbo Spring Boot](https://github.com/apache/incubator-dubbo-spring-boot-project) - Spring Boot Project for Dubbo
* [Dubbo ops](https://github.com/apache/incubator-dubbo-ops) - The reference implementation for dubbo ops (dubbo-admin, dubbo-monitor, dubbo-registry-simple, etc.)
* [Dubbo OPS](https://github.com/apache/incubator-dubbo-ops) - The reference implementation for dubbo ops (dubbo-admin, dubbo-monitor, dubbo-registry-simple, etc.)
#### Language

View File

@ -0,0 +1,43 @@
/*
* 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 com.alibaba.dubbo.common.extension;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* See @org.apache.dubbo.common.extension.Activate
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Deprecated
public @interface Activate {
String[] group() default {};
String[] value() default {};
String[] before() default {};
String[] after() default {};
int order() default 0;
}

View File

@ -82,7 +82,7 @@ public class ExtensionLoader<T> {
private final Holder<Map<String, Class<?>>> cachedClasses = new Holder<Map<String, Class<?>>>();
private final Map<String, Activate> cachedActivates = new ConcurrentHashMap<String, Activate>();
private final Map<String, Object> cachedActivates = new ConcurrentHashMap<String, Object>();
private final ConcurrentMap<String, Holder<Object>> cachedInstances = new ConcurrentHashMap<String, Holder<Object>>();
private final Holder<Object> cachedAdaptiveInstance = new Holder<Object>();
private volatile Class<?> cachedAdaptiveClass = null;
@ -187,14 +187,26 @@ public class ExtensionLoader<T> {
List<String> names = values == null ? new ArrayList<String>(0) : Arrays.asList(values);
if (!names.contains(Constants.REMOVE_VALUE_PREFIX + Constants.DEFAULT_KEY)) {
getExtensionClasses();
for (Map.Entry<String, Activate> entry : cachedActivates.entrySet()) {
for (Map.Entry<String, Object> entry : cachedActivates.entrySet()) {
String name = entry.getKey();
Activate activate = entry.getValue();
if (isMatchGroup(group, activate.group())) {
Object activate = entry.getValue();
String[] activateGroup, activateValue;
if (activate instanceof Activate) {
activateGroup = ((Activate) activate).group();
activateValue = ((Activate) activate).value();
} else if (activate instanceof com.alibaba.dubbo.common.extension.Activate) {
activateGroup = ((com.alibaba.dubbo.common.extension.Activate) activate).group();
activateValue = ((com.alibaba.dubbo.common.extension.Activate) activate).value();
} else {
continue;
}
if (isMatchGroup(group, activateGroup)) {
T ext = getExtension(name);
if (!names.contains(name)
&& !names.contains(Constants.REMOVE_VALUE_PREFIX + name)
&& isActive(activate, url)) {
&& isActive(activateValue, url)) {
exts.add(ext);
}
}
@ -237,8 +249,7 @@ public class ExtensionLoader<T> {
return false;
}
private boolean isActive(Activate activate, URL url) {
String[] keys = activate.value();
private boolean isActive(String[] keys, URL url) {
if (keys.length == 0) {
return true;
}
@ -677,6 +688,12 @@ public class ExtensionLoader<T> {
Activate activate = clazz.getAnnotation(Activate.class);
if (activate != null) {
cachedActivates.put(names[0], activate);
} else {
// support com.alibaba.dubbo.common.extension.Activate
com.alibaba.dubbo.common.extension.Activate oldActivate = clazz.getAnnotation(com.alibaba.dubbo.common.extension.Activate.class);
if (oldActivate != null) {
cachedActivates.put(names[0], oldActivate);
}
}
for (String n : names) {
if (!cachedNames.containsKey(clazz)) {

View File

@ -23,7 +23,7 @@ import org.apache.dubbo.common.extension.SPI;
import java.util.Comparator;
/**
* OrderComparetor
* OrderComparator
*/
public class ActivateComparator implements Comparator<Object> {
@ -43,42 +43,74 @@ public class ActivateComparator implements Comparator<Object> {
if (o1.equals(o2)) {
return 0;
}
// to support com.alibab.dubbo.common.extension.Activate
String[] a1Before, a2Before, a1After, a2After;
int a1Order, a2Order;
Class<?> inf = null;
if (o1.getClass().getInterfaces().length > 0) {
inf = o1.getClass().getInterfaces()[0];
if (inf.getInterfaces().length > 0) {
inf = inf.getInterfaces()[0];
}
}
Activate a1 = o1.getClass().getAnnotation(Activate.class);
if (a1 != null) {
a1Before = a1.before();
a1After = a1.after();
a1Order = a1.order();
} else {
com.alibaba.dubbo.common.extension.Activate oa1 = o1.getClass().getAnnotation(com.alibaba.dubbo.common.extension.Activate.class);
a1Before = oa1.before();
a1After = oa1.after();
a1Order = oa1.order();
}
Activate a2 = o2.getClass().getAnnotation(Activate.class);
if ((a1.before().length > 0 || a1.after().length > 0
|| a2.before().length > 0 || a2.after().length > 0)
&& o1.getClass().getInterfaces().length > 0
&& o1.getClass().getInterfaces()[0].isAnnotationPresent(SPI.class)) {
ExtensionLoader<?> extensionLoader = ExtensionLoader.getExtensionLoader(o1.getClass().getInterfaces()[0]);
if (a1.before().length > 0 || a1.after().length > 0) {
if (a2 != null) {
a2Before = a2.before();
a2After = a2.after();
a2Order = a2.order();
} else {
com.alibaba.dubbo.common.extension.Activate oa2 = o2.getClass().getAnnotation(com.alibaba.dubbo.common.extension.Activate.class);
a2Before = oa2.before();
a2After = oa2.after();
a2Order = oa2.order();
}
if ((a1Before.length > 0 || a1After.length > 0
|| a2Before.length > 0 || a2After.length > 0)
&& inf != null && inf.isAnnotationPresent(SPI.class)) {
ExtensionLoader<?> extensionLoader = ExtensionLoader.getExtensionLoader(inf);
if (a1Before.length > 0 || a1After.length > 0) {
String n2 = extensionLoader.getExtensionName(o2.getClass());
for (String before : a1.before()) {
for (String before : a1Before) {
if (before.equals(n2)) {
return -1;
}
}
for (String after : a1.after()) {
for (String after : a1After) {
if (after.equals(n2)) {
return 1;
}
}
}
if (a2.before().length > 0 || a2.after().length > 0) {
if (a2Before.length > 0 || a2After.length > 0) {
String n1 = extensionLoader.getExtensionName(o1.getClass());
for (String before : a2.before()) {
for (String before : a2Before) {
if (before.equals(n1)) {
return 1;
}
}
for (String after : a2.after()) {
for (String after : a2After) {
if (after.equals(n1)) {
return -1;
}
}
}
}
int n1 = a1 == null ? 0 : a1.order();
int n2 = a2 == null ? 0 : a2.order();
int n1 = a1 == null ? 0 : a1Order;
int n2 = a2 == null ? 0 : a2Order;
// never return 0 even if n1 equals n2, otherwise, o1 and o2 will override each other in collection like HashSet
return n1 > n2 ? 1 : -1;
}

View File

@ -21,6 +21,8 @@ import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.activate.ActivateExt1;
import org.apache.dubbo.common.extension.activate.impl.ActivateExt1Impl1;
import org.apache.dubbo.common.extension.activate.impl.GroupActivateExtImpl;
import org.apache.dubbo.common.extension.activate.impl.OldActivateExt1Impl2;
import org.apache.dubbo.common.extension.activate.impl.OldActivateExt1Impl3;
import org.apache.dubbo.common.extension.activate.impl.OrderActivateExtImpl1;
import org.apache.dubbo.common.extension.activate.impl.OrderActivateExtImpl2;
import org.apache.dubbo.common.extension.activate.impl.ValueActivateExtImpl;
@ -378,6 +380,14 @@ public class ExtensionLoaderTest {
Assert.assertEquals(1, list.size());
Assert.assertTrue(list.get(0).getClass() == GroupActivateExtImpl.class);
// test old @Activate group
url = url.addParameter(Constants.GROUP_KEY, "old_group");
list = ExtensionLoader.getExtensionLoader(ActivateExt1.class)
.getActivateExtension(url, new String[]{}, "old_group");
Assert.assertEquals(2, list.size());
Assert.assertTrue(list.get(0).getClass() == OldActivateExt1Impl2.class
|| list.get(0).getClass() == OldActivateExt1Impl3.class);
// test value
url = url.removeParameter(Constants.GROUP_KEY);
url = url.addParameter(Constants.GROUP_KEY, "value");

View File

@ -0,0 +1,27 @@
/*
* 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.extension.activate.impl;
import com.alibaba.dubbo.common.extension.Activate;
import org.apache.dubbo.common.extension.activate.ActivateExt1;
@Activate(group = "old_group")
public class OldActivateExt1Impl2 implements ActivateExt1 {
public String echo(String msg) {
return msg;
}
}

View File

@ -0,0 +1,27 @@
/*
* 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.extension.activate.impl;
import com.alibaba.dubbo.common.extension.Activate;
import org.apache.dubbo.common.extension.activate.ActivateExt1;
@Activate(group = "old_group")
public class OldActivateExt1Impl3 implements ActivateExt1 {
public String echo(String msg) {
return msg;
}
}

View File

@ -32,17 +32,20 @@ public class ActivateComparatorTest {
Filter2 f2 = new Filter2();
Filter3 f3 = new Filter3();
Filter4 f4 = new Filter4();
OldFilter5 f5 = new OldFilter5();
List<Filter0> filters = new ArrayList<>();
filters.add(f1);
filters.add(f2);
filters.add(f3);
filters.add(f4);
filters.add(f5);
Collections.sort(filters, ActivateComparator.COMPARATOR);
Assert.assertEquals(f4, filters.get(0));
Assert.assertEquals(f3, filters.get(1));
Assert.assertEquals(f2, filters.get(2));
Assert.assertEquals(f1, filters.get(3));
Assert.assertEquals(f5, filters.get(1));
Assert.assertEquals(f3, filters.get(2));
Assert.assertEquals(f2, filters.get(3));
Assert.assertEquals(f1, filters.get(4));
}
}

View File

@ -0,0 +1,20 @@
/*
* 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.extension.support;
public interface OldFilter0 extends Filter0 {
}

View File

@ -0,0 +1,24 @@
/*
* 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.extension.support;
import com.alibaba.dubbo.common.extension.Activate;
@Activate(after = "_4")
public class OldFilter5 implements OldFilter0 {
}

View File

@ -1,4 +1,6 @@
group=org.apache.dubbo.common.extension.activate.impl.GroupActivateExtImpl
value=org.apache.dubbo.common.extension.activate.impl.ValueActivateExtImpl
order1=org.apache.dubbo.common.extension.activate.impl.OrderActivateExtImpl1
order2=org.apache.dubbo.common.extension.activate.impl.OrderActivateExtImpl2
order2=org.apache.dubbo.common.extension.activate.impl.OrderActivateExtImpl2
old1=org.apache.dubbo.common.extension.activate.impl.OldActivateExt1Impl2
old2=org.apache.dubbo.common.extension.activate.impl.OldActivateExt1Impl3

View File

@ -1,4 +1,5 @@
_1=org.apache.dubbo.common.extension.support.Filter1
_2=org.apache.dubbo.common.extension.support.Filter2
_3=org.apache.dubbo.common.extension.support.Filter3
_4=org.apache.dubbo.common.extension.support.Filter4
_4=org.apache.dubbo.common.extension.support.Filter4
_5=org.apache.dubbo.common.extension.support.OldFilter5

View File

@ -18,13 +18,11 @@
package com.alibaba.dubbo.rpc;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.RpcException;
@Deprecated
public interface Invoker<T> extends org.apache.dubbo.rpc.Invoker<T> {
Result invoke(Invocation invocation) throws RpcException;
Result invoke(org.apache.dubbo.rpc.Invocation invocation) throws RpcException;
default org.apache.dubbo.rpc.Invoker<T> getOriginal() {
return null;
@ -44,8 +42,8 @@ public interface Invoker<T> extends org.apache.dubbo.rpc.Invoker<T> {
}
@Override
public Result invoke(Invocation invocation) throws RpcException {
return new Result.CompatibleResult(invoker.invoke(invocation));
public Result invoke(org.apache.dubbo.rpc.Invocation invocation) throws RpcException {
return new Result.CompatibleResult(invoker.invoke(((Invocation) invocation).getOriginal()));
}
@Override