Code Analysis For Context-Path Plugin
Before starting, you can refer to this article to start the gateway
#
BodyFirst, look at the ContextPathPlugin#doExecute
method, which is the core of this plugin.
protected Mono<Void> doExecute(final ServerWebExchange exchange, final ShenyuPluginChain chain, final SelectorData selector, final RuleData rule) { ... // 1. get the contextMappingHandle from the JVM cache ContextMappingHandle contextMappingHandle = ContextPathPluginDataHandler.CACHED_HANDLE.get().obtainHandle(CacheKeyUtils.INST.getKey(rule)); ... // 2. set shenyu context according to contextMappingHandle buildContextPath(shenyuContext, contextMappingHandle); return chain.execute(exchange);}
Get the
contextMappingHandle
from the JVM cacheThe
contextMappingHandle
here is an instance of theContextMappingHandle
class, which has two member variables:contextPath
andaddPrefix
These two variables have appeared in the Rules form in the Admin before, and they are updated when the data is synchronized.
Set shenyu context according to contextMappingHandle
Below is the source code of the
ContextPathPlugin#buildContextPath
methodprivate void buildContextPath(final ShenyuContext context, final ContextMappingHandle handle) { String realURI = ""; // 1. set the context path of shenyu, remove the prefix of the real URI according to the length of the contextPath if (StringUtils.isNoneBlank(handle.getContextPath())) { context.setContextPath(handle.getContextPath()); context.setModule(handle.getContextPath()); realURI = context.getPath().substring(handle.getContextPath().length()); } // add prefix if (StringUtils.isNoneBlank(handle.getAddPrefix())) { if (StringUtils.isNotBlank(realURI)) { realURI = handle.getAddPrefix() + realURI; } else { realURI = handle.getAddPrefix() + context.getPath(); } } context.setRealUrl(realURI);}
Set the context path of shenyu, remove the prefix of the real URI according to the length of the contextPath
You may be wondering whether there is a problem with the so-called "according to the length of the contextPath" here?
In fact, such a judgment is not a problem, because the request will be processed by the plugin only after it is matched by the Selector and Rules. Therefore, under the premise of setting up Selector and Rules, it is completely possible to meet the needs of converting a specific contextPath.
Then, the ContextPathPlugin
class has a more important method skip
, part of the code is shown below. We can find: If it is a call to the RPC service, the context_path plugin will be skipped directly.
public Boolean skip(final ServerWebExchange exchange) { ... return Objects.equals(rpcType, RpcTypeEnum.DUBBO.getName()) || Objects.equals(rpcType, RpcTypeEnum.GRPC.getName()) || Objects.equals(rpcType, RpcTypeEnum.TARS.getName()) || Objects.equals(rpcType, RpcTypeEnum.MOTAN.getName()) || Objects.equals(rpcType, RpcTypeEnum.SOFA.getName());}
Finally, the context-path plugin has another class ContextPathPluginDataHandler
. The function of this class is to subscribe to the data of the plug-in. When the plugin configuration is modified, deleted, or added, the data is modified, deleted, or added to the JVM cache.