Wie visualisiere ich ein Spring Integration-Diagramm mit Neo4j?


Das Spring Integration Framework kann den aktuellen Status aller EIP- Komponenten und ihre Beziehungen in Form eines JSON-Diagramms anzeigen. Dies scheint sehr praktisch zum Studieren und Debuggen zu sein, aber leider bietet keines der Google-Tools (von denen nur ein- / zweimal ) eine ausreichende FlexibilitĂ€t fĂŒr die Visualisierung und Analyse eines solchen Diagramms. In diesem Artikel werde ich zeigen, wie dieses Problem durch Importieren eines Diagramms in ein grafisches Neo4j- DBMS gelöst werden kann , wobei diese FlexibilitĂ€t an erster Stelle steht.


(tl;dr)


, :


  1. JSON URL.
  2. Cypher- Neo4j Browser, URL.

, , .


Der Artikel richtet sich an Personen, die mit dem Spring-Ökosystem vertraut sind und ein grundlegendes VerstĂ€ndnis des grafischen DBMS Neo4j und seiner Abfragesprache Cypher haben. Wenn nicht, spielt es keine Rolle - der Text enthĂ€lt Links zu erklĂ€renden Quellen.


JSON?


2 :


  1. spring-integration-http ( spring-integration-webflux), , Integration Graph Controller.
  2. spring-integration-core Spring Boot Actuator, endpoint integrationgraph ( web).

:


{
  "contentDescriptor": {
    "providerVersion": "5.2.4.RELEASE",
    "providerFormatVersion": 1.1,
    "provider": "spring-integration",
    "name": "analog"
  },
  "nodes": [
    {
      "nodeId": 3,
      "componentType": "ExecutorSubscribableChannel",
      "name": "brokerChannel"
    },
    // ...
  ],
  "links": [
    {
      "from": 19,
      "to": 8,
      "type": "output"
    },
    // ...
  ]
}

3 :


  • contentDescriptor – ; name ( spring.application.name).
  • nodes – EIP-, . name, componentType nodeId, , .
  • links , .. EIP-. from to nodeId . type , 5: input, output, route, error, discard.

( EIP) !
, , , componentType channel.


Spring Integration.


“”, – “”, : nodes links . .



Neo4j, - , , , http://localhost:8080/actuator/integrationgraph ( Spring Boot Actuator). JSON, , .


CORS, . Spring Boot (+Actuator) , :


management:
  endpoints:
    web:
      exposure:
        include: '*'
      cors:
        allowed-origins: '*'
        allowed-methods: '*'

( production!)


Spring Integration, . .


Neo4j?



Neo4j, 2 :


  1. Neo4j (, ?)
    :



  2. Cypher- APOC


    - Neo4j, . Neo4j Sandbox .



Neo4j 4.0.1, , . APOC , 2 Neo4j.


1:


Spring Integration, JSON-, , “ ” : – , – , – . : nodeId, nodeName componentType. org.springframework.integration.graph.IntegrationNode, ( ).


, Neo4j - :


JSON URL, .

Cypher :


// (1) load JSON from URL:
WITH "http://localhost:8080/actuator/integrationgraph" AS url
CALL apoc.load.json(url) YIELD value      
WITH value AS json, value.contentDescriptor AS jsonDescriptor
// (2) descriptor:
MERGE (descriptor:Descriptor {name: jsonDescriptor.name})
    ON CREATE SET
    descriptor.providerVersion = jsonDescriptor.providerVersion,
    descriptor.providerFormatVersion = jsonDescriptor.providerFormatVersion,
    descriptor.provider = jsonDescriptor.provider
// (3) nodes:
WITH json, descriptor
UNWIND json.nodes AS jsonNode
MERGE (node:Node {nodeId: jsonNode.nodeId})
    ON CREATE SET
    node.componentType = jsonNode.componentType,
    node.name = jsonNode.name
// (4) links:
WITH json, descriptor, node
UNWIND json.links AS jsonLink
MATCH (a:Node {nodeId: jsonLink.from}), (b:Node {nodeId: jsonLink.to})
MERGE (a)-[link:Link {type: jsonLink.type}]->(b)
// (5) result:
RETURN descriptor, node, link

URL

Neo4j Sandbox’, , .. localhost . JSON- , ó.


Cypher, ( ):


  1. APOC- apoc.load.json(url) JSON- json, – jsonDescriptor.
  2. Descriptor, jsonDescriptor.
    MERGE, , . , MERGE CREATE.
  3. JSON- ( nodes) UNWIND Node, name componentType.
  4. ( links), Link MATCH, .
  5. , : , .

Neo4j Browser JSON-, :
Das Ergebnis der Abfrage am Beispiel der Anwendung Analog


-, : EIP- , , Neo4j Browser, , Cypher-:


ZusÀtzliche Knoteneigenschaften


“” ( ) , . , .


, :


  • , EIP- , , , , , serverR... , , , .
  • , Link, type. , Cypher, “ ” .
  • , , , – , .

, , , 



2:


, : , , . Neo4j Browser ( , ), GraSS (Graph Style Sheet), Neo4j Browser’. , , :style ( ):


Eine hervorgehobene orangefarbene SchaltflĂ€che setzt den Stil auf die Standardeinstellungen zurĂŒck.


. Neo4j Browser , , ( ) Node. Neo4j Browser, , . “” EIP-: , , .. , , , Cypher- - “ ” . , Cypher “ ” : – , . APOC. apoc.merge.node, / , :


merge nodes with dynamic labels, with support for setting properties ON CREATE or ON MATCH

: , /, – , . , Cypher- , “” , , channel. CASE.


: -, , -, JSON- Cypher MERGE, APOC – apoc.merge.relationship:


merge relationship with dynamic type, with support for setting properties ON CREATE or ON MATCH

Neo4j 3.

APOC- apoc.merge.(relationship|node) 3.x ( , Neo4j Sandbox 2020) onMatchProps, .


, - “” , , , , , – , . , , , . , “” . DESCRIBES - .



, , :


// (1) load JSON from URL:
WITH "http://localhost:8080/actuator/integrationgraph" AS url
CALL apoc.load.json(url) YIELD value
WITH value AS json, value.contentDescriptor AS jsonDesc
// (2) descriptor:
MERGE (descriptor:Descriptor {name: jsonDesc.name})
  ON CREATE SET
    descriptor.providerVersion = jsonDesc.providerVersion,
    descriptor.providerFormatVersion = jsonDesc.providerFormatVersion,
    descriptor.provider = jsonDesc.provider,
    descriptor.updated = localdatetime()
  ON MATCH SET
    descriptor.updated = localdatetime()
// (3) nodes:
WITH json, descriptor
UNWIND json.nodes AS jsonNode
CALL apoc.merge.node(
  /*labels*/ ['Node',
    CASE
      WHEN jsonNode.componentType IS NULL THEN "<unknown>"
      WHEN toLower(jsonNode.componentType) ENDS WITH "channel" THEN "channel"
      WHEN toLower(jsonNode.componentType) ENDS WITH "adapter" THEN "adapter"
      WHEN jsonNode.componentType CONTAINS '$' THEN "<other>"
      ELSE jsonNode.componentType
    END],
  /*identProps*/   {nodeId: jsonNode.nodeId, appName: descriptor.name},
  /*onCreateProps*/{name: jsonNode.name, componentType: jsonNode.componentType},
  /*onMatchProps*/ {}
) YIELD node
MERGE (descriptor)-[:DESCRIBES]->(node)
// (4) links:
WITH json, descriptor, node
UNWIND json.links AS jsonLink
MATCH (a:Node {nodeId: jsonLink.from})<-[:DESCRIBES]-(descriptor)-[:DESCRIBES]->(b:Node {nodeId: jsonLink.to})
CALL apoc.merge.relationship(a, toUpper(jsonLink.type), {}, {}, b, {}) YIELD rel
// (5) result:
RETURN descriptor


URL

Neo4j Sandbox’, , .. localhost . JSON- , ó.


, - 5 ( ):


  1. JSON ;
  2. / , ;
  3. / , Node ( - ), :


    • <unknown>, (, , , , , UnzipTransformer);
    • channel, channel, , ExecutorSubscribableChannel;
    • adapter, adapter, , inbound-channel-adapter;
    • <other>, $, ( ) , , ServerConfig$$Lambda$994/0x00000008010fd440;
    • , , , "componentType": "gateway".
      componentType . DESCRIBES.

  4. / , type JSON- .
    . , , nodeId. , appName .
  5. .
    , , - . .

Spring Integration, ( 350+ 330+ , . ). Neo4j , , , :


OOM beim Import


Neo4j , . , Neo4j bin/neo4j-admin, memrec , , .


, GraSS- (, ) Neo4j Browser’, :style.



, MATCH (a) RETURN a, - . , , , . ( name):


WITH "analog" AS appName
MATCH (:Descriptor {name: appName})-[:DESCRIBES]->(n:Node)-[l*0..1]-(:Node)
RETURN n, l

, , ( ). , .


:


Erweitertes Abfrageergebnis


, . Cypher- (. .4 ), style.grass, componentType Node. , . , GraSS- EIP- :


node.Node {
  defaultCaption: "<id>";
  caption: "{name}";
}

Neo4j Browser – :


Anpassbare Farbcodes fĂŒr Knotentypen in einem Diagramm


. , , Neo4j Browser, . .



, Neo4j Spring Integration. , , , :


32 27 :


37 41 :


57 54 :


350 332 :



, JSON- EIP- Spring Integration. Neo4j . Cypher “ ” , . . , ( ) Cypher-, .


– Neo4j Browser. , ; , . , – . Cypher , . , //, / , , / / , / .. , .


Der ursprĂŒngliche Artikel zur Cypher-Syntax-Hervorhebung ist hier .


All Articles