diff --git a/HTTP_API_README.md b/HTTP_API_README.md index a987558..49a61e5 100644 --- a/HTTP_API_README.md +++ b/HTTP_API_README.md @@ -654,6 +654,174 @@ json_error(ErrCode, ErrMessage) when is_integer(ErrCode), is_binary(ErrMessage) } ``` +### **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️⃣ 未知路径处理 diff --git a/apps/iot/src/http_handlers/endpoint_handler.erl b/apps/iot/src/http_handlers/endpoint_handler.erl index de9c215..85a3e72 100644 --- a/apps/iot/src/http_handlers/endpoint_handler.erl +++ b/apps/iot/src/http_handlers/endpoint_handler.erl @@ -104,7 +104,7 @@ handle_request("POST", "/endpoint/test", _, #{<<"protocol">> := <<"http">>, <<"c ContentType = "application/json", case httpc:request(post, {Url, [], ContentType, Body}, [], []) of {ok, _} -> - {ok, 200, iot_util:json_data(<<"success">>)}; + {ok, 200, iot_util:json_data(<<"ok">>)}; {error, Reason} -> lager:debug("[endpint_handler] test http: ~p, error: ~p", [Url, Reason]), {ok, 200, iot_util:json_error(-1, <<"url failed">>)} @@ -138,7 +138,7 @@ handle_request("POST", "/endpoint/test", _, #{<<"protocol">> := <<"mqtt">>, <<"c {ok, _} -> lager:debug("[endpoint_mqtt] connect success, pid: ~p", [ConnPid]), emqtt:stop(ConnPid), - {ok, 200, iot_util:json_data(<<"success">>)}; + {ok, 200, iot_util:json_data(<<"ok">>)}; {error, Reason} -> lager:warning("[endpoint_mqtt] connect get error: ~p", [Reason]), emqtt:stop(ConnPid),