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.
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();

}
@@ -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;
}
}
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
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
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);
}

}
@@ -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;
}

}
@@ -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);
}
}
@@ -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

0 comments on commit 53a58f8

Please sign in to comment.