
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 .