數據模型對接指引
應用獲取或者發送數據時,需要向平臺操作數據,或者從平臺訂閱數據。數據操作方面,這里主要涉及4個接口:新增數據、查詢數據、刪除數據、修改數據。詳見后面的API參考。同時,為了便于應用開發,平臺提供了SDK,簡化開發。
1 數據操作API
SDK詳情請查看API調用對接指引
1.1 API 描述
API名稱 | API描述 | API Path | API 版本 |
新增數據 | 基于已經創建且被授權寫入的模型,進行數據的新增。 | /data/model/data/insert | 0.0.5 |
刪除數據 | 基于已經創建且被授權刪除的模型,進行數據的更新。 | /data/model/data/delete | 0.0.4 |
修改數據 | 基于已經創建且被授權更新的模型,進行數據的更新。 | /data/model/data/update | 0.0.4 |
查詢數據 | 基于已經創建且被授權查詢的模型,進行數據的查詢。 | /data/model/data/query | 0.0.4 |
獲取文件上傳地址 | 對于模型中指定為“圖片”標簽的字段,在該字段需要填寫文件名,并且文件名需要通過該接口獲取,該接口同時還會返回一個URL供用戶上傳文件。該地址有效期是10秒。 | /data/model/data/upload | 0.0.1 |
獲取文件下載地址 | 對于模型中指定為“圖片”標簽的字段,在該字段的內容是一個系統分配的文件名,用戶可以通過本接口,傳入這個文件名,獲取真實的文件下載地址。該地址有效期是10秒。 | /data/model/data/download | 0.0.1 |
查詢(不包含count)數據 | 按條件查詢數據模型的數據,查詢結果集中沒有count字段,即不會返回符合條件的數據集總數量。 | /data/model/without/count/data/query | 2.0.0 |
查詢總數 | 查詢滿足條件的數據總條數 | /data/model/without/count/data/query | 0.0.3 |
1.2 API 約定
日期類型的參數傳入格式:當前時間到格林威治時間1970年01月01日00時00分00秒的毫秒數。
數量查詢的一些約定:
單次查詢最多返回200條數據,未指定分頁參數情況下,查詢返回滿足條件的前200條,可根據返回參數中的hasNext判斷是否有更多數據。
若需要按照指定條件返回數據總數,則指定返回參數為COUNT,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 | 不為空 |
數據包括系統屬性,API中不允許賦值和更新系統屬性,系統屬性如下:
屬性 | 描述 |
id | 數據主鍵 |
creator | 數據創建者 |
modifier | 數據修改者 |
gmt_create | 數據創建時間 |
gmt_modified | 數據修改時間 |
1.3 數據新增API
1. 請求參數
參數 | 類型 | 描述 | 是否必傳 |
modelId | String | 數據模型id | 是 |
properties | JSON | 數據字段鍵值對,增加的字段的鍵只能是模型包含的字段,否則會報錯,其中 Boolean屬性的property傳入”true”和”false”或者0和1。如:{“name”:”xxx”,”age”:18} | 是 |
scopeId | String | 經常是項目的id,該參數非必填,一般上架應用被授權之后,會被默認綁定到一個scope中,因此當前操作會被默認操作到被綁定到的這一個scope中。但是,對于集成應用,也有可能被綁定到多個scope中,此時該操作需要填入scopeId。 | 否 |
appId | String | 對于SaaS應用,需要填該值 | 否 |
logicalModelIsoId | String | 模型的邏輯隔離id,該參數非必填,默認是oxs_iso_id | 否 |
modelInstanceId | String | 模型實例id,即模型元信信所屬的實例,非必填,默認為null,null代表是公共實例 | 否 |
dataInstanceId | String | 數據實例id,即模型物理存儲數據所屬的實例,非必填,默認為null,null代表是公共實例 | 否 |
2. 返回參數
參數 | 類型 | 描述 |
data | Long | 數據主鍵id |
3. 請求示例
{
"request": {
"apiVer": "0.0.5" // api版本號
},
"id": 1508212818676,// request里的全局唯一id透傳
"params": {
"modelId":"XXX123", //數據模型id
"scopeId":"fdbsdj1dfjdubgxxx", //數據模型id
"properties":{
"BRAND":"BMW",
"MODE":"5",
"CREATE_DATE":1526969423,
"LONG_SIZE":3.3,
"LONG_SIZE":2.2
}
},
"version": "1.0" // 請求協議版本
}
4. 返回示例
{
"code": 200,
"message": "success",
"localizedMsg": null,
"data": 12345
}
5. 返回碼
狀態碼 | 描述 | 其他說明 |
200 | 成功 | |
460 | 參數驗證異常 | 會帶有驗證異常的詳細說明 |
500 | 服務異常 | server error |
52002 | 無訪問權限 | |
52005 | 找不到目標存儲 | |
52009 | 參數和模型定義不匹配 | |
52011 | 數據類型校驗錯誤 |
1.4 數據刪除API
1. 請求參數
參數 | 類型 | 是否必傳 | 描述 |
modelId | String | 是 | 數據模型id |
conditions | JSON | 否 | 數據條件,由字段名、運算符、比較值組成一個condition。如:[{“fieldName”: “id”,”operate”: “eq”,”value”: 7}] |
appId | String | 否 | 對于SaaS應用,需要填該值 |
scopeId | String | 否 | 經常是項目的id,該參數非必填,一般上架應用被授權之后,會被默認綁定到一個scope中,因此當前操作會被默認操作到被綁定到的這一個scope中。但是,對于集成應用,也有可能被綁定到多個scope中,此時該操作需要填入scopeId。 |
logicalModelIsoId | String | 否 | 模型的邏輯隔離id,該參數非必填,默認是oxs_iso_id |
modelInstanceId | String | 否 | 模型實例id,即模型元信信所屬的實例,非必填,默認為null,null代表是公共實例 |
dataInstanceId | String | 否 | 數據實例id,即模型物理存儲數據所屬的實例,非必填,默認為null,null代表是公共實例 |
其中condition針對不同類型的屬性支持的運算符:
屬性 | 支持的運算符 |
Integer | eq,neq,lt,lteq,mt,mteq,bt,in,nin,nnull |
String | eq,neq,nnul,in,nin |
Double | eq,neq,lt,lteq,mt,mteq,bt,in,nin,nnull |
Boolean | eq,nnul |
Date | eq,neq,lt,lteq,mt,mteq,bt,nnul |
2. 返回參數
參數 | 類型 | 描述 |
data | Integer | 刪除數據的條數 |
3. 請求示例
{
"request": {
"apiVer": "0.0.4" // api版本號
},
"id": 1508212818676,// request里的全局唯一id透傳
"params": {
"modelId":"XXX123",
"conditions":[
{"fieldName":"BRAND","value":"BMW","operate":"eq"},
{"fieldName":"MODE","value":"X5","operate":"eq"}
]
},
"version": "1.0" // 請求協議版本
}
4. 返回示例
{
"code": 200,
"message": "success",
"localizedMsg": null,
"data":100
}
5. 返回碼
狀態碼 | 描述 | 說明 |
200 | 成功 | |
460 | 參數驗證異常 | 會帶有驗證異常的詳細說明 |
500 | 服務異常 | server error |
52002 | 無訪問權限 |
1.5 數據修改API
1. 請求參數
參數 | 類型 | 是否必傳 | 描述 |
modelId | String | 是 | 數據模型id |
updateDetails | JSON | 是 | 更新的具體字段和值,字段需要是模型中包含的字段,否則會報錯,其中 Boolean屬性的property傳入”true”和”false”或者0和1。如:{“name”:”xxxx”,”age”:20} |
conditions | JSON | 否 | 條件,由字段名、運算符、比較值組成一個condition,格式如下:[{“fieldName”: “id”,”operate”: “eq”,”value”: 7}]fieldName表示字段的名稱operate表示操作符,操作符見上表value表示值 |
appId | String | 否 | 對于SaaS應用,需要填該值 |
scopeId | String | 否 | 經常是項目的id,該參數非必填,一般上架應用被授權之后,會被默認綁定到一個scope中,因此當前操作會被默認操作到被綁定到的這一個scope中。但是,對于集成應用,也有可能被綁定到多個scope中,此時該操作需要填入scopeId。 |
logicalModelIsoId | String | 否 | 模型的邏輯隔離id,該參數非必填,默認是oxs_iso_id |
modelInstanceId | String | 否 | 模型實例id,即模型元信信所屬的實例,非必填,默認為null,null代表是公共實例 |
dataInstanceId | String | 否 | 數據實例id,即模型物理存儲數據所屬的實例,非必填,默認為null,null代表是公共實例 |
其中condition針對不同類型的屬性支持的運算符:
屬性 | 支持的運算符 | |
Integer | eq,neq,lt,lteq,mt,mteq,bt,in,nin,nnull | |
String | eq,neq,nnul,in,nin | |
Double | eq,neq,lt,lteq,mt,mteq,bt,in,nin,nnull | |
Boolean | eq,nnul | |
Date | eq,neq,lt,lteq,mt,mteq,bt,nnul |
2. 返回參數
參數 | 類型 | 描述 |
data | Integer | 更新數據的條數 |
3. 請求示例
{
"request": {
"apiVer": "0.0.4" // api版本號
},
"id": 1508212818676,// request里的全局唯一id透傳
"params": {
"modelId":"XXX123",
"conditions":[
{"fieldName":"BRAND","value":"BMW","operate":"eq"},
{"fieldName":"MODE","value":"X5","operate":"eq"}
],
"updateDetails":{
"LONG_SIZE":4,
"WIDTH_SIZE":3
}
},
"version": "1.0" // 請求協議版本
}
4. 返回示例
{
"code": 200,
"message": "success",
"localizedMsg": null,
"data":100
}
5. 返回碼
狀態碼 | 描述 | 其他說明 |
200 | 成功 | |
460 | 參數驗證異常 | 會帶有驗證異常的詳細說明 |
500 | 服務異常 | server error |
52002 | 無訪問權限 | |
52006 | 資源更新錯誤 | |
52011 | 數據類型校驗錯誤 |
1.6 數據查詢API
1. 請求參數
參數 | 類型 | 是否必傳 | 說明 |
modelId | String | 是 | 數據模型ID |
returnFields | JSON | 是 | 指定返回的字段。1.若期望返回所有字段,則傳入參數為["*"];2.若期望返回數據總數,則傳入參數為["COUNT"]。如:["*"]或者["name","age"]["COUNT"] |
conditions | JSON | 否 | 條件,由字段名、運算符、比較值組成一個condition。如:[{"fieldName": "id", "operate": "eq", "value": 7}] |
orderBy | JSON | 否 | 排序條件,由增序或降序以及排序字段組成。如:{"asc":"true", "orderByFields":["name","age"]} |
pageNum | Integer | 否 | 分頁頁數 |
pageSize | Integer | 否 | 分頁每頁數量 |
appId | String | 否 | 對于SaaS應用,需要填該值 |
scopeId | String | 否 | 經常是項目的id,該參數非必填,一般上架應用被授權之后,會被默認綁定到一個scope中,因此當前操作會被默認操作到被綁定到的這一個scope中。但是,對于集成應用,也有可能被綁定到多個scope中,此時該操作需要填入scopeId。 |
modelInstanceId | String | 否 | 模型實例id,即模型元信信所屬的實例,非必填,默認為null,null代表是公共實例 |
dataInstanceId | String | 否 | 數據實例id,即模型物理存儲數據所屬的實例,非必填,默認為null,null代表是公共實例 |
其中condition針對不同類型的屬性支持的運算符:
屬性 | 支持的運算符 |
Integer | eq,neq,lt,lteq,mt,mteq,bt,in,nin,nnull |
String | eq,neq,nnul,in,nin |
Double | eq,neq,lt,lteq,mt,mteq,bt,in,nin,nnull |
Boolean | eq,nnul |
Date | eq,neq,lt,lteq,mt,mteq,bt,nnul |
2. 返回參數
參數 | 類型 | 描述 |
data | String | 查詢返回數據內容,其中,Boolean類型的屬性返回值為0或1 |
3. 請求示例-1
{
"request": {
"apiVer": "0.0.4" // api版本號
},
"id": 1508212818676,// request里的全局唯一id透傳
"params": {
"modelId":"XXX123",
"returnFields":["MODE","ENGINE"],
"conditions":[
{"fieldName":"BRAND","value":"BMW","operate":"eq"},
{"fieldName":"WIDTH_SIZE","value":1,"value2":2,"operate":"bt"},
{"fieldName":"LONG_SIZE","value":"3","operate":"mt"}
],
"orderBy":{
"asc":true,
"orderByFields":["CREATE_DATA","MODE"]
},
"pageNum":1,
"pageSize":10
}
},
"version": "1.0" // 請求協議版本
}
4. 返回示例-1
{
"code": 200,
"localizedMsg": null,
"data": "{\"count\":1,
\"hasNext\":false,
\"items\":[{\"gmt_create\":1551872701000,\"MODE\":\"33\",\"ENGINE\":\"44\",\"id\":2,\"gmt_modified\":1551872714000}],
\"pageNum\":1,
\"pageSize\":10}",
"message": "success"
}
5. 請求示例-2
{
"request": {
"apiVer": "0.0.4" // api版本號
},
"id": 1508212818676,// request里的全局唯一id透傳
"params": {
"modelId":"XXX123",
"returnFields":["COUNT"],
"conditions":[
{"fieldName":"BRAND","value":"BMW","operate":"eq"},
{"fieldName":"WIDTH_SIZE","value":1,"value2":2,"operate":"bt"},
{"fieldName":"LONG_SIZE","value":"3","operate":"mt"}
],
"pageNum":1,
"pageSize":10
}
},
"version": "1.0" // 請求協議版本
}
6. 返回示例-2
{
"code": 200,
"localizedMsg": null,
"data": "{
\"hasNext\":false,
\"items\":[{
\"COUNT\":100
}]
}"
"message": "success"
}
7. 返回碼
狀態碼 | 描述 | |
200 | 成功 | |
460 | 參數驗證異常 | 會帶有驗證異常的詳細說明 |
500 | 服務異常 | server error |
52002 | 無訪問權限 | |
52005 | 目標存儲未找到 |
1.7 獲取文件上傳地址API
1. 請求參數
參數 | 類型 | 是否必傳 | 描述 |
modelId | String | 是 | 數據模型id |
version | String | 是 | 數據模型的版本號 |
fileSize | Integer | 是 | 文件大小,以字節為單位,目前系統不支持5M以上文件 |
attrName | String | 是 | 屬性名稱,模型中包含的屬性名稱,不包含會報錯進行提示 |
fileType | String | 是 | 文件類型,目前系統只支持bmp、png、gif、jpg |
appId | String | 否 | 對于SaaS應用,需要填該值 |
scopeId | String | 否 | 經常是項目的id,該參數非必填,一般上架應用被授權之后,會被默認綁定到一個scope中,因此當前操作會被默認操作到被綁定到的這一個scope中。但是,對于集成應用,也有可能被綁定到多個scope中,此時該操作需要填入scopeId。 |
2. 返回參數
參數 | 類型 | 描述 |
url | String | 數據上傳的url,url有效時間10s |
fileName | String | 文件名稱,系統隨機分配的文件名稱,用戶在得到這個文件名之后,應該將其放在相應模型數據的文件類型的字段上,例如:xxxxx.jpg |
3. 請求示例
{
"request": {
"apiVer": "0.0.1" // api版本號
},
"id": 1508212818671, // request里的全局唯一id透傳
"params": {
"modelId":"XXX123", //數據模型id
"fileSize":"3.2", //文件大小
"attrName":"name", //屬性名稱
"fileType":"jpg", //文件類型
"version":"1.0", //模型版本
},
"version": "1.0" // 請求協議版本
}
4. 返回示例
{
"code": 200, //返回是否成功,只要不是200說明返回不成功
"message": "success", //如果失敗,會返回失敗的信息描述
"localizedMsg": null,
"data": {"url":"http://xxx.xxx.xx","fileName":"xxx.jpg"} // 返回的數據
}
5. 返回碼
狀態碼 | 描述 | |
200 | 成功 | |
460 | 參數驗證異常 | 會帶有驗證異常的詳細說明 |
500 | 服務異常 | server error |
52002 | 無訪問權限 | |
52005 | 找不到目標存儲 | |
52009 | 參數和模型定義不匹配 | |
52011 | 數據類型校驗錯誤 | |
52064 | 屬性字段沒有相應的圖片標簽 | |
52063 | 文件大小不能大于5M |
1.8 獲取文件下載地址API
1. 請求參數
參數 | 類型 | 是否必傳 | 描述 |
modelId | String | 是 | 數據模型id |
version | String | 是 | 數據模型的版本號 |
attrName | String | 是 | 屬性名稱,模型中包含的屬性名稱,不包含會報錯進行提示 |
fileName | String | 是 | 文件名稱,必須為獲取文件上傳地址API中返回的fileName參數,例如:xxxxx.jpg |
appId | String | 否 | 對于SaaS應用,需要填該值 |
scopeId | String | 否 | 經常是項目的id,該參數非必填,一般上架應用被授權之后,會被默認綁定到一個scope中,因此當前操作會被默認操作到被綁定到的這一個scope中。但是,對于集成應用,也有可能被綁定到多個scope中,此時該操作需要填入scopeId。 |
2. 返回參數
參數 | 類型 | 描述 |
url | String | 數據上傳的url,url有效時間10s |
3. 請求示例
{
"request": {
"apiVer": "0.0.1" // api版本號
},
"id": 1508212818671, // request里的全局唯一id透傳
"params": {
"modelId":"XXX123", //數據模型id
"scopeId":"fdbsdj1dfjdubgxxx", //業務隔離id
"attrName":"name", //屬性名稱
"fileName":"xdsfxv.jpg", //文件類型
"version":"1.0", //模型版本
},
"version": "1.0" // 請求協議版本
}
4. 返回示例
{
"code": 200, //返回是否成功,只要不是200說明返回不成功
"message": "success", //如果失敗,會返回失敗的信息描述
"localizedMsg": null,
"data": {"url":"http://xxx.xxx.xx"} // 返回的數據下載查看的url
}
5. 返回碼
狀態碼 | 描述 | |
200 | 成功 | |
460 | 參數驗證異常 | 會帶有驗證異常的詳細說明 |
500 | 服務異常 | server error |
52002 | 無訪問權限 | |
52005 | 找不到目標存儲 | |
52009 | 參數和模型定義不匹配 | |
52011 | 數據類型校驗錯誤 | |
52064 | 屬性字段沒有相應的圖片標簽 |
1.9 查詢數據(不包含count)的API
1. 請求參數
參數 | 類型 | 是否必傳 | 說明 |
modelId | String | 是 | 數據模型ID |
returnFields | JSON | 是 | 指定返回的字段。1.若期望返回所有字段,則傳入參數為["*"];2.若期望返回數據總數,則傳入參數為["COUNT"]。如:["*"]或者["name","age"]["COUNT"] |
conditions | JSON | 否 | 條件,由字段名、運算符、比較值組成一個condition。如:[{"fieldName": "id", "operate": "eq", "value": 7}] |
orderBy | JSON | 否 | 排序條件,由增序或降序以及排序字段組成。如:{"asc":"true", "orderByFields":["name","age"]} |
pageNum | Integer | 否 | 分頁頁數 |
pageSize | Integer | 否 | 分頁每頁數量 |
appId | String | 否 | 對于SaaS應用,需要填該值 |
scopeId | String | 否 | 經常是項目的id,該參數非必填,一般上架應用被授權之后,會被默認綁定到一個scope中,因此當前操作會被默認操作到被綁定到的這一個scope中。但是,對于集成應用,也有可能被綁定到多個scope中,此時該操作需要填入scopeId。 |
modelInstanceId | String | 否 | 模型實例id,即模型元信信所屬的實例,非必填,默認為null,null代表是公共實例 |
dataInstanceId | String | 否 | 數據實例id,即模型物理存儲數據所屬的實例,非必填,默認為null,null代表是公共實例 |
其中condition針對不同類型的屬性支持的運算符:
屬性 | 支持的運算符 |
Integer | eq,neq,lt,lteq,mt,mteq,bt,in,nin,nnull |
String | eq,neq,nnul,in,nin |
Double | eq,neq,lt,lteq,mt,mteq,bt,in,nin,nnull |
Boolean | eq,nnul |
Date | eq,neq,lt,lteq,mt,mteq,bt,nnul |
2. 返回參數
參數 | 類型 | 描述 |
data | String | 查詢返回數據內容,其中,Boolean類型的屬性返回值為0或1 |
3. 請求示例-1
{
"request": {
"apiVer": "2.0.0" // api版本號
},
"id": 1508212818676,// request里的全局唯一id透傳
"params": {
"modelId":"XXX123",
"returnFields":["MODE","ENGINE"],
"conditions":[
{"fieldName":"BRAND","value":"BMW","operate":"eq"},
{"fieldName":"WIDTH_SIZE","value":1,"value2":2,"operate":"bt"},
{"fieldName":"LONG_SIZE","value":"3","operate":"mt"}
],
"orderBy":{
"asc":true,
"orderByFields":["CREATE_DATA","MODE"]
},
"pageNum":1,
"pageSize":10
}
},
"version": "1.0" // 請求協議版本
}
4. 返回示例-1
{
"code": 200,
"localizedMsg": null,
"data": "{\"hasNext\":false,
\"items\":[{\"gmt_create\":1551872701000,\"MODE\":\"33\",\"ENGINE\":\"44\",\"id\":2,\"gmt_modified\":1551872714000}],
\"pageNum\":1,
\"pageSize\":10}",
"message": "success"
}
5. 請求示例-2
{
"request": {
"apiVer": "2.0.0" // api版本號
},
"id": 1508212818676,// request里的全局唯一id透傳
"params": {
"modelId":"XXX123",
"returnFields":["COUNT"],
"conditions":[
{"fieldName":"BRAND","value":"BMW","operate":"eq"},
{"fieldName":"WIDTH_SIZE","value":1,"value2":2,"operate":"bt"},
{"fieldName":"LONG_SIZE","value":"3","operate":"mt"}
],
"pageNum":1,
"pageSize":10
}
},
"version": "1.0" // 請求協議版本
}
6. 返回示例-2
{
"code": 200,
"localizedMsg": null,
"data": "{
\"hasNext\":false,
\"items\":[{
\"COUNT\":100
}"
"message": "success"
}
7. 返回碼
狀態碼 | 描述 | |
200 | 成功 | |
460 | 參數驗證異常 | 會帶有驗證異常的詳細說明 |
500 | 服務異常 | server error |
52002 | 無訪問權限 | |
52005 | 目標存儲未找到 |
2.0 查詢總數的API
1. 請求參數
參數 | 類型 | 是否必傳 | 說明 |
modelId | String | 是 | 數據模型ID |
conditions | JSON | 否 | 條件,由字段名、運算符、比較值組成一個condition。如:[{“fieldName”: “id”,”operate”: “eq”,”value”: 7}] |
appId | String | 否 | 對于SaaS應用,需要填該值 |
scopeId | String | 否 | 經常是項目的id,該參數非必填,一般上架應用被授權之后,會被默認綁定到一個scope中,因此當前操作會被默認操作到被綁定到的這一個scope中。但是,對于集成應用,也有可能被綁定到多個scope中,此時該操作需要填入scopeId。 |
modelInstanceId | String | 否 | 模型實例id,即模型元信信所屬的實例,非必填,默認為null,null代表是公共實例 |
dataInstanceId | String | 否 | 數據實例id,即模型物理存儲數據所屬的實例,非必填,默認為null,null代表是公共實例 |
其中condition針對不同類型的屬性支持的運算符:
屬性 | 支持的運算符 |
Integer | eq,neq,lt,lteq,mt,mteq,bt,in,nin,nnull |
String | eq,neq,nnul,in,nin |
Double | eq,neq,lt,lteq,mt,mteq,bt,in,nin,nnull |
Boolean | eq,nnul |
Date | eq,neq,lt,lteq,mt,mteq,bt,nnul |
2. 返回參數
參數 | 類型 | 描述 |
data | String | 查詢返回數據內容,其中,Boolean類型的屬性返回值為0或1 |
3. 請求示例-1
{
"request": {
"apiVer": "0.0.3" // api版本號
},
"id": 1508212818676,// request里的全局唯一id透傳
"params": {
"modelId":"XXX123",
"conditions":[
{"fieldName":"BRAND","value":"BMW","operate":"eq"},
{"fieldName":"WIDTH_SIZE","value":1,"value2":2,"operate":"bt"},
{"fieldName":"LONG_SIZE","value":"3","operate":"mt"}
]
},
"version": "1.0" // 請求協議版本
}
4. 返回示例-1
{
"code": 200,
"localizedMsg": null,
"data": "{\"count\":23,
\"pageNum\":1,
\"pageSize\":10}",
"message": "success"
}
9. 返回碼
狀態碼 | 描述 | |
200 | 成功 | |
460 | 參數驗證異常 | 會帶有驗證異常的詳細說明 |
500 | 服務異常 | server error |
52002 | 無訪問權限 | |
52005 | 目標存儲未找到 |
2. 應用開發 - 數據訂閱
應用可以通過AMQP方式,訂閱數據的變更消息(新增、刪除、修改)。應用自身不需要發布數據的變更消息到通道中,這些消息的產生是由應用通過上面的數據操作API,對數據進行操作之后,由平臺產生。平臺產生時間之后,會將消息通過訂閱關系發送到訂閱方。在這個消息通信中,每一個應用實例,由AppKey標識身份。對于單租戶型的應用,每一個AppKey代表了一次應用分發的實例;但是,對于SaaS應用,他的一個AppKey代表了該應用對應的所有租戶的身份,因此,在SaaS應用按照AppKey得到消息之后,需要自行根據訂閱到的數據內容中的AppID字段,將數據對應到不用的用戶中。
2.1 SDK介紹
2.1.1 Java SDK
1. 依賴引用
對于企業實例和公共實例,都可以使用AMQP方式訂閱,需要添加以下依賴
<!-- amqp 1.0 qpid client -->
<dependency>
<groupId>org.apache.qpid</groupId>
<artifactId>qpid-jms-client</artifactId>
<version>0.40.0</version>
</dependency>
<!-- util for base64-->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
2. 身份認證
對于使用AMQP方式訂閱,示例代碼如下所示:
public static void main(String[] args) throws Exception {
String clientId = UUID.randomUUID().toString(); //填寫唯一的id,比如uuid
String random = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 6);
//按照阿里云IoT規范,組裝UserName
String userName = clientId + "|authMode=appkey"
+ ",signMethod=SHA256"
+ ",random=" + random
+ ",appKey=" + "{appkey:純數字}"
//+ ",iotInstanceId=" + iotInstanceId, //如果是企業實例ID,那么需要補充這個參數。如果是公共實例ID,那么隱藏這個參數
+ ",groupId=" + "{appkey:純數字}"
+ "|";
//按照阿里云IoT規范,計算簽名,組裝password
String signContent = "random=" + random;
String password = doSign(signContent, "{app-secret}", "HmacSHA256");
//如果是公共實例,那么使用如下鏈接地址。如果是企業實例,需要在實例管理中查看amqp鏈接地址。
String connectionUrl =
"failover:(amqps://{aliyun-uid}.iot-amqp.cn-shanghai.aliyuncs.com:5671?amqp.idleTimeout=80000)"
+ "?failover.maxReconnectAttempts=10&failover.reconnectDelay=30";
Hashtable<String, String> hashtable = new Hashtable<String, String>();
hashtable.put("connectionfactory.SBCF", connectionUrl);
hashtable.put("queue.QUEUE", "default");
hashtable.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.qpid.jms.jndi.JmsInitialContextFactory");
Context context = new InitialContext(hashtable);
ConnectionFactory cf = (ConnectionFactory)context.lookup("SBCF");
Destination queue = (Destination)context.lookup("QUEUE");
Connection connection = cf.createConnection(userName, password);
MyJmsConnectionListener myJmsConnectionListener = new MyJmsConnectionListener();
((JmsConnection)connection).addConnectionListener(myJmsConnectionListener);
// Create Session
// Session.CLIENT_ACKNOWLEDGE: 收到消息后,需要手動調用message.acknowledge()
// Session.AUTO_ACKNOWLEDGE: SDK自動ack(推薦)
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
connection.start();
// Create Receiver Link
MessageConsumer consumer = session.createConsumer(queue);
}
/**
* 按照指定簽名算法計算password簽名
*/
private static String doSign(String toSignString, String secret, String signMethod) throws Exception {
SecretKeySpec signingKey = new SecretKeySpec(secret.getBytes(), signMethod);
Mac mac = Mac.getInstance(signMethod);
mac.init(signingKey);
byte[] rawHmac = mac.doFinal(toSignString.getBytes());
return Hex.encodeHexString(rawHmac);
}
}
注:connectionUrlTemplate 的寫法如下所示:
上海:
公共實例:amqps://${uid}.iot-amqp.cn-shanghai.aliyuncs.com:5671
購買的實例:在LP控制臺“實例管理”--“查看終端節點”里找到AMQP接入點
3. 設置消息接受接口
使用AMQP方式,建立連接之前,需要提供消息接收接口,用于處理回調的消息,需要通過 ((JmsConnection) connection).addConnectionListener(myJmsConnectionListener)來設置,其中 myJmsConnectionListener是一個自定義實現JmsConnectionListener接口的類,如下所示:
class MyJmsConnectionListener impJmsConnectionListener() {
/**
* 連接成功建立
* @param remoteURI
*/
@Override
public void onConnectionEstablished(URI remoteURI) {
logger.info("onConnectionEstablished, remoteUri:{}", remoteURI);
}
/**
* 最終連接失敗,嘗試過最大重試次數之后
* @param error
*/
@Override
public void onConnectionFailure(Throwable error) {
logger.error("onConnectionFailure, {}", error.getMessage());
}
/**
* 連接中斷
* @param remoteURI
*/
@Override
public void onConnectionInterrupted(URI remoteURI) {
logger.info("onConnectionInterrupted, remoteUri:{}", remoteURI);
}
/**
* 連接中斷后又自動重連上
* @param remoteURI
*/
@Override
public void onConnectionRestored(URI remoteURI) {
logger.info("onConnectionRestored, remoteUri:{}", remoteURI);
}
@Override
public void onInboundMessage(JmsInboundMessageDispatch envelope) {
logger.info("onInboundMessage, {}", envelope);
JmsMessage message = envelope.getMessage();
try {
byte[] body = message.getBody(byte[].class);
String content = new String(body);
String topic = message.getStringProperty("topic");
String messageId = message.getStringProperty("messageId");
logger.info("receive message"
+ ", topic = " + topic
+ ", messageId = " + messageId
+ ", content = " + content);
//如果創建Session選擇的是Session.CLIENT_ACKNOWLEDGE,這里需要手動ack
//Thread.sleep(2000);
message.acknowledge();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onSessionClosed(Session session, Throwable cause) {
logger.error("onSessionClosed, " + session, cause);
}
@Override
public void onConsumerClosed(MessageConsumer consumer, Throwable cause) {
logger.error("onConsumerClosed, " + consumer, cause);
}
@Override
public void onProducerClosed(MessageProducer producer, Throwable cause) {
logger.error("onProducerClosed, " + producer, cause);
}
}
其中的content內容是一個JSON對象字符串,字段信息如下:
// 模型ID
String modelId;
// 變更數據的ID
List<Long> dataIds;
// 操作類型:insert/update/delete
String operateType;
// 訂閱的appId, 以appKey授權時為空
String appId;
String scopeId;
// 模型的邏輯隔離id
String logicalModelIsoId;
// 模型實例id
String modelInstanceId;
// 數據實例id
String dataInstanceId;