Hintergrund
Um beispielsweise eine interne AMQP API an eine externe AMQP API anzubinden, ist es notwendig, die Datenstrukturen der beiden APIs aufeinander abzubilden. Dazu wird das Framework Jolt verwendet, welches eine JSON-Struktur in eine andere JSON-Struktur abbilden kann. Die Abbildung wird dabei durch eine Konfigurationsdatei definiert, die die Abbildungsregeln enthält.
Der Json Translator Service ist ein eigenständiger SpringBoot Microservice.
Konfiguration
Der Service kann mit oder ohne Docker installiert werden.
Der Service wird über die Datei application.properties
konfiguriert. Relevante Settings dabei
Server Port
Mit diesem Parameter kann der Port der Applikation gesetzt werden. Der Default ist 8080
.
server.port=8080
RabbitMQ Configuration
Um den Message Broker verwenden zu können, muss er konfiguriert werden.
rabbitmq.host=localhost
rabbitmq.port=5672
rabbitmq.username=guest
rabbitmq.password=guest
Json Translator Consumer
Der JSON-Translator unterstützt bis zu vier verschiedene JSON-Consumer. Jeder Consumer arbeitet unabhängig und verwendet eine eigene Spezifikationsdatei für die Zuordnung. Die Anwendung konsumiert JSON-Daten aus den Queues jsonTranslatorConsumerExchangeName(1-4). Der Name der Queue setzt sich aus dem ExchangeName und der Group <jsonTranslatorConsumerExchangeName(1-4>.<jsonTranslatorConsumerGroup(1-4)>. Der ExchangeType kann über den Parameter jsonTranslatorConsumerExchangeType(1-4) konfiguriert werden. Wenn für die Queue Routing eingerichtet ist, muss der Wert, nachdem geroutet werden soll, an der jsonTranslatorConsumerGroup angegeben werden. Ein konfiguriertes Routing am Producer ist hierfür notwendig.
Konfiguration für alle vier Consumer:
spring.cloud.function.definition= consumeEvent1;consumeEvent2;consumeEvent3;consumeEvent4
jsonTranslatorConsumerExchangeName1=json.translator.consumer.1
jsonTranslatorConsumerGroup1=default
jsonTranslatorConsumerExchangeType1=direct
jsonTranslatorConsumerExchangeName2=json.translator.consumer.2
jsonTranslatorConsumerGroup2=default
jsonTranslatorConsumerExchangeType2=direct
jsonTranslatorConsumerExchangeName3=json.translator.consumer.3
jsonTranslatorConsumerGroup3=default
jsonTranslatorConsumerExchangeType3=direct
jsonTranslatorConsumerExchangeName4=json.translator.consumer.4
jsonTranslatorConsumerGroup4=default
jsonTranslatorConsumerExchangeType4=direct
Die Eigenschaft spring.cloud.function.definition definiert, welche Consumer aktiv sind.
Soll nur durch einen bestimmten routingKey in diese Queue geroutet werden, so kann dies über den bindingRoutingKey angegeben werden. Im Beispiel für Consumer 1 und Consumer 2.
spring.cloud.stream.rabbit.bindings.consumeEvent1-in-0.consumer.bindingRoutingKey=9900000000001
spring.cloud.stream.rabbit.bindings.consumeEvent2-in-0.consumer.bindingRoutingKey=9900000000002
Soll anhand von mehreren Routingkeys in die Queue geroutet werden, so können mehrere angegeben werden. In diesem Beispiel kommasepariert.
spring.cloud.stream.rabbit.bindings.consumeEvent1-in-0.consumer.bindingRoutingKey=9900000000001,9900000000002
spring.cloud.stream.rabbit.bindings.consumeEvent1-in-0.consumer.bindingRoutingKeyDelimiter=,
spring.cloud.stream.rabbit.bindings.consumeEvent2-in-0.consumer.bindingRoutingKey=9900000000001,9900000000002,9900000000003,9900000000004
spring.cloud.stream.rabbit.bindings.consumeEvent2-in-0.consumer.bindingRoutingKeyDelimiter=,
Max Concurrency - Parallelität
Es ist möglich für dein Consumer die Eigenschaft max-concurrency
zu setzen. Diese definiert die maximale Anzahl von gleichzeitigen Verarbeitungsthreads, die für einen Consumer gestartet werden können. Der Default liegt bei 50.
jsonTranslatorConsumerMaxConcurrency1=50
jsonTranslatorConsumerMaxConcurrency2=50
jsonTranslatorConsumerMaxConcurrency3=50
jsonTranslatorConsumerMaxConcurrency4=50
Json Translator Producer
Nachdem die JSON-Daten auf eine andere JSON-Struktur abgebildet wurden, sendet der Service die abgebildeten JSON-Daten an die entsprechende Queue. Jeder der vier Consumer hat einen spezifischen Producer.
Der ExchangeName kann über <jsonTranslatorProducerExchangeName(1-4)> konfiguriert werden. Der ExchangeType kann über den Parameter jsonTranslatorProducerExchangeType(1-4) konfiguriert werden. Der RoutingKey kann über den Parameter jsonTranslatorRoutingkeyExpression(1-4) konfiguriert werden. Stellen Sie sicher, dass der Routing-Schlüssel in Anführungszeichen steht, da er statisch ist. Bei dynamischen Routingkeys, wie beispielsweise beim Routing nach tenant, muss diese Funktion nach dem Muster konfiguriert werden, wie es im nachfolgendem Beispiel unter jsonTranslatorRoutingkeyExpression3 angegeben ist.
jsonTranslatorProducerExchangeName1=json.translator.producer.1
jsonTranslatorRoutingkeyExpression1='default'
jsonTranslatorProducerExchangeType1=direct
jsonTranslatorProducerExchangeName2=json.translator.producer.2
jsonTranslatorRoutingkeyExpression2='delivery'
jsonTranslatorProducerExchangeType2=direct
jsonTranslatorProducerExchangeName3=json.translator.producer.3
jsonTranslatorRoutingkeyExpression3=headers.tenant
jsonTranslatorProducerExchangeType3=direct
jsonTranslatorProducerExchangeName4=json.translator.producer.4
jsonTranslatorRoutingkeyExpression4='default'
jsonTranslatorProducerExchangeType4=direct
ACHTUNG: die Producer-Queue wird nicht vom Service selbst erstellt. Es muss vor Verwendung sicher gestellt werden, dass die Queue vorhanden ist, damit keine Nachrichten verloren gehen.
Json Translator Mapping
Die Mapping Regeln können als Konfigurationsdatei bereitgestellt werden. Der Pfad zur Mapping Datei kann über den Parameter jsonSpecPath
konfiguriert werden.
Der Default Pfad ist /var/lib/config/spec<1-4>.json
und muss nur gesetzt werden, wenn ein anderer Pfad benötigt wird. Es kann für jeden Consumer, eine Konfigurationsdatei genutzt werden.
jsonSpecPath1=/var/lib/config/spec1.json
jsonSpecPath2=/var/lib/config/spec2.json
jsonSpecPath3=/var/lib/config/spec3.json
jsonSpecPath4=/var/lib/config/spec4.json
Release Download
Der Json Translator Service
kann als Docker Image docker-nob-erp.next-level-apps.com/aep/json-translator-service:${TRANSLATOR_VER} bezogen werden oder über das PrivateDL (mit berechtigtem Zugang) als Artefakt heruntergeladen werden.
Deployment
Docker Container
Beispiel Eintrag in docker-compose.yml zum Start einer Json Translator Service Instanz. In diesem Fall muss die application.properties und die Mapping Datei im Verzeichnis ./conf/json-translator-service/ liegen.
services:
json-translator-service:
image: docker-nob-erp.next-level-apps.com/aep/json-translator-service:${TRANSLATOR_VER}
hostname: json-translator-service
container_name: json-translator-service
restart: always
environment:
- SPRING_CONFIG_ADDITIONAL-LOCATION=/var/lib/config/application.properties
- TZ=${TIME_ZONE}
- RABBITMQ_PASSWORD=${RABBITMQ_PASSWORD}
volumes:
- ./conf/json-translator-service/:/var/lib/config
Start ohne Docker
Das Artefakt des Json Translator Service kann einfach mit dem Befehl
java -jar json-translator-service.jar –spring.config.additional-location=classpath:./json-translator-service.properties –server.port=8096
im Verzeichnis des Artefakts ausgeführt werden.
Hinweis: Der edi-json.converter läuft mit Java 17, welches hierbei verwendet werden muss.
Der ausgeführte Service kann dabei durch ein application.properties File, welches neben der jar gelegt wird, konfiguriert werden. Die Default Einstellungen aus dem Artefakt sehen wie folgt aus:
spring.application=json-translator-service
#==== RabbitMQ
rabbitmq.host=host
rabbitmq.port=port
rabbitmq.username=user
rabbitmq.password=pw
spring.cloud.function.definition= consumeEvent1;consumeEvent2;consumeEvent3;consumeEvent4
#Consumer variables
jsonTranslatorConsumerExchangeName1=json.translator.consumer.1
jsonTranslatorConsumerGroup1=default
jsonTranslatorConsumerExchangeType1=direct
jsonTranslatorConsumerExchangeName2=json.translator.consumer.2
jsonTranslatorConsumerGroup2=default
jsonTranslatorConsumerExchangeType2=direct
jsonTranslatorConsumerExchangeName3=json.translator.consumer.3
jsonTranslatorConsumerGroup3=default
jsonTranslatorConsumerExchangeType3=direct
jsonTranslatorConsumerExchangeName4=json.translator.consumer.4
jsonTranslatorConsumerGroup4=default
jsonTranslatorConsumerExchangeType4=direct
#Producer variables
jsonTranslatorProducerExchangeName1=json.translator.producer.1
jsonTranslatorRoutingkeyExpression1='default'
jsonTranslatorHeaderName1=tenant
jsonTranslatorProducerExchangeType1=direct
jsonTranslatorProducerExchangeName2=json.translator.producer.2
jsonTranslatorRoutingkeyExpression2='default'
jsonTranslatorHeaderName2=tenant
jsonTranslatorProducerExchangeType2=direct
jsonTranslatorProducerExchangeName3=json.translator.producer.3
jsonTranslatorRoutingkeyExpression3='default'
jsonTranslatorHeaderName3=tenant
jsonTranslatorProducerExchangeType3=direct
jsonTranslatorProducerExchangeName4=json.translator.producer.4
jsonTranslatorRoutingkeyExpression4='default'
jsonTranslatorHeaderName4=tenant
jsonTranslatorProducerExchangeType4=direct
#Path to the json specification file
jsonSpecPath1=/var/lib/config/spec1.json
jsonSpecPath2=/var/lib/config/spec2.json
jsonSpecPath3=/var/lib/config/spec3.json
jsonSpecPath4=/var/lib/config/spec4.json
Die minimal Konfiguration wäre lediglich das Eintragen der Werte für die Anbindung der AMQP:
#==== RabbitMQ
rabbitmq.host=host
rabbitmq.port=port
rabbitmq.username=user
rabbitmq.password=pw
Andere Propertys hätten bei der minimal Konfiguration die oben gezeigten default Werte.
View Me Edit Me