【华为云IoTEdge开发实战】Java开发如何通过集成IoT边缘ModuleSDK进行工业子系统接入
一家智能工厂一天就可以产生1PB的数据。如果这些海量的“边缘数据”全部传输到网络上,对于任何企业的计算系统都会产生巨大压力。如何通过技术实现在更靠近制造设备端部署边缘节点进行本地化的感知、决策、控制、分析一体化,降低网络需求的同时提高响应实时性?下面为大家讲解Java是如何通过集成IoT边缘ModuleSDK完成工业子系统接入,进而实现有效提高现有工业互联网平台处理能力。
1 操作场景
开发应用集成ModuleSDK进行工业子系统接入。
用户在个节点下部署了多个子系统(如erp),北向应用NA需要调用某个子系统的接口,该子系统需要将order数据上传到用户的北向应用NA上。
2 代码解析
项目结构如下
- 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五种方式。
3 项目打包
打包方式idea右上方>Maven>选择ero-integration模块>选择package>点击上方绿色三角按钮。完成打包。
4 制作镜像包
将jar打包成镜像文件上传,请参照制作镜像包或插件包。
5 添加应用
添加边缘应用具体请参考添加应用。
1.应用配置:功能用途请选择“本地子系统集成”
2.软件和运行配置需要在高级设置中的数据存储添加挂载点。
o 本地卷名称:config
o 类型:CONFIG
o 主机目录:config
o 容器目录:config
o 权限:读写
3.端点和部署配置
不添加端点,网络类型选择端口映射。
添加端口映射是自定义的,如
容器端口:8080
主机端口:8080
6 注册节点
创建边缘节点请参照注册边缘节点。
注意对于需要部署IT应用的节点,节点需要绑定工业资源包。
如没有工业网关资源包选项,请先购买。工业网关资源包计费及使用请参考工业资源包。
绑定方法如下。
1.资源包类型选择“工业网关资源包”。
2.绑定工业资源包选择工业子系统采集服务。
7 创建API
1.创建API分组。
API网关>开放API>右上方创建分组。
编辑分组
填写分组名称(自定义),带年纪确定完成创建。
2.创建API。
进入API分组,创建API,API提供erp数据上传的请求转发功能。
创建过程说明:
- 基本信息。
API名称:自定义。
所属分组:默认。
网关响应:默认。
类型:公开。
安全认证:App认证。
其他根据需要填写,没有则默认。
2.定义API请求。
域名:默认。
请求协议:根据需要选择。
请求path:
IT应用发送数据的请求地址:/orders
匹配模式:绝对匹配。
Method:POST(根据请求方式选择)。
入参定义:
对于带有参数的请求需要声明入参定义,如请求path为"/configs/{ia_id}",则入参定义为:
参数名:ia_id
参数位置:path
3.定义后端请求。
后端服务类型提供了三种方式。
后端服务类型选择HTTP/HTTPS时的配置:
协议:根据北向应用NA使用的协议填写。
请求方式:根据北向应用NA定义的请求方式填写。
vpc通道:根据需求选择。
Virtual Private Network,虚拟专用网络。在公用网络上建立专用网络,进行加密通讯。在企业网络中有广泛应用。VPN网关通过对数据包的加密和数据包目标地址的转换实现远程访问。VPN可通过服务器、硬件、软件等多种方式实现。
后端服务地址:北向应用NA接受请求的ip或域名。
后端请求Path:北向应用NA接受请求的地址。
后端超时:自定义。
注意:
后端服务地址和后端请求Path很重要,这两项决定NA的请求地址。
后端服务类型选择Mock时的配置:
定义后端请求即定义API网关接受的请求将转发的位置,可通过Mock模拟后端响应。
Mock返回结果:此处定义的内容会被返回到请求端。(非必填)
返回示例:
{
"configs": [
{
"id": "config1203",
"name": "config1202",
"value": "config1202",
"description": "config1202",
"version": "1606878222614",
"state": "SUCCESS",
"create_time": "2020-12-02T03:02:42Z",
"update_time": "2020-12-16T08:44:33Z"
}
]
}
须知:
使用mock不能显示请求携带的数据,只能接收到请求后返回定义的结果。
4.定义返回结果
成功响应示例:自定义。
失败响应示例:自定义。
5.发布API
将创建的API发布到release环境。
API网关>API分组>选择创建的API分组>API管理>勾选创建API>点击发布。
8 网关应用创建及绑定
1.创建网关应用
API网关>调用API>应用管理。
2.绑定API
勾选前面创建的API,点击绑定。
9 添加数据端点
IoT边缘>路由管理>添加数据接收端点。
端点名称:自定义。
端点ID:erp (端点id即为NA的id,代码中IA请求NA地址需要与此对应,如"/nas/erp/orders")。
数据接收地址:
API分组绑定的子域名。创建API时会自动分配一个访问量和性能都极低的子域名用于开发测试(API分组>选择创建的API>概览),用于生产环境请绑定子域名!
接入方式:选择ROMA。
集成应用key和secret选择API应用分配的key和AppSecret(API网关>调用API>应用管理)
绑定节点:勾选为部署IT应用注册的节点。
10 部署应用
IoTEdge 边缘>节点边缘>选择创建的节点>模块管理。
1.部署$edge_apigw
2.部署It应用
3.最终节点部署了四个应用
11 使用
- 验证北向应用NA通过云端ITIntegration调用IT应用(IA)
验证方法可选择华为API Explorer、Postman等接口测试工具、实际构建南向应用NA三种方式来验证。
如果使用Postman等接口调试工具或者实际构建南向应用NA来测试请参考API参考。
API Explorer界面如下:
如果调用开发的IT应用erp-integration中ApiController下的GetTest()方法,
即对应工程代码中的请求路径/api/get。
API Explorer设置如下:
在模块调试区域选择IoT>边缘>北向http请求代理>InvokeGetProxy。
Region:选择所在区域
Headers:选择AK/SK认证,即使用Authorization。
Params:
project_id:选择Region后自动填充(如没有自动填充请开通统一身份认证服务,开通参照统一身份认证服务IAM文档,项目id获取参照 获取项目ID)。
node_id:节点id,获取方式:IoT边缘>边缘节点>点击节点列表中节点名称>基本信息。
ia_id:IA应用id,获取方式:IoT边缘>边缘节点>点击节点列表中节点名称>模块管理。
ia_uri:IA应用的接口地址,/api/get
填写完成后点击“调试”
右侧的返回结果即是IT应用(IA)响应的结果。
- 验证IT应用(IA)通过API网关调用北向应用NA
以下代码是模拟NA接受来自API网关的转发请求。
@Controller
@Slf4j
public class ReceiveDataController {
@RequestMapping(value = "/orders", method = RequestMethod.POST)
@ResponseBody
public void receive(HttpServletRequest request) {
InputStream inputStream = null;
ByteArrayOutputStream outputStream = null;
try {
inputStream = request.getInputStream();
outputStream = new ByteArrayOutputStream();
byte[] b = new byte[1024];
int len;
while ((len = inputStream.read(b)) != -1) {
outputStream.write(b, 0, len);
}
log.info(new String("receive data:----------->" + new String(outputStream.toByteArray())));
} catch (Exception e) {
log.error("get InputStream from request failed");
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
log.error("close inputStream failed");
}
}
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
log.error("close outputStream failed");
}
}
}
}
}
将以上工程打包,部署到创建API时定义的后端服务器上运行(创建API网关时定义的host主机)。可以看到IA定时发送的数据。
至此,运用IoT边缘,Java开发工业子系统接入完成。
- 点赞
- 收藏
- 关注作者
评论(0)