
Kerangka Spring Integrasi mampu memberikan keadaan saat ini dari semua komponen EIP dan hubungan mereka dalam bentuk grafik JSON. Tampaknya sangat nyaman untuk belajar dan debugging, tetapi sayangnya, tidak satu pun alat google (yang hanya sekali / dua kali ) memberikan fleksibilitas yang cukup untuk memvisualisasikan dan menganalisis grafik seperti itu. Pada artikel ini saya akan menunjukkan cara mengatasi masalah ini dengan mengimpor grafik ke dalam DBMS grafis Neo4j , di mana fleksibilitas seperti itu lebih dulu.
(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 , . , //, / , , / / , / .. , .
Artikel utama sintaksis Cypher asli ada di sini .