应用开发
本章主要介绍应用托管边缘集群中需要的应用改造和相关的操作流程。
1. 对接说明
应用开发对接分为:操作系统适配、OAuth对接、数据模型对接、服务模型对接、LinkEdge对接、LinkVisual对接、其他平台相关的组件对接。其中,“操作系统适配”是必须项,其他均为可选项,根据使用场景和项目总体设计方案而定
操作系统适配
:目前平台基于CentOS 7.6构建,因此应用在对接前,请先确保能够在此操作系统上正常运行,否则应用需要做适当适配;OAuth对接
:通过边缘集群控制台,直接访问应用内部,无需重复登录;数据模型、服务模型对接
:通过集成工作台,对接领域服务;Link IoT Edge对接
:云端指令下发边缘集群,LE平台会将指令转发至某一组设备;LinkVisual对接
:边缘集群内部调用功能算法与图像处理;2. OAuth对接
2.1 业务代码改造
系统应用环境变量中获取访问域名。System.getenv(“iot.hosting.api.domain”)
应用跳转IoT oauth验证地址,同时携带认证后跳转的callback地址
IoT认证后,携带授权码oauthcode跳转第2步callback的地址
应用获取到oauthcode后可以换取accesscode,并通过accesscode获取到用户的完整信息
调用流程
接入流程
获取部署应用的免登地址应用通过API发送请求,获取部署在边缘集群内部应用的免登地址url。请求格式及示例具体参考文档:边缘集群免登开发文档
http://30.42.82.42:32187/api/console/app/get?appKey=28135051
获取部署应用的host请求地址应用通过API发起请求,获取部署在边缘集群内部应用的请求host。请求格式及示例具体参考文档:边缘集群免登开发文档
http://30.42.82.42:32187/api/console/host/account
3.应用请求发起用户通过在应用免登地址配置时的默认地址来发起浏览器访问,应用需要判断当前请求需要进行IoT OAuth2免登IoT在验证当前用户合法后,将生成当前用户授权码oauthcode,在回跳redirect_uri地址时通过GET方式传递oauthcode,并同时返回state
2.2 请求格式及示例
具体参考文档:边缘集群免登开发文档
http://30.42.82.42:32187/oauth2/auth?
redirect_uri=http://30.42.82.42:32187/index&
client_id=28135051&state=28135051&
response_type=code
2.3 入参说明
入参名称 | 数据类型 | 是否必须 | 入参示例 | 入参描述 |
client_id | String | 是 | 28135051 | 应用的appkey |
redirect_uri | String | 是 | OAuth认证通过后的重定向应用的URI,包含完整的域名 | |
response_type | String | 是 | code | 返回类型。根据OAuth 2.0标准,目前支持设置此参数的取值为 |
state | String | 否 | 28135051 | 应用的appkey携带项 |
scope | String | 否 | 空格分隔的OAuth范围列表。如不指定此参数取值,则默认为应用注册的全部OAuth范围,加上scopid |
2.4 出参列表
出参名称 | 数据类型 | 出参描述 |
code | 整形 | 响应码, 200: 成功 |
message | 字符串 | 错误消息 |
localizedMsg | 字符串 | 本地语言错误消息 |
data | 长整型 | 响应结果 |
返回结果示例
http://30.42.82.42:32187/index?code=64a67ee15534defea7ad0d0535189b24&state=28135051
1.通过oauthcode换取accessToken接口获取OAuth授权code后可通过该接口获取accessToken身份信息。具体参考文档:边缘集群免登开发文档2.通过accessToken换取用户信息获取accessToken信息后,可通过accessToken来换取登录用户的用户信息。具体参考文档:边缘集群免登开发文档
3. 数据模型-代码改造
数据集成标准化的目标是规范应用之间数据的传递方式和表达方式。
传递方式:即应用之间的数据如何流通。平台提供了对数据进行增删改查的4个API,以及HTTP2方式的消息订阅机制。
表达方式:即应用之间如何对数据内容有一致的理解。为了实现这个目标,需要做到如下两点,一是数据结构需要由小二后台统一管控(目前全部由小二后台录入,未来会引入审核机制);二是应用集成对接之前(比如应用上架的时候)需要声明本应用对哪些数据模型产生什么样的数据操作(如查询、新增,或者订阅)。
API 描述
具体参考文档:边缘集群数据模型开发文档
API名称 | API描述 | API Path | API 版本 |
新增数据 | 基于已经创建且被授权写入的模型,进行数据的新增。 | /data/model/data/insert | 0.0.3 |
删除数据 | 基于已经创建且被授权删除的模型,进行数据的更新。 | /data/model/data/delete | 0.0.2 |
修改数据 | 基于已经创建且被授权更新的模型,进行数据的更新。 | /data/model/data/update | 0.0.2 |
查询数据 | 基于已经创建且被授权查询的模型,进行数据的查询。 | /data/model/data/query | 0.0.3 |
获取文件上传地址 | 对于模型中指定为“图片”标签的字段,在该字段需要填写文件名,并且文件名需要通过该接口获取,该接口同时还会返回一个URL供用户上传文件。该地址有效期是10秒。 | /data/model/data/upload | 0.0.1 |
获取文件下载地址 | 对于模型中指定为“图片”标签的字段,在该字段的内容是一个系统分配的文件名,用户可以通过本接口,传入这个文件名,获取真实的文件下载地址。该地址有效期是10秒。 | /data/model/data/download | 0.0.1 |
日期类型的参数传入格式:当前时间到格林威治时间1970年01月01日00时00分00秒的毫秒数。
数量查询的一些约定:
单次查询最多返回200条数据,未指定分页参数情况下,查询返回满足条件的前200条,可根据返回参数中的hasNext判断是否有更多数据。
若需要按照指定条件返回数据总数,则指定返回参数为COUNT,API返回参数中会带有COUNT以及对应的值。
若需要按照指定条件,及按照字段分组进行数量查询,则指定返回参数为COUNT(分组字段1,分组字段2),API返回参数中会带有COUNT以及对应的值。
更新删除的约定:单次操作,最多支持200条数据。
运算符定义:
运算符 | 含义 | 备注 |
eq | equals | 相等 |
neq | not equals | 不相等 |
lt | less than | 小于 |
lteq | less than or equals | 小于等于 |
mt | more than | 大于 |
mteq | more than or equals | 大于等于 |
bt | between | 在..之间 |
in | in | 在..之内 |
nin | not in | 不在..之内 |
nul | is null | 为空 |
nnul | is not null | 不为空 |
5.数据包括系统属性,API中不允许赋值和更新系统属性,系统属性如下:
属性 | 描述 |
id | 数据主键 |
creator | 数据创建者 |
modifier | 数据修改者 |
gmt_create | 数据创建时间 |
gmt_modified | 数据修改时间 |
4.服务模型-代码改造
4.1设计目标
用于规范应用之间行为表达方式和对结果的预期。
对于服务提供方来讲,通过服务标准化,能够清晰而简洁的表达本服务提供了哪些接口、定义、以及他们所应实现的具体功能,并且任何对该服务所提供的能力有依赖的应用,都必须按照这套接口来实现服务供应;
对于服务依赖方来讲,(即使用该服务的应用)能够清晰而简洁的表达他所依赖的接口有哪些,分别期望这些接口完成什么样的具体功能,并且任何为其提供服务的应用,只要遵循相同的服务模型,即可实现服务提供方的替换。
4.2 概念定义
对服务模型的定义,如下几点说明:
服务即接口。我们这里定义的服务,从概念上理解,这是一个对应用能力的抽象表达;但是从实际操作层面,服务的实际体现方式,就是RESTful风格的HTTP接口。
接口是分组的。分组的原则是能力原子化,即我们按照接口的能力范围,将一组完成功能闭环的接口标定为一组。并且,我们将这一组接口,定义为“一个服务模型”。
服务模型是受管控的。目前,每一个服务模型都是由行业小二在后台制定并发布。ISV在实践过程中可以根据实际情况,向相关小儿提出调整意见。
服务模型是有版本的。一个基础服务模型,随着不用ISV、不同场景的需求,会有版本迭代。因此,唯一确定一个服务模型提供的接口信息的,是模型ID+版本。
具体参考文档:边缘集群服务模型开发文档
4.3 具体对接步骤
系统应用环境变量中获取访问域名。System.getenv(“iot.hosting.mesh.domain”)
用appkey和appsecret进行鉴权和建立连接。
填写对应服务模型接口的参数值和API版本。
发送请求到iot网关路由,获取到服务模型接口返回结果。
请求示例
/**
* 系统环境变量中获取的
*/
public static final String appKey = System.getenv("iot.hosting.appKey");
public static final String AppSecret = System.getenv("iot.hosting.appSecret");
//服务模型请求的路由
private static final String SERVICE_EDGE__PATH = System.getenv("iot.hosting.mesh.domain");
public static void main(String[] args) throws UnsupportedEncodingException {
IoTApiClientBuilderParams ioTApiClientBuilderParams =
new IoTApiClientBuilderParams();
ioTApiClientBuilderParams.setAppKey("你的<AppKey>");
ioTApiClientBuilderParams.setAppSecret("你的<AppSecret>");
SyncApiClient syncClient = new SyncApiClient(ioTApiClientBuilderParams);
IoTApiRequest request = new IoTApiRequest();
//设置api的版本
request.setApiVer("1.0");
request.putParam("requestId", "213123");
request.putParam("meterNo", "213123");
request.putParam("amount", "213123");
request.putParam("sourceAppId", "213123");
request.putParam("targetAppId", "213123");
//请求参数版本,域名、path、request
request.setVersion("1.0");
//请求参数域名、path、request
ApiResponse response = syncClient.postBody(SERVICE_EDGE__PATH,
"/服务名称/接口名称", request, true);
System.out.println( "response code = " + response.getCode()
+ " response = " + new String(response.getBody(), "UTF-8"));
}