The Management API in WildFly is accessible through multiple channels, one of them being HTTP and JSON.
Even if you haven’t used a curl command line you might already have used this channel since it is how the web console interact with the Management API.
WildFly is distributed secured by default, the default security mechanism is username / password based making use of HTTP Digest for the authentication process.
Thus you need to create a user with the add-user.sh script.
Since we must be authenticated , the client will have to support HTTP Digest authentication.
For example this can be activated in curl using the --digest option.
The WildFly HTTP Management API adheres to the REST principles so the GET operations must be idempotent.
This means that using a request with method GET can be used to read the model but you won’t be able to change it.
You must use POST to change the model or read it. A POST request may contain the operation either in DMR or in JSON format as its body.
You have to define the Content-Type=application/json header in the request to specify that you are using some JSON.
If you want to submit DMR in the request body then the Content-Type or the Accept header should be "application/dmr-encoded".
While you can do everything with POST, some operations can be called through a 'classical' GET request.
These are the supported operations for a GET :
-
attribute : for a read-attribute operation
-
resource : for a read-resource operation
-
resource-description : for a read-resource-description operation
-
snapshots : for the list-snapshots operation
-
operation-description : for a read-operation-description operation
-
operation-names : for ad read-operation-names operation
The URL format is the following one : http://server:9990/management/ <path_to_resource>?operation=<operation_name>&operation_parameter=<value>…
path_to_resource is the path to the wanted resource replacing all '=' with '/' : thus for example subsystem=undertow/server=default-server becomes subsystem/undertow/server/default-server.
So to read the server-state :
http://localhost:9990/management?operation=attribute&name=server-state&json.pretty=1
-
This is simple operation that is equivalent of running :read-attribute(name=server-state) with CLI in root directory
-
Using GET
http://localhost:9990/management?operation=attribute&name=server-state&json.pretty=1
-
Using POST
$ curl --digest -L -D - http://localhost:9990/management --header "Content-Type: application/json" -d '{"operation":"read-attribute","name":"server-state","json.pretty":1}' -u admin Enter host password for user 'admin': HTTP/1.1 401 Unauthorized Connection: keep-alive WWW-Authenticate: Digest realm="ManagementRealm",domain="/management",nonce="P80WU3BANtQNMTQwNjg5Mzc5MDQ2MlpjmRaZ+Vlp1OVeNEGBeXg=",opaque="00000000000000000000000000000000",algorithm=MD5 Content-Length: 77 Content-Type: text/html Date: Fri, 01 Aug 2014 11:49:50 GMT HTTP/1.1 200 OK Connection: keep-alive Authentication-Info: nextnonce="M+h9aADejeINMTQwNjg5Mzc5MDQ2OPQbHKdAS8pRE8BbGEDY5uI=" Content-Type: application/json; charset=utf-8 Content-Length: 55 Date: Fri, 01 Aug 2014 11:49:50 GMT { "outcome" : "success", "result" : "running" }
-
-
Here’s an example of an operation on a resource with a nested address and passed parameters. This is same as if you would run /host=primary/server=server-01:read-attribute(name=server-state)
$ curl --digest -L -D - http://localhost:9990/management --header "Content-Type: application/json" -d '{"operation":"read-attribute","address":[{"host":"primary"},{"server":"server-01"}],"name":"server-state","json.pretty":1}'
HTTP/1.1 200 OK
Transfer-encoding: chunked
Content-type: application/json
Date: Tue, 17 Apr 2012 04:02:24 GMT
{
"outcome" : "success",
"result" : "running"
}
-
Following example will get us information from http connection in undertow subsystem including run-time attributes
This is the same as running /subsystem=undertow/server=default-server:read-resource(include-runtime=true,recursive=true) in CLI-
Using GET
http://localhost:9990/management/subsystem/undertow/server/default-server?operation=resource&recursive=true&json.pretty=1 { "default-host" : "default-host", "servlet-container" : "default", "ajp-listener" : null, "host" : {"default-host" : { "alias" : ["localhost"], "default-web-module" : "ROOT.war", "filter-ref" : { "server-header" : {"predicate" : null}, "x-powered-by-header" : {"predicate" : null} }, "location" : {"/" : { "handler" : "welcome-content", "filter-ref" : null }}, "setting" : null }}, "http-listener" : {"default" : { "allow-encoded-slash" : false, "allow-equals-in-cookie-value" : false, "always-set-keep-alive" : true, "buffer-pipelined-data" : true, "buffer-pool" : "default", "certificate-forwarding" : false, "decode-url" : true, "enabled" : true, "max-buffered-request-size" : 16384, "max-cookies" : 200, "max-header-size" : 51200, "max-headers" : 200, "max-parameters" : 1000, "max-post-size" : 10485760, "proxy-address-forwarding" : false, "read-timeout" : null, "receive-buffer" : null, "record-request-start-time" : false, "redirect-socket" : "https", "send-buffer" : null, "socket-binding" : "http", "tcp-backlog" : null, "tcp-keep-alive" : null, "url-charset" : "UTF-8", "worker" : "default", "write-timeout" : null }}, "https-listener" : null }
-
Using POST
$ curl --digest -D - http://localhost:9990/management --header "Content-Type: application/json" -d '{"operation":"read-resource", "include-runtime":"true" , "recursive":"true", "address":["subsystem","undertow","server","default-server"], "json.pretty":1}' -u admin:admin HTTP/1.1 401 Unauthorized Connection: keep-alive WWW-Authenticate: Digest realm="ManagementRealm",domain="/management",nonce="a3paQ9E0/l8NMTQwNjg5OTU0NDk4OKjmim2lopZNc5zCevjYWpk=",opaque="00000000000000000000000000000000",algorithm=MD5 Content-Length: 77 Content-Type: text/html Date: Fri, 01 Aug 2014 13:25:44 GMT HTTP/1.1 200 OK Connection: keep-alive Authentication-Info: nextnonce="nTOSJd3ufO4NMTQwNjg5OTU0NDk5MeUsRw5rKXUT4Qvk1nbrG5c=" Content-Type: application/json; charset=utf-8 Content-Length: 1729 Date: Fri, 01 Aug 2014 13:25:45 GMT { "outcome" : "success", "result" : { "default-host" : "default-host", "servlet-container" : "default", "ajp-listener" : null, "host" : {"default-host" : { "alias" : ["localhost"], "default-web-module" : "ROOT.war", "filter-ref" : { "server-header" : {"predicate" : null}, "x-powered-by-header" : {"predicate" : null} }, "location" : {"/" : { "handler" : "welcome-content", "filter-ref" : null }}, "setting" : null }}, "http-listener" : {"default" : { "allow-encoded-slash" : false, "allow-equals-in-cookie-value" : false, "always-set-keep-alive" : true, "buffer-pipelined-data" : true, "buffer-pool" : "default", "certificate-forwarding" : false, "decode-url" : true, "enabled" : true, "max-buffered-request-size" : 16384, "max-cookies" : 200, "max-header-size" : 51200, "max-headers" : 200, "max-parameters" : 1000, "max-post-size" : 10485760, "proxy-address-forwarding" : false, "read-timeout" : null, "receive-buffer" : null, "record-request-start-time" : false, "redirect-socket" : "https", "send-buffer" : null, "socket-binding" : "http", "tcp-backlog" : null, "tcp-keep-alive" : null, "url-charset" : "UTF-8", "worker" : "default", "write-timeout" : null }}, "https-listener" : null } }
-
-
You may also used some encoded DMR but the result won’t be human readable
curl --digest -u admin:admin --header "Content-Type: application/dmr-encoded" -d bwAAAAMACW9wZXJhdGlvbnMADXJlYWQtcmVzb3VyY2UAB2FkZHJlc3NsAAAAAAAHcmVjdXJzZVoB http://localhost:9990/management
-
You can deploy applications on the server
-
First upload the file which will create a managed content. You will have to use http://localhost:9990/management/add-content
curl --digest -u admin:admin --form file=@tiny-webapp.war http://localhost:9990/management/add-content {"outcome" : "success", "result" : { "BYTES_VALUE" : "+QJlHTDrogO9pm/57GkT/vxWNz0=" }}
-
Now let’s deploy the application
curl --digest -u admin:admin -L --header "Content-Type: application/json" -d '{"content":[{"hash": {"BYTES_VALUE" : "+QJlHTDrogO9pm/57GkT/vxWNz0="}}], "address": [{"deployment":"tiny-webapp.war"}], "operation":"add", "enabled":"true"}' http://localhost:9990/management {"outcome" : "success"}
-
HttpAuthenticationFeature feature = HttpAuthenticationFeature.digest("admin", "admin");
Client client = ClientBuilder.newClient();
client.register(feature);
Entity<SimpleOperation> operation = Entity.entity(
new SimpleOperation("read-resource", true, "subsystem", "undertow", "server", "default-server"),
MediaType.APPLICATION_JSON_TYPE);
WebTarget managementResource = client.target("http://localhost:9990/management");
String response = managementResource.request(MediaType.APPLICATION_JSON_TYPE)
.header("Content-type", MediaType.APPLICATION_JSON)
.post(operation, String.class);
System.out.println(response);
{"outcome" : "success", "result" : {"default-host" : "default-host", "servlet-container" : "default", "ajp-listener" : null, "host" : {"default-host" : {"alias" : ["localhost"], "default-web-module" : "ROOT.war", "filter-ref" : {"server-header" : {"predicate" : null}, "x-powered-by-header" : {"predicate" : null}}, "location" : {"/" : {"handler" : "welcome-content", "filter-ref" : null}}, "setting" : null}}, "http-listener" : {"default" : {"allow-encoded-slash" : false, "allow-equals-in-cookie-value" : false, "always-set-keep-alive" : true, "buffer-pipelined-data" : true, "buffer-pool" : "default", "certificate-forwarding" : false, "decode-url" : true, "enabled" : true, "max-buffered-request-size" : 16384, "max-cookies" : 200, "max-header-size" : 51200, "max-headers" : 200, "max-parameters" : 1000, "max-post-size" : 10485760, "proxy-address-forwarding" : false, "read-timeout" : null, "receive-buffer" : null, "record-request-start-time" : false, "redirect-socket" : "https", "send-buffer" : null, "socket-binding" : "http", "tcp-backlog" : null, "tcp-keep-alive" : null, "url-charset" : "UTF-8", "worker" : "default", "write-timeout" : null}}, "https-listener" : null}}