From 06d25e2a5db083f6d26dd6a53b384e9038fb74e2 Mon Sep 17 00:00:00 2001 From: Carsten Lohmann Date: Sat, 9 Sep 2023 15:48:35 +0200 Subject: [PATCH 1/3] [#499] Fix cloud2edge chart ditto resource config. Signed-off-by: Carsten Lohmann --- packages/cloud2edge/values.yaml | 51 ++++++++++++--------------------- 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/packages/cloud2edge/values.yaml b/packages/cloud2edge/values.yaml index e0f88717..dabfcd9e 100644 --- a/packages/cloud2edge/values.yaml +++ b/packages/cloud2edge/values.yaml @@ -114,60 +114,47 @@ ditto: user: ditto password: ditto - # do not set cpu limits for Ditto to avoid CFS scheduler limits - # ref: https://doc.akka.io/docs/akka/snapshot/additional/deploy.html#in-kubernetes connectivity: resources: - requests: - cpu: 200m - limits: - memory: "1Gi" + cpu: 0.2 + memoryMi: 1024 gateway: resources: - requests: - cpu: 200m - limits: - memory: "768Mi" + cpu: 0.2 + memoryMi: 768 nginx: service: type: NodePort resources: - requests: - cpu: 50m - limits: - cpu: 150m - memory: "32Mi" + cpu: 0.05 + memoryMi: 32 policies: resources: - requests: - cpu: 200m - limits: - memory: "768Mi" + cpu: 0.2 + memoryMi: 768 swaggerui: resources: - requests: - cpu: 50m - limits: - cpu: 100m - memory: "32Mi" + cpu: 0.05 + memoryMi: 32 things: resources: - requests: - cpu: 200m - limits: - memory: "768Mi" + cpu: 0.2 + memoryMi: 768 thingsSearch: resources: - requests: - cpu: 200m - limits: - memory: "768Mi" + cpu: 0.2 + memoryMi: 768 + + dittoui: + resources: + cpu: 0.05 + memoryMi: 32 mongodb: # usage of default name (including release name) not supported in hono.deviceRegistryExample.mongoDBBasedDeviceRegistry.mongodb for now From d5a3fe00d31a25708c3187b095580a0c498bb8fd Mon Sep 17 00:00:00 2001 From: Carsten Lohmann Date: Sun, 10 Sep 2023 10:23:49 +0200 Subject: [PATCH 2/3] [#501] Use Connections HTTP API instead of piggyback commands. Signed-off-by: Carsten Lohmann --- homepage/_packages/cloud2edge/tour.md | 514 +++++++++--------- .../post-install/hono-amqp-connection.json | 202 ++++--- .../post-install/hono-kafka-connection.json | 324 ++++++----- .../cloud2edge/post-install/post-install.sh | 22 +- 4 files changed, 512 insertions(+), 550 deletions(-) diff --git a/homepage/_packages/cloud2edge/tour.md b/homepage/_packages/cloud2edge/tour.md index 585d9eb6..bccfa630 100644 --- a/homepage/_packages/cloud2edge/tour.md +++ b/homepage/_packages/cloud2edge/tour.md @@ -312,171 +312,161 @@ KAFKA_CERT=$(kubectl --namespace ${NS} get secret ${RELEASE}-kafka-example-keys Then, create the connection: {% clipboard %} -curl -i -X POST -u devops:${DITTO_DEVOPS_PWD} -H 'Content-Type: application/json' --data '{ - "targetActorSelection": "/system/sharding/connection", - "headers": { - "aggregate": false - }, - "piggybackCommand": { - "type": "connectivity.commands:createConnection", - "connection": { - "id": "hono-kafka-connection-for-'"${HONO_TENANT/./_}"'", - "name": "[Hono/Kafka] '"${HONO_TENANT}"'", - "connectionType": "kafka", - "connectionStatus": "open", - "uri": "ssl://ditto-c2e:verysecret@'"${RELEASE}"'-kafka:9092", - "ca": "'"${KAFKA_CERT}"'", - "failoverEnabled": true, - "sources": [ - { - "addresses": [ - "hono.telemetry.'"${HONO_TENANT}"'" - ], - "consumerCount": 1, - "authorizationContext": [ - "pre-authenticated:hono-connection-'"${HONO_TENANT}"'" - ], - "qos": 0, - "enforcement": { - "input": "{{ header:device_id }}", - "filters": [ - "{{ entity:id }}" - ] - }, - "headerMapping": {}, - "payloadMapping": [], - "replyTarget": { - "enabled": true, - "address": "hono.command.'"${HONO_TENANT}"'/{{ thing:id }}", - "headerMapping": { - "device_id": "{{ thing:id }}", - "subject": "{{ header:subject | fn:default(topic:action-subject) | fn:default(topic:criterion) }}-response", - "correlation-id": "{{ header:correlation-id }}" - }, - "expectedResponseTypes": [ - "response", - "error" - ] - }, - "acknowledgementRequests": { - "includes": [], - "filter": "fn:delete()" - }, - "declaredAcks": [] - }, - { - "addresses": [ - "hono.event.'"${HONO_TENANT}"'" - ], - "consumerCount": 1, - "authorizationContext": [ - "pre-authenticated:hono-connection-'"${HONO_TENANT}"'" - ], - "qos": 1, - "enforcement": { - "input": "{{ header:device_id }}", - "filters": [ - "{{ entity:id }}" - ] - }, - "headerMapping": {}, - "payloadMapping": [], - "replyTarget": { - "enabled": true, - "address": "hono.command.'"${HONO_TENANT}"'/{{ thing:id }}", - "headerMapping": { - "device_id": "{{ thing:id }}", - "subject": "{{ header:subject | fn:default(topic:action-subject) | fn:default(topic:criterion) }}-response", - "correlation-id": "{{ header:correlation-id }}" - }, - "expectedResponseTypes": [ - "response", - "error" - ] - }, - "acknowledgementRequests": { - "includes": [] - }, - "declaredAcks": [] +curl -i -X PUT -u devops:${DITTO_DEVOPS_PWD} -H 'Content-Type: application/json' --data '{ + "name": "[Hono/Kafka] '"${HONO_TENANT}"'", + "connectionType": "kafka", + "connectionStatus": "open", + "uri": "ssl://ditto-c2e:verysecret@'"${RELEASE}"'-kafka:9092", + "ca": "'"${KAFKA_CERT}"'", + "failoverEnabled": true, + "sources": [ + { + "addresses": [ + "hono.telemetry.'"${HONO_TENANT}"'" + ], + "consumerCount": 1, + "authorizationContext": [ + "pre-authenticated:hono-connection-'"${HONO_TENANT}"'" + ], + "qos": 0, + "enforcement": { + "input": "{{ header:device_id }}", + "filters": [ + "{{ entity:id }}" + ] + }, + "headerMapping": {}, + "payloadMapping": [], + "replyTarget": { + "enabled": true, + "address": "hono.command.'"${HONO_TENANT}"'/{{ thing:id }}", + "headerMapping": { + "device_id": "{{ thing:id }}", + "subject": "{{ header:subject | fn:default(topic:action-subject) | fn:default(topic:criterion) }}-response", + "correlation-id": "{{ header:correlation-id }}" }, - { - "addresses": [ - "hono.command_response.'"${HONO_TENANT}"'" - ], - "consumerCount": 1, - "authorizationContext": [ - "pre-authenticated:hono-connection-'"${HONO_TENANT}"'" - ], - "qos": 0, - "enforcement": { - "input": "{{ header:device_id }}", - "filters": [ - "{{ entity:id }}" - ] - }, - "headerMapping": { - "correlation-id": "{{ header:correlation-id }}", - "status": "{{ header:status }}" - }, - "payloadMapping": [], - "replyTarget": { - "enabled": false, - "expectedResponseTypes": [ - "response", - "error" - ] - }, - "acknowledgementRequests": { - "includes": [], - "filter": "fn:delete()" - }, - "declaredAcks": [] - } + "expectedResponseTypes": [ + "response", + "error" + ] + }, + "acknowledgementRequests": { + "includes": [], + "filter": "fn:delete()" + }, + "declaredAcks": [] + }, + { + "addresses": [ + "hono.event.'"${HONO_TENANT}"'" + ], + "consumerCount": 1, + "authorizationContext": [ + "pre-authenticated:hono-connection-'"${HONO_TENANT}"'" ], - "targets": [ - { - "address": "hono.command.'"${HONO_TENANT}"'/{{ thing:id }}", - "authorizationContext": [ - "pre-authenticated:hono-connection-'"${HONO_TENANT}"'" - ], - "headerMapping": { - "device_id": "{{ thing:id }}", - "subject": "{{ header:subject | fn:default(topic:action-subject) }}", - "correlation-id": "{{ header:correlation-id }}", - "response-required": "{{ header:response-required }}" - }, - "topics": [ - "_/_/things/live/commands", - "_/_/things/live/messages" - ] + "qos": 1, + "enforcement": { + "input": "{{ header:device_id }}", + "filters": [ + "{{ entity:id }}" + ] + }, + "headerMapping": {}, + "payloadMapping": [], + "replyTarget": { + "enabled": true, + "address": "hono.command.'"${HONO_TENANT}"'/{{ thing:id }}", + "headerMapping": { + "device_id": "{{ thing:id }}", + "subject": "{{ header:subject | fn:default(topic:action-subject) | fn:default(topic:criterion) }}-response", + "correlation-id": "{{ header:correlation-id }}" }, - { - "address": "hono.command.'"${HONO_TENANT}"'/{{thing:id}}", - "authorizationContext": [ - "pre-authenticated:hono-connection-'"${HONO_TENANT}"'" - ], - "topics": [ - "_/_/things/twin/events", - "_/_/things/live/events" - ], - "headerMapping": { - "device_id": "{{ thing:id }}", - "subject": "{{ header:subject | fn:default(topic:action-subject) }}", - "correlation-id": "{{ header:correlation-id }}" - } - } + "expectedResponseTypes": [ + "response", + "error" + ] + }, + "acknowledgementRequests": { + "includes": [] + }, + "declaredAcks": [] + }, + { + "addresses": [ + "hono.command_response.'"${HONO_TENANT}"'" ], - "specificConfig": { - "saslMechanism": "plain", - "bootstrapServers": "'"${RELEASE}"'-kafka:9092", - "groupId": "'"${HONO_TENANT}"'_{{ connection:id }}" + "consumerCount": 1, + "authorizationContext": [ + "pre-authenticated:hono-connection-'"${HONO_TENANT}"'" + ], + "qos": 0, + "enforcement": { + "input": "{{ header:device_id }}", + "filters": [ + "{{ entity:id }}" + ] + }, + "headerMapping": { + "correlation-id": "{{ header:correlation-id }}", + "status": "{{ header:status }}" }, - "clientCount": 1, - "failoverEnabled": true, - "validateCertificates": true + "payloadMapping": [], + "replyTarget": { + "enabled": false, + "expectedResponseTypes": [ + "response", + "error" + ] + }, + "acknowledgementRequests": { + "includes": [], + "filter": "fn:delete()" + }, + "declaredAcks": [] } - } -}' ${DITTO_API_BASE_URL:?}/devops/piggyback/connectivity + ], + "targets": [ + { + "address": "hono.command.'"${HONO_TENANT}"'/{{ thing:id }}", + "authorizationContext": [ + "pre-authenticated:hono-connection-'"${HONO_TENANT}"'" + ], + "headerMapping": { + "device_id": "{{ thing:id }}", + "subject": "{{ header:subject | fn:default(topic:action-subject) }}", + "correlation-id": "{{ header:correlation-id }}", + "response-required": "{{ header:response-required }}" + }, + "topics": [ + "_/_/things/live/commands", + "_/_/things/live/messages" + ] + }, + { + "address": "hono.command.'"${HONO_TENANT}"'/{{thing:id}}", + "authorizationContext": [ + "pre-authenticated:hono-connection-'"${HONO_TENANT}"'" + ], + "topics": [ + "_/_/things/twin/events", + "_/_/things/live/events" + ], + "headerMapping": { + "device_id": "{{ thing:id }}", + "subject": "{{ header:subject | fn:default(topic:action-subject) }}", + "correlation-id": "{{ header:correlation-id }}" + } + } + ], + "specificConfig": { + "saslMechanism": "plain", + "bootstrapServers": "'"${RELEASE}"'-kafka:9092", + "groupId": "'"${HONO_TENANT}"'_{{ connection:id }}" + }, + "clientCount": 1, + "failoverEnabled": true, + "validateCertificates": true +}' ${DITTO_API_BASE_URL:?}/api/2/connections/hono-kafka-connection-for-${HONO_TENANT//./_} {% endclipboard %} {% endvariant %} @@ -484,117 +474,107 @@ curl -i -X POST -u devops:${DITTO_DEVOPS_PWD} -H 'Content-Type: application/json {% variant AMQP Messaging %} {% clipboard %} -curl -i -X POST -u devops:${DITTO_DEVOPS_PWD} -H 'Content-Type: application/json' --data '{ - "targetActorSelection": "/system/sharding/connection", - "headers": { - "aggregate": false - }, - "piggybackCommand": { - "type": "connectivity.commands:createConnection", - "connection": { - "id": "hono-amqp-connection-for-'"${HONO_TENANT/./_}"'", - "name": "[Hono/AMQP1.0] '"${HONO_TENANT}"'", - "connectionType": "amqp-10", - "connectionStatus": "open", - "uri": "amqp://consumer%40HONO:verysecret@'"${RELEASE}"'-dispatch-router-ext:15672", - "failoverEnabled": true, - "sources": [ - { - "addresses": [ - "telemetry/'"${HONO_TENANT}"'", - "event/'"${HONO_TENANT}"'" - ], - "authorizationContext": [ - "pre-authenticated:hono-connection-'"${HONO_TENANT}"'" - ], - "enforcement": { - "input": "{%raw%}{{ header:device_id }}{%endraw%}", - "filters": [ - "{%raw%}{{ entity:id }}{%endraw%}" - ] - }, - "headerMapping": { - "hono-device-id": "{%raw%}{{ header:device_id }}{%endraw%}", - "content-type": "{%raw%}{{ header:content-type }}{%endraw%}" - }, - "replyTarget": { - "enabled": true, - "address": "{%raw%}{{ header:reply-to }}{%endraw%}", - "headerMapping": { - "to": "command/'"${HONO_TENANT}"'/{%raw%}{{ header:hono-device-id }}{%endraw%}", - "subject": "{%raw%}{{ header:subject | fn:default(topic:action-subject) | fn:default(topic:criterion) }}{%endraw%}-response", - "correlation-id": "{%raw%}{{ header:correlation-id }}{%endraw%}", - "content-type": "{%raw%}{{ header:content-type | fn:default('"'"'application/vnd.eclipse.ditto+json'"'"') }}{%endraw%}" - }, - "expectedResponseTypes": [ - "response", - "error" - ] - }, - "acknowledgementRequests": { - "includes": [], - "filter": "fn:filter(header:qos,'"'"'ne'"'"','"'"'0'"'"')" - } - }, - { - "addresses": [ - "command_response/'"${HONO_TENANT}"'/replies" - ], - "authorizationContext": [ - "pre-authenticated:hono-connection-'"${HONO_TENANT}"'" - ], - "headerMapping": { - "content-type": "{%raw%}{{ header:content-type }}{%endraw%}", - "correlation-id": "{%raw%}{{ header:correlation-id }}{%endraw%}", - "status": "{%raw%}{{ header:status }}{%endraw%}" - }, - "replyTarget": { - "enabled": false, - "expectedResponseTypes": [ - "response", - "error" - ] - } - } +curl -i -X PUT -u devops:${DITTO_DEVOPS_PWD} -H 'Content-Type: application/json' --data '{ + "name": "[Hono/AMQP1.0] '"${HONO_TENANT}"'", + "connectionType": "amqp-10", + "connectionStatus": "open", + "uri": "amqp://consumer%40HONO:verysecret@'"${RELEASE}"'-dispatch-router-ext:15672", + "failoverEnabled": true, + "sources": [ + { + "addresses": [ + "telemetry/'"${HONO_TENANT}"'", + "event/'"${HONO_TENANT}"'" + ], + "authorizationContext": [ + "pre-authenticated:hono-connection-'"${HONO_TENANT}"'" ], - "targets": [ - { - "address": "command/'"${HONO_TENANT}"'", - "authorizationContext": [ - "pre-authenticated:hono-connection-'"${HONO_TENANT}"'" - ], - "topics": [ - "_/_/things/live/commands", - "_/_/things/live/messages" - ], - "headerMapping": { - "to": "command/'"${HONO_TENANT}"'/{%raw%}{{ thing:id }}{%endraw%}", - "subject": "{%raw%}{{ header:subject | fn:default(topic:action-subject) }}{%endraw%}", - "content-type": "{%raw%}{{ header:content-type | fn:default('"'"'application/vnd.eclipse.ditto+json'"'"') }}{%endraw%}", - "correlation-id": "{%raw%}{{ header:correlation-id }}{%endraw%}", - "reply-to": "{%raw%}{{ fn:default('"'"'command_response/'"${HONO_TENANT}"'/replies'"'"') | fn:filter(header:response-required,'"'"'ne'"'"','"'"'false'"'"') }}{%endraw%}" - } + "enforcement": { + "input": "{%raw%}{{ header:device_id }}{%endraw%}", + "filters": [ + "{%raw%}{{ entity:id }}{%endraw%}" + ] + }, + "headerMapping": { + "hono-device-id": "{%raw%}{{ header:device_id }}{%endraw%}", + "content-type": "{%raw%}{{ header:content-type }}{%endraw%}" + }, + "replyTarget": { + "enabled": true, + "address": "{%raw%}{{ header:reply-to }}{%endraw%}", + "headerMapping": { + "to": "command/'"${HONO_TENANT}"'/{%raw%}{{ header:hono-device-id }}{%endraw%}", + "subject": "{%raw%}{{ header:subject | fn:default(topic:action-subject) | fn:default(topic:criterion) }}{%endraw%}-response", + "correlation-id": "{%raw%}{{ header:correlation-id }}{%endraw%}", + "content-type": "{%raw%}{{ header:content-type | fn:default('"'"'application/vnd.eclipse.ditto+json'"'"') }}{%endraw%}" }, - { - "address": "command/'"${HONO_TENANT}"'", - "authorizationContext": [ - "pre-authenticated:hono-connection-'"${HONO_TENANT}"'" - ], - "topics": [ - "_/_/things/twin/events", - "_/_/things/live/events" - ], - "headerMapping": { - "to": "command/'"${HONO_TENANT}"'/{%raw%}{{ thing:id }}{%endraw%}", - "subject": "{%raw%}{{ header:subject | fn:default(topic:action-subject) }}{%endraw%}", - "content-type": "{%raw%}{{ header:content-type | fn:default('"'"'application/vnd.eclipse.ditto+json'"'"') }}{%endraw%}", - "correlation-id": "{%raw%}{{ header:correlation-id }}{%endraw%}" - } - } - ] + "expectedResponseTypes": [ + "response", + "error" + ] + }, + "acknowledgementRequests": { + "includes": [], + "filter": "fn:filter(header:qos,'"'"'ne'"'"','"'"'0'"'"')" + } + }, + { + "addresses": [ + "command_response/'"${HONO_TENANT}"'/replies" + ], + "authorizationContext": [ + "pre-authenticated:hono-connection-'"${HONO_TENANT}"'" + ], + "headerMapping": { + "content-type": "{%raw%}{{ header:content-type }}{%endraw%}", + "correlation-id": "{%raw%}{{ header:correlation-id }}{%endraw%}", + "status": "{%raw%}{{ header:status }}{%endraw%}" + }, + "replyTarget": { + "enabled": false, + "expectedResponseTypes": [ + "response", + "error" + ] + } } - } -}' ${DITTO_API_BASE_URL:?}/devops/piggyback/connectivity + ], + "targets": [ + { + "address": "command/'"${HONO_TENANT}"'", + "authorizationContext": [ + "pre-authenticated:hono-connection-'"${HONO_TENANT}"'" + ], + "topics": [ + "_/_/things/live/commands", + "_/_/things/live/messages" + ], + "headerMapping": { + "to": "command/'"${HONO_TENANT}"'/{%raw%}{{ thing:id }}{%endraw%}", + "subject": "{%raw%}{{ header:subject | fn:default(topic:action-subject) }}{%endraw%}", + "content-type": "{%raw%}{{ header:content-type | fn:default('"'"'application/vnd.eclipse.ditto+json'"'"') }}{%endraw%}", + "correlation-id": "{%raw%}{{ header:correlation-id }}{%endraw%}", + "reply-to": "{%raw%}{{ fn:default('"'"'command_response/'"${HONO_TENANT}"'/replies'"'"') | fn:filter(header:response-required,'"'"'ne'"'"','"'"'false'"'"') }}{%endraw%}" + } + }, + { + "address": "command/'"${HONO_TENANT}"'", + "authorizationContext": [ + "pre-authenticated:hono-connection-'"${HONO_TENANT}"'" + ], + "topics": [ + "_/_/things/twin/events", + "_/_/things/live/events" + ], + "headerMapping": { + "to": "command/'"${HONO_TENANT}"'/{%raw%}{{ thing:id }}{%endraw%}", + "subject": "{%raw%}{{ header:subject | fn:default(topic:action-subject) }}{%endraw%}", + "content-type": "{%raw%}{{ header:content-type | fn:default('"'"'application/vnd.eclipse.ditto+json'"'"') }}{%endraw%}", + "correlation-id": "{%raw%}{{ header:correlation-id }}{%endraw%}" + } + } + ] +}' ${DITTO_API_BASE_URL:?}/api/2/connections/hono-amqp-connection-for-${HONO_TENANT//./_} {% endclipboard %} {% endvariant %} diff --git a/packages/cloud2edge/post-install/hono-amqp-connection.json b/packages/cloud2edge/post-install/hono-amqp-connection.json index 5edb7e62..439d4d85 100644 --- a/packages/cloud2edge/post-install/hono-amqp-connection.json +++ b/packages/cloud2edge/post-install/hono-amqp-connection.json @@ -1,111 +1,101 @@ { - "targetActorSelection": "/system/sharding/connection", - "headers": { - "aggregate": false - }, - "piggybackCommand": { - "type": "connectivity.commands:createConnection", - "connection": { - "id": "hono-amqp-connection-for-{{ .Values.demoDevice.tenant | replace "." "_" }}", - "name": "[Hono/AMQP1.0] {{ .Values.demoDevice.tenant }}", - "connectionType": "amqp-10", - "connectionStatus": "open", - "uri": "amqp://{{ .Values.honoConnection.username }}:{{ .Values.honoConnection.password }}@{{ .Release.Name }}-dispatch-router-ext:15672", - "failoverEnabled": true, - "sources": [ - { - "addresses": [ - "telemetry/{{ .Values.demoDevice.tenant }}", - "event/{{ .Values.demoDevice.tenant }}" - ], - "authorizationContext": [ - "pre-authenticated:hono-connection-{{ .Values.demoDevice.tenant }}" - ], - "enforcement": { - "input": {{ "{{ header:device_id }}" | quote }}, - "filters": [ - {{ "{{ entity:id }}" | quote }} - ] - }, - "headerMapping": { - "hono-device-id": {{ "{{ header:device_id }}" | quote }}, - "content-type": {{ "{{ header:content-type }}" | quote }} - }, - "replyTarget": { - "enabled": true, - "address": {{ "{{ header:reply-to }}" | quote }}, - "headerMapping": { - "to": {{ printf "command/%s/{{ header:hono-device-id }}" .Values.demoDevice.tenant | quote }}, - "subject": {{ "{{ header:subject | fn:default(topic:action-subject) | fn:default(topic:criterion) }}-response" | quote }}, - "correlation-id": {{ "{{ header:correlation-id }}" | quote }}, - "content-type": {{ "{{ header:content-type | fn:default('application/vnd.eclipse.ditto+json') }}" | quote }} - }, - "expectedResponseTypes": [ - "response", - "error" - ] - }, - "acknowledgementRequests": { - "includes": [], - "filter": "fn:filter(header:qos,'eq','1')" - } - }, - { - "addresses": [ - "command_response/{{ .Values.demoDevice.tenant }}/replies" - ], - "authorizationContext": [ - "pre-authenticated:hono-connection-{{ .Values.demoDevice.tenant }}" - ], - "headerMapping": { - "content-type": {{ "{{ header:content-type }}" | quote }}, - "correlation-id": {{ "{{ header:correlation-id }}" | quote }}, - "status": {{ "{{ header:status }}" | quote }} - }, - "replyTarget": { - "enabled": false, - "expectedResponseTypes": [ - "response", - "error" - ] - } - } + "name": "[Hono/AMQP1.0] {{ .Values.demoDevice.tenant }}", + "connectionType": "amqp-10", + "connectionStatus": "open", + "uri": "amqp://{{ .Values.honoConnection.username }}:{{ .Values.honoConnection.password }}@{{ .Release.Name }}-dispatch-router-ext:15672", + "failoverEnabled": true, + "sources": [ + { + "addresses": [ + "telemetry/{{ .Values.demoDevice.tenant }}", + "event/{{ .Values.demoDevice.tenant }}" + ], + "authorizationContext": [ + "pre-authenticated:hono-connection-{{ .Values.demoDevice.tenant }}" ], - "targets": [ - { - "address": "command/{{ .Values.demoDevice.tenant }}", - "authorizationContext": [ - "pre-authenticated:hono-connection-{{ .Values.demoDevice.tenant }}" - ], - "topics": [ - "_/_/things/live/commands", - "_/_/things/live/messages" - ], - "headerMapping": { - "to": {{ printf "command/%s/{{ thing:id }}" .Values.demoDevice.tenant | quote }}, - "subject": {{ "{{ header:subject | fn:default(topic:action-subject) }}" | quote }}, - "content-type": {{ "{{ header:content-type | fn:default('application/vnd.eclipse.ditto+json') }}" | quote }}, - "correlation-id": {{ "{{ header:correlation-id }}" | quote }}, - "reply-to": {{ printf "{{ fn:default('command_response/%s/replies') | fn:filter(header:response-required,'ne','false') }}" .Values.demoDevice.tenant | quote }} - } + "enforcement": { + "input": {{ "{{ header:device_id }}" | quote }}, + "filters": [ + {{ "{{ entity:id }}" | quote }} + ] + }, + "headerMapping": { + "hono-device-id": {{ "{{ header:device_id }}" | quote }}, + "content-type": {{ "{{ header:content-type }}" | quote }} + }, + "replyTarget": { + "enabled": true, + "address": {{ "{{ header:reply-to }}" | quote }}, + "headerMapping": { + "to": {{ printf "command/%s/{{ header:hono-device-id }}" .Values.demoDevice.tenant | quote }}, + "subject": {{ "{{ header:subject | fn:default(topic:action-subject) | fn:default(topic:criterion) }}-response" | quote }}, + "correlation-id": {{ "{{ header:correlation-id }}" | quote }}, + "content-type": {{ "{{ header:content-type | fn:default('application/vnd.eclipse.ditto+json') }}" | quote }} }, - { - "address": "command/{{ .Values.demoDevice.tenant }}", - "authorizationContext": [ - "pre-authenticated:hono-connection-{{ .Values.demoDevice.tenant }}" - ], - "topics": [ - "_/_/things/twin/events", - "_/_/things/live/events" - ], - "headerMapping": { - "to": {{ printf "command/%s/{{ thing:id }}" .Values.demoDevice.tenant | quote }}, - "subject": {{ "{{ header:subject | fn:default(topic:action-subject) }}" | quote }}, - "content-type": {{ "{{ header:content-type | fn:default('application/vnd.eclipse.ditto+json') }}" | quote }}, - "correlation-id": {{ "{{ header:correlation-id }}" | quote }} - } - } - ] + "expectedResponseTypes": [ + "response", + "error" + ] + }, + "acknowledgementRequests": { + "includes": [], + "filter": "fn:filter(header:qos,'eq','1')" + } + }, + { + "addresses": [ + "command_response/{{ .Values.demoDevice.tenant }}/replies" + ], + "authorizationContext": [ + "pre-authenticated:hono-connection-{{ .Values.demoDevice.tenant }}" + ], + "headerMapping": { + "content-type": {{ "{{ header:content-type }}" | quote }}, + "correlation-id": {{ "{{ header:correlation-id }}" | quote }}, + "status": {{ "{{ header:status }}" | quote }} + }, + "replyTarget": { + "enabled": false, + "expectedResponseTypes": [ + "response", + "error" + ] + } + } + ], + "targets": [ + { + "address": "command/{{ .Values.demoDevice.tenant }}", + "authorizationContext": [ + "pre-authenticated:hono-connection-{{ .Values.demoDevice.tenant }}" + ], + "topics": [ + "_/_/things/live/commands", + "_/_/things/live/messages" + ], + "headerMapping": { + "to": {{ printf "command/%s/{{ thing:id }}" .Values.demoDevice.tenant | quote }}, + "subject": {{ "{{ header:subject | fn:default(topic:action-subject) }}" | quote }}, + "content-type": {{ "{{ header:content-type | fn:default('application/vnd.eclipse.ditto+json') }}" | quote }}, + "correlation-id": {{ "{{ header:correlation-id }}" | quote }}, + "reply-to": {{ printf "{{ fn:default('command_response/%s/replies') | fn:filter(header:response-required,'ne','false') }}" .Values.demoDevice.tenant | quote }} + } + }, + { + "address": "command/{{ .Values.demoDevice.tenant }}", + "authorizationContext": [ + "pre-authenticated:hono-connection-{{ .Values.demoDevice.tenant }}" + ], + "topics": [ + "_/_/things/twin/events", + "_/_/things/live/events" + ], + "headerMapping": { + "to": {{ printf "command/%s/{{ thing:id }}" .Values.demoDevice.tenant | quote }}, + "subject": {{ "{{ header:subject | fn:default(topic:action-subject) }}" | quote }}, + "content-type": {{ "{{ header:content-type | fn:default('application/vnd.eclipse.ditto+json') }}" | quote }}, + "correlation-id": {{ "{{ header:correlation-id }}" | quote }} + } } - } + ] } diff --git a/packages/cloud2edge/post-install/hono-kafka-connection.json b/packages/cloud2edge/post-install/hono-kafka-connection.json index 090fd063..b19fced3 100644 --- a/packages/cloud2edge/post-install/hono-kafka-connection.json +++ b/packages/cloud2edge/post-install/hono-kafka-connection.json @@ -1,175 +1,165 @@ { - "targetActorSelection": "/system/sharding/connection", - "headers": { - "aggregate": false - }, - "piggybackCommand": { - "type": "connectivity.commands:createConnection", - "connection": { - "id": "hono-kafka-connection-for-{{ .Values.demoDevice.tenant | replace "." "_" }}", - "name": "[Hono/Kafka] {{ .Values.demoDevice.tenant }}", - "connectionType": "kafka", - "connectionStatus": "open", - {{- if .Values.hono.kafkaMessagingClusterExample.enabled }} - "uri": "ssl://{{ .Values.honoConnection.username }}:{{ .Values.honoConnection.password }}@{{ .Release.Name }}-kafka:9092", - {{- else }} - {{ $kafka := .Values.hono.adapters.kafkaMessagingSpec.commonClientConfig }} - {{ $kafkaServers := splitList "," (index $kafka "bootstrap.servers") }} - "uri": "tcp://{{ .Values.honoConnection.username }}:{{ .Values.honoConnection.password }}@{{ first $kafkaServers }}", - {{- end }} - "sources": [ - { - "addresses": [ - "hono.telemetry.{{ .Values.demoDevice.tenant }}" - ], - "consumerCount": 1, - "authorizationContext": [ - "pre-authenticated:hono-connection-{{ .Values.demoDevice.tenant }}" - ], - "qos": 0, - "enforcement": { - "input": {{ "{{ header:device_id }}" | quote }}, - "filters": [ - {{ "{{ entity:id }}" | quote }} - ] - }, - "headerMapping": {}, - "payloadMapping": [], - "replyTarget": { - "enabled": true, - "address": {{ printf "hono.command.%s/{{ thing:id }}" .Values.demoDevice.tenant | quote }}, - "headerMapping": { - "device_id": {{ "{{ thing:id }}" | quote }}, - "subject": {{ "{{ header:subject | fn:default(topic:action-subject) | fn:default(topic:criterion) }}-response" | quote }}, - "correlation-id": {{ "{{ header:correlation-id }}" | quote }} - }, - "expectedResponseTypes": [ - "response", - "error" - ] - }, - "acknowledgementRequests": { - "includes": [], - "filter": "fn:delete()" - }, - "declaredAcks": [] - }, - { - "addresses": [ - "hono.event.{{ .Values.demoDevice.tenant }}" - ], - "consumerCount": 1, - "authorizationContext": [ - "pre-authenticated:hono-connection-{{ .Values.demoDevice.tenant }}" - ], - "qos": 1, - "enforcement": { - "input": {{ "{{ header:device_id }}" | quote }}, - "filters": [ - {{ "{{ entity:id }}" | quote }} - ] - }, - "headerMapping": {}, - "payloadMapping": [], - "replyTarget": { - "enabled": true, - "address": {{ printf "hono.command.%s/{{ thing:id }}" .Values.demoDevice.tenant | quote }}, - "headerMapping": { - "device_id": {{ "{{ thing:id }}" | quote }}, - "subject": {{ "{{ header:subject | fn:default(topic:action-subject) | fn:default(topic:criterion) }}-response" | quote }}, - "correlation-id": {{ "{{ header:correlation-id }}" | quote }} - }, - "expectedResponseTypes": [ - "response", - "error" - ] - }, - "acknowledgementRequests": { - "includes": [] - }, - "declaredAcks": [] + "name": "[Hono/Kafka] {{ .Values.demoDevice.tenant }}", + "connectionType": "kafka", + "connectionStatus": "open", + {{- if .Values.hono.kafkaMessagingClusterExample.enabled }} + "uri": "ssl://{{ .Values.honoConnection.username }}:{{ .Values.honoConnection.password }}@{{ .Release.Name }}-kafka:9092", + {{- else }} + {{ $kafka := .Values.hono.adapters.kafkaMessagingSpec.commonClientConfig }} + {{ $kafkaServers := splitList "," (index $kafka "bootstrap.servers") }} + "uri": "tcp://{{ .Values.honoConnection.username }}:{{ .Values.honoConnection.password }}@{{ first $kafkaServers }}", + {{- end }} + "sources": [ + { + "addresses": [ + "hono.telemetry.{{ .Values.demoDevice.tenant }}" + ], + "consumerCount": 1, + "authorizationContext": [ + "pre-authenticated:hono-connection-{{ .Values.demoDevice.tenant }}" + ], + "qos": 0, + "enforcement": { + "input": {{ "{{ header:device_id }}" | quote }}, + "filters": [ + {{ "{{ entity:id }}" | quote }} + ] + }, + "headerMapping": {}, + "payloadMapping": [], + "replyTarget": { + "enabled": true, + "address": {{ printf "hono.command.%s/{{ thing:id }}" .Values.demoDevice.tenant | quote }}, + "headerMapping": { + "device_id": {{ "{{ thing:id }}" | quote }}, + "subject": {{ "{{ header:subject | fn:default(topic:action-subject) | fn:default(topic:criterion) }}-response" | quote }}, + "correlation-id": {{ "{{ header:correlation-id }}" | quote }} }, - { - "addresses": [ - "hono.command_response.{{ .Values.demoDevice.tenant }}" - ], - "consumerCount": 1, - "authorizationContext": [ - "pre-authenticated:hono-connection-{{ .Values.demoDevice.tenant }}" - ], - "qos": 0, - "enforcement": { - "input": {{ "{{ header:device_id }}" | quote }}, - "filters": [ - {{ "{{ entity:id }}" | quote }} - ] - }, - "headerMapping": { - "correlation-id": {{ "{{ header:correlation-id }}" | quote }}, - "status": {{ "{{ header:status }}" | quote }} - }, - "payloadMapping": [], - "replyTarget": { - "enabled": false, - "expectedResponseTypes": [ - "response", - "error" - ] - }, - "acknowledgementRequests": { - "includes": [], - "filter": "fn:delete()" - }, - "declaredAcks": [] - } + "expectedResponseTypes": [ + "response", + "error" + ] + }, + "acknowledgementRequests": { + "includes": [], + "filter": "fn:delete()" + }, + "declaredAcks": [] + }, + { + "addresses": [ + "hono.event.{{ .Values.demoDevice.tenant }}" + ], + "consumerCount": 1, + "authorizationContext": [ + "pre-authenticated:hono-connection-{{ .Values.demoDevice.tenant }}" ], - "targets": [ - { - "address": {{ printf "hono.command.%s/{{ thing:id }}" .Values.demoDevice.tenant | quote }}, - "authorizationContext": [ - "pre-authenticated:hono-connection-{{ .Values.demoDevice.tenant }}" - ], - "headerMapping": { - "device_id": {{ "{{ thing:id }}" | quote }}, - "subject": {{ "{{ header:subject | fn:default(topic:action-subject) }}" | quote }}, - "correlation-id": {{ "{{ header:correlation-id }}" | quote }}, - "response-required": {{ "{{ header:response-required }}" | quote }} - }, - "topics": [ - "_/_/things/live/commands", - "_/_/things/live/messages" - ] + "qos": 1, + "enforcement": { + "input": {{ "{{ header:device_id }}" | quote }}, + "filters": [ + {{ "{{ entity:id }}" | quote }} + ] + }, + "headerMapping": {}, + "payloadMapping": [], + "replyTarget": { + "enabled": true, + "address": {{ printf "hono.command.%s/{{ thing:id }}" .Values.demoDevice.tenant | quote }}, + "headerMapping": { + "device_id": {{ "{{ thing:id }}" | quote }}, + "subject": {{ "{{ header:subject | fn:default(topic:action-subject) | fn:default(topic:criterion) }}-response" | quote }}, + "correlation-id": {{ "{{ header:correlation-id }}" | quote }} }, - { - "address": {{ printf "hono.command.%s/{{thing:id}}" .Values.demoDevice.tenant | quote }}, - "authorizationContext": [ - "pre-authenticated:hono-connection-{{ .Values.demoDevice.tenant }}" - ], - "topics": [ - "_/_/things/twin/events", - "_/_/things/live/events" - ], - "headerMapping": { - "device_id": {{ "{{ thing:id }}" | quote }}, - "subject": {{ "{{ header:subject | fn:default(topic:action-subject) }}" | quote }}, - "correlation-id": {{ "{{ header:correlation-id }}" | quote }} - } - } + "expectedResponseTypes": [ + "response", + "error" + ] + }, + "acknowledgementRequests": { + "includes": [] + }, + "declaredAcks": [] + }, + { + "addresses": [ + "hono.command_response.{{ .Values.demoDevice.tenant }}" ], - "specificConfig": { - {{- if .Values.hono.kafkaMessagingClusterExample.enabled }} - "saslMechanism": "plain", - "bootstrapServers": "{{ .Release.Name }}-kafka:9092", - {{- else }} - {{ $kafka := .Values.hono.adapters.kafkaMessagingSpec.commonClientConfig }} - "saslMechanism": "{{ (or (index $kafka "sasl.mechanism") "PLAIN") | lower }}", - "bootstrapServers": "{{ index $kafka "bootstrap.servers" }}", - {{- end }} - "groupId": {{ printf "%s_{{ connection:id }}" .Values.demoDevice.tenant | quote }} + "consumerCount": 1, + "authorizationContext": [ + "pre-authenticated:hono-connection-{{ .Values.demoDevice.tenant }}" + ], + "qos": 0, + "enforcement": { + "input": {{ "{{ header:device_id }}" | quote }}, + "filters": [ + {{ "{{ entity:id }}" | quote }} + ] + }, + "headerMapping": { + "correlation-id": {{ "{{ header:correlation-id }}" | quote }}, + "status": {{ "{{ header:status }}" | quote }} + }, + "payloadMapping": [], + "replyTarget": { + "enabled": false, + "expectedResponseTypes": [ + "response", + "error" + ] + }, + "acknowledgementRequests": { + "includes": [], + "filter": "fn:delete()" + }, + "declaredAcks": [] + } + ], + "targets": [ + { + "address": {{ printf "hono.command.%s/{{ thing:id }}" .Values.demoDevice.tenant | quote }}, + "authorizationContext": [ + "pre-authenticated:hono-connection-{{ .Values.demoDevice.tenant }}" + ], + "headerMapping": { + "device_id": {{ "{{ thing:id }}" | quote }}, + "subject": {{ "{{ header:subject | fn:default(topic:action-subject) }}" | quote }}, + "correlation-id": {{ "{{ header:correlation-id }}" | quote }}, + "response-required": {{ "{{ header:response-required }}" | quote }} }, - "clientCount": 1, - "failoverEnabled": true, - "validateCertificates": true + "topics": [ + "_/_/things/live/commands", + "_/_/things/live/messages" + ] + }, + { + "address": {{ printf "hono.command.%s/{{thing:id}}" .Values.demoDevice.tenant | quote }}, + "authorizationContext": [ + "pre-authenticated:hono-connection-{{ .Values.demoDevice.tenant }}" + ], + "topics": [ + "_/_/things/twin/events", + "_/_/things/live/events" + ], + "headerMapping": { + "device_id": {{ "{{ thing:id }}" | quote }}, + "subject": {{ "{{ header:subject | fn:default(topic:action-subject) }}" | quote }}, + "correlation-id": {{ "{{ header:correlation-id }}" | quote }} + } } - } + ], + "specificConfig": { + {{- if .Values.hono.kafkaMessagingClusterExample.enabled }} + "saslMechanism": "plain", + "bootstrapServers": "{{ .Release.Name }}-kafka:9092", + {{- else }} + {{ $kafka := .Values.hono.adapters.kafkaMessagingSpec.commonClientConfig }} + "saslMechanism": "{{ (or (index $kafka "sasl.mechanism") "PLAIN") | lower }}", + "bootstrapServers": "{{ index $kafka "bootstrap.servers" }}", + {{- end }} + "groupId": {{ printf "%s_{{ connection:id }}" .Values.demoDevice.tenant | quote }} + }, + "clientCount": 1, + "failoverEnabled": true, + "validateCertificates": true } diff --git a/packages/cloud2edge/post-install/post-install.sh b/packages/cloud2edge/post-install/post-install.sh index 19415e46..6695a98f 100755 --- a/packages/cloud2edge/post-install/post-install.sh +++ b/packages/cloud2edge/post-install/post-install.sh @@ -14,8 +14,7 @@ DITTO_DEVOPS_USER_PW="devops:$(cat /var/run/c2e/ditto-gw-users/devops-password)" DEVICE_REGISTRY_BASE_URL="http://{{ .Release.Name }}-service-device-registry:8080/v1" -# TODO use HTTP API instead of piggyback commands (https://eclipse.dev/ditto/connectivity-manage-connections.html) -DITTO_CONNECTIVITY_URL="http://{{ .Release.Name }}-ditto-nginx:8080/devops/piggyback/connectivity" +DITTO_CONNECTIONS_BASE_URL="http://{{ .Release.Name }}-ditto-nginx:8080/api/2/connections" DITTO_THINGS_BASE_URL="http://{{ .Release.Name }}-ditto-nginx:8080/api/2/things" DEMO_TENANT="{{ .Values.demoDevice.tenant }}" @@ -79,13 +78,16 @@ add_hono_device_credentials(){ } add_connection_in_ditto(){ - connection_name="$1" - http_request_body_file="$2" + connection_id_prefix="$1" + tenant_id="$2" + http_request_body_file="$3" - echo "Adding $connection_name ditto connection [URL: $DITTO_CONNECTIVITY_URL]" + tenant_adapted=$(echo "$tenant_id" | sed "s/\./_/g") + connection_id="${connection_id_prefix}${tenant_adapted}" + echo "Adding ditto connection '$connection_id' [URL: ${DITTO_CONNECTIONS_BASE_URL}/${connection_id}]" response_body_and_status=$(curl --silent --write-out "\n%{http_code}" \ - -X POST -u "$DITTO_DEVOPS_USER_PW" --header 'Content-Type: application/json' \ - --data-binary "@$http_request_body_file" "$DITTO_CONNECTIVITY_URL") + -X PUT -u "$DITTO_DEVOPS_USER_PW" --header 'Content-Type: application/json' \ + --data-binary "@$http_request_body_file" "${DITTO_CONNECTIONS_BASE_URL}/${connection_id}") check_status $? "$response_body_and_status" } @@ -93,7 +95,7 @@ add_ditto_device(){ device="$1" http_request_body_file="$2" - echo "Adding '$device' ditto thing [URL: $DITTO_THINGS_BASE_URL/$device]" + echo "Adding ditto thing '$device' [URL: $DITTO_THINGS_BASE_URL/$device]" response_body_and_status=$(curl --silent --write-out "\n%{http_code}" \ -X PUT -u ditto:ditto --header 'Content-Type: application/json' \ --data-binary "@$http_request_body_file" "$DITTO_THINGS_BASE_URL/$device") @@ -108,7 +110,7 @@ register_hono_device "$DEMO_TENANT" "$DEMO_DEVICE" "{}" add_hono_device_credentials "$DEMO_TENANT" "$DEMO_DEVICE" "demo-device-credentials.json" if [ "$IS_USING_AMQP" = "true" ]; then - add_connection_in_ditto "Hono AMQP" "hono-amqp-connection.json" + add_connection_in_ditto "hono-amqp-connection-for-" "$DEMO_TENANT" "hono-amqp-connection.json" fi if [ "$IS_USING_KAFKA" = "true" ]; then cp hono-kafka-connection.json /tmp/hono-kafka-connection.json @@ -121,7 +123,7 @@ if [ "$IS_USING_KAFKA" = "true" ]; then cert="$(< $certPath tr -d '\n' | sed 's/E-----/E-----\\\\n/g' | sed 's/-----END/\\\\n-----END/g')" sed -i '/uri/ a '"\"ca\": \"$cert\","'' /tmp/hono-kafka-connection.json fi - add_connection_in_ditto "Hono Kafka" "/tmp/hono-kafka-connection.json" + add_connection_in_ditto "hono-kafka-connection-for-" "$DEMO_TENANT" "/tmp/hono-kafka-connection.json" fi add_ditto_device "$DEMO_DEVICE" "demo-device-thing.json" From c8ad8b79ced18b8c5b5d6fc244e360efec292b76 Mon Sep 17 00:00:00 2001 From: Carsten Lohmann Date: Sun, 10 Sep 2023 10:26:52 +0200 Subject: [PATCH 3/3] Update cloud2Edge chart version to 0.5.1. Signed-off-by: Carsten Lohmann --- packages/cloud2edge/Chart.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cloud2edge/Chart.yaml b/packages/cloud2edge/Chart.yaml index 662d6d55..bfa47681 100644 --- a/packages/cloud2edge/Chart.yaml +++ b/packages/cloud2edge/Chart.yaml @@ -11,8 +11,8 @@ # SPDX-License-Identifier: EPL-2.0 # apiVersion: v1 -version: 0.5.0 -appVersion: 0.5.0 +version: 0.5.1 +appVersion: 0.5.1 name: cloud2edge description: | Eclipse IoT Cloud2Edge (C2E) is an integrated suite of services developers can use to build IoT applications