templete.md
10.5 KB
${事件名称}
1.概述
${事件说明}
2.请求地址
请求方法 | 协议 | 地址 |
---|---|---|
post | HTTP/REST | http://${ESB服务地址}/api/esb/execute |
execute | SOAP/WebService | http://${ESB服务地址}/services/ESBServiceV2?wsdl |
3.请求参数
名称 | 类型 | 必须 | 描述 |
---|---|---|---|
appkey | string | 是 | ESB 分配给产品的 AppKey ,进入 ESB 中心"产品管理-安全设置"可查看该产品的公共参数信息。 |
timestamp | long | 是 | 时间戳,精确到毫秒,时区需与 ESB 中心所在服务器的一致,ESB API 允许客户端最大时间误差为 15 分钟 |
username | string | 否 | 认证用户名,ESB 中心“产品管理-安全设置”中认证开启时必填 指定加密方式后,值为加密(username+timestamp) |
password | string | 否 | 认证密码,ESB 中心“产品管理-安全设置”中认证开启时必填 指定加密方式后,值为加密(password+timestamp) |
sign | string | 否 | API 输入参数签名结果,签名算法参照下面的介绍 |
format | string | 否 | 响应格式(${数据格式}) |
eventkey | string | 是 | 事件标识(${事件标识}) |
params | ${数据格式} | 是 | 请求数据 |
${请求参数}
4.响应参数
名称 | 类型 | 描述 |
---|---|---|
code | string | 请求返回的状态码 |
msg | string | 请求返回的状态说明 |
partialFailure | boolean | 是否存在接口执行失败跳过的情况发生(true:存在) |
data | ${数据格式} | 响应数据 |
${响应参数}
5.请求示例
5.1 SDK 请求示例
外部系统可以通过引入SDK的方式,调用SDK中提供的方法,触发ESB中的事件。 注: 1.SDK在"ESB中心-业务系统集成ESB导航-业务系统集成"中下载。 2.SDK中已对timestamp、sign、format等参数进行了处理,外部系统调用时,只需按照以下示例,传递参数即可。 3.requestConfig中设置的参数,可参考第3节中的请求参数说明。 4.事件返回结果,可参考第6节中的响应示例。
RequestConfig requestConfig = new RequestConfig();
requestConfig.setAppKey(appKey); //应用标识
requestConfig.setServerUrl(serverUrl);//ESB 服务所在地址
requestConfig.setSign(Boolean.True); //启用签名
requestConfig.setSercetKey(sercetKey);//签名密钥
requestConfig.setUserName(userName); //认证用户名,通过 SDK 调用无需加密,SDK 将根据加密方式自动加密
requestConfig.setPassword(password); //认证密码,通过 SDK 调用无需加密,SDK 将根据加密方式自动加密
requestConfig.setEncryption(encryption); //加密方式 MD5、SHA1
String eventkey = "${事件标识}"; //事件标识
String params = "${请求数据}"; //事件请求数据
EsbService service = EsbManager.getService("http", requestConfig); //获取 ESB 服务
String response = service.execute(eventkey, params); //触发 ESB 事件
5.2 OA 请求示例
OA系统已经集成了ESB相关的SDK,可参考以下方式触发ESB事件。 注: 1.请求参数,可参考第3节中的请求参数说明。 2.事件返回结果,可参考第6节中的响应示例。
String eventKey = "${事件标识}"; //事件标识
String params = "${请求数据}"; //事件请求参数
//EsbService其他方法及说明见ESB API接口说明文档
EsbService service = EsbClient.getService(); //获取 ESB 服务
String result = service.execute(eventkey, params);
5.3 HTTP 请求示例
HTTP请求包含2种方式,使用加密传输传输时,请求参数中需要对用户名、密码进行加密。
#用户名密码非加密传输
POST /api/esb/execute?appkey=应用标识&username=用户名&password=密码×tamp=时间戳format=${数据格式}&eventkey=${事件标识}¶ms=${请求数据} HTTP/1.1
Cache-Control: no-cache
Host: ${ESB服务地址}
#用户名密码加密传输
POST /api/esb/execute?appkey=应用标识&username=加密方法(用户名+时间戳)&password=加密方法(密码+时间戳)×tamp=时间戳format=${数据格式}&eventkey=${事件标识}¶ms=${请求数据} HTTP/1.1
Cache-Control: no-cache
Host: ${ESB服务地址}
6. 响应示例
${响应数据}
7. 错误码解释
错误码 | 错误消息 | 解决方案 |
---|---|---|
100 | 执行成功 | |
101 | 无有效应用 | 查看对应事件是否已发布应用 |
102 | 无同步应用 | 查看对应事件已发布的应用是否有同步类别的应用 |
201 | 无效的Appkey | 检查 appkey与 ESB 中心-产品管理-安全设置中的 appkey 是否一致 |
202 | 请求超时 | 检查传递的时间戳是否精确到毫秒 检查调用方的服务器时间与 ESB 中心的服务时间是否一致 |
203 | 签名错误 | 根据文档中的签名算法进行签名计算 关闭 ESB 中心-产品管理-安全设置中的签名校验开关 |
204 | IP 地址不在可访问名单 | 检查调用方的 IP 是否在ESB 中心-产品管理-安全设置-IP 白名单中 检查调用方的 IP 是否在ESB 中心-产品管理-安全设置-IP 黑名单中 关闭ESB 中心-产品管理-安全设置中的IP 限制开关 |
205 | 用户名、密码不正确 | 检查调用方传递的用户名、密码与 ESB 中心-产品管理-安全设置中的用户名、密码是否一致 关闭 ESB 中心-产品管理-安全设置中的认证开关 |
301 | 系统错误 | 检查系统日志 |
302 | 无有效事件 | 检查调用方传递的事件标识是否存在,且状态是否正确 |
303 | 执行失败 | 检查系统日志,查看应用对应接口是否可访问 查看对应接口配置的成功标识是否正确 |
304 | 模块标识格式错误 | 标识只能由字符、数字、下划线组成 |
305 | 事件标识格式错误 | 标识只能由字符、数字、下划线组成 |
306 | 模块标识已存在 | 更换模块标识(新建编辑事件时) |
307 | 事件标识已存在 | 更换事件标识(新建编辑事件时) |
308 | 模块所属产品AppKey不一致 | 更换模板标识 |
309 | 参数格式不正确 | 检查事件发送的数据是否正确 检查事件发送的数据,与 ESB 中心事件定义的数据格式是否一致 |
404 | 未找到对应数据 | 检查请求数据 |
8. 签名算法
为了防止API调用过程中被黑客恶意篡改,可在 ESB 中心"产品管理-安全设置"中开启签名,开启签名后调用任何 API需要携带签名,ESB 中心根据请求参数,对签名进行验证,签名不合法的请求将会被拒绝。
签名大体过程如下:
- 对所有API(除去sign参数),根据参数名称的ASCII码表的顺序排序。如:
foo:1, bar:2, foo_bar:3, foobar:4
排序后的顺序是:
bar:2, foo:1, foo_bar:3, foobar:4
- 将排序好的参数名和参数值拼装在一起,根据上面的示例得到的结果为:
3. 用app的secret初始化HMAC_MD5算法后,再进行摘要,如:
```java
SecretKey secretKey = new SecretKeySpec(secret.getBytes(), "HmacMD5");
Mac mac = Mac.getInstance(secretKey.getAlgorithm());
mac.init(secretKey);
bytes = mac.doFinal(“bar2foo1foo_bar3foobar4”.getBytes());
- 将摘要得到的字节流结果使用十六进制表示,如:
hex(“helloworld”.getBytes(“utf-8”)) = “68656C6C6F776F726C64”
8.1 JAVA 签名算法示例
public static String sign( Map<String,String> params, String secret){
// 第一步:检查参数是否已经排序
String[] keys = params.keySet().toArray(new String[0]);
Arrays.sort(keys);
// 第二步:把所有参数名和参数值串在一起
StringBuilder query = new StringBuilder();
for (String key : keys) {
if(key != null && !key.isEmpty()) {
String value = params.get(key);
if (value != null && !value.isEmpty()) {
query.append(key).append(value);
}
}
}
// 第三步:使用HMAC加密
byte[] bytes = encryptHMAC(query.toString(), secret);
// 第四步:把二进制转化为大写的十六进制(正确签名应该为32大写字符串,此方法需要时使用)
return byte2hex(bytes);
}
/**
* 使用HMAC加密
* @param data
* @param secret
* @return
*/
private static byte[] encryptHMAC(String data, String secret) {
byte[] bytes = null;
try {
SecretKey secretKey = new SecretKeySpec(secret.getBytes(), "HmacMD5");
Mac mac = Mac.getInstance(secretKey.getAlgorithm());
mac.init(secretKey);
bytes = mac.doFinal(data.getBytes());
} catch (Exception e) {
}
return bytes;
}
/**
* 二进制转化为大写的十六进制
* @param bytes
* @return
*/
private static String byte2hex(byte[] bytes) {
StringBuilder sign = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
String hex = Integer.toHexString(bytes[i] & 0xFF);
if (hex.length() == 1) {
sign.append("0");
}
sign.append(hex.toUpperCase());
}
return sign.toString();
}