The main class to use is org.jboss.dmr.scala.ModelNode. Its companion object acts as a factory for creating new
model node instances.
// creates an empty model nodeval node = ModelNode()
// creates a new model node holding a simple valueval node = ModelNode(42)
// creates a new model node with structureval node = ModelNode(
"flag" -> true,
"hello" -> "world",
"answer" -> 42,
"child" -> ModelNode(
"inner-a" -> 123,
"inner-b" -> "test",
"deep-inside" -> ModelNode("foo" -> "bar"),
"deep-list" -> List(
ModelNode("one" -> 1),
ModelNode("two" -> 2),
ModelNode("three" -> 3)
)
)
)
Addressing and operations
You can use a DSL like API to set the address and operation for a model node. To describe the "read-resource"
operation on "/subsystem=datasources/data-source=ExampleDS" use the following code:
ModelNode() at ("subsystem" -> "datasources") / ("data-source" -> "ExampleDS") op 'read_resource(
'include_runtime -> false,
'recursive_depth -> 2
)
Addresses can be written down as (String, String) tuples separated by "/". Operations are specified using
scala.Symbols and an optional list of parameters. Each parameter is made up of another scala.Symbol and a
value. Using symbols makes the DSL both more readable and extentable.
However there's one drawback in using symbols: they cannot contain characters like "-". 'read-resource is
therefore an illegal symbol. As most DMR operations and many parameters do contain "-", this library will replace
all underscores in a symbol with dashes:
ModelNode() op 'read_resource('include_runtime -> true)
// is exactly the same as
ModelNode() op Symbol("read-resource")(Symbol("include-runtime") -> true)
Here are some more examples using addresses and operations:
// root is a constant for an empty address
ModelNode() at root op 'read_resource
ModelNode() at ("subsystem" -> "datasources") / ("data-source" -> "ExampleDS") op 'disable
// parameters are specified as pairs (Symbol -> Any)
ModelNode() at ("core-service" -> "platform-mbean") / ("type" -> "runtime") op 'read_resource(
'attributes_only -> true,
'include_runtime -> false,
'recursive_depth -> 3,
'custom_parameter -> "custom-value"
)
// unsupported parameter types will throw an IllegalArgumentException
ModelNode() at root op 'read_resource('proxies -> Console.out)
Reading Nodes
Reading values from a model node follows the sementics of a Map[String, ModelNode], but instead of a string you
provide a org.jboss.dmr.scala.Path as key. Thanks to an implicit conversion expression like "a" / "b" / "c"
are automatically converted to a path.
val node = ModelNode(
"flag" -> true,
"hello" -> "world",
"answer" -> 42,
"level0" -> ModelNode(
"level1" -> ModelNode(
"level2" -> ModelNode(
"level3" -> ModelNode(
"level4" -> ModelNode("foo" -> "bar")
)
)
)
)
)
val flag = node("flag")
val boom = node("gag") // throws a NoSuchelementExceptionval hello = node.get("hello") // returns an Option[ModelNode]val x = node.getOrElse("nope", ModelNode("y"))
val check = node.contains("level0" / "level1" / "level2" / "level3")
val level3 = node("level0" / "level1" / "level2" / "level3")
val level2 = for {
l0 <- node.get("level0")
l1 <- l0.get("level1")
l2 <- l1.get("level2")
} yield l2
Since the result of node.get("a" / "b" / "c") is Option[ModelNode], reading nested model nodes is safe even
if some children in the path do not exist. In this case None wil be returned:
val nope = node.get("level0", "oops", "level2", "level3")
Reading Values
You can use the folowing methods to read values from model nodes:
ModelNode.asBoolean
ModelNode.asInt
ModelNode.asLong
ModelNode.asBigInt
ModelNode.asDouble
ModelNode.asString
These methods return Option instances of the relevant type. This is because not all methods make sense on all
kind of model nodes:
val node = ModelNode(
"flag" -> true,
"child" -> ModelNode(
"size" -> 0
)
)
val nonsense = node("child").asDouble
Writing
Simple values can be set using node("foo") = "bar". If "foo" doesn't exist it will be created and updated
otherwise. As an alternative you can use the += operator, which comes in handy if you want to add multiple
key / value pairs:
Reading and writing can also be combined in one call:
node("child" / "deep-inside") += ("foo" -> "xyz")
Colection Operations
Since org.jboss.dmr.scala.ModelNode mixes in ( S t r i n g, M o d e l N o d e )] you can use
all those nifty collection methods like foreach, map or filter
A composite operation is setup using the ModelNode.composite(n: ModelNode, xn: ModelNode*) factory method:
ModelNode.composite(
ModelNode.empty at ("core-service" -> "management") / ("access" -> "authorization") op 'read_resource(
'recursive_depth -> 2),
ModelNode.empty at ("core-service" -> "management") / ("access" -> "authorization") op 'read_children_names(
'name -> "role-mapping"),
ModelNode.empty at ("subsystem" -> "mail") / ("mail-session" -> "*") op 'read_resource_description,
ModelNode.empty at ("subsystem" -> "datasources") / ("data-source" -> "ExampleDS") op 'disable ,
ModelNode.empty at ("core-service" -> "platform-mbean") / ("type" -> "runtime") op 'read_attribute(
'name -> "start-time")
)
==Implicit Conversions==
This package contains the following implicit conversions which are used to support a DSL like API:
- `(String, String)` to [[org.jboss.dmr.scala.Address]]
- [[scala.Symbol]] to [[org.jboss.dmr.scala.Operation]]
- String to [[org.jboss.dmr.scala.Path]]
Provides classes for dealing with the management model of a WildFly, JBoss or EAP instance.
Getting started
Please make sure to import the following packages in order to bring the necessary implicit conversions into scope and to save you some keystrokes.
Creating model nodes
The main class to use is org.jboss.dmr.scala.ModelNode. Its companion object acts as a factory for creating new model node instances.
Addressing and operations
You can use a DSL like API to set the address and operation for a model node. To describe the "read-resource" operation on "/subsystem=datasources/data-source=ExampleDS" use the following code:
Addresses can be written down as
(String, String)tuples separated by "/". Operations are specified using scala.Symbols and an optional list of parameters. Each parameter is made up of another scala.Symbol and a value. Using symbols makes the DSL both more readable and extentable.However there's one drawback in using symbols: they cannot contain characters like "-".
'read-resourceis therefore an illegal symbol. As most DMR operations and many parameters do contain "-", this library will replace all underscores in a symbol with dashes:ModelNode() op 'read_resource('include_runtime -> true) // is exactly the same as ModelNode() op Symbol("read-resource")(Symbol("include-runtime") -> true)Here are some more examples using addresses and operations:
Reading Nodes
Reading values from a model node follows the sementics of a
Map[String, ModelNode], but instead of a string you provide a org.jboss.dmr.scala.Path as key. Thanks to an implicit conversion expression like"a" / "b" / "c"are automatically converted to a path.Since the result of
node.get("a" / "b" / "c")isOption[ModelNode], reading nested model nodes is safe even if some children in the path do not exist. In this caseNonewil be returned:Reading Values
You can use the folowing methods to read values from model nodes:
ModelNode.asBooleanModelNode.asIntModelNode.asLongModelNode.asBigIntModelNode.asDoubleModelNode.asStringThese methods return
Optioninstances of the relevant type. This is because not all methods make sense on all kind of model nodes:Writing
Simple values can be set using
node("foo") = "bar". If "foo" doesn't exist it will be created and updated otherwise. As an alternative you can use the+=operator, which comes in handy if you want to add multiple key / value pairs:Reading and writing can also be combined in one call:
Colection Operations
Since org.jboss.dmr.scala.ModelNode mixes in ( S t r i n g, M o d e l N o d e )] you can use all those nifty collection methods like
foreach,maporfilterComposites
A composite operation is setup using the
ModelNode.composite(n: ModelNode, xn: ModelNode*)factory method: