參考官方DataHub API規范:
https://help.aliyun.com/document_detail/99302.html?spm=a2c4g.11186623.6.549.74374f52zTkMPO
以下 “接口規范”~~~”簽名計算原理說明“~~~“寫入數據” 原封不動的摘自官網API介紹.
...重點 常見問題 及 DEMO程序...
一. 接口規范
1.公共請求Header
名字 | 描述 |
---|---|
x-datahub-client-version | API版本信息 |
x-datahub-security-token | Security Token,如果存在 |
Date | 標准GMT時間,格式: EEE, dd MMM yyyy HH:mm:ss z |
Authorization | 簽名信息 |
Content-Type | 傳輸數據序列化協議 |
2. 公共返回Header
名字 | 描述 |
---|---|
Content-Type | 傳輸數據序列化協議 |
Content-Length | 傳輸數據長度 |
x-datahub-request-id | 全局唯一請求ID |
3. 錯誤碼
名字 | 描述 | 備注 |
---|---|---|
InvalidParameter | 參數錯誤 | |
InvalidCursor | Cursor無效 | |
NoSuchXXX | 資源不存在 | |
XXXAlreadyExist | 資源已存在 | |
Unauthorized | 認證失敗 | AccessKey信息錯誤,用戶時間戳不對等 |
NoPermission | 鑒權失敗 | RAM權限錯誤 |
OperationDenied | 禁止操作 | 操作禁止,比如刪除有topic存在的project |
LimitExceeded | 流控受限 | 服務端QPS、流量等限制 |
InvalidShardOperation | Shard分裂或合並,變成Sealed | |
MalformedRecord | 數據格式不正確 | |
OffsetReseted | 點位重置 | |
OffsetSessionChanged | SubId被其他用戶open占用 | |
SubscriptionOffline | 訂閱下線 | |
InternalServerError | 系統內部錯誤 | |
其他 | 其他非可重試異常,后續可能會被回收 |
4. 統一錯誤返回格式
名字 | 描述 |
---|---|
ErrorCode | 錯誤碼 |
ErrorMessage | 詳細錯誤描述信息 |
錯誤響應示例:
HTTP/1.1403
x-datahub-request-id:2018050817492199d6650a00000039
Content-Type: application/json
Content-Length: xxx
{
"ErrorCode":"Unauthorized",
"ErrorMessage":"Authroize failed"
}
5. 限制描述
名字 | 描述 |
---|---|
ProjectName | 長度:[3, 32],僅包含字母、數字和’_’, 以字母開頭,不區分大小寫 |
TopicName | 長度:[3, 128],僅包含字母、數字和’_’, 以字母開頭,不區分大小寫 |
二、Authorization字段計算的方法
Authorization="DATAHUB "+AccessId+":"+Signature
Signature= base64(hmac-sha1(AccessKey,
HTTPMethod+"\n"
+Content-Type+"\n"
+Date+"\n"
+CanonicalizedDataHubHeaders+"\n"
+CanonicalizedResource))
AccessKey
表示簽名所需的密鑰。HTTPMethod
表示HTTP 請求的Method,主要有PUT、GET、POST、HEAD、DELETE等。\n
表示換行符。Content-Type
表示請求內容的類型,一般固定為“application/json”。Date
表示此次操作的時間,且必須為GMT格式,如“Sun, 22 Nov 2015 08:16:38 GMT”。CanonicalizedDataHubHeaders
表示以x-datahub-
為前綴的HTTP Header的字典序排列。CanonicalizedResource
表示用戶想要訪問的DataHub資源的Url,若包含param,必須按字典序。
CanonicalizedDataHubHeaders構造方法
所有以 x-datahub-
為前綴的HTTP Header被稱為 CanonicalizedDataHubHeaders
。構造方法如下:
- 將所有以
x-datahub-
為前綴的HTTP請求頭的名字轉換成小寫 。如X-DATAHUB-Client-Version:1.1
需要轉換成x-datahub-client-version:1.1
。 - 如果請求是以STS獲得的AccessKeyId和AccessKeySecret發送時,還需要將獲得的security-token值以
x-datahub-security-token:token
的形式加入到簽名字符串中。 - 將上一步得到的所有HTTP請求頭按照名字的字典序進行升序排列。
- 刪除請求頭和內容之間分隔符兩端出現的任何空格。如
x-datahub-client-versionn : 1.1
轉換成:x-datahub-client-version:1.1
。 - 將每一個頭和內容用
\n
分隔符分隔拼成最后的CanonicalizedDataHubHeaders
。
CanonicalizedResource構造方法
用戶發送請求中想訪問的DataHub目標資源被稱為CanonicalizedResource。構造方法如下:
- 將
CanonicalizedResource
置成空字符串 “”; - 放入要訪問的DataHub資源,如某個topic:
/projects/test_project/topics/test_topic
- 如果請求的資源包含額外的url參數,按照字典序,從小到大排列並以 & 為分隔符生成參數字符串。在CanonicalizedResource字符串尾添加 ?和參數字符串。此時的CanonicalizedResource如:
/projects/test_project/topics/test_topic/connectors/sink_odps?donetime
計算簽名頭規則
- 簽名的字符串必須為 UTF-8 格式。含有中文字符的簽名字符串必須先進行 UTF-8 編碼,再與
AccessKey
計算最終簽名。 - 簽名的方法用RFC 2104中定義的HMAC-SHA1方法,其中Key為
AccessKey
。 - 以
x-datahub-
開頭的header在簽名驗證前需要符合以下規范:- header的名字需要變成小寫。
- header按字典序自小到大排序。
- 分割header name和value的冒號前后不能有空格。
- 每個Header之后都有一個換行符“\n”,如果沒有Header,CanonicalizedDataHubHeaders就設置為空。
簽名示例
假如AccessKeyId是”44CF9590006BF252F707”,AccessKeySecret是”OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV”
請求 | 簽名字符串計算公式 | 簽名字符串 |
---|---|---|
POST /projects/test_project/topics/test_topic HTTP/1.1 Host: http://dh-cn-hangzhou.aliyuncs.com User-Agent: customer x-datahub-client-version: 1.1 Content-Type: application/json Date: Thu, 10 Jan 2019 07:28:29 GMT | Signature = base64(hmac-sha1(AccessKey,HTTPMethod + “\n” + Content-Type + “\n” + Date + “\n” + CanonicalizedDataHubHeaders+ CanonicalizedResource)) | POST\napplication/json\nThu, 10 Jan 2019 07:28:29 GMT\nx-datahub-client-version:1.1\n/projects/test_project/topics/test_topic |
寫入數據 - 不按shard寫入
請求
-
請求語法
POST
-
請求元素
名稱 | 類型 | 描述 |
---|---|---|
Action | String | Action為: pub |
ShardId | String | ShardId |
Attributes | Map<string, string=""> | 用戶屬性字段 |
Data | 如果為BLOB類型,Data為數據Base64編碼后數據;如果為TUPLE數據,為String類型數組 |
響應
-
響應語法
HTTP/1.1 200 OK
-
響應元素
名稱 | 類型 | 描述 |
---|---|---|
FailedRecordCount | Int | 失敗條數 |
FailedRecords | Array | 失敗詳情 |
示例
-
請求示例
POST
x-datahub-client-version: 1.1
Date: Tue, 08 May 2018 09:47:48 GMT
Authorization: AuthorizationString
Content-Type: applicaton/json
Conent-Length: xxx
{
"Action": "pub",
"Records": [
{
"ShardId": "0",
"Attributes": {
"attr1": "value1",
"attr2": "value2"
},
"Data": ["A","B","3","4"]
}
]
}
// BLOB
{
"Action": "pub",
"Record": [
{
"ShardId": "0",
"Attributes": {
"attr1": "value1",
"attr2": "value2"
},
"Data": "Base64String"
}
]
}
-
響應示例
HTTP/1.1 200 OK
x-datahub-request-id: 2018050817492199d6650a00000039
Content-Type: applicaton/json
Conent-Length: xxx
{
"FailedRecordCount": 1,
"FailedRecords": [
{
"Index": 0,
"ErrorCode": "errorCode",
"ErrorMessage": "errorMsg"
}
]
}
-------------------------------------------------------------------------- 華麗的分割線--------------------------------------------------------------------------
簽名算法:參考阿里官方給出的JAVA版工具類 UrlUtil.java SignatureUtils.java,可以直接使用。
https://www.alibabacloud.com/help/zh/doc-detail/28618.htm
官方提供的Java SDK 方式對Java版本要求最低JDK1.8,我這里是一個基於JDK1.6的老項目無法滿足;故而使用HTTP API的方式;
-------------------------------------------------------------------------- 華麗的分割線--------------------------------------------------------------------------
常見問題:
1. Unauthorized “The signature is Time-Expired.”
客戶端與服務器端時間不一致,兩端時間差不能超過15分鍾, 另外可能存在時區不一致的情況,當時我的客戶端應用默認是東八區的服務器比我晚了8小時,還是我們用抓包工具發現的問題。
2. Unauthorized “Invalid date format .”
用於計算簽名或發送請求頭的Date字段時間格式不對, 這里必須使用GMT格式字符串 "EEE, dd MMM yyyy HH:mm:ss 'GMT'"
3. Unauthorized “Authorize failed .”
授權失敗,這個只能服務器端分析日志來幫客戶端定位問題了。 我當時是在計算簽名的時候使用轉義后的\n 而導致了這樣的問題
4. InvalidParameter “Parse body failed,Offset 1 ”
解析報文體的時候,位置一的字符不合法; 因為官方只支持雙引號的字符串,若使用單引號傳數據會報類似這樣的錯誤.
5. InvalidParameter “Parse body failed,Offset 118 ”
解析報文體的時候,位置118處的字符是中文; 只需要在發送數據的實體里面加上UTF-8編碼即可.
最佳實踐DEMO源碼:
1,計算簽名;
2,組裝符合要求的數據;
3, 發送HTTP請求
DEMO程序截圖:
demo程序執行結果:
索要demo程序源碼~售價10元~微信或支付寶付款后發郵箱 yangw1006@163.com 通知!!!