Skip to content

Commit

Permalink
引入TagRouter
Browse files Browse the repository at this point in the history
  • Loading branch information
xujingfeng committed Dec 26, 2018
1 parent ac49a7d commit 53a58f8
Show file tree
Hide file tree
Showing 16 changed files with 368 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,11 @@ public interface Router extends Comparable<Router> {
*/
<T> List<Invoker<T>> route(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException;

/**
* router priority
*
* @return
*/
int getPriority();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.alibaba.dubbo.rpc.cluster.router;

import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.rpc.cluster.Router;

public abstract class AbstractRouter implements Router {

protected int priority;
protected URL url;

@Override
public URL getUrl() {
return url;
}

@Override
public int getPriority() {
return priority;
}

@Override
public int compareTo(Router o) {
return (this.getPriority() >= o.getPriority()) ? 1 : -1;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
* If a request is configured to use mock, then this router guarantees that only the invokers with protocol MOCK appear in final the invoker list, all other invokers will be excluded.
*
*/
public class MockInvokersSelector implements Router {
public class MockInvokersSelector extends AbstractRouter {

@Override
public <T> List<Invoker<T>> route(final List<Invoker<T>> invokers,
Expand Down Expand Up @@ -87,11 +87,12 @@ private <T> boolean hasMockProviders(final List<Invoker<T>> invokers) {
return hasMockProvider;
}

@Override
public URL getUrl() {
return null;
}

/**
* Always stay on the top of the list
*
* @param o
* @return
*/
@Override
public int compareTo(Router o) {
return 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.RpcException;
import com.alibaba.dubbo.rpc.cluster.Router;
import com.alibaba.dubbo.rpc.cluster.router.AbstractRouter;

import java.text.ParseException;
import java.util.ArrayList;
Expand All @@ -42,12 +42,10 @@
* ConditionRouter
*
*/
public class ConditionRouter implements Router, Comparable<Router> {
public class ConditionRouter extends AbstractRouter {

private static final Logger logger = LoggerFactory.getLogger(ConditionRouter.class);
private static Pattern ROUTE_PATTERN = Pattern.compile("([&!=,]*)\\s*([^&!=,\\s]+)");
private final URL url;
private final int priority;
private final boolean force;
private final Map<String, MatchPair> whenCondition;
private final Map<String, MatchPair> thenCondition;
Expand Down Expand Up @@ -174,20 +172,6 @@ public <T> List<Invoker<T>> route(List<Invoker<T>> invokers, URL url, Invocation
return invokers;
}

@Override
public URL getUrl() {
return url;
}

@Override
public int compareTo(Router o) {
if (o == null || o.getClass() != ConditionRouter.class) {
return 1;
}
ConditionRouter c = (ConditionRouter) o;
return this.priority == c.priority ? url.toFullString().compareTo(c.url.toFullString()) : (this.priority > c.priority ? 1 : -1);
}

boolean matchWhen(URL url, Invocation invocation) {
return whenCondition == null || whenCondition.isEmpty() || matchCondition(whenCondition, url, null, invocation);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.RpcContext;
import com.alibaba.dubbo.rpc.RpcException;
import com.alibaba.dubbo.rpc.cluster.Router;
import com.alibaba.dubbo.rpc.cluster.router.AbstractRouter;

import javax.script.Bindings;
import javax.script.Compilable;
Expand All @@ -42,20 +42,16 @@
* ScriptRouter
*
*/
public class ScriptRouter implements Router {
public class ScriptRouter extends AbstractRouter {

private static final Logger logger = LoggerFactory.getLogger(ScriptRouter.class);

private static final Map<String, ScriptEngine> engines = new ConcurrentHashMap<String, ScriptEngine>();

private final ScriptEngine engine;

private final int priority;

private final String rule;

private final URL url;

public ScriptRouter(URL url) {
this.url = url;
String type = url.getParameter(Constants.TYPE_KEY);
Expand All @@ -79,11 +75,6 @@ public ScriptRouter(URL url) {
this.rule = rule;
}

@Override
public URL getUrl() {
return url;
}

@Override
@SuppressWarnings("unchecked")
public <T> List<Invoker<T>> route(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException {
Expand Down Expand Up @@ -114,13 +105,4 @@ public <T> List<Invoker<T>> route(List<Invoker<T>> invokers, URL url, Invocation
}
}

@Override
public int compareTo(Router o) {
if (o == null || o.getClass() != ScriptRouter.class) {
return 1;
}
ScriptRouter c = (ScriptRouter) o;
return this.priority == c.priority ? rule.compareTo(c.rule) : (this.priority > c.priority ? 1 : -1);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* 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.rpc.cluster.router.tag;

import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.common.logger.Logger;
import com.alibaba.dubbo.common.logger.LoggerFactory;
import com.alibaba.dubbo.common.utils.StringUtils;
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.RpcContext;
import com.alibaba.dubbo.rpc.RpcException;
import com.alibaba.dubbo.rpc.cluster.router.AbstractRouter;

import java.util.ArrayList;
import java.util.List;

/**
* TagRouter
*/
public class TagRouter extends AbstractRouter {

private static final Logger logger = LoggerFactory.getLogger(TagRouter.class);
private static final int DEFAULT_PRIORITY = 100;
private static final URL ROUTER_URL = new URL("tag", Constants.ANYHOST_VALUE, 0, Constants.ANY_VALUE).addParameters(Constants.RUNTIME_KEY, "true");

public TagRouter(URL url) {
this.url = url;
this.priority = url.getParameter(Constants.PRIORITY_KEY, DEFAULT_PRIORITY);
}

public TagRouter() {
this.url = ROUTER_URL;
this.priority = url.getParameter(Constants.PRIORITY_KEY, DEFAULT_PRIORITY);
}

@Override
public URL getUrl() {
return url;
}

@Override
public <T> List<Invoker<T>> route(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException {
// filter
List<Invoker<T>> result = new ArrayList<Invoker<T>>();
try {
// Dynamic param
String tag = RpcContext.getContext().getAttachment(Constants.REQUEST_TAG_KEY);
// Tag request
if (!StringUtils.isEmpty(tag)) {
// Select tag invokers first
for (Invoker<T> invoker : invokers) {
if (tag.equals(invoker.getUrl().getParameter(Constants.TAG_KEY))) {
result.add(invoker);
}
}
}
// If Constants.REQUEST_TAG_KEY unspecified or no invoker be selected, downgrade to normal invokers
if (result.isEmpty()) {
for (Invoker<T> invoker : invokers) {
if (StringUtils.isEmpty(invoker.getUrl().getParameter(Constants.TAG_KEY))) {
result.add(invoker);
}
}
}
return result;
} catch (Exception e) {
logger.error("Route by tag error,return all invokers.", e);
}
// Downgrade to all invokers
return invokers;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* 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.rpc.cluster.router.tag;

import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.rpc.cluster.Router;
import com.alibaba.dubbo.rpc.cluster.RouterFactory;

public class TagRouterFactory implements RouterFactory {

public static final String NAME = "tag";

@Override
public Router getRouter(URL url) {
return new TagRouter(url);
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
file=com.alibaba.dubbo.rpc.cluster.router.file.FileRouterFactory
script=com.alibaba.dubbo.rpc.cluster.router.script.ScriptRouterFactory
condition=com.alibaba.dubbo.rpc.cluster.router.condition.ConditionRouterFactory
condition=com.alibaba.dubbo.rpc.cluster.router.condition.ConditionRouterFactory
tag=com.alibaba.dubbo.rpc.cluster.router.tag.TagRouterFactory
Loading

0 comments on commit 53a58f8

Please sign in to comment.