
A estrutura do Spring Integration é capaz de fornecer o estado atual de todos os componentes EIP e seus relacionamentos na forma de um gráfico JSON. Parece muito conveniente para estudar e depurar, mas, infelizmente, nenhuma das ferramentas do Google (das quais apenas uma / duas vezes ) oferece flexibilidade suficiente para visualizar e analisar esse gráfico. Neste artigo, mostrarei como resolver esse problema importando um gráfico para um DBMS gráfico do Neo4j , onde essa flexibilidade vem primeiro.
(tl;dr)
, :
- JSON URL.
- Cypher- Neo4j Browser, URL.
, , .
, Spring Neo4j Cypher. , – .
JSON?
2 :
spring-integration-http ( spring-integration-webflux), , Integration Graph Controller.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 :
Neo4j (, ?)
:
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
URLNeo4j Sandbox’, , .. localhost . JSON- , ó.
Cypher, ( ):
- APOC-
apoc.load.json(url) JSON- json, – jsonDescriptor. Descriptor, jsonDescriptor.
MERGE, , . , MERGE CREATE.- JSON- (
nodes) UNWIND Node, name componentType. - (
links), Link MATCH, . - , : , .
Neo4j Browser JSON-, :

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

“” ( ) , . , .
, :
- , EIP- , , , , ,
serverR... , , , . - ,
Link, type. , Cypher, “ ” . - , , , – , .
, , , …
2:
, : , , . Neo4j Browser ( , ), GraSS (Graph Style Sheet), Neo4j Browser’. , , :style ( ):

. 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
URLNeo4j Sandbox’, , .. localhost . JSON- , ó.
, - 5 ( ):
- JSON ;
- / , ;
/ , Node ( - ), :
<unknown>, (, , , , , UnzipTransformer);channel, channel, , ExecutorSubscribableChannel;adapter, adapter, , inbound-channel-adapter;<other>, $, ( ) , , ServerConfig$$Lambda$994/0x00000008010fd440;- , , ,
"componentType": "gateway".
componentType . DESCRIBES.
- / ,
type JSON- .
. , , nodeId. , appName . - .
, , - . .
Spring Integration, ( 350+ 330+ , . ). Neo4j , , , :

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

, . Cypher- (. .4 ), style.grass, componentType Node. , . , GraSS- EIP- :
node.Node {
defaultCaption: "<id>";
caption: "{name}";
}
Neo4j Browser – :

. , , Neo4j Browser, . .
, Neo4j Spring Integration. , , , :
32 27 :

37 41 :

57 54 :

350 332 :

, JSON- EIP- Spring Integration. Neo4j . Cypher “ ” , . . , ( ) Cypher-, .
– Neo4j Browser. , ; , . , – . Cypher , . , //, / , , / / , / .. , .
O artigo original de destaque da sintaxe Cypher está aqui .