1165 lines
23 KiB
Markdown
1165 lines
23 KiB
Markdown
# 🧩 IoT 容器管理接口文档
|
||
|
||
**模块**:`container_handler`
|
||
**作者**:licheng5
|
||
**创建时间**:2020-04-26
|
||
**说明**:提供容器的部署、配置、启动、停止、查询等管理 API 接口。
|
||
|
||
## 服务器地址
|
||
http://127.0.0.1:18090
|
||
|
||
---
|
||
## 📦 模块结构
|
||
|
||
| 模块 | 说明 |
|
||
|------|------|
|
||
| `container_handler` | 提供容器管理的 HTTP 接口处理 |
|
||
| `iot_util` | 工具模块,用于生成标准化 JSON 响应 |
|
||
|
||
---
|
||
|
||
## ⚙️ `iot_util` 模块函数声明
|
||
|
||
```erlang
|
||
%%--------------------------------------------------------------------
|
||
%% @doc
|
||
%% 将数据封装为标准 JSON 响应:
|
||
%% {"result": Data}
|
||
%%--------------------------------------------------------------------
|
||
json_data(Data) ->
|
||
jiffy:encode(#{
|
||
<<"result">> => Data
|
||
}, [force_utf8]).
|
||
|
||
%%--------------------------------------------------------------------
|
||
%% @doc
|
||
%% 生成错误响应 JSON:
|
||
%% {
|
||
%% "error": {
|
||
%% "code": ErrCode,
|
||
%% "message": ErrMessage
|
||
%% }
|
||
%% }
|
||
%%--------------------------------------------------------------------
|
||
json_error(ErrCode, ErrMessage) when is_integer(ErrCode), is_binary(ErrMessage) ->
|
||
jiffy:encode(#{
|
||
<<"error">> => #{
|
||
<<"code">> => ErrCode,
|
||
<<"message">> => ErrMessage
|
||
}
|
||
}, [force_utf8]).
|
||
```
|
||
|
||
### 📘 返回格式说明
|
||
|
||
| 字段 | 说明 |
|
||
|------|------|
|
||
| `result` | 正常返回数据 |
|
||
| `error.code` | 错误代码 |
|
||
| `error.message` | 错误信息 |
|
||
|
||
---
|
||
|
||
## 🌐 HTTP API 接口列表
|
||
|
||
以下为 `container_handler` 模块导出的全部 HTTP 接口。
|
||
|
||
---
|
||
|
||
### 1️⃣ 获取容器列表
|
||
|
||
**URL**:`/container/get_all`
|
||
**Method**:`GET`
|
||
|
||
#### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| uuid | binary (string) | ✅ | 主机唯一标识符 |
|
||
|
||
#### 响应参数
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| result | list | 容器信息列表 |
|
||
|
||
#### 示例响应
|
||
```json
|
||
{
|
||
"result": [
|
||
{"name": "container_1", "status": "running"},
|
||
{"name": "container_2", "status": "stopped"}
|
||
]
|
||
}
|
||
```
|
||
|
||
#### 错误响应
|
||
```json
|
||
{
|
||
"error": {
|
||
"code": -1,
|
||
"message": "host not found"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 2️⃣ 下发配置文件
|
||
|
||
**URL**:`/container/push_config`
|
||
**Method**:`POST`
|
||
|
||
#### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| uuid | binary (string) | ✅ | 主机唯一标识符 |
|
||
| container_name | binary (string) | ✅ | 容器名称 |
|
||
| config | binary (string, JSON) | ✅ | 容器配置内容(JSON 字符串) |
|
||
| timeout | integer | ✅ | 超时时间(秒) |
|
||
|
||
### 请求示例
|
||
```json
|
||
{"uuid": "qbxmjyzrkpntfgswaevodhluicqzxplkm", "container_name": "my_nginx_new", "config": "{\"application\":{\"namexyz\":\"RandomConfigApp\",\"version\":\"1.2.7\",\"environment\":{\"debug_mode\":true,\"log_level\":\"info\",\"max_log_files\":10}},\"server\":{\"host\":\"127.0.0.1\",\"port\":8080,\"ssl_enabled\":false,\"allowed_origins\":[\"https:\\/\\/example.com\",\"http:\\/\\/localhost:3000\"]},\"database\":{\"type\":\"postgresql\",\"host\":\"db.example.com\",\"port\":5432,\"username\":\"admin_7xq9f\",\"password\":\"p@ssw0rd!r4nd\",\"connection_pool\":15,\"timeout_seconds\":30},\"features\":{\"enable_analytics\":true,\"enable_cache\":false,\"experimental_features\":[\"ai_enhancement\",\"realtime_sync\"]},\"third_party\":{\"api_key\":\"a3b8c2d4e5f6g7h8i9j0k1l2m3n4o5p\",\"weather_service_url\":\"https:\\/\\/api.weather.example\\/v3\",\"payment_gateway\":{\"endpoint\":\"https:\\/\\/pay.example.com\",\"merchant_id\":\"M123456789\"}},\"scheduled_tasks\":[{\"name\":\"nightly_backup\",\"cron\":\"0 3 * * *\",\"enabled\":true},{\"name\":\"log_cleanup\",\"interval_minutes\":1440,\"retention_days\":7}],\"admins\":[{\"username\":\"alice_dev\",\"email\":\"alice@example.com\",\"permissions\":[\"read\",\"write\",\"admin\"]},{\"username\":\"bob_ops\",\"email\":\"bob@example.org\",\"permissions\":[\"read\",\"audit\"]}]}", "timeout": 10}
|
||
```
|
||
|
||
#### 响应参数
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| result | map | 配置结果 |
|
||
|
||
#### 示例响应
|
||
```json
|
||
{
|
||
"result": {
|
||
"container_name": "sensor_service",
|
||
"status": "config pushed"
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 错误响应
|
||
```json
|
||
{
|
||
"error": {
|
||
"code": -1,
|
||
"message": "host not found"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 3️⃣ 部署容器服务
|
||
|
||
**URL**:`/container/deploy`
|
||
**Method**:`POST`
|
||
|
||
#### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| uuid | binary (string) | ✅ | 主机唯一标识符 |
|
||
| task_id | integer | ✅ | 任务 ID |
|
||
| config | map | ✅ | 部署配置内容 |
|
||
|
||
#### 响应参数
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| result | map | 部署结果 |
|
||
|
||
### 请求示例
|
||
```json
|
||
{
|
||
"uuid": "qbxmjyzrkpntfgswaevodhluicqzxplkm",
|
||
"task_id": 1,
|
||
"timeout": 10,
|
||
"config": {
|
||
"image": "docker.1ms.run/library/nginx:latest",
|
||
"container_name": "my_nginx_new",
|
||
"command": [
|
||
"nginx",
|
||
"-g",
|
||
"daemon off;"
|
||
],
|
||
"entrypoint": [
|
||
"/docker-entrypoint.sh"
|
||
],
|
||
"envs": [
|
||
"ENV1=val1",
|
||
"ENV2=val2"
|
||
],
|
||
"env_file": [
|
||
"./env.list"
|
||
],
|
||
"ports": [
|
||
"8080:80",
|
||
"443:443"
|
||
],
|
||
"expose": [
|
||
"80",
|
||
"443"
|
||
],
|
||
"volumes": [
|
||
"/host/data:/data",
|
||
"/host/log:/var/log"
|
||
],
|
||
"networks": [
|
||
"mynet"
|
||
],
|
||
"labels": {
|
||
"role": "web",
|
||
"env": "prod"
|
||
},
|
||
"restart": "always",
|
||
"user": "www-data",
|
||
"working_dir": "/app",
|
||
"hostname": "myhost",
|
||
"privileged": true,
|
||
"cap_add": [
|
||
"NET_ADMIN"
|
||
],
|
||
"cap_drop": [
|
||
"MKNOD"
|
||
],
|
||
"devices": [
|
||
"/dev/snd:/dev/snd"
|
||
],
|
||
"mem_limit": "512m",
|
||
"mem_reservation": "256m",
|
||
"cpu_shares": 512,
|
||
"cpus": 1.5,
|
||
"ulimits": {
|
||
"nofile": "1024:2048"
|
||
},
|
||
"sysctls": {
|
||
"net.ipv4.ip_forward": "1"
|
||
},
|
||
"tmpfs": [
|
||
"/tmp"
|
||
],
|
||
"extra_hosts": [
|
||
"host1:192.168.0.1"
|
||
],
|
||
"healthcheck": {
|
||
"test": [
|
||
"CMD-SHELL",
|
||
"curl -f http://localhost || exit 1"
|
||
],
|
||
"interval": "30s",
|
||
"timeout": "10s",
|
||
"retries": 3
|
||
}
|
||
}
|
||
}
|
||
|
||
```
|
||
|
||
#### 示例响应
|
||
```json
|
||
{
|
||
"result": {
|
||
"task_id": 1001,
|
||
"status": "deployed"
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 错误响应
|
||
```json
|
||
{
|
||
"error": {
|
||
"code": 404,
|
||
"message": "host not found"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 4️⃣ 启动容器服务
|
||
|
||
**URL**:`/container/start`
|
||
**Method**:`POST`
|
||
|
||
#### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| uuid | binary (string) | ✅ | 主机唯一标识符 |
|
||
| container_name | binary (string) | ✅ | 容器名称 |
|
||
|
||
### 请求示例
|
||
```json
|
||
{"uuid": "qbxmjyzrkpntfgswaevodhluicqzxplkm", "container_name": "my_nginx_new"}
|
||
```
|
||
|
||
#### 响应参数
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| result | map | 启动结果 |
|
||
|
||
#### 示例响应
|
||
```json
|
||
{
|
||
"result": {
|
||
"container_name": "sensor_service",
|
||
"status": "started"
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 错误响应
|
||
```json
|
||
{
|
||
"error": {
|
||
"code": 404,
|
||
"message": "host not found"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 5️⃣ 停止容器服务
|
||
|
||
**URL**:`/container/stop`
|
||
**Method**:`POST`
|
||
|
||
#### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| uuid | binary (string) | ✅ | 主机唯一标识符 |
|
||
| container_name | binary (string) | ✅ | 容器名称 |
|
||
|
||
### 请求示例
|
||
```json
|
||
{"uuid": "qbxmjyzrkpntfgswaevodhluicqzxplkm", "container_name": "my_nginx_new"}
|
||
```
|
||
|
||
#### 响应参数
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| result | map | 停止结果 |
|
||
|
||
#### 示例响应
|
||
```json
|
||
{
|
||
"result": {
|
||
"container_name": "sensor_service",
|
||
"status": "stopped"
|
||
}
|
||
}
|
||
```
|
||
|
||
### 6 强制停止容器服务
|
||
|
||
**URL**:`/container/kill`
|
||
**Method**:`POST`
|
||
|
||
#### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| uuid | binary (string) | ✅ | 主机唯一标识符 |
|
||
| container_name | binary (string) | ✅ | 容器名称 |
|
||
|
||
### 请求示例
|
||
```json
|
||
{"uuid": "qbxmjyzrkpntfgswaevodhluicqzxplkm", "container_name": "my_nginx_new"}
|
||
```
|
||
|
||
#### 响应参数
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| result | map | 停止结果 |
|
||
|
||
#### 示例响应
|
||
```json
|
||
{
|
||
"result": {
|
||
"container_name": "sensor_service",
|
||
"status": "stopped"
|
||
}
|
||
}
|
||
```
|
||
|
||
### 7 删除容器
|
||
|
||
**URL**:`/container/remove`
|
||
**Method**:`POST`
|
||
|
||
#### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| uuid | binary (string) | ✅ | 主机唯一标识符 |
|
||
| container_name | binary (string) | ✅ | 容器名称 |
|
||
|
||
### 请求示例
|
||
```json
|
||
{"uuid": "qbxmjyzrkpntfgswaevodhluicqzxplkm", "container_name": "my_nginx_new"}
|
||
```
|
||
|
||
#### 响应参数
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| result | map | 停止结果 |
|
||
|
||
#### 示例响应
|
||
```json
|
||
{
|
||
"result": {
|
||
"container_name": "sensor_service",
|
||
"status": "stopped"
|
||
}
|
||
}
|
||
```
|
||
|
||
|
||
#### 错误响应
|
||
```json
|
||
{
|
||
"error": {
|
||
"code": 404,
|
||
"message": "host not found"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 6️⃣ 未知路径处理
|
||
|
||
**说明**:如果请求路径未匹配任何定义接口,将返回错误信息。
|
||
|
||
#### 示例响应
|
||
```json
|
||
{
|
||
"error": {
|
||
"code": -1,
|
||
"message": "url: /unknown/path not found"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 🧾 返回约定总结
|
||
|
||
| 类型 | 说明 |
|
||
|------|------|
|
||
| `{"result": Data}` | 表示请求成功 |
|
||
| `{"error": {"code": N, "message": Text}}` | 表示请求失败 |
|
||
|
||
|
||
|
||
# 🧩 IoT Endpoint 管理接口文档
|
||
|
||
**模块**:`endpoint_handler`
|
||
**作者**:licheng5
|
||
**创建时间**:2020-04-26
|
||
**说明**:用于管理 IoT Endpoint 的运行状态,包括启动、停止、重启、状态查询等。
|
||
|
||
---
|
||
|
||
## 📦 模块结构
|
||
|
||
| 模块 | 说明 |
|
||
|------|------|
|
||
| `endpoint_handler` | 提供 Endpoint 管理的 HTTP 接口处理 |
|
||
| `iot_util` | 工具模块,用于生成标准化 JSON 响应 |
|
||
|
||
---
|
||
|
||
## ⚙️ `iot_util` 模块函数声明
|
||
|
||
```erlang
|
||
%%--------------------------------------------------------------------
|
||
%% @doc
|
||
%% 将数据封装为标准 JSON 响应:
|
||
%% {"result": Data}
|
||
%%--------------------------------------------------------------------
|
||
json_data(Data) ->
|
||
jiffy:encode(#{
|
||
<<"result">> => Data
|
||
}, [force_utf8]).
|
||
|
||
%%--------------------------------------------------------------------
|
||
%% @doc
|
||
%% 生成错误响应 JSON:
|
||
%% {
|
||
%% "error": {
|
||
%% "code": ErrCode,
|
||
%% "message": ErrMessage
|
||
%% }
|
||
%% }
|
||
%%--------------------------------------------------------------------
|
||
json_error(ErrCode, ErrMessage) when is_integer(ErrCode), is_binary(ErrMessage) ->
|
||
jiffy:encode(#{
|
||
<<"error">> => #{
|
||
<<"code">> => ErrCode,
|
||
<<"message">> => ErrMessage
|
||
}
|
||
}, [force_utf8]).
|
||
```
|
||
|
||
### 📘 返回格式说明
|
||
|
||
| 字段 | 说明 |
|
||
|------|------|
|
||
| `result` | 正常返回数据 |
|
||
| `error.code` | 错误代码 |
|
||
| `error.message` | 错误信息 |
|
||
|
||
---
|
||
|
||
## 🌐 HTTP API 接口列表
|
||
|
||
以下为 `endpoint_handler` 模块导出的全部 HTTP 接口。
|
||
|
||
---
|
||
|
||
### 1️⃣ 获取 Endpoint 运行状态
|
||
|
||
**URL**:`/endpoint/run_statuses`
|
||
**Method**:`POST`
|
||
|
||
#### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| Ids | list | ✅ | Endpoint ID 列表 |
|
||
|
||
#### 响应参数
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| result | list | 每个 ID 对应状态:`0` 未运行,`1` 运行中 |
|
||
|
||
#### 示例请求
|
||
```json
|
||
[1, 2, 3]
|
||
```
|
||
|
||
#### 示例响应
|
||
```json
|
||
{
|
||
"result": [1, 0, 1]
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 2️⃣ 启动 Endpoint
|
||
|
||
**URL**:`/endpoint/start`
|
||
**Method**:`POST`
|
||
|
||
#### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| id | integer | ✅ | Endpoint 唯一 ID |
|
||
|
||
#### 响应参数
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| result | string | 启动结果,如 `"success"` |
|
||
|
||
#### 示例响应
|
||
```json
|
||
{
|
||
"result": "success"
|
||
}
|
||
```
|
||
|
||
#### 错误响应
|
||
```json
|
||
{
|
||
"error": {
|
||
"code": 404,
|
||
"message": "endpoint not found"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 3️⃣ 停止 Endpoint
|
||
|
||
**URL**:`/endpoint/stop`
|
||
**Method**:`POST`
|
||
|
||
#### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| id | integer | ✅ | Endpoint 唯一 ID |
|
||
|
||
#### 响应参数
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| result | string | 停止结果,如 `"success"` |
|
||
|
||
#### 示例响应
|
||
```json
|
||
{
|
||
"result": "success"
|
||
}
|
||
```
|
||
|
||
#### 错误响应
|
||
```json
|
||
{
|
||
"error": {
|
||
"code": 404,
|
||
"message": "stop endpoint error"
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 错误响应
|
||
```json
|
||
{
|
||
"error": {
|
||
"code": 404,
|
||
"message": "stop endpoint error"
|
||
}
|
||
}
|
||
```
|
||
|
||
|
||
---
|
||
|
||
### 4️⃣ 重启 Endpoint
|
||
|
||
**URL**:`/endpoint/restart`
|
||
**Method**:`POST`
|
||
|
||
#### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| id | integer | ✅ | Endpoint 唯一 ID |
|
||
|
||
#### 响应参数
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| result | string | 重启结果,如 `"success"` |
|
||
|
||
#### 示例响应
|
||
```json
|
||
{
|
||
"result": "success"
|
||
}
|
||
```
|
||
|
||
#### 错误响应
|
||
```json
|
||
{
|
||
"error": {
|
||
"code": 404,
|
||
"message": "restart endpoint error"
|
||
}
|
||
}
|
||
```
|
||
|
||
### 5. 向endpoint发送消息
|
||
|
||
**URL**:`/endpoint/publish_metric`
|
||
**Method**:`POST`
|
||
|
||
###### **示例请求**
|
||
metric字段支持字符串,map或者数组,其他为非法数据; 如何要发送数字,可以采用数字的字符串格式, 比如: "5"
|
||
|
||
```json
|
||
{
|
||
"route_key": "/dhlr/warning",
|
||
"metric": {
|
||
"xyz": "test"
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 示例响应
|
||
```json
|
||
{
|
||
"result": "ok"
|
||
}
|
||
```
|
||
|
||
#### 错误响应
|
||
```json
|
||
{
|
||
"error": {
|
||
"code": 404,
|
||
"message": "restart endpoint error"
|
||
}
|
||
}
|
||
```
|
||
|
||
### **POST /endpoint/test
|
||
用于测试指定协议(HTTP / MQTT / Kafka)配置是否可用**
|
||
|
||
#### **请求方式**
|
||
|
||
```
|
||
POST /endpoint/test
|
||
Content-Type: application/json
|
||
```
|
||
|
||
---
|
||
|
||
#### **通用参数**
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
| -------- | ------ | -- | ------------------------------- |
|
||
| protocol | string | 是 | 选择测试类型,可为:`http`、`mqtt`、`kafka` |
|
||
| config | object | 是 | 各协议对应的配置对象 |
|
||
|
||
---
|
||
|
||
#### **一、测试 HTTP Endpoint**
|
||
|
||
###### **请求参数**
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
| --------- | ------- | -- | ------------- |
|
||
| url | string | 是 | 要请求的 HTTP 地址 |
|
||
| pool_size | integer | 是 | 连接池大小(必须 > 0) |
|
||
|
||
###### **示例请求**
|
||
|
||
```json
|
||
{
|
||
"protocol": "http",
|
||
"config": {
|
||
"url": "http://example.com/ping",
|
||
"pool_size": 5
|
||
}
|
||
}
|
||
```
|
||
|
||
###### **返回结果**
|
||
|
||
| 状态 | 内容 |
|
||
| ------- |--------------------------------------|
|
||
| success | `{"data":"ok"}` |
|
||
| failed | `{"error": -1, "msg": "url failed"}` |
|
||
|
||
---
|
||
|
||
##### **二、测试 MQTT Endpoint**
|
||
|
||
###### **请求参数**
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
| --------- | ------ | -- | --------------- |
|
||
| host | string | 是 | MQTT 服务器地址 |
|
||
| port | int | 是 | MQTT 端口(>0) |
|
||
| client_id | string | 是 | 客户端 ID(仅用于配置校验) |
|
||
| username | string | 是 | 用户名 |
|
||
| password | string | 是 | 密码 |
|
||
| topic | string | 是 | topic 名称 |
|
||
| qos | int | 是 | 0/1/2 |
|
||
|
||
###### **参数限制**
|
||
|
||
* host ≠ 空
|
||
* username/password/topic ≠ 空
|
||
* qos ∈ {0,1,2}
|
||
|
||
###### **示例请求**
|
||
|
||
```json
|
||
{
|
||
"protocol": "mqtt",
|
||
"config": {
|
||
"host": "test.mqttserver.com",
|
||
"port": 1883,
|
||
"client_id": "test-client-01",
|
||
"username": "user1",
|
||
"password": "pass123",
|
||
"topic": "device/event",
|
||
"qos": 1
|
||
}
|
||
}
|
||
```
|
||
|
||
###### **返回结果**
|
||
|
||
| 状态 | 内容 |
|
||
| ------- |------------------------------------------------------|
|
||
| success | `{"data": "ok"}` |
|
||
| failed | `{"error": -1, "msg": "connect mqtt server failed"}` |
|
||
|
||
---
|
||
|
||
##### **三、测试 Kafka Endpoint**
|
||
|
||
###### **请求参数(无认证)**
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
| ----------------- | ------------ | -- | ---------------------- |
|
||
| bootstrap_servers | list(string) | 是 | 服务器列表,格式 `"host:port"` |
|
||
| topic | string | 是 | Topic 名称 |
|
||
|
||
###### **请求参数(SASL 认证)**
|
||
|
||
当需要 SASL 认证时,增加:
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
| --------------------- | ------ | -- | --------------------------------- |
|
||
| sasl_config.username | string | 是 | 用户名 |
|
||
| sasl_config.password | string | 是 | 密码 |
|
||
| sasl_config.mechanism | string | 是 | `"plain"` `"sha_256"` `"sha_512"` |
|
||
|
||
###### **合法 mechanism 值**
|
||
|
||
* `plain` → SASL/PLAIN
|
||
* `sha_256` → SCRAM-SHA-256
|
||
* `sha_512` → SCRAM-SHA-512
|
||
|
||
###### **bootstrap_servers 校验规则**
|
||
|
||
* 必须是 list(binary())
|
||
* 每项格式必须为 `"host:port"`
|
||
* port 必须为整数并 > 0
|
||
|
||
---
|
||
|
||
###### **示例 1:无认证 Kafka**
|
||
|
||
```json
|
||
{
|
||
"protocol": "kafka",
|
||
"config": {
|
||
"bootstrap_servers": ["broker1:9092", "broker2:9092"],
|
||
"topic": "device-log"
|
||
}
|
||
}
|
||
```
|
||
|
||
###### **示例 2:带 SASL 认证 Kafka**
|
||
|
||
```json
|
||
{
|
||
"protocol": "kafka",
|
||
"config": {
|
||
"sasl_config": {
|
||
"username": "kafka_user",
|
||
"password": "kafka_pass",
|
||
"mechanism": "sha_256"
|
||
},
|
||
"bootstrap_servers": ["kafka.example.com:9094"],
|
||
"topic": "iot-event"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## **返回结果**
|
||
|
||
| 状态 | 内容 |
|
||
| ------- | ---------------------------------------------------- |
|
||
| success | `{"data": "ok"}` |
|
||
| failed | `{"error": -1, "msg": "config kafka server failed"}` |
|
||
|
||
---
|
||
|
||
### 5️⃣ 未知路径处理
|
||
|
||
**说明**:如果请求路径未匹配任何定义接口,将返回错误信息。
|
||
|
||
#### 示例响应
|
||
```json
|
||
{
|
||
"error": {
|
||
"code": -1,
|
||
"message": "url: /unknown/path not found"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 🧾 返回约定总结
|
||
|
||
| 类型 | 说明 |
|
||
|------|------|
|
||
| `{"result": Data}` | 表示请求成功 |
|
||
| `{"error": {"code": N, "message": Text}}` | 表示请求失败 |
|
||
|
||
|
||
# 🧩 IoT Host 管理接口文档
|
||
|
||
**模块**:`host_handler`
|
||
**作者**:licheng5
|
||
**创建时间**:2020-04-26
|
||
**说明**:用于管理 IoT 主机,包括主机指标、状态查询、激活、删除、发布事件等接口。
|
||
|
||
---
|
||
|
||
## 📦 模块结构
|
||
|
||
| 模块 | 说明 |
|
||
|------|------|
|
||
| `host_handler` | 提供 Host 管理的 HTTP 接口处理 |
|
||
| `iot_util` | 工具模块,用于生成标准化 JSON 响应 |
|
||
|
||
---
|
||
|
||
## ⚙️ `iot_util` 模块函数声明
|
||
|
||
```erlang
|
||
%%--------------------------------------------------------------------
|
||
%% @doc
|
||
%% 将数据封装为标准 JSON 响应:
|
||
%% {"result": Data}
|
||
%%--------------------------------------------------------------------
|
||
json_data(Data) ->
|
||
jiffy:encode(#{
|
||
<<"result">> => Data
|
||
}, [force_utf8]).
|
||
|
||
%%--------------------------------------------------------------------
|
||
%% @doc
|
||
%% 生成错误响应 JSON:
|
||
%% {
|
||
%% "error": {
|
||
%% "code": ErrCode,
|
||
%% "message": ErrMessage
|
||
%% }
|
||
%% }
|
||
%%--------------------------------------------------------------------
|
||
json_error(ErrCode, ErrMessage) when is_integer(ErrCode), is_binary(ErrMessage) ->
|
||
jiffy:encode(#{
|
||
<<"error">> => #{
|
||
<<"code">> => ErrCode,
|
||
<<"message">> => ErrMessage
|
||
}
|
||
}, [force_utf8]).
|
||
```
|
||
|
||
### 📘 返回格式说明
|
||
|
||
| 字段 | 说明 |
|
||
|------|------|
|
||
| `result` | 正常返回数据 |
|
||
| `error.code` | 错误代码 |
|
||
| `error.message` | 错误信息 |
|
||
|
||
---
|
||
|
||
## 🌐 HTTP API 接口列表
|
||
|
||
以下为 `host_handler` 模块导出的全部 HTTP 接口。
|
||
|
||
---
|
||
|
||
### 1️⃣ 获取主机指标
|
||
|
||
**URL**:`/host/metric`
|
||
**Method**:`GET`
|
||
|
||
#### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| uuid | binary (string) | ✅ | 主机唯一标识符 |
|
||
|
||
#### 响应参数
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| result | map | 主机指标信息 |
|
||
|
||
#### 示例响应
|
||
```json
|
||
{
|
||
"result": {"cpu": 20, "memory": 1024, "disk": 51200}
|
||
}
|
||
```
|
||
|
||
#### 错误响应
|
||
```json
|
||
{
|
||
"error": {
|
||
"code": 404,
|
||
"message": "host not found"
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 无指标信息响应
|
||
```json
|
||
{
|
||
"error": {
|
||
"code": 404,
|
||
"message": "no metric info"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 2️⃣ 查询主机状态
|
||
|
||
**URL**:`/host/status`
|
||
**Method**:`GET`
|
||
|
||
#### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| uuid | binary (string) | ✅ | 主机唯一标识符 |
|
||
|
||
#### 响应参数
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| result | map | 主机状态信息 |
|
||
|
||
#### 示例响应
|
||
```json
|
||
{
|
||
"result": {"authorize_status": 1, "active": true}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 3️⃣ 重新加载主机信息
|
||
|
||
**URL**:`/host/reload`
|
||
**Method**:`POST`
|
||
|
||
#### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| uuid | binary (string) | ✅ | 主机唯一标识符 |
|
||
|
||
#### 响应参数
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| result | string | 重新加载结果,如 `"success"` |
|
||
|
||
#### 错误响应
|
||
```json
|
||
{
|
||
"error": {
|
||
"code": 404,
|
||
"message": "reload error"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 4️⃣ 删除主机
|
||
|
||
**URL**:`/host/delete`
|
||
**Method**:`POST`
|
||
|
||
#### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| uuid | binary (string) | ✅ | 主机唯一标识符 |
|
||
|
||
#### 响应参数
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| result | string | 删除结果,如 `"success"` |
|
||
|
||
#### 错误响应
|
||
```json
|
||
{
|
||
"error": {
|
||
"code": 404,
|
||
"message": "error"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 5️⃣ 激活主机
|
||
|
||
**URL**:`/host/activate`
|
||
**Method**:`POST`
|
||
|
||
#### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| uuid | binary (string) | ✅ | 主机唯一标识符 |
|
||
| auth | boolean | ✅ | `true` 激活, `false` 取消激活 |
|
||
|
||
#### 响应参数
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| result | string | 激活结果,如 `"success"` |
|
||
|
||
#### 错误响应
|
||
```json
|
||
{
|
||
"error": {
|
||
"code": 400,
|
||
"message": "host not found"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 6️⃣ 发布主机事件
|
||
|
||
**URL**:`/host/pub`
|
||
**Method**:`POST`
|
||
|
||
#### 请求参数
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|---------|-----------------|------|------------------|
|
||
| uuid | binary (string) | ✅ | 主机唯一标识符 |
|
||
| topic | binary (string) | ✅ | 事件主题 |
|
||
| qos | integer | ✅ | 消息的qos,qos = 0,1 |
|
||
| content | binary (string) | ✅ | 发布内容 |
|
||
|
||
### 请求示例
|
||
|
||
```json
|
||
{
|
||
"uuid": "qbxmjyzrkpntfgswaevodhluicqzxplkm",
|
||
"topic": "/device/1234/all",
|
||
"qos": 1,
|
||
"content": "this is a topic payload",
|
||
"timeout": 10
|
||
}
|
||
```
|
||
|
||
#### 响应参数
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| result | string | 发布结果,如 `"success"` |
|
||
|
||
#### 错误响应
|
||
```json
|
||
{
|
||
"error": {
|
||
"code": 400,
|
||
"message": "host not found"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 7️⃣ 未知路径处理
|
||
|
||
**说明**:如果请求路径未匹配任何定义接口,将返回错误信息。
|
||
|
||
#### 示例响应
|
||
```json
|
||
{
|
||
"error": {
|
||
"code": -1,
|
||
"message": "url: /unknown/path not found"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 🧾 返回约定总结
|
||
|
||
| 类型 | 说明 |
|
||
|------|------|
|
||
| `{"result": Data}` | 表示请求成功 |
|
||
| `{"error": {"code": N, "message": Text}}` | 表示请求失败 |
|