目录:
1. Cloud Foundry App
1.1. Session
1.1.1. JS 代码调用示例
1.1.2. 通过第三方工具 postman 调用测试验证 API 
1.2. User Token 
1.3. Technical User
1.4. App Credential 
1.4.1. 应用凭证介绍
1.4.2. APP Token Management Service 置换token
1.4.3. 应用凭证的应用流程
1.4.4. 应用凭证生成 token 
1.5. WebScoket
1.5.1. Example
 
 
 
 
1. Cloud Foundry App
 
1.1. Session
通过浏览器 session 调用 api 方式主要是适用于前端 app 去访问部署在 Cloud Foundry , 不同 space 下的后端 app. 而且前
提条件是被访问的后端 app 必须在 MindSphere 系统中已经注册。
在前端 app 开发过程中必须注意一点就是在调用另一个 app 或者服务提供的接口时 , URL 不是以 ”gateway” 开头的;如果使
用了“ gateway ”开头的这种形式的 URL, 一旦使用就会报跨域的错误 , 这是因为 MindSphere 为了安全考虑 , 前端禁用带有
gateway api 调用 , 如前端使用 https //gateway.cn1.mindsphere-in.cn/api/datasource-supplab/v1/getValue 这地址
去调用 datasource 应用程序 getValue 这接口是错误的 , 将报跨域错误 , 正确调用格式为 /api/{app 名称 }-{ 租户名称 }/{ 版本
信息 }/{app 接口地址 }. 在地址构成格式中需要注意版本信息有两种情况:
1. developer 类型的 tenant , 如果 app MindSphere 的注册版本无论是什么格式 , 版本都默认为 V1 :即
/api/datasource-supplab/V1/getValue
2. 对应到 operator 类型的 tenant , 所有的 operator tenant 暴露的接口 , 其版本都是以 developer cockpit 中输入为准
, 所以就默认不是 V1 . 如果 app MindSphere 的注册版本以 v 打头( v1.0.5 , 则版本应默认为 v1, 因为系统会自
动将小数转为整数 , /api/datasource-supplab/v1/getValue.
*Note : 2020 5 月的 release 过后 , 这个将会被改变 , 如何改变请参见 Link 1 .
Link1: 这里附上一个 developer cockpit , 如何填写 version 的说明及格式介绍 , 以及填写过后对后续提供对外访问接口时
如何选择版本的介绍: https //documentation.mindsphere.io/resources/html/developer-cockpit/en
US/124503468811.html . 以及一个多个前端访问一个后端的注册介绍 PPT
 
在以 session 访问 MindSphere api App api , 常用方式有 GET POST PUT DELETE 。需要注意的是在调用
MindSphere 平台 api , 需要 APP 添加在 Developer Cockpit 的授权管理中对 app 添加相关 api 的服务的角色。
如请求为 ajax 请求 , 且类型是 GET/POST/PUT/DELETE 方法调用时 , 需要在请求 header 添加 cookie X-XSRF-TOKEN
个参数 ( 请参考 : https://community.sw.siemens.com/s/article/ajax-post-403 ) cookie 参数的添加 不是必须的 , 这和所
使用浏览器安全规则有关系;在示例中 url 地址为换 MindShpere api 同样适用“ /api/iottimeseries/v3/timeseries
cookie 设置值格式为:
{”Cockie” :“ SESSION= SESSION 值’; XSRF-TOKEN= XSRF-TOKEN 值’” }
X-XSRF-TOKEN 设置格式: { X-XSRF-TOKEN ”: XSRF-TOKEN }
XSRF-TOKEN 值和 SESSION 值分别从浏览器中的 cookie 中获取如下图所示
 
1.1.1. JS 代码调用示例
function testData() {
var apiReq = null;
if (typeof (XMLHttpRequest) != undefined) {
apiReq = new XMLHttpRequest();
} else {
apiReq = new ActiveXObject("Microsoft.XMLHttp");
}
var url = "/api/datasource-supplab/v1/updateValue";
//var apiReq = new XMLHttpRequest();
apiReq.withCredentials = true;
var xtoken = getCookie("XSRF-TOKEN");
console.log('come from cookie XSRF-TOKEN:' + xtoken);
var ss = getCookie("SESSION");
var sessin = "SESSION=" + ss + ";" + "XSRF-TOKEN=" + xtoken;
apiReq.open("post", url, false);// 'false' makes the request synchronous
apiReq.setRequestHeader("X-XSRF-TOKEN", xtoken);
apiReq.setRequestHeader("Cookie", sessin);
apiReq.onreadystatechange = function () {
if (apiReq.readyState === 4) { // When readyState property is 4 and status property is 200,
the response is ready
if (apiReq.status === 200) {
console.log('POST API response:' + apiReq.response);
document.getElementById("response_api_value").innerHTML = "POST API response:
" + apiReq.response;
} else {
console.error('Request status text:' + apiReq.statusText);
}
}
}
console.log('POST:' + url);
apiReq.send(null);
}
function getCookie(name) {
var strcookie = document.cookie;//获取 cookie 字符串
var arrcookie = strcookie.split(";");//分割
//遍历匹配
for (var i = 0;i < arrcookie.length;i++) {
var arr = arrcookie[i].split("=");
if (arr[0] == name) {
return arr[1];
}
}
return null;
}
GET api 方法比较简单 , 一般情况直接调用即可 , 有时候需要参考 POST 方法调用需要添加参数 , 在示例中 url 地址为换
MindShpere api 同样适用“ /api/iottimeseries/v3/timeseries/{entityId}/{propertySetName}
调用实例:
 
function callGetApi() {
var apiReq = null;
if (typeof (XMLHttpRequest) != undefined) {
apiReq = new XMLHttpRequest(); } else {
apiReq = new ActiveXObject("Microsoft.XMLHttp"); }
var url = "/api/datasource-supplab/v1/getValue"
apiReq.open("get", url, false);// 'false' makes the request synchronous
apiReq.onreadystatechange = function () {
if (apiReq.readyState === 4) { // When readyState property is 4 and status property is 200, 
the response is ready
if (apiReq.status === 200) {
console.log('Get API response:' + apiReq.response);
document.getElementById("response_api_value").innerHTML = "GET API response: " + apiReq.response; } else {
console.error('Request status text:' + apiReq.statusText); } } }
console.log('GET:' + url);
apiReq.send(null); }
APP 的开发过程中 , 我们可以直接在浏览器验证 app 提供或者 MindShpere 平台提供 API 接口是否可用 , 此方法只适用于
GET 方法的接口:
1. app 自己调用自己开发 api, 直接点击 app, 在浏览器中地址栏的地址末端添加“ / ”后接接口如: datasource app 提供的
getValue 接口调用
2. app 调用另外一个 app api, callpostappApi 调用 datasource app 提供的 getValue 接口 , 此方法 GET 方法调用
类似 , 直接点击 app, 在浏览器中地址栏的地址末端添加 /api/{app 名称 }-{ 租户名称 }/{ 版本信息 }/{app 接口地址 },
如:
1.1.2. 通过第三方工具 postman 调用测试验证 API
1. app 调用自己的 api, 点击 app, app 地址直接添加接口“ / 接口”或者 /api/{app 名称 } -{ 租户名称 }/{ 版本信息 }/{app
口地址 } 格式;如 https //supplab-datasource-supplab.cn1.mindsphere-in.cn/ updateValue https
//supplab-datasource-supplab.cn1.mindsphere-in.cn/api/datasource-supplab/v1/updateValue
POST 方法;点击 app, f12, cockie 中取出 XSRF-TOKEN 值和 SESSION 值添加到 header
postman 地址栏中输入 https
//supplab-datasource-supplab.cn1.mindsphere-in.cn/api/datasource-supplab/v1/updateValue 或者 https
//supplab-datasource-supplab.cn1.mindsphere-in.cn/api/datasource-supplab/v1/updateValue 接口 ,
cockie 中取出 XSRF-TOKEN 值和 SESSION 值添加到 headers , 设置 Cockie 参数值和 X-XSRF-TOKEN 参数值 {X
XSRF-TOKEN XSRF-TOKEN} {Cockie SESSION=SESSION 值; XSRF-TOKEN =XSRF-TOKEN }
GET 调用方法和 POST 调用方法差不多都需要在 header 中添加参数 , 这里可以不用在 header 添加 X-XSRF-TOKEN
值只需要设置 Cockie 值即可 , postman 地址栏中输入 https //supplab-datasource
supplab.cn1.mindsphere-in.cn/api/datasource-supplab/v1/getValue 或者 https //supplab-datasource
supplab.cn1.mindsphere-in.cn/api/datasource-supplab/v1/getValue 接口 , cockie 中取出 XSRF-TOKEN值和 SESSION 值添加到 headers , 设置 Cockie {Cockie SESSION=SESSION 值;XSRF-TOKEN =XSRF-TOKEN

2. app 调用另外一个 app api , callpostappApi 调用 datasource app 提供的 getValue 接口 , 此方法 GET 方法调用
类似 , 直接点击 app, 在浏览器中地址栏的地址末端添加 /api/{app 名称 }-{ 租户名称 }/{ 版本信息 }/{app 接口地址 } 如:
POST 方法将点击调用 app, f12, cockie 中取出 XSRF-TOKEN 值和 SESSION 值添加到 headers , https
//supplab-callpostappapi-supplab.cn1.mindsphere-in.cn/api/datasource-supplab/v1/updateValue 地址调用

 

Postman 调用将 https://supplab-callpostappapi-supplab.cn1.mindsphere-in.cn/api/datasource-supplab/v1/updateValue 口地址复制到 postman 地址栏中, 将 cockie 和 X-XSRF-TOKEN 添加到 headers 中, 从 cockie 中取出 XSRF-TOKEN 值和SESSION 值添加到 headers 中设置 Cockie 参数值和 X-XSRF-TOKEN 参数值{X-XSRF-TOKEN:XSRF-TOKEN};{Cockie:SESSION=SESSION 值;XSRF-TOKEN =XSRF-TOKEN 值}如

 

GET 方法在 postman 中调用方法和 POST 调用方法差不多都需要在 header 中添加参数, 这里可以不用在 header 添加 X-XSRF-TOKEN 值只需要设置 Cockie 值即可, postman 调用将 https://supplab-callpostappapi-supplab.cn1.mindsphere-in.cn/api/datasource-supplab/v1/getValue 接口地址复制到 postman 地址栏中, 从 cockie 中取出 XSRF-TOKEN 值和 SESSION 值添加到 headers 中, 设置 Cockie {Cockie:SESSION=SESSION 值;XSRF-TOKEN =XSRF-TOKEN 值}如

 

1.2. User Token

这里的 User token 指的是从 MindShpere 平台中, RequestHeader 中获的 Authorization 的值, Authorization 是在后端程序在实现过程从 RequestHeader 中获取, 我们一般称呼它为 User Token. 利用这个 user token 可以去访问 MindSphere 平台提供 api 和已经注册 app 的 api. 获取 user token 的 Java 代码示例:

@RequestMapping("/getAccessToken")
public String getAccessToken(@RequestHeader("Authorization") String userToken) throws IOException, 
MindsphereException {
 return userToken; }
  1. 利用 user token 访问 MindSphere 的 api, 要使 user token 能够访问 MindSphere api, 必须在 DeveloperCockpit 的授权管理中, 给 app 添加访问 MindSphere api 的相关服务角色(Role), 如要使 user token 能够访问 time series service 提供 api 读写数据, 就必须给 APP 添加 mdsp:core:iot.timAdmin 的角色, 如下图所示:
 @RequestMapping("/getAccessTokenValue")
public String getAccessTokenValue(@RequestHeader("Authorization") String token) throws 
IOException, MindsphereException {
 HttpHeaders headers = new HttpHeaders();
 headers.set("cache-control", "no-cache");
 headers.set("Content-Type", "application/json");
 headers.add("Authorization", token);
 RestTemplate restTemplate = new RestTemplate();
 String url = "https://gateway.cn1.mindspherein.cn/api/iottimeseries/v3/timeseries/9ab3f21ff8ad43638ed74ea6e413bb72/modbus_model";
 String bodyJson = "";
 HttpEntity<String> requestEntity = new HttpEntity<String>(bodyJson, headers);
 ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, 
requestEntity, String.class);
 String responseBody = responseEntity.getBody().toString();
 System.out.println("responser body:" + responseBody);
 return responseBody; }

2. 利用 user token 访问 自己开发 app 的 api, 这个方法主要用来验证 app 提供 api, 一般后端程序可以直接获取利用 usertoken 去访问相关的资源, 除非两个后台 app 之间的交互, 这样的情况, 要先获取被访问 app 的 user token

  1. 访问格式 https://gateway.cn1.mindsphere-in.cn /api/{app 名称} -{租户名称}/{版本信息}/{app 接口地址};如 https//gateway.cn1.mindsphere-in.cn/api/datasource-supplab/v1/getValue
  2. 利用 user token 通过 postman 访问 app api, 在 postman 中地址栏中输入 https://gateway.cn1.mindspherein.cn/api/datasource-supplab/v1/getValue, 然后选择 Auth->type->bearer Token, headers 中设置{ key: Content-Type ;Value:application/json } 然后在 Token 中输入 uesrtoken, 点击发送

         

  3. 可以 https://jwt.io/址中输入 Authorzation 的 token 可以查看 token 可以访问接口的权限, 如图所示

        

 

1.3. Technical User

Service credential(租户服务凭证信息). 一般只有开发者账号才有权限申请, 当您购买了 MindSphere 开发者账号时, 就可以创建工单提交工单, 申请开通服务凭证, 具体申请格式可以查看链接中的 https//developer.mindsphere.io/zh/howto/howtoselfhosted-api-access.html 建服务凭证内容, 申请的开发者账号(tenant name)服务凭证包括两个内容 client_id 和 client _secret, 我们将开通租房凭证获取的 client_id 和 client_secret 称为 Tech user, 使用 tech user 信息与 MindSphere

平台交互获取 token, 然后应用 token 访问 MindSphere 平台的提供所有 api, 这个 token 的有效时间是 30 分钟, 超过 30 分钟需要重新获取。通过 tech user 获取 token 权限比较高, 几乎可以访问 mindsphere 平台提供的一切资源, 为了您的账户安全,

tech user 信息应注意保存, 防止泄露, 如果发现 tech user 信息泄露, 为了您账号的安全, 请及时重新申请. 利用租户服务凭证信息获取 token 方法有:

1. 通过代码方式从后端程序中获取 token, 中国区获取地址格式为 https://{租户名称}.piam.cn1.mindspherein.cn/uaa/oauth/token, 代码示例如下

 @RequestMapping("/getTechUser")
public String getTechUser() throws IOException, MindsphereException {
 String token = "";
 HttpHeaders headers = new HttpHeaders();
 headers.set("Content-Type", "application/x-www-form-urlencoded");
 headers.set("Accept", "application/json");
 RestTemplate restTemplate = new RestTemplate();
 String url = "https://supplab.piam.cn1.mindsphere-in.cn/uaa/oauth/token";
 String bodyJson = "client_id={服务凭证 id} &client_secret={服务凭证密码} 
&grant_type=client_credentials";
 HttpEntity<String> requestEntity = new HttpEntity<String>(bodyJson, headers);
 ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, 
requestEntity, String.class);
 JSONObject jsonObject = new JSONObject(responseEntity.getBody());
 if (!jsonObject.isNull("access_token")) {
 token = jsonObject.getString("access_token");
 } else {
 System.out.println("ge response body access_token is null");
 return null;
 }
 return token; }

在上述代码需要将 bodyJson="client_id={服务凭证 id} &client_secret={服务凭证密码}&grant_type=client_credentials"中的服务凭证 id 和服务凭证密码替换为您自己的服务凭证信息, 其次代码返回是一个 json 格式的字符串, 需要将字符串中 access_token 作为 token 值.

2. 利用凭证信息通过 postman 获取 token, 在 postman 中 Params 中设置为 grant_type, VAULE 为 client_credentials 或者直接在地址栏输入 https://supplab1.piam.cn1.mindsphere-in.cn/uaa/oauth/token?grant_type=client_credentials 址;Auth type 选择 Basic Auth, 然后 Username 填入服务凭证 idclient_id, Password 填入服务凭证密码(client_secret)如图所示:

3。 通过代码方式利用 access_token 直接调用 MindSphere api 或已注册的 app 的 api;调用方式基本相同只需要将调用接口进行替换即可:

  1. 调用 MindSphere api 地址格式为:https://gateway.cn1.mindsphere-in.cn/{MindSphere api};如: https://gateway.cn1.mindspherein.cn/api/iottimeseries/v3/timeseries/9ab3f21ff8ad43638ed74ea6e413bb72/modbus_model
  2. 调用已注册 APP API 地址格式为:https://gateway.cn1.mindsphere-in.cn /api/{app 名称}-{租户名称}/{版本信息}/{app 接口地址}, 如 https://gateway.cn1.mindsphere-in.cn/api/datasource-supplab/v1/getValue
  3. 代码示例:
@RequestMapping("/getTechTokenValue")
public String getTechTokenValue() throws IOException, MindsphereException {
 HttpHeaders headers = new HttpHeaders();
 headers.set("cache-control", "no-cache");
 headers.set("Content-Type", "application/json");
 String token = getTechUser();
 headers.add("Authorization", token);
 RestTemplate restTemplate = new RestTemplate();
 String url = "https://gateway.cn1.mindspherein.cn/api/iottimeseries/v3/timeseries/9ab3f21ff8ad43638ed74ea6e413bb72/modbus_model";
 String bodyJson = "";
 HttpEntity<String> requestEntity = new HttpEntity<String>(bodyJson, headers);
 ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, 
String.class);
 String responseBody = responseEntity.getBody().toString();
 System.out.println("responser body:" + responseBody);
 return responseBody; }

上述代码中将 url 地址替换为访问 app 地址(https://gateway.cn1.mindsphere-in.cn/api/datasourcesupplab/v1/getValue)同样有效

 

4. 利用 https://gateway.cn1.mindspherein.cn/api/iottimeseries/v3/timeseries/9ab3f21ff8ad43638ed74ea6e413bb72/modbus_model 通过 postman 工具调用 MindSphere api 或已注册 app api;调用方式基本相同只需要将调用接口进行替换即可:

  • 通过 postman 调用 MindSphere api, 在 postman 中地址栏中输入 https://gateway.cn1.mindspherein.cn/api/iottimeseries/v3/timeseries/9ab3f21ff8ad43638ed74ea6e413bb72/modbus_model, 送然后选择 Auth->type->bearer Token, headers 中设置{key:Content-Type;Value:application/json} 然后在 Token 中输入 uesrtoken, 点击发送

      

 

1.4. App Credential

1.4.1. 应用凭证介绍

在 app 开发过程中, app 与 MindSphere 平台或是自己后端 app 进行资源交互时, 我们推荐是应用凭证方式进行;App

Credentials( 应用凭证)是 MindSphere 平台的 token management service 管理应用凭证的一项功能, app 在开发过程中, 如果在 Developer Cockpit 中创建应用凭证, 通过应用凭证信息与 MindSphere 平台 token management service 交互获取 token, 这个 token 有效期也是 30 分钟, 但是 token 在快过期的时 token management service 会提前 5 分钟 token 置换, 用户可以不用关心有效期的问题。

通过应用凭证信息获取的 token 具备跨租户访问数据的能力, 这个功能只有在具有应用凭证的 APP 在分配到 operator 环境, 在从 operator 环境分配用户环境(IoT 用户)时, 只有 IOT 用户授予同意时, 在 operator 部署的环境中 APP 使用此 token 可以获取 IOT 用户中资源。

应用凭证支持自托管程序和 MindSphere Cloud Foundry APP, 它们之间的区别是 MindSphere Cloud Foundry APP 在 operator 对应 Cloud Foundry 中是自动将应用凭证信息设置为环境变量中, 而自托管程序应用则是保存在文件中, 需要用户自行下载。

需要注意的是 developer 环境和 operator 环境中产生的应用凭证是不一样的, 主要区别如下:

  • 在 Developer 环境中的应用凭证只能在 developer 环境中有效, 不具备跨租户访问能力, 手动产生, 需要手动记录便于开发测试, 不能将将 developer 环境的应用凭证设置到 operator 环境
  • 在 Operator 环境中的应用凭证也只能在 operator 环境中有效, 通过 IoT 用户授权之后具备跨租户访问能力, 自动生成应用凭证, 在 cloudfoundry 中自动设置为环境变量, selfhost 自动生成保存在 execel 文件中, 需要手动下载。

在开发过程中每个 app 的应用凭证具有唯一性且有有效期, 所以每个 app 只用使用自己的应用凭证, 不要将应用凭信息证嵌入到代码中, 尽量使用官网提供 sdk, 有的 sdk 已经封装了此类接口如(JavaSDK)或者开发语言具有获取自动获取环境变量接口, 便于应用凭证到期的时候能够自动获取延期的变量值, 也便于维护。

关于 token management service 介绍可以参考 https://developer.mindsphere.io/zh/apis/exchangetokenmanager/api-tokenmanager-overview.html 接中的内容。

1.4.2. APP 与 Token Management Service 置换 token

在 app 应用凭证创建时会提供两个相信 client_id 和 client_secret 两个信息, 此信息只生成一次, 有效期为 365 天。App 必须提供应用凭证信息 client_id, client_secret 及注册应用 appname、appversion 和 hosttenant 名称、usertenant 名称与 token management service 置换 token, 在这个过程需要特别注意一点是 app 从 Developer Cockpit 上传时所选择 read

(受限的)和 readwrite(读和写)在生成 token 分别对应权限为 mdsp:core:Default3rdPartyTechUser 与 mdsp:core:Admin3rdPartyTechUser.

➢ 在 developer 账号中创建的应用凭证需要手动保存文件, 手动设置在环境变量中或者报错 manifest 文件中。

  • 在 Cloud Foundry 中通过 cf set-env APP_NAME ENV_VAR_NAME ENV_VAR_VALUE 手动设置环境变量, 如:

 

cf set-env appname MDSP_KEY_STORE_CLIENT_ID client_id

cf set-env appname MDSP_KEY_STORE_CLIENT_ID client_secret

 

  • Manifest 文件保存, 重现 push APP 设置环境变量如下

---

applications:

- name:dataSource

instances:1

path:dataSource-0.0.1-SNAPSHOT.jar

memory:1G

random-route:true

env:

HOST_ENVIRONMENT:cn1

MDSP_OS_VM_APP_NAME:app name

MDSP_OS_VM_APP_VERSION:app version

MDSP_KEY_STORE_CLIENT_ID:client_id

MDSP_KEY_STORE_CLIENT_SECRET:client_sercret

MDSP_HOST_TENANT:tenant name

MDSP_USER_TENANT:tenant name

JAVA_OPTS:'-XX:ReservedCodeCacheSize=512M

  • Operator Cockpit 环境中 MindSphere Cloud Foundry APP 创建应用凭证, 注册成功会自动保存在环境变量值 MDSP_KEY_STORE_CLIENT_ID, MDSP_KEY_STORE_CLIENT_SECRET 中;Self Hosted app 创建应用凭证注册成 功时会自动保存在文件中, 用户在应用注册项自行下载保存。
Operator Cockpit 中将 app 分配 iot 用户时 , 后台服务将会发送邮件给予 IoT Plan 租户是否接受 app 使用后台服务访问
IoT 租户中的资源;用户如果不接受 , App 应用凭证信息 client id client secret appname appversion
hosttenant usertenant token management service 进行交互获取 token 就无法访问 iot 用户的中资源 , 这个凭证信息
对于所有 IoT Plan 租户来说是不可见。
app 开发过程 , MindSphere 为一些常见的开发言语提供了 SDK, SDK MindSphere 平台的各个服务的 API 进行封装 ,
便 app 的开发实现 , 当然用户也可以直接使用官网( https://developer.mindsphere.io/zh/apis/index.html )提供服务 api
进行实现。

 

1.4.3. 应用凭证的应用流程

 

不同性质的 app 有不同应用凭证流程 , 目前有两种应用凭证应用流程 MindSphere Cloud Foundry APP 和自托管 APP
MindSphere Cloud Foundry APP 创建应用流程

1. 创建 , 注册 app
2. 上传 app 审核选择 , 上传 app , 根据 app 获取资源的权限 , 选择应用凭证 read (受限的)或者 readwrite (读和写)。
read (受限的):产生的 token scope mdsp core Default3rdPartyTechUser
readwrite (读和写):产生的 token scope mdsp core Admin3rdPartyTechUser
3. 审核 app
4. Developer Cockpit 中等待审核时间一般为 5
5. 审核结束 , 点击 app, Developer Cockpit 中已通过审核应用显示
6. 分配 app Operator Plan
7. 等待 operator Plan 接受
8. Operator Plan 选择是否接受 app 分配
9. Operator Plan 接受 app 分配
10. Developer Plan 授权 app OperatorPlan
11. Operator Plan app 进行部署注册 , 注册成功时 Operator Cockpit 对应的 cloud foundry 环境中自动将应用凭证信息 client_id client_secret
添加 app 环境变量中 MDSP_KEY_STORE_CLIENT_ID MDSP_KEY_STORE_CLIENT_SECRET
12. Operator Plan app 从开通服务中分配至 IoT Plan
13. 等待接收收件邮件 , IoT Plan 用户收到 Operator Plan 分配 App 邮件并在邮件中点击接受 , 同意带有应用凭证的 App 在使用后台服务读取本
租户中的数据
14. 等待 IoT Plan 用户同意 app 分配
15. 同意接受 app 服务 , Operator Cockpit 开通服务显示已开通服务状态
16. IoT Plan 用户使用 app, app 根据调用的接口可以选择自动获取 cloud foundry 环境中所设置的 app 环境变量信息 , APP 名称、 APP 版本信
息、 client_id, client_secert 和通过 mindsphere 平台请求 header user token 分离出来 host tenat 名称 user tenant 名称与 token
management service 交互获取 token, 利用 token 去访问用户租户中的相关资源

自托管 APP 应用创建流程
1. 创建 , 注册 app
2. 上传 app 审核选择 , 上传 app , 根据 app 获取资源的权限 , 选择应用凭证 read (受限的)或者 readwrite (读和写)。
read (受限的):产生的 token scope mdsp core Default3rdPartyTechUser
readwrite (读和写):产生的 token scope mdsp core Admin3rdPartyTechUser
3. 审核 app
4. Developer Cockpit 中等待审核时间一般为 5
5. 审核结束 , 点击 app, Developer Cockpit 中已通过审核应用显示
6. 分配 app Operator Plan
7. 等待 operator Plan 接受
8. Operato rPlan 选择是否接受 app 分配
9. Operator Plan 接受 app 分配
10. Developer Plan 授权 app Operator Plan
11. Operator Plan app 进行部署注册 , 注册成功时将在注册项生成应用凭证信息 client_id client_secret, 将应用凭证信息下载保存 , 随后将应
用凭证信息 client_id client_secret 添加 app 部署环境的环境变量中 MDSP_KEY_STORE_CLIENT_ID MDSP_KEY_STORE_CLIENT_SECRET,
12. Operator Plan app 从开通服务中分配至 IoTPlan
13. IoT Plan 用户收 Operator Plan 分配 App 邮件提示 , 在邮件中点击接受 , 同意带有应用凭证的 App 在使用后台服务读取本租户中的数据
14. 等待 IoT Plan 用户同意 app 分配
15. 同意接受 app , Operator Cockpit 开通服务中显示已开通服务
16. IoT Plan 用户使用 app, app 根据调用的接口可以选择自动获取 app 环境变量信息 APP 名称 ( 设置环境变量 MDSP_OS_VM_APP_NAME APP
名称 ) APP 版本信息 ( 设置环境变量 MDSP_OS_VM_APP_VERSION :: APP 版本信息 ), client_id, client_secert 和通过 mindsphere 平台请求
header usertoken 分离出来 hosttenant 名称 usertenant 名称与 token management service 置换获取 token, 利用 token 去访问用户租户中的
相关资源
注意 :针对 self-hosted app, 从环境变量获取凭证信息及 app 名称、版本只是其中的一种方法 , 也从配置文件中获取或界面输入
 
 
1.4.4. 应用凭证生成 token
通过代码生成 , 利用生成 token 可以访问 MindSphere api 或者 APP api, 访问方法与租户凭证生成 token 访问方法一致
代码示例
 
public String getInterfaceToken(String appName, String appVersion, String hostTenant, String 
userTenant) {
 String responseBody = "";
 String token = "";
 String bodyJson =
 "{\n" + " \"appName\":\"" + appName + "\",\n" + " \"appVersion\":\"" + appVersion 
+ "\",\n" + " \"hostTenant\":\"" + hostTenant
 + "\",\n" + " \"userTenant\":\"" + userTenant + "\",\n" + " 
\"grant_type\":\"client_credentials\"\n" + "}";
 String strClientID = "{应用凭证 Id/client_id} ";
 String strClientSceret = "{应用凭证密钥/client_secret}";
 String strBase64 = getBase64(strClientID, strClientSceret);
 HttpHeaders headers = new HttpHeaders();
 headers.set("cache-control", "no-cache");
 headers.set("Content-Type", "application/json;charset=UTF-8");
 headers.add("x-space-auth-key", "Bearer " + strBase64);
 RestTemplate restTemplate = new RestTemplate();
 String url = "https://gateway.cn1.mindsphere-in.cn/api/technicaltokenmanager/v3/oauth/token";
 HttpEntity<String> requestEntity = new HttpEntity<String>(bodyJson, headers);
 ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, 
requestEntity, String.class);
 responseBody = responseEntity.getBody();
 JSONObject jsonObject = new JSONObject(responseBody);
 if (!jsonObject.isNull("access_token")) {
 token = jsonObject.getString("access_token");
 } else {
 System.out.println("ge response body access_token is null");
 return;
 }
 System.out.println("responser body:" + token);
 return token; }
// 应用凭证信息转化为 base64
public String getBase64(String clientID, String clientSceret) {
 String strGorp = clientID + ":" + clientSceret;
 String base64Creds = "";
 try {
 byte[] base64CredsBytes = Base64.encodeBase64(strGorp.getBytes("UTF-8"));
 base64Creds = new String(base64CredsBytes, "UTF-8");
 } catch (UnsupportedEncodingException e) {
 System.out.println(e.getMessage());
 }
 return base64Creds; }
通过 postman 工具生成 token, 利用生成 token 可以访问 MindSphere api 或者 app api, 访问方法与租户凭证生成
token 访问方法一致
  •  首先在 postman 地址栏中输入 https://gateway.cn1.mindsphere-in.cn/api/technicaltokenmanager/v3/oauth/token 地址

  • 首先使用 https://www.base64encode.org 网址中工具 APP 应用凭证 client_id client_secret 转化为 Base64, 化格式为”client_idclient_secret”;点击 ENCODE 将转化 base64 保存。

  

  • postman 中设置 headers, 添加

Keyvalue cache-controlno-cache

Keyvalue Content-Typeapplication/json

  • 添加 body, body 设置为 json 格式

{

"appName""app name",

"appVersion""app version",

"hostTenant""operator 租户名称",

"userTenant""iot 用户名称",

"grant_type""client_credentials"

}

对于未发布的 app Developer 环境中 hostTenant userTenant 设置为 developer 租户名称, 已经发布的 app

hostTenant userTenant 根据 app 分配情况, 从而来设置 operator 租户名称和 iot 用户名称, 有时候为测试同时设置

operator 租户名称, 但是不能同时设置为 iot 租户名称。

如:

{

"appName""datasource",

"appVersion""v1", //

"hostTenant""supplab", //必须填 operator tenant 名称如果传参数的时候{{ hostTenant name}}

"userTenant""supplab" // lot 用户的 tetant 名称如果传参数的时候{{ userTenant name}},

"grant_type""client_credentials"

  • 点击发送获取 access_token通过上述获取的 access_token 访问 MindSphere api 或 app api 方法与 Tenant Credentials 中 access_token 访问MindSphere api 或 app api 方法一致, 请参考前面的内容.
 

1.5. WebScoket

 
https://developer.mindsphere.io/zh/concepts/concept-gateway-url-schemas.html#websockets.
根据官网的描述 :
WebSocket 通信协议允许通过 TCP 连接进行全双工通信。 MindSphere 网关支持在 Web 客户端和 Web 应用服务器之间建立
WebSocket 连接。为启用 WebSockets, Web 客户端和后端服务器必须能够使用安全的 wss 方案建立和驱动 WebSocket
接。 MindSphere 网关充当 WebSocket 连接的代理服务器 , 类似于 HTTP 请求。
Note: 目前 MindSphere 不支持通过 southgate 进行 WebSocket 访问。
支持的 WebSocket 协议
MindSphere 网关不限制在 WebSockets 上使用的协议。这允许两个应用程序(使用 WebSocket 通过 MindSphere
Gateway 进行通信)因此应用能够自由选择“语言” , 但前提是 MindSphere 网关和应用必须支持相同的协议。 MindSphere
关将每个 WebSocket 消息以二进制转发 , 不会干扰所使用的协议。例如 , 可用协议包括: STOMP Socket.IO MQTT 或自定
义协议 *
通信流
1. Web 客户端对在 MindSphere 网关上注册的应用的端点执行 WebSocket 协议升级 HTTP 请求。
2. MindSphere 网关评估会话消息头和被调用的应用端点。
3. MindSphere 网关创建与目标端点的 WebSocket web 客户端连接。
4. MindSphere 网关向注册的应用程序后台发起新的 WebSocket 协议升级的 HTTP 请求。
5. MindSphere 网关对 WebSocket 升级返回状态码为 101 且携带必要头部的 HTTP 响应。
6. 如果请求成功 , 客户端和后端能够通过代理的 WebSocket 双向发送消息。
7. 如果 MindSphere 网关与应用后端的连接失败 , MindSphere 网关将关闭 HTTP Web 客户端的连接 , 并返回状态 400
Bad Request

 

WebSocket 通信示例

1.5.1. Example
NodeJS 前端 , 该片段模拟了一个前端调用后端 WebSocket 接口的案例; /websocket/stomp 为接口的代理 broker 地址 :

 

var Stomp = require('stompjs');
var WebSocket = require('ws');
var SockJS = require("sockjs-client");
// ajax post 请求默认添加请求头
var cookie = "SESSION=NmVkYzZjOWYtYzdhNy00NzZkLTgxYzUtZDZkMGIyOTYyMGQy";
var stompClient = null;
function connect() {
var url = "https://supplab1-websocket-supplab1.cn1.mindsphere-in.cn/websocket/stomp";
var socket = new WebSocket(
url, {
headers: {
"Cookie": cookie
} }
);
stompClient = Stomp.over(socket);
stompClient.connect(
{},
function (frame) {
console.log('Connected: ' + frame);
stompClient.subscribe('/topic/greetings', function (greeting) {
showGreeting(JSON.parse(greeting.body).content);
});
sendName();
},
function (error) {
console.log('Failed to connect, unsuccessfully: [' + error + ']');
}
);
}
function disconnect() {
if (stompClient !== null) {
stompClient.disconnect();
}
setConnected(false);
console.log("Disconnected");
}
function sendName() {
stompClient.send("/app/hello", {}, JSON.stringify({ 'name': "Hello world is my name" }));
}
function showGreeting(message) {
console.log("Received message: " + message);
}
connect();

 

Java 服务端
@Configuration
@EnableWebSocketMessageBroker
@EnableScheduling
public class MessageBrokerConfig extends AbstractWebSocketMessageBrokerConfigurer {
 public static final String STOMP_ENDPOINT = "/websocket/stomp";
 @Override
 public void configureMessageBroker(final MessageBrokerRegistry config) {
 config.enableSimpleBroker("/topic");
 config.setApplicationDestinationPrefixes("/app");
 }
 @Override
 public void registerStompEndpoints(final StompEndpointRegistry registry) {
 registry.addEndpoint(STOMP_ENDPOINT).setAllowedOrigins("*");
 registry.addEndpoint(STOMP_ENDPOINT).setAllowedOrigins("*").withSockJS();
 } }

 

 

 

 

 

 

 

 

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐