代码解析
项目结构如下
- ApiController:提供被北向应用NA调用的接口。
- Application:主启动类
- AuthFilter:鉴权过滤器。
- ConfigController:被云端调用进行配置处理。
- ConfigService:配置管理服务 。
- ItIntegrationService:向北向应用NA发送数据。
代码解释使用ModuleSDK开发it子系统集成服务时使用的主要ItClient类。
ItClient类有以下几个关键方法(具体参考JavaDoc)。
- createFromEnv(): ItClient创建时由此方法自动获取环境变量。
- syncConfigs():IT应用启动时由此方法实现从北向应用NA同步配置。
- confirmConfigs():向北向应用NA确认已经同步的配置。
- sign():对于发送到APIGW的请求,需要使用此方法进行签名。
- verify():对于来自APIGW的请求,由此方法进行鉴权。
- **Json():根据需求选择不同的方法向NA发送请求。
片段一
ItIntegrationService 类
@Scheduled(cron = "0 0/5 * * * ?") public void collectData() throws HttpException, CryptException { //TODO 采集订单数据 String body = "{\"orders\":\"data of orders\"}"; itClient.postJson("/nas/erp/orders", body); }
对于来自子系统erp的数据orders(此处未真正接入erp系统),采用定时任务进行发送。
注意请求的地址(demo为"/nas/erp/orders"),erp为NA的id(创建路由管理时定义)。
最终请求地址http://sys-edge-apigw:8900/nas/erp/orders
http://sys-edge-apigw:8900为Api GW接收请求的地址,Api GW接收到此请求会查询本地存储的NA信息中的API网关地址向网关发送请求,如API网关分组下的子域名为
068b72f3b75444dda67cc6e********.apic.cn-south-1.huaweicloudapis.com
则Api GW转发地址为https://068b72f3b75444dda67cc6e********.apic.cn-south-1.huaweicloudapis.com/oreders
API网关再将请求转发到定义的NA地址。如如API定义的后端NA为:
请求方式:http
host地址:110.*.*.*
端口号:8080
则API网关会将请求转发至http://110.*.*.*:8080/orders
Api GW保存NA与IA信息的位置为:/var/IoTEdge/db/sys_edge_apigw/db
Api GW无法转发请求请查看该sqlite数据库是否正确保存了NA与IA的信息。
片段二
AuthFilter 类
@Order(1) @WebFilter(filterName = "authFilter", urlPatterns = "/*") @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; try { itClient.verify(request.getHeader("Authorization")); filterChain.doFilter(servletRequest, servletResponse); } catch (AuthException e) { HttpServletResponse response = (HttpServletResponse) servletResponse; response.sendError(HttpStatus.SC_FORBIDDEN); } }
对于来自Api GW的请求,此过滤器会进行拦截,并由itClient.verify()方法进行鉴权。
鉴权的方式为在请求头中增加Authorization字段,值的示例如下所示:
Algorithm=HMAC_SHA_256;AK=ia_1;SignedTime=1600763045361;Signature=0A1B0C3D
其中:
Algorithm:表示签名使用的算法名称。
AK:表示客户端身份。
SignedTime:表示签名时间戳。
Signature:为使用由Algorithm指定的签名算法对以上相应字段进行签名的结果。
对于发送到Api GW的请求,ItClient中提供的**Json()方法已做鉴权相关处理。
片段三
ConfigService 类
//创建时运行一次 @PostConstruct public void syncConfigs() { //TODO 先从本地加载配置项 //从云端同步配置 try { List<Config> configs = itClient.syncConfigs(); configs.forEach(config -> configMap.put(config.getId(), config)); //TODO 持久化保存配置 //确认已同步的配置 itClient.confirmConfigs(configs); } catch (GeneraException e) { System.out.println(e.getMessage()); } }
创建时ItClient从云端ITIntegration获取配置并确认(IA>Api GW>云端ITIntegration)。
片段四
/** * 该类实现供北向应用调用的接口 */ @RestController @RequestMapping(value = "/api") public class ApiController { private final String moduleId; @Autowired public ApiController(ItClient itClient) { this.moduleId = itClient.getConfig().getModuleId(); } @GetMapping("/get") public AppResponse GetTest() { return AppResponse.success("GetTest Success", new ReturnDto(moduleId)); } @PostMapping("/post") public AppResponse PostTest(@RequestBody Map<String, Object> inputArgs) { return AppResponse.success("PostTest Success", new ReturnDto(moduleId, inputArgs)); } }
APIGW能将来自北向NA的响应(如配置)自ITIntegration请求转发送到iT应用(NA>ITIntegration>Api GW>IA),IT应用可以由此实现对本地子系统的控制。
EdgeApiGW收到南向3rdIA的应答后,需要将应答信息构造成用于进行websocket传输的ResponseDto,并调用sendResponse接口,发送该数据到云端。
/api/** 注:支持GET/POST/PUT/DELETE/PATCH五种方式。