use of org.apache.dubbo.rpc.Invoker in project dubbo by alibaba.
the class TagRouter method route.
@Override
public <T> List<Invoker<T>> route(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException {
if (CollectionUtils.isEmpty(invokers)) {
return invokers;
}
// since the rule can be changed by config center, we should copy one to use.
final TagRouterRule tagRouterRuleCopy = tagRouterRule;
if (tagRouterRuleCopy == null || !tagRouterRuleCopy.isValid() || !tagRouterRuleCopy.isEnabled()) {
return filterUsingStaticTag(invokers, url, invocation);
}
List<Invoker<T>> result = invokers;
String tag = StringUtils.isEmpty(invocation.getAttachment(TAG_KEY)) ? url.getParameter(TAG_KEY) : invocation.getAttachment(TAG_KEY);
// if we are requesting for a Provider with a specific tag
if (StringUtils.isNotEmpty(tag)) {
List<String> addresses = tagRouterRuleCopy.getTagnameToAddresses().get(tag);
// filter by dynamic tag group first
if (CollectionUtils.isNotEmpty(addresses)) {
result = filterInvoker(invokers, invoker -> addressMatches(invoker.getUrl(), addresses));
// if result is not null OR it's null but force=true, return result directly
if (CollectionUtils.isNotEmpty(result) || tagRouterRuleCopy.isForce()) {
return result;
}
} else {
// dynamic tag group doesn't have any item about the requested app OR it's null after filtered by
// dynamic tag group but force=false. check static tag
result = filterInvoker(invokers, invoker -> tag.equals(invoker.getUrl().getParameter(TAG_KEY)));
}
// to false, which means it will invoke any providers without a tag unless it's explicitly disallowed.
if (CollectionUtils.isNotEmpty(result) || isForceUseTag(invocation)) {
return result;
} else // FAILOVER: return all Providers without any tags.
{
List<Invoker<T>> tmp = filterInvoker(invokers, invoker -> addressNotMatches(invoker.getUrl(), tagRouterRuleCopy.getAddresses()));
return filterInvoker(tmp, invoker -> StringUtils.isEmpty(invoker.getUrl().getParameter(TAG_KEY)));
}
} else {
// List<String> addresses = tagRouterRule.filter(providerApp);
// return all addresses in dynamic tag group.
List<String> addresses = tagRouterRuleCopy.getAddresses();
if (CollectionUtils.isNotEmpty(addresses)) {
result = filterInvoker(invokers, invoker -> addressNotMatches(invoker.getUrl(), addresses));
// 1. all addresses are in dynamic tag group, return empty list.
if (CollectionUtils.isEmpty(result)) {
return result;
}
// 2. if there are some addresses that are not in any dynamic tag group, continue to filter using the
// static tag group.
}
return filterInvoker(result, invoker -> {
String localTag = invoker.getUrl().getParameter(TAG_KEY);
return StringUtils.isEmpty(localTag) || !tagRouterRuleCopy.getTagNames().contains(localTag);
});
}
}
use of org.apache.dubbo.rpc.Invoker in project dubbo by alibaba.
the class ZoneAwareClusterInvoker method list.
@Override
protected List<Invoker<T>> list(Invocation invocation) throws RpcException {
List<Invoker<T>> invokers = super.list(invocation);
if (null == invokers || invokers.size() < 2) {
return invokers;
}
List<Invoker<T>> interfaceInvokers = new ArrayList<>();
List<Invoker<T>> serviceInvokers = new ArrayList<>();
boolean addressChanged = false;
for (Invoker<T> invoker : invokers) {
MigrationClusterInvoker migrationClusterInvoker = (MigrationClusterInvoker) invoker;
if (migrationClusterInvoker.isServiceInvoker()) {
serviceInvokers.add(invoker);
} else {
interfaceInvokers.add(invoker);
}
if (migrationClusterInvoker.invokersChanged().compareAndSet(true, false)) {
addressChanged = true;
}
}
if (serviceInvokers.isEmpty() || interfaceInvokers.isEmpty()) {
return invokers;
}
MigrationRule rule = null;
for (Invoker<T> invoker : serviceInvokers) {
MigrationClusterInvoker migrationClusterInvoker = (MigrationClusterInvoker) invoker;
if (rule == null) {
rule = migrationClusterInvoker.getMigrationRule();
continue;
}
// inconsistency rule
if (!rule.equals(migrationClusterInvoker.getMigrationRule())) {
rule = MigrationRule.queryRule();
break;
}
}
MigrationStep step = rule.getStep();
switch(step) {
case FORCE_INTERFACE:
clusterRefresh(addressChanged, interfaceInvokers);
clusterDestroy(addressChanged, serviceInvokers, true);
if (logger.isDebugEnabled()) {
logger.debug("step is FORCE_INTERFACE");
}
return interfaceInvokers;
case APPLICATION_FIRST:
clusterRefresh(addressChanged, serviceInvokers);
clusterRefresh(addressChanged, interfaceInvokers);
boolean serviceAvailable = !serviceInvokers.isEmpty();
if (serviceAvailable) {
if (shouldMigrate(addressChanged, serviceInvokers, interfaceInvokers)) {
if (logger.isDebugEnabled()) {
logger.debug("step is APPLICATION_FIRST shouldMigrate true get serviceInvokers");
}
return serviceInvokers;
}
}
if (logger.isDebugEnabled()) {
logger.debug("step is APPLICATION_FIRST " + (serviceInvokers.isEmpty() ? "serviceInvokers is empty" : "shouldMigrate false") + " get interfaceInvokers");
}
return interfaceInvokers;
case FORCE_APPLICATION:
clusterRefresh(addressChanged, serviceInvokers);
clusterDestroy(addressChanged, interfaceInvokers, true);
if (logger.isDebugEnabled()) {
logger.debug("step is FORCE_APPLICATION");
}
return serviceInvokers;
}
throw new UnsupportedOperationException(rule.getStep().name());
}
use of org.apache.dubbo.rpc.Invoker in project dubbo by alibaba.
the class MockClusterInvoker method doMockInvoke.
@SuppressWarnings({ "unchecked", "rawtypes" })
private Result doMockInvoke(Invocation invocation, RpcException e) {
Result result = null;
Invoker<T> minvoker;
List<Invoker<T>> mockInvokers = selectMockInvoker(invocation);
if (CollectionUtils.isEmpty(mockInvokers)) {
minvoker = (Invoker<T>) new MockInvoker(getUrl(), directory.getInterface());
} else {
minvoker = mockInvokers.get(0);
}
try {
result = minvoker.invoke(invocation);
} catch (RpcException me) {
if (me.isBiz()) {
result = AsyncRpcResult.newDefaultAsyncResult(me.getCause(), invocation);
} else {
throw new RpcException(me.getCode(), getMockExceptionMessage(e, me), me.getCause());
}
} catch (Throwable me) {
throw new RpcException(getMockExceptionMessage(e, me), me.getCause());
}
return result;
}
use of org.apache.dubbo.rpc.Invoker in project dubbo by alibaba.
the class ClassLoaderFilterTest method testInvoke.
@Test
public void testInvoke() throws Exception {
URL url = URL.valueOf("test://test:11/test?accesslog=true&group=dubbo&version=1.1");
String path = DemoService.class.getResource("/").getPath();
final URLClassLoader cl = new URLClassLoader(new java.net.URL[] { new java.net.URL("file:" + path) }) {
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
try {
return findClass(name);
} catch (ClassNotFoundException e) {
return super.loadClass(name);
}
}
};
final Class<?> clazz = cl.loadClass(DemoService.class.getCanonicalName());
Invoker invoker = new MyInvoker(url) {
@Override
public Class getInterface() {
return clazz;
}
@Override
public Result invoke(Invocation invocation) throws RpcException {
Assertions.assertEquals(cl, Thread.currentThread().getContextClassLoader());
return null;
}
};
Invocation invocation = Mockito.mock(Invocation.class);
classLoaderFilter.invoke(invoker, invocation);
}
use of org.apache.dubbo.rpc.Invoker in project dubbo by alibaba.
the class ContextFilterTest method testSetContext.
@SuppressWarnings("unchecked")
@Test
public void testSetContext() {
invocation = mock(Invocation.class);
given(invocation.getMethodName()).willReturn("$enumlength");
given(invocation.getParameterTypes()).willReturn(new Class<?>[] { Enum.class });
given(invocation.getArguments()).willReturn(new Object[] { "hello" });
given(invocation.getObjectAttachments()).willReturn(null);
invoker = mock(Invoker.class);
given(invoker.isAvailable()).willReturn(true);
given(invoker.getInterface()).willReturn(DemoService.class);
AppResponse result = new AppResponse();
result.setValue("High");
given(invoker.invoke(invocation)).willReturn(result);
URL url = URL.valueOf("test://test:11/test?group=dubbo&version=1.1");
given(invoker.getUrl()).willReturn(url);
contextFilter.invoke(invoker, invocation);
assertNull(RpcContext.getContext().getInvoker());
}
Aggregations