WildFly Model Graph
Tool which reads the management model from a WildFly instance and stores it as a graph in a Neo4j database. If not specified otherwise the tool starts at the root resource and reads the resource descriptions in a recursive way.
The tool creates the following graph:
There are five main nodes in the database:
The resource node holds the fully qualified address and the name of the resource. The name of a resource is the resource type. For singleton resources the name consists of the type and the name:
Address Name /subsystem=datasources/data-source=* data-source /subsystem=mail/mail-session=default/server=imap server=imap
Parent resources have a
CHILD_OFrelationship with their children. This makes traversing through the model tree very convenient.
The attribute node holds most of the attribute’s metadata such as type, required, nillable or storage.
The operation node holds information about an operation. Global operations are stored only once (except the
addoperation). Use the flag
globalto distinguish between global and resource dependent operations.
The parameter node holds information about the request properties and has similar properties as the
The capability node holds just the name of the capability.
In addition the database contains a
Version node with information about the WildFly and management model version. See the Neo4j browser for the complete list of nodes, relations and properties.
To get started, you need a running WildFly and Neo4j instance. To install Neo4j, download it from https://neo4j.com/download/ or use
brew install neo4j. Start Neo4j using
neo4j start from the command line and open http://localhost:7474/. If you login for the first time, you have to change your password. To change it back to the default use
and refresh your browser. This makes it easier to use the default options when analysing the model tree. Anyway you can specify the WildFly and Neo4j instance using one of the command line options:
Usage: <main class> [options] Options: -help, --help Shows this help -clean Removes all indexes, nodes, relationships and properties before analysing the model tree. -neo4j Neo4j database as <server>[:<port>] with 7687 as default port. Omit to connect to a local Neo4j database at localhost:7687. -neo4j-password Neo4j password Default: neo4j -neo4j-user Neo4j username Default: neo4j -resource The root resource to analyse. Default: / -wildfly WildFly instance as <server>[:<port>] with 9990 as default port. Omit to connect to a local WildFly instance at localhost:9990. -wildfly-password WildFly password Default: admin -wildfly-user WildFly username Default: admin
If everything runs locally using the default ports and credentials, you just need to run
java -jar model-graph-0.1.0.jar
The tool will populate the Neo4j instance with nodes, relations and properties of the specified resource (sub)tree. Please make sure the Neo4j instance is empty or use the
-clean option to remove existing data.
If you want to analyse different management model versions, you need to setup multiple Neo4j instances and point the tool to the relevant instance. After the tool has finished, head to http://localhost:7474/ and enter some queries.
Here are a few examples how to query the database:
Resources & Relationships
requires relations of the
MATCH g=(r:Resource)-->(:Attribute)-[:ALTERNATIVE|:REQUIRES]->(:Attribute) WHERE r.name = "connection-definitions" RETURN g
Show all resources where’s a
requires relation between attributes:
MATCH g=(r:Resource)-->(:Attribute)-[:REQUIRES]->(:Attribute) RETURN g
data-source resource trees:
MATCH g=(r:Resource)-[:CHILD_OF*..10]->() WHERE r.name = "data-source" RETURN g
The top twenty resources with lots of attributes:
MATCH (r:Resource)-[has:HAS_ATTRIBUTE]->() RETURN r.address, COUNT(has) as attributes ORDER BY attributes DESC LIMIT 20
List all attributes which have a capability reference to
MATCH (r:Resource)-->(a:Attribute)-[:REFERENCES_CAPABILITY]->(c:Capability) WHERE c.name = "org.wildfly.network.socket-binding" RETURN r.address, a.name
List all attributes which match the regexp
.*socket-binding.*, but do not have a capability reference
MATCH (r:Resource)-->(a:Attribute) WHERE a.name =~ ".*socket-binding.*" AND NOT (a)-[:REFERENCES_CAPABILITY]-() RETURN r.address, a.name
List all attributes which are both required and nillable together with their alternatives:
MATCH (r:Resource)-->(a:Attribute)-[:ALTERNATIVE]-(alt) WHERE a.required = true AND a.nillable = true AND a.storage = "configuration" RETURN r.address, a.name, alt.name
List all attributes which are both required and nillable, but which don’t have alternatives:
MATCH (r:Resource)-->(a:Attribute) WHERE NOT (a)-[:ALTERNATIVE]-() AND a.required = true AND a.nillable = true AND a.storage = "configuration" RETURN r.address, a.name
List all attributes which are required and have a default value:
MATCH (r:Resource)-->(a:Attribute) WHERE a.required = true AND exists(a.default) RETURN r.address, a.name, a.default
List all complex attributes (i.e. attributes with a value type other than
MATCH (r:Resource)-->(a:Attribute) WHERE exists(a.`value-type`) AND a.`value-type` = "OBJECT" RETURN r.address, a.name
List all deprecated attributes:
MATCH (r:Resource)-->(a:Attribute) WHERE exists(a.deprecated) RETURN r.address, a.name, a.since ORDER BY a.since DESC
List all resources with more than five non-global operations:
MATCH (r:Resource)-[p:PROVIDES]->(o:Operation) WHERE NOT o.global WITH r, count(p) as operations WHERE operations > 5 RETURN r.address, operations ORDER BY operations DESC
add operations with more than two required parameters:
MATCH (r:Resource)-[:PROVIDES]->(o:Operation)-[a:ACCEPTS]->(p:Parameter) WHERE o.name = "add" AND p.required WITH r, o, count(a) as parameters WHERE parameters > 2 RETURN r.address, o.name, parameters ORDER BY parameters DESC
List all deprecated operation parameters:
MATCH (r:Resource)-->(o:Operation)-->(p:Parameter) WHERE exists(p.deprecated) RETURN r.address, o.name, p.name, p.since ORDER BY p.since DESC
Show the release and management model version:
MATCH (v:Version) RETURN v.`release-codename` + " " + v.`release-version` as Release, v.`management-major-version` + "." + v.`management-minor-version` + "." + v.`management-micro-version` as `Management Model Version`
See https://neo4j.com/docs/cypher-refcard/current/ for a quick reference of the Cypher query language.