背景
有一个服务负责调用第三方服务,每个第三方的服务都设置了开关,开关打开的时候调用第三方服务获取数据,开关关闭的时候返回模拟数据。
这里使用aspectj的around来拦截所有请求,如果是测试环境且满足特定条件,加载模拟数据并返回,否则调用真实服务。
aspectj官方文档
http://www.eclipse.org/aspectj/doc/released/progguide/index.html
maven中的配置
增加aspectj依赖
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.9</version>
</dependency>
增加aspectj plugin配置
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.9</version>
</plugin>
eclipse安装ajdt插件
插件地址: http://download.eclipse.org/tools/ajdt/46/dev/update
java项目转为aspectj项目
选中项目,右键Configure-> Convert to AspectJ Project
eclipse会自动修改对应的配置文件:
.classpath中增加
<classpathentry kind="con" path="org.eclipse.ajdt.core.ASPECTJRT_CONTAINER"/>
.project中javabuilder被修改为ajbuilder
<buildCommand>
<name>org.eclipse.ajdt.core.ajbuilder</name>
<arguments>
</arguments>
</buildCommand>
拦截服务
public aspect MockServiceAspect {
private static final Logger LOG = Logger.getLogger(MockServiceAspect.class);
pointcut toolsRouter(Request request, BasicDBObject response) :
args(request, response) && execution(public void xx.xxx.xxx.ToolsRouter.route(Request, BasicDBObject));
void around(Request request, BasicDBObject response) : toolsRouter(request, response) {
try {
String environment = Config.environment;
String mockServices = Config.mockServices;
String mockFilePath = Config.mockFilePath;
if(environment.contains("test") && StringUtils.isNotEmpty(mockServices)) {
String uri = request.getUri();
String filePath = "";
String[] serviceArray = mockServices.split(",");
for(String service : serviceArray) {
if(uri.contains(service) && MgoUtil.hasShutdown(service)) {
filePath = mockFilePath + service + ".json";
break;
}
}
if(StringUtils.isNotEmpty(filePath)) {
LOG.info("uri:" + uri + ", 返回模拟数据。");
String info = FileUtil.readAll(filePath);
BasicDBObject mockObj = StringUtil.parseJson(info);
response.clear();
response.putAll((BSONObject)mockObj);
LOG.info("uri:" + uri + ", mock response:" + response);
return;
}
}
proceed(request, response);
} catch (Exception e) {
LOG.error("拦截服务出现异常, error:" + e.getMessage(), e);
}
}
}
配置对应的服务及相应数据
config.properties中配置数据
mockServices=xxx,xxx,xx_xx,xxx
mockFilePath=xxx/
把响应数据放到对应目录下