Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
import org.apache.dubbo.rpc.cluster.router.tag.model.TagRouterRule;
import org.apache.dubbo.rpc.cluster.router.tag.model.TagRuleParser;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
Expand All @@ -54,6 +57,7 @@ public class TagStateRouter<T> extends AbstractStateRouter<T> implements Configu
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(TagStateRouter.class);
private static final String RULE_SUFFIX = ".tag-router";
public static final char TAG_SEPERATOR = '|';
private static final String TAGS_SUPPORT = "tags.support";

private volatile TagRouterRule tagRouterRule;
private String application;
Expand Down Expand Up @@ -137,8 +141,7 @@ public BitList<Invoker<T>> doRoute(
} 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)));
result = filterInvoker(invokers, predicateEqual(tag, url.getParameter(TAGS_SUPPORT, false)));
}
// If there's no tagged providers that can match the current tagged request. force.tag is set by default
// to false, which means it will invoke any providers without a tag unless it's explicitly disallowed.
Expand Down Expand Up @@ -196,19 +199,17 @@ public BitList<Invoker<T>> doRoute(
* @param invokers
* @param url
* @param invocation
* @param <T>
* @return
*/
private <T> BitList<Invoker<T>> filterUsingStaticTag(BitList<Invoker<T>> invokers, URL url, Invocation invocation) {
private BitList<Invoker<T>> filterUsingStaticTag(BitList<Invoker<T>> invokers, URL url, Invocation invocation) {
BitList<Invoker<T>> result;
// Dynamic param
String tag = StringUtils.isEmpty(invocation.getAttachment(TAG_KEY))
? url.getParameter(TAG_KEY)
: invocation.getAttachment(TAG_KEY);
// Tag request
if (!StringUtils.isEmpty(tag)) {
result = filterInvoker(
invokers, invoker -> tag.equals(invoker.getUrl().getParameter(TAG_KEY)));
result = filterInvoker(invokers, predicateEqual(tag, url.getParameter(TAGS_SUPPORT, false)));
if (CollectionUtils.isEmpty(result) && !isForceUseTag(invocation)) {
result = filterInvoker(
invokers,
Expand All @@ -221,6 +222,26 @@ private <T> BitList<Invoker<T>> filterUsingStaticTag(BitList<Invoker<T>> invoker
return result;
}

private Predicate<Invoker<T>> predicateEqual(String tag, boolean tagsEnable) {
return invoker -> {
List<String> consumerTags;
List<String> providerTags;
if (tagsEnable) {
consumerTags = StringUtils.splitToList(tag, ',');
} else {
consumerTags = tag != null ? Arrays.asList(tag) : Collections.emptyList();
}
boolean providerTagEnable = invoker.getUrl().getParameter(TAGS_SUPPORT, false);
if (providerTagEnable) {
providerTags = StringUtils.splitToList(invoker.getUrl().getParameter(TAG_KEY), ',');
} else {
String providerTag = invoker.getUrl().getParameter(TAG_KEY);
providerTags = providerTag != null ? Arrays.asList(providerTag) : Collections.emptyList();
}
return !Collections.disjoint(consumerTags, providerTags);
};
}

@Override
public boolean isRuntime() {
return tagRouterRule != null && tagRouterRule.isRuntime();
Expand All @@ -237,7 +258,7 @@ private boolean isForceUseTag(Invocation invocation) {
invocation.getAttachment(FORCE_USE_TAG, this.getUrl().getParameter(FORCE_USE_TAG, "false")));
}

private <T> BitList<Invoker<T>> filterInvoker(BitList<Invoker<T>> invokers, Predicate<Invoker<T>> predicate) {
private BitList<Invoker<T>> filterInvoker(BitList<Invoker<T>> invokers, Predicate<Invoker<T>> predicate) {
if (invokers.stream().allMatch(predicate)) {
return invokers;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,4 +298,37 @@ public void tagLevelForceTest() {
Set<String> selectedAddresses = TagStateRouter.selectAddressByTagLevel(tagAddresses, "beta", true);
Assertions.assertEquals(addresses, selectedAddresses);
}

@Test
void testTagsRoutePickInvokers() {
StateRouter router = new TagStateRouterFactory().getRouter(TagRouterRule.class, url);

List<Invoker<String>> originInvokers = new ArrayList<>();

URL url1 = URL.valueOf("test://127.0.0.1:7777/DemoInterface?dubbo.tag=tag2,tag1")
.setScopeModel(moduleModel);
url1 = url1.addParameter("tags.support", "true");
URL url2 = URL.valueOf("test://127.0.0.1:7778/DemoInterface?dubbo.tag=tag1")
.setScopeModel(moduleModel);
URL url3 = URL.valueOf("test://127.0.0.1:7779/DemoInterface?dubbo.tag=tag2")
.setScopeModel(moduleModel);
URL url4 = URL.valueOf("test://127.0.0.1:7779/DemoInterface").setScopeModel(moduleModel);
Invoker<String> invoker1 = new MockInvoker<>(url1, true);
Invoker<String> invoker2 = new MockInvoker<>(url2, true);
Invoker<String> invoker3 = new MockInvoker<>(url3, true);
Invoker<String> invoker4 = new MockInvoker<>(url4, true);

originInvokers.add(invoker1);
originInvokers.add(invoker2);
originInvokers.add(invoker3);
originInvokers.add(invoker4);
BitList<Invoker<String>> invokers = new BitList<>(originInvokers);
RpcInvocation invocation = new RpcInvocation();
invocation.setAttachment(TAG_KEY, "tag2");
List<Invoker<String>> filteredInvokers =
router.route(invokers.clone(), invokers.get(0).getUrl(), invocation, false, new Holder<>());
Assertions.assertEquals(2, filteredInvokers.size());
Assertions.assertTrue(filteredInvokers.contains(invoker1));
Assertions.assertTrue(filteredInvokers.contains(invoker3));
}
}
Loading