我在AWS智能领域框架中尝试了FIWARE(第1部分:代理)

AWS在2022年7月12日宣布,他们将加入FIWARE基金会,并在智慧城市开发方面展开合作。这个消息也在2022年9月14日至15日的FIWARE全球峰会上讨论过。

作为其中的一部分,aws-stf 已经从 AWS 上发布。STF(智能领域框架)是一个用于构建 FIWARE 生态系统的工具包,它使用 AWS CDK 在 TypeScript 和 Python 等语言中以声明式的方式定义复杂的基础设施,并能够轻松地启动环境。

所以这次,我们打算使用aws-stf在AWS上搭建FIWARE生态系统,来确认实际上会构建出怎样的环境。

STF core scorpio

来源:NEC Scorpio Broker使用的智能领域框架核心 – STF Core

验证环境

本次验证是在以下环境中进行的。请确保aws cli和node.js已经安装好。还请快速设置AWS的认证信息(由于我觉得麻烦,我使用了一个拥有AdministratorAccess权限的账户)。

ツールバージョンAWS CLIaws-cli/2.7.31 Python/3.10.6 Darwin/20.6.0 source/x86_64 prompt/offnode.jsv16.17.0
[default]
output = json
region = us-west-2
[default]
aws_secret_access_key = xxxxxxxx
aws_access_key_id = xxxxxxxx

请注意

截至2022年9月18日,选择us-west-2(俄勒冈州)地区是比较明智的选择。使用Scorpio版本的STF将在内部启动AWS Aurora Serverless或Amazon Managed Streaming for Apache Kafka,但在北弗吉尼亚、俄亥俄、北加利福尼亚和东京等地区,可能会发生以下错误,在构建过程中失败并回滚。这是因为这些区域的可用区不支持Aurora Serverless或MSK的一些原因。

您可以修改CDK网络相关的代码,以便能够指定适合该地区的合适可用区,这可能会更好。但在这次验证中,我们将继续在代码中不做修改,并在us-west-2地区进行验证。

您的子网组只有一个由Aurora Serverless支持的可用区us-west-1a。

一个或多个子网属于不支持的可用区:[us-east-1b]。(服务:Kafka,状态码:400)

启动STF堆栈

那么,我们快速启动STF堆栈。
FIWARE生态系统的核心是经常使用的NGSI v1/v2兼容的FIWARE Orion,以及其支持NGSI-LD的版本orion-ld,还有为NGSI-LD编写的Scorpio和stellio等多个组件。STF在概念上支持多个代理组件,但截至9月18日,可使用Scorpio和AWS无服务器服务的组合发布版本。
现在让我们快速启动STF堆栈吧。

我们提供以下STF核心不同风味的列表,其中包括多个可用的FIWARE上下文经纪人实现。

获取aws-stf(Scorpio版本)

nmatsui@:aws-stf$ git clone https://github.com/aws-samples/aws-stf-core-scorpio.git
nmatsui@:aws-stf$ cd aws-stf-core-scorpio/
nmatsui@:aws-stf-core-scorpio (main =)$ 

CDK库的安装

在9月18日时,对于node.js的CDK,最新版本是2.42.0。但是,我们决定在本地安装和使用指定的版本2.13.0。

nmatsui@:aws-stf-core-scorpio (main =)$ npm install
nmatsui@:aws-stf-core-scorpio (main =)$ npx cdk --version
2.13.0 (build b0b744d)

准备CDK

首先执行bootstrap,将所需的CDK资产准备在指定的地区上。以后不需要再次执行bootstrap。

nmatsui@:aws-stf-core-scorpio (main =)$ npx cdk bootstrap
 ⏳  Bootstrapping environment aws://xxxxxxxxxxxx/us-west-2...
Trusted accounts for deployment: (none)
Trusted accounts for lookup: (none)
Using default execution policy of 'arn:aws:iam::aws:policy/AdministratorAccess'. Pass '--cloudformation-execution-policies' to customize.
CDKToolkit: creating CloudFormation changeset...

 ✅  Environment aws://xxxxxxxxxxxx/us-west-2 bootstrapped.

STF堆栈的部署

那么,我们将部署主要的STF堆栈。这个过程大约需要30到45分钟,所以请耐心等待。

nmatsui@:aws-stf-core-scorpio (main =)$ npx cdk deploy

✨  Synthesis time: 6.4s

StfCore: deploying...
[0%] start: Publishing 4a575666d1c2c6412590d2a56f328e040a81ad1ef59aecee31ae9b393d05f659:current_account-current_region

 ✅  StfCore

✨  Deployment time: 2264.27s

Outputs:
StfCore.StfCoreEndpoint = https://xxxxxxxx.execute-api.us-west-2.amazonaws.com
StfCore.StfCoreIotQueueArn = arn:aws:sqs:us-west-2:xxxxxxxxxxxx:StfIoTQueue-us-west-2
Stack ARN:
arn:aws:cloudformation:us-west-2:xxxxxxxxxxxx:stack/StfCore/490d76b0-36d0-11ed-bd00-029c3f5cbc51

✨  Total time: 2270.67s

确认CDK启动环境

让我们来确认一下由CDK构建的环境。实际上,在这个阶段,我们不仅启动了经纪人功能,还启动了连接物联网设备和经纪人的堆栈(STF IoT)。但是这次我们只确认与经纪人功能有关的环境。

云形成堆叠

AWS CDK会根据AWS CloudFormation模板生成并部署AWS上的资源。通过观察,我们可以发现STF堆栈实际上由ScorpioServerlessNestedStack和IoTNestedStack组成。

nmatsui@:aws-stf-core-scorpio (main =)$ aws cloudformation list-stacks --stack-status-filter CREATE_COMPLETE --query "StackSummaries[].StackName"
[
    "StfCore-IoTNestedStackIoTNestedStackResource15FB5E08-19AKRXNQCBVG",
    "StfCore-ScorpioServerlessNestedStackScorpioServerlessNestedStackResourceF6005A66-1ASHOUNTIXFG0",
    "StfCore",
    "CDKToolkit"
]

AWS Aurora 无服务器版

这次使用的Scorpio在内部依赖于Apache Kafka和PostgreSQL。STF作为这个PostgreSQL,使用AWS Aurora Serverless来启动和使用。通过使用Aurora Serverless,当负载较低时,成本较低。

nmatsui@:aws-stf-core-scorpio (main =)$ aws rds describe-db-clusters --query "DBClusters[].{name:DatabaseName,engine:Engine,version:EngineVersion,mode:EngineMode}"
[
    {
        "name": "scorpio",
        "engine": "aurora-postgresql",
        "version": "10.18",
        "mode": "serverless"
    }
]

亚马逊托管的Apache Kafka流处理平台

由于Scorpio依赖于kafka,Apache Kafka的托管服务已经启动。可能是因为成本问题,我认为只启动了2个最小节点大小的broker。(如果成本是问题的话,我想也可以考虑使用MSK Serverless,但是可能有无法使用Serverless的原因吧?)

nmatsui@:aws-stf-core-scorpio (main =)$ aws kafka list-clusters --query "ClusterInfoList[].{name:ClusterName,kafkaVersion:CurrentBrokerSoftwareInfo.KafkaVersion,numberOfBrokerNodes:NumberOfBrokerNodes,size:BrokerNodeGroupInfo.InstanceType}"
[
    {
        "name": "ScorpioCluster",
        "kafkaVersion": "2.8.1",
        "numberOfBrokerNodes": 2,
        "size": "kafka.t3.small"
    }
]

天蝎座的本质

Scorpio本体似乎作为Fargate上的容器启动。看起来是以active-active方式运行了两个任务。我们使用的是位于Amazon ECR上的自定义镜像scorpiobroker/scorpio-aio,而不是Scorpio的官方Docker镜像。我们没有确认这个自定义镜像与官方镜像之间是否有差异。

nmatsui@:aws-stf-core-scorpio (main =)$ export ECS_CLUSTER=$(aws ecs list-clusters --query "clusterArns[0]" --output text)
nmatsui@:aws-stf-core-scorpio (main =)$ export ECS_SERVICE=$(aws ecs list-services --cluster $ECS_CLUSTER --query "serviceArns[0]" --output text)
nmatsui@:aws-stf-core-scorpio (main =)$ export ECS_TASK=$(aws ecs list-tasks --cluster $ECS_CLUSTER --service-name $ECS_SERVICE --query "taskArns[0]" --output text)
nmatsui@:aws-stf-core-scorpio (main =)$ aws ecs describe-services --cluster $ECS_CLUSTER --services $ECS_SERVICE --query "services[].{launchType:launchType,desiredCount:desiredCount,runningCount:runningCount}"
[
    {
        "launchType": "FARGATE",
        "desiredCount": 2,
        "runningCount": 2
    }
]
nmatsui@:aws-stf-core-scorpio (main =)$ aws ecs describe-tasks --cluster $ECS_CLUSTER --tasks $ECS_TASK --query "tasks[].{containers:containers[].{image:image,status:lastStatus},cpu:cpu,memory:memory}"
[
    {
        "containers": [
            {
                "image": "public.ecr.aws/scorpiobroker/scorpio-aio:latest",
                "status": "RUNNING"
            }
        ],
        "cpu": "512",
        "memory": "2048"
    }
]

另外,Scorpio的图像貌似在parameters.ts中指定。无论是官方图像,还是能在Aurora Serverless或MSK上运行吗?

export const Parameters = {
    image_context_broker: 'public.ecr.aws/scorpiobroker/scorpio-aio:latest',
    smart_data_model_url : 'https://raw.githubusercontent.com/smart-data-models/data-models/master/context.jsonld',
    shadow_prefix: "Stf",
    timeout: '0', // Timeout for the API call in the Lambda that sync with context broker. Has to be a string to pass it in env variable
}

亚马逊API网关

最后是Amazon API Gateway。它将公开一个端点在互联网上,并将请求路由到Scoprio的容器。
值得注意的是,/iot/things/*的GET、POST和DELETE请求是由STF IoT堆栈创建的用于IoT设备的路由,这里不进行详细解释。其他的请求将匹配到ANY /{proxy+}路由,并通过VPCLink路由到Scorpio的容器。

nmatsui@:aws-stf-core-scorpio (main =)$ export API_ID=$(aws apigatewayv2 get-apis --query "Items[0].ApiId" --output text)
nmatsui@:aws-stf-core-scorpio (main =)$ aws apigatewayv2 get-routes --api-id $API_ID --query "Items[].RouteKey"
[
    "GET /iot/things",
    "GET /iot/things/{thingName}",
    "DELETE /iot/things/{thingName}",
    "ANY /{proxy+}",
    "POST /iot/things"
]

那么,我们尝试向 API Gateway 的端点发送 GET 请求,路径分别为 /actuator/info 和 /actuator/health。当 Scorpio 接收到这些请求时,作为内部使用的 Spring Boot 将返回构建信息和运行状况。

nmatsui@:aws-stf-core-scorpio (main =)$ export ENDPOINT=$(aws apigatewayv2 get-apis --query "Items[0].ApiEndpoint" --output text)
nmatsui@:aws-stf-core-scorpio (main =)$ curl -sS "$ENDPOINT/actuator/info" | jq .
{
  "build": {
    "artifact": "AllInOneRunner",
    "name": "AllInOneRunner",
    "time": "2022-09-08T13:51:46.913Z",
    "version": "1.1.0-SNAPSHOT",
    "group": "eu.neclab.ngsildbroker"
  }
}
nmatsui@:aws-stf-core-scorpio (main =)$ curl -sS "$ENDPOINT/actuator/health" | jq .
{
  "status": "UP"
}

向Amazon API Gateway添加令牌认证

好了,我们已经确认Scorpio可以正常运行并连接到互联网。但是,经纪人在互联网上以实时公开的方式存在,虽然是为了验证,但确实有问题。在NEC Scorpio经纪人堆栈的README中,也提到在生产环境中使用之前要考虑访问控制的问题。

在将此堆栈用于生产之前,请考虑添加一种机制来控制和管理对StfCoreEndpoint的访问。

本来,GET请求对于实体是无限制的,但是POST/PATCH/DELETE请求需要对每个请求进行身份验证并且只允许授权用户进行访问,这样可以制定认证和授权策略并实现。但是,此次为了验证目的,我们将在所有路由上实施简易的令牌认证。

注册用于认证的Lambda函数

注册一个非常简单的用于验证的Lambda函数,用于检查请求中的”authorization”头部是否包含特定的字符串。

将以下内容用中文翻译,并且只提供一种选择:注册用于认证的 Lambda 函数
nmatsui@:aws-stf-core-scorpio (main =)$ export TOKEN=your_token
nmatsui@:aws-stf-core-scorpio (main =)$ export REGION=$(aws configure get region –output text)
nmatsui@:aws-stf-core-scorpio (main =)$ export ACCOUNT=$(aws sts get-caller-identity –query “Account” –output text)
nmatsui@:aws-stf-core-scorpio (main =)$ aws iam create-role –role-name lambda-auth-role \
–assume-role-policy-document ‘{“Version”: “2012-10-17″,”Statement”: [{ “Effect”: “Allow”, “Principal”: {“Service”: “lambda.amazonaws.com”}, “Action”: “sts:AssumeRole”}]}’
nmatsui@:aws-stf-core-scorpio (main =)$ cat <<__EOF__ > lambda-auth.js
exports.handler = async(event) => {
let response = {
“isAuthorized”: false
};

if (event.headers.authorization === “$TOKEN”) {
response = {
“isAuthorized”: true
};
}
return response;
};
__EOF__
nmatsui@:aws-stf-core-scorpio (main =)$ zip function.zip lambda-auth.js
nmatsui@:aws-stf-core-scorpio (main =)$ aws lambda create-function –function-name lambda-auth \
–zip-file fileb://function.zip \
–handler lambda-auth.handler \
–runtime nodejs12.x \
–role arn:aws:iam::$ACCOUNT:role/lambda-auth-role

将上述代码注册为用于认证的 Lambda 函数
nmatsui@:aws-stf-core-scorpio (main =)$ export TOKEN=your_token
nmatsui@:aws-stf-core-scorpio (main =)$ export REGION=$(aws configure get region –output text)
nmatsui@:aws-stf-core-scorpio (main =)$ export ACCOUNT=$(aws sts get-caller-identity –query “Account” –output text)
nmatsui@:aws-stf-core-scorpio (main =)$ aws iam create-role –role-name lambda-auth-role \
–assume-role-policy-document ‘{“Version”: “2012-10-17″,”Statement”: [{ “Effect”: “Allow”, “Principal”: {“Service”: “lambda.amazonaws.com”}, “Action”: “sts:AssumeRole”}]}’
nmatsui@:aws-stf-core-scorpio (main =)$ cat <<__EOF__ > lambda-auth.js
exports.handler = async(event) => {
let response = {
“isAuthorized”: false
};

if (event.headers.authorization === “$TOKEN”) {
response = {
“isAuthorized”: true
};
}
return response;
};
__EOF__
nmatsui@:aws-stf-core-scorpio (main =)$ zip function.zip lambda-auth.js
nmatsui@:aws-stf-core-scorpio (main =)$ aws lambda create-function –function-name lambda-auth \
–zip-file fileb://function.zip \
–handler lambda-auth.handler \
–runtime nodejs12.x \
–role arn:aws:iam::$ACCOUNT:role/lambda-auth-role

创建授权者

将已创建的Lambda函数注册为Amazon API Gateway的授权者。

创建Authorizer
nmatsui@:aws-stf-core-scorpio (main =)$ aws apigatewayv2 create-authorizer \
–api-id $API_ID \
–authorizer-type REQUEST \
–identity-source ‘$request.header.Authorization’ \
–name lambda-authorizer \
–authorizer-uri “arn:aws:apigateway:$REGION:lambda:path/2015-03-31/functions/arn:aws:lambda:$REGION:$ACCOUNT:function:lambda-auth/invocations” \
–authorizer-payload-format-version ‘2.0’ \
–enable-simple-responses

给lambda函数添加权限

为了让 Amazon API Gateway 能够执行 lambda 函数,授予其权限。

将权限添加到Lambda函数nmatsui@:aws-stf-core-scorpio (main =)$ export AUTHORIZER_ID=$(aws apigatewayv2 get-authorizers –api-id $API_ID –query “Items[?Name==\`lambda-authorizer\`].AuthorizerId” –output text)

nmatsui@:aws-stf-core-scorpio (main =)$ aws lambda add-permission \
–function-name lambda-auth \
–statement-id apigateway-invoke-permission-lambda-authorizer \
–action lambda:InvokeFunction \
–principal apigateway.amazonaws.com \
–source-arn “arn:aws:execute-api:$REGION:$ACCOUNT:$API_ID/authorizers/$AUTHORIZER_ID”

在所有路由中添加授权器。

由于这样,现在可以从Amazon API Gateway调用authorizer的lambda函数,因此将authorizer分配给每个路由。

在所有路由中添加authorizer
nmatsui @:aws-stf-core-scorpio(主=)$ export ROUTES = $(aws apigatewayv2 get-routes –api-id $ API_ID –query “Items []. RouteId”–output text)
nmatsui @:aws-stf-core-scorpio(主=)$ for route in $ ROUTES; 做
aws apigatewayv2 update-route \
–api-id $ API_ID \
–route-id $ route \
–authorization-type CUSTOM \
–authorizer-id $ AUTHORIZER_ID

对令牌认证进行操作验证

那么,我们将确认令牌认证是否有效。虽然只是最基本的验证,但这样就可以了!

没有授权头 → 401 未授权
nmatsui@:aws-stf-core-scorpio (main =)$ curl -i “$ENDPOINT/actuator/info”结果
HTTP/2 401
date: Sun, 18 Sep 2022 08:40:16 GMT
content-type: application/json
content-length: 26
apigw-requestid: YpbpliAfPHcEPQw=

{“message”:”未授权”}

使用以下命令查询 “$ENDPOINT/actuator/info” 并设置请求头中的 “Authorization” 字段为 “$TOKEN”:“`
nmatsui@:aws-stf-core-scorpio (main =)$ curl -i “$ENDPOINT/actuator/info” \
-H “Authorization: $TOKEN”
“`

结果返回:

“`
HTTP/2 200
date: 日, 18 九月 2022 08:41:34 GMT
content-type: application/vnd.spring-boot.actuator.v3+json
content-length: 157
apigw-requestid: Ypb1tg7wPHcEMUw=
vary: Origin
vary: Access-Control-Request-Method
vary: Access-Control-Request-Headers
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
cache-control: no-cache, no-store, max-age=0, must-revalidate
pragma: no-cache
expires: 0
x-frame-options: DENY

{“build”:{“artifact”:”AllInOneRunner”,”name”:”AllInOneRunner”,”time”:”2022-09-08T13:51:46.913Z”,”version”:”1.1.0-SNAPSHOT”,”group”:”eu.neclab.ngsildbroker”}}
“`

确认经纪人功能

因为FIWARE的经纪人功能已经平稳地在AWS上启动,所以我们来简单验证一下Entity的CRUD操作。
※ 关于NGSI-LD规范,请参考ETSI的官方API规范、FIWARE的逐步指南、Scorpio的API演示等。

上下文的处理

与NGSI v2不同,NGSI-LD需要context来确定结构化数据的词汇。这个context可以通过以下两种方法来指定。

    • “Link”ヘッダでcontextを指定し、リクエストボディには何も書かない

 

    “Content-Type”ヘッダにapplication/ld+jsonを指定し、リクエストボディの@contextでcontextを指定する

在空的状态下获取实体列表。

与NGSI v2不同,如果不在QueryString中指定type,则会导致400 Bad Request错误。
另外,由于GET请求本来不包含请求体(Request Body),应该只能使用Link来指定方式,但是Scorpio似乎可以通过在”Content-Type”头中指定application/ld+json来使请求通过。

用Link头部指定上下文
nmatsui@:aws-stf-core-scorpio (main =)$ curl -sSG “$ ENDPOINT / ngsi-ld / v1 / entities /” \
-H“ Authorization:$ TOKEN” \
-H ‘Link:<https://raw.githubusercontent.com/smart-data-models/data-models/master/context.jsonld>; rel=”http://www.w3.org/ns/json-ld#context”; type=”application/ld+json’ \
-d类型=TempSensor \
| jq。响应
[]

在请求体中指定上下文。
nmatsui@:aws-stf-core-scorpio (主要=) $ curl -sSG $ENDPOINT/ngsi-ld/v1/entities/ \
-H “授权: $ TOKEN” \
-H “内容类型: application/ld+json” \
-d 类型=TempSensor \
| jq。响应
[]

注册实体

NGSI-LD的实体与NGSI v2在外观上看起来相似,但实体的标识方法和元数据的添加方式不同。请查阅NGSI-LD的规范以了解详细信息。暂时来说,我们将其设置为几乎与NGSI v2相同的数据模型。

以Link头指定上下文
nmatsui@:aws-stf-core-scorpio (main =)$ curl -iX POST “$ENDPOINT/ngsi-ld/v1/entities/” \
-H “Authorization: $TOKEN” \
-H ‘Content-Type: application/json’ \
-H ‘Link: <https://raw.githubusercontent.com/smart-data-models/data-models/master/context.jsonld>; rel=”http://www.w3.org/ns/json-ld#context”; type=”application/ld+json’ \
-d @- <<EOS
{
“id”: “urn:ngsi-ld:TempSensor:001”,
“type”: “TempSensor”,
“category”: {
“type”: “Property”,
“value”: “sensor”
},
“temperature”: {
“type”: “Property”,
“value”: 25.2,
“unitCode”: “CEL”
}
}
EOS响应
HTTP/2 201
日期:2022年9月18日 星期日 11:08:57 GMT
内容长度:0
apigw-requestid:YpxbZgo0PHcEJcA=
变量:起源
变量:控制访问请求方法
变量:控制访问请求头
位置:/ngsi-ld/v1/entities/urn:ngsi-ld:TempSensor:001
x-content-type-options:无编译,无嗅探
x-xss-protection:1;模式=block
缓存控制:无缓存,无存储,最大年龄=0,必须重新验证
特权:无特权
过期时间:0
x-frame-options:拒绝

在请求体中指定上下文
nmatsui@:aws-stf-core-scorpio (main =)$ curl -iX POST “$ENDPOINT/ngsi-ld/v1/entities/” \
-H “Authorization: $TOKEN” \
-H ‘Content-Type: application/ld+json’ \
-d @- <<EOS
{
“id”: “urn:ngsi-ld:TempSensor:002”,
“type”: “TempSensor”,
“category”: {
“type”: “Property”,
“value”: “sensor”
},
“temperature”: {
“type”: “Property”,
“value”: 28.4,
“unitCode”: “CEL”
},
“@context”: [
“https://raw.githubusercontent.com/smart-data-models/data-models/master/context.jsonld”
]
}
EOS响应
HTTP/2 201
日期: Sun, 18 Sep 2022 11:10:53 GMT
内容长度: 0
apigw-requestid: YpxtrhRkPHcEMCw=
变化: Origin
变化: Access-Control-Request-Method
变化: Access-Control-Request-Headers
位置: /ngsi-ld/v1/entities/urn:ngsi-ld:TempSensor:002
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
缓存控制: no-cache, no-store, max-age=0, must-revalidate
pragma: no-cache
过期: 0
x-frame-options: DENY

获取实体列表

通过使用/ngsi-ld/v1/entities/进行GET请求,可以获取到实体的列表。如果没有在原来的Link标头中指定上下文,在属性名称中似乎会包含上下文。

用中国盗用Link头指定上下文的方法
nmatsui@:aws-stf-core-scorpio (main =)$ curl -sSG “$ENDPOINT/ngsi-ld/v1/entities/” \
-H “Authorization: $TOKEN” \
-H ‘Link: <https://raw.githubusercontent.com/smart-data-models/data-models/master/context.jsonld>; rel=”http://www.w3.org/ns/json-ld#context”; type=”application/ld+json’ \
-d type=TempSensor \
| jq .响应
[
{
“id”: “urn:ngsi-ld:TempSensor:001”,
“type”: “TempSensor”,
“category”: {
“type”: “Property”,
“value”: “sensor”
},
“temperature”: {
“type”: “Property”,
“value”: 25.2,
“unitCode”: “CEL”
}
},
{
“id”: “urn:ngsi-ld:TempSensor:002”,
“type”: “TempSensor”,
“category”: {
“type”: “Property”,
“value”: “sensor”
},
“temperature”: {
“type”: “Property”,
“value”: 28.4,
“unitCode”: “CEL”
}
}
]

使用curl命令在请求体中指定上下文:
nmatsui@:aws-stf-core-scorpio (main =)$ curl -sSG “$ENDPOINT/ngsi-ld/v1/entities/” \
-H “Authorization: $TOKEN” \
-H “Content-Type: application/ld+json” \
-d type=TempSensor \
| jq .[
{
“id”: “urn:ngsi-ld:TempSensor:001”,
“type”: “TempSensor”,
“https://smart-data-models.github.io/data-models/terms.jsonld#/definitions/category”: {
“type”: “Property”,
“value”: “sensor”
},
“https://smart-data-models.github.io/data-models/terms.jsonld#/definitions/temperature”: {
“type”: “Property”,
“value”: 25.2,
“unitCode”: “CEL”
}
},
{
“id”: “urn:ngsi-ld:TempSensor:002”,
“type”: “TempSensor”,
“https://smart-data-models.github.io/data-models/terms.jsonld#/definitions/category”: {
“type”: “Property”,
“value”: “sensor”
},
“https://smart-data-models.github.io/data-models/terms.jsonld#/definitions/temperature”: {
“type”: “Property”,
“value”: 28.4,
“unitCode”: “CEL”
}
}
]

使用ID参数获取实体

与NGSI v2类似,通过GET请求/ngsi-ld/v1/entities//可以获取到对应的实体。在这种情况下,不需要通过查询字符串来指定类型。

使用Link标头指定上下文:
nmatsui@:aws-stf-core-scorpio (main =)$ curl -sSG “$ENDPOINT/ngsi-ld/v1/entities/urn:ngsi-ld:TempSensor:001” \
-H “Authorization: $TOKEN” \
-H ‘Link: <https://raw.githubusercontent.com/smart-data-models/data-models/master/context.jsonld>; rel=”http://www.w3.org/ns/json-ld#context”; type=”application/ld+json’ \
| jq.响应:
{
“id”: “urn:ngsi-ld:TempSensor:001”,
“type”: “TempSensor”,
“category”: {
“type”: “Property”,
“value”: “sensor”
},
“temperature”: {
“type”: “Property”,
“value”: 25.2,
“unitCode”: “CEL”
}
}

在请求体中指定上下文
nmatsui@:aws-stf-core-scorpio (main =)$ curl -sSG “$ENDPOINT/ngsi-ld/v1/entities/urn:ngsi-ld:TempSensor:002” \
-H “Authorization: $TOKEN” \
-H “Content-Type: application/ld+json” \
| jq .返回结果
{
“id”: “urn:ngsi-ld:TempSensor:002”,
“type”: “TempSensor”,
“https://smart-data-models.github.io/data-models/terms.jsonld#/definitions/category”: {
“type”: “Property”,
“value”: “sensor”
},
“https://smart-data-models.github.io/data-models/terms.jsonld#/definitions/temperature”: {
“type”: “Property”,
“value”: 28.4,
“unitCode”: “CEL”
}
}

对Entity进行筛选

您可以通过使用q参数在QueryString中编写过滤条件来过滤实体。

在Link头信息中指定上下文。
nmatsui@:aws-stf-core-scorpio (main =)$ curl -sSG “$ENDPOINT/ngsi-ld/v1/entities/” \
-H “Authorization: $TOKEN” \
-H ‘Link: <https://raw.githubusercontent.com/smart-data-models/data-models/master/context.jsonld>; rel=”http://www.w3.org/ns/json-ld#context”; type=”application/ld+json’ \
-d type=TempSensor \
-d q=temperature==26..30 \
| jq .响应
[
{
“id”: “urn:ngsi-ld:TempSensor:002”,
“type”: “TempSensor”,
“category”: {
“type”: “Property”,
“value”: “sensor”
},
“temperature”: {
“type”: “Property”,
“value”: 28.4,
“unitCode”: “CEL”
}
}
]

仅获取特定属性

如果在Query String中指定了attrs参数,则只能获取指定属性。

使用curl命令从指定的URL获取带有设置头部的数据,这里使用了Link头部指定了文档的上下文- JSON LD。
回应包含了两个TempSensor的实体,包含id、类型和温度属性。

更新实体

通过在请求的主体中指定需要更新的属性,并对/ngsi-ld/v1/entities//发起PATCH请求,可以更新该属性。在这种情况下,由于请求主体中仅列出需要更新的属性,因此必须通过”Link”头来指定上下文。

在Link头部指定上下文。nmatsui@:aws-stf-core-scorpio (main =)$ curl -iX PATCH “$ENDPOINT/ngsi-ld/v1/entities/urn:ngsi-ld:TempSensor:002/attrs”
-H “Authorization: $TOKEN”
-H ‘Content-Type: application/json’
-H ‘Link: <https://raw.githubusercontent.com/smart-data-models/data-models/master/context.jsonld>; rel=”http://www.w3.org/ns/json-ld#context”; type=”application/ld+json’
-d @- <<EOS
{
“temperature”: {
“type”: “Property”,
“value”: 31.2,
“unitCode”: “CEL”
}
}
EOS

响应
HTTP/2 204
date: Sun, 18 Sep 2022 11:46:52 GMT
apigw-requestid: Yp2-5jksvHcEMQA=
vary: Origin
vary: Access-Control-Request-Method
vary: Access-Control-Request-Headers
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
cache-control: no-cache, no-store, max-age=0, must-revalidate
pragma: no-cache
expires: 0
x-frame-options: DENY

确认更新后的实体。nmatsui@:aws-stf-core-scorpio (main =)$ curl -sSG “$ENDPOINT/ngsi-ld/v1/entities/” -H “Authorization: $TOKEN” -H ‘Link: <https://raw.githubusercontent.com/smart-data-models/data-models/master/context.jsonld>; rel=”http://www.w3.org/ns/json-ld#context”; type=”application/ld+json’ -d type=TempSensor | jq .回应
[
{
“id”: “urn:ngsi-ld:TempSensor:001”,
“type”: “TempSensor”,
“category”: {
“type”: “Property”,
“value”: “sensor”
},
“temperature”: {
“type”: “Property”,
“value”: 25.2,
“unitCode”: “CEL”
}
},
{
“id”: “urn:ngsi-ld:TempSensor:002”,
“type”: “TempSensor”,
“category”: {
“type”: “Property”,
“value”: “sensor”
},
“temperature”: {
“type”: “Property”,
“value”: 31.2,
“unitCode”: “CEL”
}
}
]

删除实体

您可以通过最后一个步骤,即对/ngsi-ld/v1/entities//发送DELETE请求,来删除该实体。

使用curl命令时,通过Link标头指定上下文如下:nmatsui@:aws-stf-core-scorpio (main =)$ curl -iX DELETE “$ENDPOINT/ngsi-ld/v1/entities/urn:ngsi-ld:TempSensor:001” \
-H “Authorization: $TOKEN” \
-H ‘Link: <https://raw.githubusercontent.com/smart-data-models/data-models/master/context.jsonld>; rel=”http://www.w3.org/ns/json-ld#context”; type=”application/ld+json’

响应:
HTTP/2 204
date: Sun, 18 Sep 2022 12:00:51 GMT
apigw-requestid: Yp5CGjrfvHcEPWA=
vary: Origin
vary: Access-Control-Request-Method
vary: Access-Control-Request-Headers
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
cache-control: no-cache, no-store, max-age=0, must-revalidate
pragma: no-cache
expires: 0
x-frame-options: DENY

确认更新后的Entitynmatsui@:aws-stf-core-scorpio (main =)$ curl -sSG “$ENDPOINT/ngsi-ld/v1/entities/” \
-H “Authorization: $TOKEN” \
-H ‘Link: <https://raw.githubusercontent.com/smart-data-models/data-models/master/context.jsonld>; rel=”http://www.w3.org/ns/json-ld#context”; type=”application/ld+json’ \
-d type=TempSensor \
| jq .

回复:
[
{
“id”: “urn:ngsi-ld:TempSensor:002”,
“type”: “TempSensor”,
“category”: {
“type”: “Property”,
“value”: “sensor”
},
“temperature”: {
“type”: “Property”,
“value”: 31.2,
“unitCode”: “CEL”
}
}
]

总结

利用AWS STF(智慧領域框架),可以輕鬆地在AWS上構建FIWARE NGSI-LD上下文代理(Scorpio)。
然而,如果用作NGSI-LD的驗證環境是可以的,但如果用作生產環境,需要注意以下幾點。建議基於AWS STF,創建符合自身情況的CDK堆疊。

请求认证和授权

如果将AWS STF用作数据协作基础设施,就需要为每个HTTP方法和路径设置适当的身份验证和授权。并且,需要选择适当的身份验证和授权中间件,包括管理授权用户的操作负担,并对CDK堆栈进行修改,以与Amazon API Gateway进行协作。

托管服务资源配置

STF Core的CDK堆栈已经配置了与AWS Aurora Serverless和较小的Amazon Managed Streaming for Apache Kafka的集成。这对于验证目的是很好的,但如果用作生产环境,则有可能成为性能瓶颈。请实时监控和预测实际请求的频率以及预期的请求,并相应调整合适的资源大小。

与其他FIWARE组件或自定义组件进行协作

在实际构建数据协作基础设施时,除了经纪人功能之外,还需要与其他功能进行协作。例如,基于时间序列记录实体更新的时间序列数据库组件,用于可视化协作数据状态的BI组件,或者根据特定用途自行开发的特殊组件等。这些协作需要集成到CDK堆栈中。

首先…

在数字化田园城市国家构想中,需要一个开放的数据协作基础设施,据说需要基于FIWARE orion的代理功能。这个FIWARE orion和AWS STF所采用的scorpio,虽然都是基于FIWARE的Context Broker组件,但orion处理NGSI v2的数据模型,而scorpio处理NGSI-LD,它们之间没有兼容性。将来在数据协作基础设施之间进行数据交换时,可能会面临问题。

以下是对文档的中文翻译选项:1. 创建Amazon MSK群集,请参阅链接:
https://docs.aws.amazon.com/msk/latest/developerguide/msk-create-cluster.html

2. ScorpioBroker安装指南,请参阅链接:
https://github.com/ScorpioBroker/ScorpioBroker/blob/development/docs/en/source/installationGuide.rst

3. 未来的数字电化政府服务:
https://www.chisou.go.jp/sousei/about/mirai/pdf/digitaldenenseidoyoukou.pdf

4. 电力供应合同评价报告:
https://www.chisou.go.jp/sousei/about/mirai/pdf/denenkouhukin_jissou_type23_hyoka.pdf

5. 电力供应合同问答1-3:
https://www.chisou.go.jp/sousei/about/mirai/pdf/denenkouhukin_jissou_type23_qa1-3.pdf

6. 数字政府政策,预算和补贴:
https://www.digital.go.jp/assets/contents/node/basic_page/field_ref_resources/82a1ea56-128f-4cf6-bbd5-9ef6d4b7bafc/40d603f5/20220812_policies_budget_subsidies_02.pdf

广告
将在 10 秒后关闭
bannerAds