# AI连接器扩展
AI连接器中目前内置了秘塔、博查、百度地图、高德地图。如需新增其他连接器可在连接器管理菜单中新增连接器即可,可参考AI连接器。其中新建连接器时,连接器认证类路径参数为需要新建连接器的认证类全类名。例如百度地图认证实现类 com.primeton.gocom.afcenter.connector.sdk.auth.BaiDuDiTuAuth,如下图

# 实现接口方法
该认证类路径需要自行扩展,实现com.primeton.gocom.afcenter.connector.sdk.api.IConnectorAuth#auth方法即可。
# 认证方法入参
该接口方法入参为com.primeton.gocom.afcenter.connector.sdk.model.HttpMessage
| 属性名 | 类型 | 说明 |
|---|---|---|
| actionId | String | 连接器操作connectorAction的主键id,用来在认证实现方法中获取连接器操作对象,继而获取相关信息 |
| authId | String | 连接器认证connectorAuth的主键id,用来获取连接器认证配置信息,方便实现方法中获取相关认证信息。 |
| pathParams | Map<String, Object> | 连接器操作中操作方法的路径参数,根据连接器操作url中存在路径参数时,这里入参获取到pathParams后,根据认证需要组装路径参数到返回结果AuthResult中 |
| queryParams | Map<String, Object> | 连接器操作中操作方法的请求参数,根据操作url中请求参数结合连接器认证方式组装queryParams到返回结果AuthResult中 |
| body | Object | post请求body体参数,根据连接器认证需求组装body信息后返回到结果AuthResult中 |
| method | String | 连接器操作中操作方法,1-GET,2-POST,3-DELETE,4-PUT,5-PATCH |
| pathWay | String | 连接器操作中操作URL |
# 认证方法出参
该接口方法入参为com.primeton.gocom.afcenter.connector.sdk.model.AuthResult
| 属性名 | 类型 | 说明 | 是否必须返回 |
|---|---|---|---|
| state | int | 认证状态,0:成功 1:失败 | 是 |
| busAddr | String | 业务地址,由认证方法auth中从认证参数中获取服务地址拼接连接器操作中操作url得来,例如百度地图认证服务地址为https://api.map.baidu.com,操作坐标转换操作url为/geoconv/v2/,最终busAddr为https://api.map.baidu.com/geoconv/v2/ | 是 |
| message | String | 认证失败异常信息message | 否 |
| method | String | 业务接口的方法类型 1-GET,2-POST,3-DELETE,4-PUT,5-PATCH | 是 |
| pathParams | Map<String,Object> | 远程请求连接器接口路径参数 | 否 |
| headerParams | Map<String,Object> | 远程请求连接器接口header请求头信息 | 否 |
| queryParams | Map<String,Object> | 远程请求连接器接口请求参数 | 否 |
| body | Object | 远程请求连接器接口body体入参 | 否 |
# 示例
例如百度地图认证实现类
package com.primeton.gocom.afcenter.connector.sdk.auth;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.primeton.eos.api.springboot.EOS8ApplicationContext;
import com.primeton.gocom.afcenter.connector.model.ConnectorAuth;
import com.primeton.gocom.afcenter.connector.model.ConnectorAuthParam;
import com.primeton.gocom.afcenter.connector.model.Result;
import com.primeton.gocom.afcenter.connector.sdk.api.IConnectorAuth;
import com.primeton.gocom.afcenter.connector.sdk.model.AuthResult;
import com.primeton.gocom.afcenter.connector.sdk.model.HttpMessage;
import com.primeton.gocom.afcenter.connector.service.ConnectorAuthService;
import com.primeton.gocom.afcenter.connector.util.SignUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;
import java.util.Map.Entry;
/**
* 百度地图认证实现类
*/
@Component
public class BaiDuDiTuAuth implements IConnectorAuth {
//以下为验证需要的字段
private final String SERVER_URL = "server_url"; //应用地址,地址部分
private final String AK = "ak"; //秘钥
private final String SK = "sk"; //私钥
private final String AUTH_TYPE = "auth_type"; //认证方式:IPWhiteList:IP白名单 SNSignature:sn校验
private final String IPWhiteList = "IPWhiteList"; //认证方式为白名单
private final String SNSignature = "SNSignature"; //认证方式为 sn校验
private String ak = null;
private String sk = null;
private String server_url = null;
private String auth_type = null; //认证方式
private String pathWay = null;
//get请求的参数字符串
private String getParamStr = null;
private byte[] postBodyBytes = null;
@Override
public AuthResult auth(HttpMessage httpMessage) {
AuthResult result = new AuthResult();
try {
ConnectorAuthService connectorAuthService = EOS8ApplicationContext.INSTANCE.getBean(ConnectorAuthService.class);
Result connectorAuthInfoById = connectorAuthService.getConnectorAuthInfoById(httpMessage.getAuthId());
if(Objects.isNull(connectorAuthInfoById.getData())){
throw new RuntimeException("找不到对应的认证信息,连接器认证id:"+httpMessage.getAuthId());
}
ConnectorAuth connectorAuth = (ConnectorAuth)connectorAuthInfoById.getData();
//从认证参数中获取配置的参数信息
List<ConnectorAuthParam> connectorAuthParams = connectorAuth.getConnectorAuthParams();
if(CollectionUtils.isEmpty(connectorAuthParams)){
result.setState(1);
result.setMessage("认证失败,百度地图认证参数未设置");
return result;
}
Map<String, String> authParam = connectorAuthParams.stream().collect(Collectors.toMap(ConnectorAuthParam::getConnectorKey, ConnectorAuthParam::getConnectorValue));
ak = authParam.get(AK);
sk = authParam.get(SK);
server_url = authParam.get(SERVER_URL);
auth_type = authParam.get(AUTH_TYPE);
pathWay = httpMessage.getPathWay();
result.setBusAddr(server_url + pathWay);
String actionMethod = httpMessage.getMethod();
result.setMethod(actionMethod);
TreeMap<String,Object> pathParams = new TreeMap<String,Object>();
//get请求方式
if("1".equalsIgnoreCase(actionMethod)){
Map<String, Object> queryParams = httpMessage.getQueryParams();
pathParams.putAll(queryParams);
}else if("2".equalsIgnoreCase(actionMethod)){
//post请求方式
Object body = httpMessage.getBody();
String bodyString = null;
if (body instanceof byte[]) {
String oldEncoding = "UTF-8";
bodyString = new String((byte[])body, oldEncoding);
}else{
bodyString = (String) body;
}
pathParams = getParamStrByPost(bodyString);
}
pathParams.put("ak",ak);
String sn = "";
if(SNSignature.equals(auth_type)){
sn = getSign(pathWay,pathParams,sk);
getParamStr = getParamStr + "&sn="+sn;
}else{
getParamStr = toQueryString(pathParams);
}
if("1".equalsIgnoreCase(actionMethod)){
result.getQueryParams().put("ak",ak);
result.getQueryParams().put("sn",sn);
}else if("2".equalsIgnoreCase(actionMethod)){
postBodyBytes = getParamStr.getBytes("UTF-8");
result.setBody(postBodyBytes);
result.getHeaderParams().put("Content-Type", "application/x-www-form-urlencoded");
}
result.setState(0);
result.setMessage("认证成功");
}catch (Exception e){
result.setState(1);
result.setMessage("认证失败:"+e.getMessage());
}
return result;
}
/**
* 通过原始POST请求参数获取参数集合
* @param paramStr
* @return
*/
private TreeMap<String,Object> getParamStrByPost(String paramStr){
TreeMap<String,Object> pathParams = new TreeMap<String,Object>();
if(null != paramStr){
try{
ObjectMapper objectMapper = new ObjectMapper();
JsonNode bodyNode = objectMapper.readTree(paramStr); // 尝试解析为 JSON
Iterator<String> fields = bodyNode.fieldNames();
if (null != fields && fields.hasNext()) {
while (fields.hasNext()) {
String fieldName = fields.next();
JsonNode fieldNode = bodyNode.get(fieldName);
String fieldValue = fieldNode.asText();
if(fieldNode.isArray() || fieldNode.isObject() || fieldNode.isContainerNode()){
fieldValue = fieldNode.toString();
}
pathParams.put(fieldName,fieldValue);
}
}
}catch (Exception e){
e.printStackTrace();
}
}
return pathParams;
}
public String getSign(String pathWay,TreeMap<String,Object> pathParams,String sk) throws Exception{
getParamStr = toQueryString(pathParams);
String sigStr = pathWay + "?" + getParamStr + sk;
System.out.println("sigStr:" + sigStr);
// 对上面wholeStr再作utf8编码
String tempStr = URLEncoder.encode(sigStr, "UTF-8");
// 调用下面的MD5方法得到最后的sn签名7de5a22212ffaa9e326444c75a58f9a0
return SignUtils.md5(tempStr);
}
/**
* 对Map内所有value作utf8编码,拼接返回结果
*/
public static String toQueryString(Map<?, ?> data) throws Exception {
StringBuffer queryString = new StringBuffer();
for (Entry<?, ?> pair : data.entrySet()) {
queryString.append(pair.getKey() + "=");
//判断是否经过了encode
String value = pair.getValue().toString();
if(SignUtils.isEncoded(value)){
queryString.append(value + "&");
}else{
queryString.append(URLEncoder.encode(pair.getValue().toString(), "UTF-8") + "&");
}
}
if (queryString.length() > 0) {
queryString.deleteCharAt(queryString.length() - 1);
}
return queryString.toString();
}
}