Der Json Translator Service kann beliebige JSON-Daten auf beliebige andere JSON-Strukturen mit Hilfe des Frameworks Jolt abbilden.

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