blob: 752fe04cbf30eadac97c8b8f1bb86f109ce9cfb1 [file] [view]
---
title: Code Analysis For Context-Path Plugin
author: Kunshuai Zhu
author_title: Apache ShenYu Contributor
author_url: https://github.com/JooKS-me
author_image_url: https://avatars1.githubusercontent.com/u/62384022?v=4
tags: [Context-Path, Apache ShenYu]
---
> Before starting, you can refer to [this article](./start-demo) to start the gateway
### Body
First, look at the `ContextPathPlugin#doExecute` method, which is the core of this plugin.
```java
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);
}
```
1. Get the `contextMappingHandle` from the JVM cache
The `contextMappingHandle` here is an instance of the `ContextMappingHandle` class, which has two member variables: `contextPath` and `addPrefix`
These two variables have appeared in the Rules form in the Admin before, and they are updated when the data is synchronized.
2. Set shenyu context according to contextMappingHandle
Below is the source code of the `ContextPathPlugin#buildContextPath` method
```java
private 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.**
```java
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.