
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 .