PRIMETON INFORMATION TECHNOLOGIES, INC. 普元信息技术股份有限公司 Primeton ESB6.6 程序员手册 - 拦截器开发手册 普元公司对包括但不限于提供的产品或服务的全部内容及本材料拥有版权等知识产权, 受法律保 护 未经本公司书面许可, 任何单位及个人不得以任何方式或理由对上述产品 服务 信息 材 料的任何部分进行使用 复制 修改 抄录 传播或与其它产品捆绑使用 销售 Copyright 2003-2017 普元信息技术股份有限公司版权所有
目录 第 1 章简介...3 1.1 拦截器介绍...3 1.2 拦截器开发目录介绍...4 第 2 章拦截器开发...6 2.1 拦截器开发 ( 黑名单拦截器开发为例 )...6 2.1.1 拦截器开发 ( 黑名单拦截器 )...6 2.1.2 拦截器策略数据...7 2.1.3 拦截器 RuntimeHandler...8 2.2 策略数据初始化... 9 2.2.1 命名变量接口...9 2.2.2 策略数据加载...9 2.2.3 PolicyDataHander 类...11 2.2.4 策略工厂...13 2.3 JMX 服务数据同步处理...15 第 3 章拦截器配置... 16 3.1 Server 启动配置...16 3.2 配置文件 esb_interception.xml...17 3.3 配置文件 hander_startup.xml...17 3.4 配置文件 config esb-jdbc.properties...18 3.5 把拦截器 jar 包导入 server...19 第 4 章拦截器测试... 20 4.1 黑名单拦截器实例展示...20 第 5 章附录... 23
第 1 章 简介 1.1 拦截器介绍 本文以黑名单拦截为例, 说明如何开发符合客户需求的拦截器 拦截器接口为 IInterceptor4Service<Message<?>, ITransport<T>>, 用户开发拦截器必须实现这个接口, 在这个接口的 beforehandle(msg message, CTX contex t),afterhandle(msg message, CTX context) 加入对拦截器的要求, 例如 : 该拦截器需要落日志, 对文件进行操作, 对数据库进行操作等等 拦截器接口 IInterceptor4Service 说明 : open() close() isopen() beforehandle(message<?> message, 方法打开拦截器方法关闭拦截器方法标识拦截器是否打开方法是在该服务的消息进行转换前调用 ITransport<T> transport) afterhandle(message<?> message, IT 方法是在该服务的消息进行转换后调用 ransport<t> context) 代码 : public class IpBlackListControlInterceptor <T> implements ice<message<?>, ITransport<T>>{ IInterceptor4Serv protected final static ILogger logger = LoggerFactory.getInstance().getLogger(IpBl acklistcontrolinterceptor.class); public int beforehandle(message<?> message, ITransport<T> transport) { return CONTINUE; public int afterhandle(message<?> message, ITransport<T> context) { 第 3 页共 23 页
return 0; public boolean isopen() { return true; public void open() { public void close() { 1.2 拦截器开发目录介绍 com.primeton.esb.governance.interceptor.blackip 包是关于黑名单拦截器的 com.primeton.esb.governance.testinterceptor.common 包是关于拦截器类型变量定义接口 根据拦截器类型获取拦截器对象和重加载策略数据 加载策略数据 拦截器的策略工厂 第 4 页共 23 页
com.primeton.esb.governance.interceptor.policy.data 包是拦截器策略数据加载 com.primeton.esb.governance.interceptor.policy.runtimehandler 包是策略数据对外的接口 第 5 页共 23 页
第 2 章 拦截器开发 2.1 拦截器开发 ( 黑名单拦截器开发为例 ) 当用户访问 esb 部署的服务时, 拦截器可以在 Transport 代理服务 业务服务进行请求 响应 异常信息的拦截, 可以拦截协议头 消息体等信息, 进行业务处理 2.1.1 拦截器开发 ( 黑名单拦截器 ) 返回 CONTINUE, 则表示请求通过拦截器, 进入下个业务逻辑 ;BLOCK 表示 驳回请求 6
返回请求失败的响应消息 注 : 1. 黑名单拦截器应在服务消息进行转换前调用, 相关代码应写入 beforehandle (){ 2. 从消息中提取访问者 ip, 利用 BlackIpTestListControlPolicyRuntimeHandl er 的 exists() 方法判断该访问者是否需要拦截 如果该 IP 在黑名单中, 调用 send RejectMessage() 方法返回 error 消息 2.1.2 拦截器策略数据 黑名单拦截器策略数据定义代码 : public class BlackIpTestListControlPolicyData { private List<String> ipblacklist = new ArrayList<String>(); public List<String> getipblacklist() { return ipblacklist; public void setipblacklist(list<string> ipblacklist) { this.ipblacklist = ipblacklist; 第 7 页共 23 页
public boolean exists(string ip) { return ipblacklist.contains(ip); 注 : 1.BlackIpTestListControlPolicyData 类是黑名单策略数据的模型, 它会在 se rver 启动后初始化里面的数据, 在策略工厂里 BlackIpTestListControlPolicyDat a 对象中 ipblacklist 是有值的,ipBlackList 存放黑名单中的 ip 2.Exists() 方法判断参数中的 ip 是否存在于黑名单中 2.1.3 拦截器 RuntimeHandler RuntimeHandler 类主要提供了拦截器使用策略数据的接口 BlackIpTestListControlPolicyRuntimeHandler 类代码 : public class BlackIpTestListControlPolicyRuntimeHandler mehandler{ implements IPolicyRunti public Object getoperationpolicy(object obj) { BlackIpTestListControlPolicyData blackiptestlistcontrolpolicydata =Intercepto rtestpolicymanagefactory. getinstance().getblackiptestlistcontrolpolicydata(); String clientid = (String) obj; return blackiptestlistcontrolpolicydata.exists(clientid); 注 :BlackIpTestListControlPolicyRuntimeHandler 类实现了 com.primeton.e sb.governance.service.policy.manage 包的 IPolicyRuntimeHandler 接口, 重写 g etoperationpolicy() 方法 实现了判断访问者 IP 是否在黑名单中的功能, 它相当于一个操作黑名单策略数据模型的接口 第 8 页共 23 页
2.2 策略数据初始化 2.2.1 命名变量接口 接口 IInterceptorPolicyConstants: public interface IInterceptorPolicyConstants extends IPolicyConstants{ // 访问黑名单控制策略 public static String BIT_POLICY_TYPE="bit"; // 访问用户名密码验证控制策略 public static String ULT_POLICY_TYPE = "ult"; 注 : 定义了黑名单拦截器类型和服务访问控制拦截器类型, 该类继承了 IPolic yconstants 类, 定义的类型, 在 governer 前端业务逻辑根据类型调用拦截器会用到 2.2.2 策略数据加载 InterceptorPolicyDataInit 类 : 该类继承 com.primeton.esb.governance.service.policy.manage.impl 包中的 DefaultPolicyDataInit 类, 重写了 loadpolicydata() 方法 public void loadpolicydata() { super.loadpolicydata(); loadblackiplist(); loaduserpassword(); 注 : 这个扩展的子类 loadpolicydata() 方法来加载所有自定义拦截器的策略数 据, 该类会在 server 启动时调用, 初始化策略工厂里所有对象的数据 第 9 页共 23 页
public void loadblackiplist(){ List<String> ipblacklist = InterceptorTestPolicyManageFactory.getInstance().g etblackiptestlistcontrolpolicyd ata().getipblacklist(); Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { conn = DBConnectionManager.getInstance().getConnetion(); if (conn!= null) { String sql = "select app_ip from SAM_APPSYSTEM_BLACK_IP "; stmt = conn.preparestatement(sql); rs = stmt.executequery(); List<String> tmpipblacklist = new ArrayList<String>(); while (rs.next()) { tmpipblacklist.add(rs.getstring(1)); synchronized (ipblacklist) { ipblacklist.clear(); ipblacklist.addall(tmpipblacklist); catch (SQLException e) { logger.error(e); finally { DBConnectionManager.getInstance().close(rs); DBConnectionManager.getInstance().close(stmt); 第 10 页共 23 页
DBConnectionManager.getInstance().close(conn); 注 :loadblackiplist() 方法实现 : 把数据库 sam_appsystem_black_ip 表中的 i p 存放到工厂里的 blackiptestlistcontrolpolicydata 对象中, 实现了策略数据初始化 2.2.3 PolicyDataHander 类 InterceptorPolicyDataHandler 类 : 当 governer 对数据进行更新时, 数据库的数据会发生改变 但是策略数据在 server 启动时初始化的, 为了数据的同步, 通过 jms 消息通知 server 进行策略数据同步 该类继承 com.primeton.esb.governance.service.policy.manage.impl 包 Def aultpolicydatahandler 类, 重写了 getpolicydata() 和 notifypolicyupdate() 方法 public class InterceptorPolicyDataHandler extends DefaultPolicyDataHandler{ @SuppressWarnings("unchecked") @Override public <T> T getpolicydata(string policytype) { TYPE)) if (policytype.equalsignorecase(iinterceptorpolicyconstants.bit_policy_ return (T) InterceptorTestPolicyManageFactory.getInstance().getUser LoginTestControlPolicyData(); TYPE)) if (policytype.equalsignorecase(iinterceptorpolicyconstants.ult_policy_ return (T) InterceptorTestPolicyManageFactory.getInstance().getBlack IpTestListControlPolicyData(); else 第 11 页共 23 页
return null; ; @Override public void notifypolicyupdate(string policytype) { super.notifypolicyupdate(policytype); if (policytype.equalsignorecase(iinterceptorpolicyconstants.bit_policy_ TYPE)) { ydatainit() InterceptorTestPolicyManageFactory.getInstance().getInterceptorPolic.loadBlackIPList(); ainit() InterceptorTestPolicyManageFactory.getInstance().getDefaultPolicyDat.loadServiceIDData(); YPE)){ ainit() if(policytype.equalsignorecase(iinterceptorpolicyconstants.ult_policy_t InterceptorTestPolicyManageFactory.getInstance().getInterceptorPolicyDat.loadUserPassword(); ainit() InterceptorTestPolicyManageFactory.getInstance().getDefaultPolicyDat.loadServiceIDData(); 注 : 1.getPolicyData() 方法依赖策略类型获得策略数据对象 第 12 页共 23 页
2.notifyPolicyUpdate() 方法 : 通过 JMX 服务,client 端调用 server 端的 not ifypolicyupdate() 方法, 实现拦截器策略数据实时更新 2.2.4 策略工厂 InterceptorTestPolicyManageFactory 类 : 该类继承了 com.primeton.esb.governance.service.policy.factory 包的 Pol icymanagefactory 类, 对父类的扩展, 自定义的拦截器都可以加进去, 当 server 启动, 调用该类对象进行初始化操作 声明了所有关于拦截器的对象 public class InterceptorTestPolicyManageFactory extends ory{ PolicyManageFact public InterceptorTestPolicyManageFactory() { private static InterceptorTestPolicyManageFactory interceptorpolicyman agefactory = new InterceptorTestPolicyManageFactory(); public static InterceptorTestPolicyManageFactory getinstance() { return interceptorpolicymanagefactory; BlackIpTestListControlPolicyRuntimeHandler blackiptestlistcontrolpolicy RuntimeHandler = null; l; BlackIpTestListControlPolicyData blackiptestlistcontrolpolicydata = nul InterceptorPolicyDataInit interceptorpolicydatainit = null; UserLoginTestControlPolicyRuntimeHandler userlogintestcontrolpolicyr 第 13 页共 23 页
untimehandle = null; UserLoginTestControlPolicyData userlogintestcontrolpolicydata = null; 注 : 声明了所有对象, 创建调用工厂对象的方法 public void initsystem() { this.createobjectinstanceall(); super.getinstance().initsystem(); interceptorpolicydatainit.loadpolicydata(); 注 :initsystem() 方法先调用 createobjectinstanceall() 方法创建所 有对象, 调用 loadpolicydata() 方法初始化策略数据, 然后调用父类的 in itsystem 开启父类的自动更新策略数据 public void createobjectinstanceall() { InterceptorPolicyDataInit = new InterceptorPolicyDataInit(); blackiptestlistcontrolpolicyruntimehandler = new BlackIpTestListCo ntrolpolicyruntimehandler(); userlogintestcontrolpolicyruntimehandle = new UserLoginTestContr olpolicyruntimehandler(); ata(); a(); blackiptestlistcontrolpolicydata = new BlackIpTestListControlPolicyD userlogintestcontrolpolicydata = new UserLoginTestControlPolicyDat ; 注 :createobjectinstanceall() 方法创建所有声明对象的实例 public BlackIpTestListControlPolicyRuntimeHandler getblackiptestlistco ntrolpolicyruntimehandler() { 第 14 页共 23 页
return blackiptestlistcontrolpolicyruntimehandler; public BlackIpTestListControlPolicyData getblackiptestlistcontrolpolicyd ata() { return blackiptestlistcontrolpolicydata; public InterceptorPolicyDataInit getinterceptorpolicydatainit() { return interceptorpolicydatainit; public UserLoginTestControlPolicyRuntimeHandler getuserlogintestcont rolpolicyruntimehandle() { return userlogintestcontrolpolicyruntimehandle; public UserLoginTestControlPolicyData getuserlogintestcontrolpolicyda ta() { return userlogintestcontrolpolicydata; 注 : 后面是所有声明对象的 get 方法 2.3 JMX 服务数据同步处理 数据同步指的是 : 当 governer 对数据进行更新, 数据库的数据已经改变, 但是策略数据是 server 启动时初始化的, 为了数据的同步, 通过 jmx 消息通知 server 进行策略数据同步处理 com.primeton.esb.governance.service.runtime.jmx 包中的 JMXService 类 第 15 页共 23 页
当注册 Policy Data MBean 时,PolicyDataHandler 类 notifypolicyupdat e 方法应调用刚创建的子类 InterceptorPolicyDataHandler 的 notifypolicyup date 方法, 这样做自定义的拦截器策略数据才会更新 ( 下图 ): 第 3 章 拦截器配置 3.1 Server 启动配置 com.primeton.esb.governance.service.startup 包中的 ESBExtStartup 类 需要对策略启动类进行扩展, 把开发的拦截器加进去, 需要调用策略工厂对象来初始化策略数据 Start() 中策略数据初始化是应该调用刚创建的 InterceptorTestPolicyManage Factory 工厂类的 inisystem() 方法 第 16 页共 23 页
3.2 配置文件 esb_interception.xml 拦截器配置文件目录 server/eos/_srv/config/esb_interception.xml 3.3 配置文件 hander_startup.xml 目录 :\server\eos\_srv\config\system\hander_startup.xml 第 17 页共 23 页
打开启动加载数据库相关策略的配置 3.4 配置文件 config esb-jdbc.properties 目录 : esb_server\server\eos\_srv\config esb-jdbc.properties Esb 数据库配置 : 第 18 页共 23 页
3.5 把拦截器 jar 包导入 server 导出黑名单 IP 拦截器 : com.primeton.esb.governance.interceptor.ext.jar 将 jar 包粘贴到 [Server 安装目录 ]\server\plugins 目录下 第 19 页共 23 页
第 4 章 拦截器测试 4.1 黑名单拦截器实例展示 进入黑名单 IP 认证及配置 功能 前提 : 已创建好部署了服务的系统 需要拦截的访问系统 : 系统编码 com.primeton.esb.privider.custsystem 本地的 server IP 地址 : 127.0.0.1 访问我部署的 ws 代理服务的 u rl: http://127.0.0.1:9090/com.primeton.esb.provi der.custsystem.custmgrservice 在 Header 中配置 ClientId 访 问系统编码 : com.primeton.esb.provider.custsystem( 这是必 须配置的, 用来被拦截器识别系统 ) 访问结果 : 被黑名单拦截器拦截, 返回 error 信息 6
注 : 删除了本地 ip, 再次访问 : 第 21 页共 23 页
黑名单拦截器执行完成 ; 第 22 页共 23 页
第 5 章 附录 内附 PolicyDataHandler 和 ESBExtStartup 类代码 : 拦截器开发实例.rar 6