Comment visualiser un graphique d'intégration Spring à l'aide de Neo4j?


Le framework d'intégration de Spring est capable de donner l'état actuel de tous les composants EIP et leurs relations sous la forme d'un graphe JSON. Cela semble très pratique pour étudier et déboguer, mais hélas, aucun des outils Google (dont une ou deux fois seulement ) offre une flexibilité suffisante pour visualiser et analyser un tel graphique. Dans cet article, je montrerai comment résoudre ce problème en important un graphique dans un SGBD graphique Neo4j , où cette flexibilité vient en premier.


(tl;dr)


, :


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

, , .


, Spring Neo4j Cypher. , – .


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-, :
Le résultat de la requête sur l'exemple de l'application Analogique


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


Propriétés de nœud supplémentaires


“” ( ) , . , .


, :


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

, , , …


2:


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


Un bouton orange en surbrillance réinitialise le style par défaut.


. 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 , , , :


MOO Ă  l'importation


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

, , ( ). , .


:


RĂ©sultat de requĂŞte Ă©tendu


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


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

Neo4j Browser – :


Codes de couleurs personnalisables pour les types de nœuds dans un graphique


. , , Neo4j Browser, . .



, Neo4j Spring Integration. , , , :


32 27 :


37 41 :


57 54 :


350 332 :



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


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


L'article original sur la syntaxe Cypher est ici .


All Articles