├── .gitignore
├── .travis.yml
├── LICENSE
├── README.adoc
├── pom.xml
└── src
├── main
├── assembly
│ └── module-assembly.xml
├── java
│ └── org
│ │ ├── rhq
│ │ └── wfly
│ │ │ └── monitor
│ │ │ ├── extension
│ │ │ ├── DiagnosticsAdd.java
│ │ │ ├── DiagnosticsDefinition.java
│ │ │ ├── DiagnosticsRemove.java
│ │ │ ├── DiagnosticsWriteAttributeHandler.java
│ │ │ ├── InputAdd.java
│ │ │ ├── InputDefinition.java
│ │ │ ├── InputRemove.java
│ │ │ ├── InputWriteAttributeHandler.java
│ │ │ ├── MonitorAdd.java
│ │ │ ├── MonitorDefinition.java
│ │ │ ├── MonitorLogger.java
│ │ │ ├── MonitorRemove.java
│ │ │ ├── MonitorWriteAttributeHandler.java
│ │ │ ├── RootDefinition.java
│ │ │ ├── StorageAdd.java
│ │ │ ├── StorageDefinition.java
│ │ │ ├── StorageRemove.java
│ │ │ ├── StorageWriteAttributeHandler.java
│ │ │ ├── SubsystemAdd.java
│ │ │ ├── SubsystemDefinition.java
│ │ │ ├── SubsystemExtension.java
│ │ │ ├── SubsystemParser.java
│ │ │ └── SubsystemRemove.java
│ │ │ └── service
│ │ │ └── RhqMetricsService.java
│ │ └── wildfly
│ │ └── metrics
│ │ └── scheduler
│ │ ├── ModelControllerClientFactory.java
│ │ ├── SchedulerLogger.java
│ │ ├── Service.java
│ │ ├── TopologyChangeListener.java
│ │ ├── config
│ │ ├── Address.java
│ │ ├── ConfigLoader.java
│ │ ├── Configuration.java
│ │ ├── ConfigurationInstance.java
│ │ ├── Interval.java
│ │ └── ResourceRef.java
│ │ ├── diagnose
│ │ ├── Diagnostics.java
│ │ └── StorageReporter.java
│ │ ├── polling
│ │ ├── AbstractScheduler.java
│ │ ├── ClientFactoryImpl.java
│ │ ├── IntervalBasedScheduler.java
│ │ ├── IntervalGrouping.java
│ │ ├── OperationBuilder.java
│ │ ├── ReadAttributeOperationBuilder.java
│ │ ├── Scheduler.java
│ │ ├── Task.java
│ │ ├── TaskGroup.java
│ │ └── TaskGrouping.java
│ │ └── storage
│ │ ├── BufferedStorageDispatcher.java
│ │ ├── DataPoint.java
│ │ ├── DefaultKeyResolution.java
│ │ ├── InfluxStorageAdapter.java
│ │ ├── KeyResolution.java
│ │ ├── RHQStorageAdapter.java
│ │ └── StorageAdapter.java
└── resources
│ ├── META-INF
│ └── services
│ │ └── org.jboss.as.controller.Extension
│ ├── config
│ ├── monitor-domain.xml
│ ├── monitor-host.xml
│ └── standalone-monitor.xml
│ ├── module
│ └── main
│ │ └── module.xml
│ ├── org
│ └── rhq
│ │ └── wfly
│ │ └── monitor
│ │ └── extension
│ │ └── LocalDescriptions.properties
│ ├── schema
│ └── wildfly-monitor-subsystem.xsd
│ └── subsystem.xml
└── test
├── java
└── org
│ └── rhq
│ └── wfly
│ └── monitor
│ └── extension
│ ├── SubsystemBaseParsingTestCase.java
│ └── SubsystemParsingTestCase.java
└── resources
└── org
└── rhq
└── wfly
└── monitor
└── extension
└── subsystem.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | *.class
2 | .target
3 | *.jar
4 | *.war
5 | *.ear
6 | wildfly-sender.iml
7 | .idea
8 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
9 | hs_err_pid*
10 | # eclipse files
11 | .classpath
12 | .project
13 | target
14 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 | jdk:
3 | - oraclejdk8
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
203 |
--------------------------------------------------------------------------------
/README.adoc:
--------------------------------------------------------------------------------
1 | # ARCHIVED AND NO LONGER MAINTAINED
2 |
3 | = WildFly Monitor
4 |
5 | image:https://travis-ci.org/rhq-project/wildfly-monitor.svg?branch=master["Build Status", link="https://travis-ci.org/rhq-project/wildfly-monitor"]
6 |
7 | This is a module to be deployed into WildFlyAS and which then takes
8 | measurements from the WildFly model and sends them to a https://github.com/rhq-project/wildfly-monitor/wiki/RHQ[RHQ-Metrics server] or https://github.com/rhq-project/wildfly-monitor/wiki/InfluxDB[InfluxDB]
9 |
10 | == Prerequisites
11 |
12 | === Wildfly 8.1.0
13 |
14 | Get and install Wildfly 8.1.0: http://download.jboss.org/wildfly/8.1.0.Final/wildfly-8.1.0.Final.zip
15 |
16 | It's currently been tested against WF 8.1.0 and the default server configuration (standalone-monitor.xml) is configured for WF 8.
17 | But apart from that there should be no reason to not use it on WF 9.
18 |
19 | === RHQ Metrics
20 |
21 | https://github.com/rhq-project/rhq-metrics[RHQ Metrics] is not part of this module. It needs to be installed separately. Please consult the RHQ metrics documentation,
22 | how to install the core metric components and the REST services onto Wildfly 8.
23 |
24 |
25 | == Build & Install
26 |
27 | Build the top level project:
28 |
29 | ----
30 | $ mvn clean install
31 | ----
32 |
33 | This will also create a wildfly-monitor-module.zip, that can be installed on Wildfly:
34 |
35 | `unzip target/wildfly-monitor-module.zip -d $WILDFLY_HOME`
36 |
37 | This will add an additional module that contains the monitor extension and subsystem:
38 |
39 | `modules/system/layers/base/org/rhq/metrics/wildfly-monitor/`
40 |
41 | == Package Contents
42 |
43 | The following contents will be installed when you unpack the wildfly-monitor-module.zip:
44 |
45 | ....
46 | modules/system/layers/base/org/rhq/metrics/wildfly-monitor/main/module.xml (1)
47 | modules/system/layers/base/org/rhq/metrics/wildfly-monitor/main/*.jar (2)
48 | standalone/configuration/standalone-monitor.xml (3)
49 | domain/configuration/monitor-domain.xml (4)
50 | domain/configuration/monitor-host.xml (5)`
51 | ....
52 |
53 | . The module descriptor
54 | . Required libraries to run the monitor on Wildfly
55 | . An example configuration for standalone servers
56 | . An example configuration for managed domains
57 | . An example host configuration
58 |
59 | ## Server Configuration Profiles
60 |
61 | The wildfly-monitor-module.zip server profiles for both standalone and domain mode that can be used to start a pre-configured Wildfly instance:
62 |
63 | ### Standalone Mode
64 |
65 | `./bin/standalone.sh -c standalone-monitor.xml -b 127.0.0.1`
66 |
67 | ### Domain Mode
68 |
69 | `./bin/domain.sh --domain-config=monitor-domain.xml --host-config=monitor-host.xml -b 127.0.0.1`
70 |
71 |
72 | ## Get In touch
73 |
74 | The best way to reach out and discuss the monitor subsystem is the RHQ mailing list and/or the Chat Room:
75 |
76 | - Mailing List: https://lists.fedorahosted.org/mailman/listinfo/rhq-devel
77 | - IRC: irc://freenode.org/#rhq
78 |
79 | ## License
80 |
81 | - http://www.apache.org/licenses/LICENSE-2.0.html
82 |
83 | ## Resources
84 | - https://docs.jboss.org/author/display/WFLY8/Documentation
85 |
86 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | 4.0.0
7 |
8 |
9 | org.rhq.metrics
10 | wildfly-monitor
11 | 0.2.4-SNAPSHOT
12 |
13 | RHQ Metrics WildFly Monitor Subsystem
14 | A WildFly extension that is able to take server metrics and send them to RHQ Metrics.
15 |
16 | jar
17 |
18 |
19 | 0.0.6-SNAPSHOT
20 | 8.1.0.Final
21 | 4.11
22 | 18.0
23 | UTF-8
24 | 8.1.0.Final
25 | 0.2.4
26 | 3.1.0
27 | 3.1.4.GA
28 | 1.2.0.Final
29 |
30 |
31 |
32 |
34 | ${project.artifactId}
35 |
36 |
37 | org.apache.maven.plugins
38 | maven-assembly-plugin
39 | 2.4
40 |
41 |
42 | src/main/assembly/module-assembly.xml
43 |
44 |
45 |
46 |
47 | make-module
48 | package
49 |
50 | single
51 |
52 |
53 |
54 |
55 |
56 | maven-compiler-plugin
57 | 3.1
58 |
59 | 1.7
60 | 1.7
61 |
62 |
63 |
64 | org.apache.maven.plugins
65 | maven-surefire-plugin
66 | 2.16
67 |
68 | true
69 | true
70 | -Xmx512m
71 |
72 |
73 | jboss.home
74 | ${jboss.home}
75 |
76 |
77 |
78 | **/*TestCase.java
79 |
80 | once
81 |
82 |
83 |
84 |
85 | org.apache.maven.plugins
86 | maven-source-plugin
87 |
88 |
89 | attach-sources
90 |
91 | jar
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 | org.apache.maven.plugins
102 | maven-compiler-plugin
103 | 3.1
104 |
105 |
106 | org.apache.maven.plugins
107 | maven-source-plugin
108 | 2.4
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 | test.debug
120 |
121 |
122 | test.debug
123 |
124 |
125 |
126 |
127 |
128 | -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=8797,server=y,suspend=y
129 |
130 |
131 |
132 |
133 | publish
134 |
135 |
136 |
137 |
138 | maven-source-plugin
139 |
140 |
141 | attach-sources
142 |
143 | jar
144 |
145 |
146 |
147 |
148 |
149 |
150 | maven-javadoc-plugin
151 |
152 |
153 | attach-javadocs
154 |
155 | jar
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 | install-wf
167 |
168 |
169 | install-wf
170 |
171 |
172 |
173 |
174 |
175 | org.jboss.plugins
176 | wildfly-extension-maven-plugin
177 | 0.1-SNAPSHOT
178 |
179 | ${project.build.directory}/${project.artifactId}-module.zip
180 | ${jboss.home}
181 |
182 |
183 |
184 | build-dist
185 | install
186 |
187 | deploy
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 | org.wildfly
202 | wildfly-controller
203 | ${version.wildfly}
204 |
205 |
206 | org.wildfly
207 | wildfly-server
208 | ${version.wildfly}
209 |
210 |
211 | org.wildfly
212 | wildfly-subsystem-test
213 | pom
214 | test
215 | ${version.wildfly}
216 |
217 |
218 | junit
219 | junit
220 | test
221 | ${version.junit}
222 |
223 |
224 |
225 | org.jboss.logging
226 | jboss-logging
227 | ${version.org.jboss.logging.jboss-logging}
228 |
229 |
230 |
231 | org.jboss.logging
232 | jboss-logging-annotations
233 |
235 | provided
236 | true
237 | ${version.org.jboss.logging.jboss-logging-tools}
238 |
239 |
240 | org.jboss.logging
241 | jboss-logging-processor
242 |
244 | provided
245 | true
246 | ${version.org.jboss.logging.jboss-logging-tools}
247 |
248 |
249 |
250 |
251 |
252 |
253 | com.google.guava
254 | guava
255 | ${version.guava}
256 |
257 |
258 | org.rhq.metrics
259 | clients-common
260 | ${rhq-metric.clients-common.version}
261 |
262 |
263 | org.wildfly
264 | wildfly-controller
265 | ${wildfly.version}
266 |
267 |
268 | org.wildfly
269 | wildfly-controller-client
270 | ${wildfly.version}
271 |
272 |
273 | org.wildfly
274 | wildfly-server
275 |
276 |
277 | org.influxdb
278 | influxdb-java
279 | 1.2
280 |
281 |
282 | org.apache.httpcomponents
283 | httpclient
284 | 4.2.1
285 | provided
286 |
287 |
288 | org.wildfly
289 | wildfly-subsystem-test
290 | pom
291 | test
292 |
293 |
294 | io.dropwizard.metrics
295 | metrics-core
296 | ${codehale.version}
297 |
298 |
299 | junit
300 | junit
301 | test
302 |
303 |
304 | org.jboss.logging
305 | jboss-logging-annotations
306 |
308 | provided
309 | true
310 |
311 |
312 | org.jboss.logging
313 | jboss-logging-processor
314 |
316 | provided
317 | true
318 |
319 |
320 |
321 |
322 |
323 |
324 | jboss-public-repository-group
325 | JBoss Public Maven Repository Group
326 | https://repository.jboss.org/nexus/content/groups/public/
327 | default
328 |
329 | never
330 |
331 |
332 | never
333 |
334 |
335 |
336 |
337 |
338 |
339 | clojars
340 | clojars
341 | https://clojars.org/repo
342 |
343 |
344 |
345 |
346 |
347 |
348 | jboss-snapshots-repository
349 | JBoss Snapshots Repository
350 | https://repository.jboss.org/nexus/content/repositories/snapshots/
351 |
352 |
353 |
354 | jboss-releases-repository
355 | JBoss Releases Repository
356 | https://repository.jboss.org/nexus/service/local/staging/deploy/maven2/
357 |
358 |
359 |
360 | local-site-tmp
361 | RHQ-metrics
362 | file:///tmp/rhq-metrics-site
363 |
364 |
365 |
366 |
367 |
368 |
369 | Apache License, Version 2.0
370 | http://www.apache.org/licenses/LICENSE-2.0.txt
371 | repo
372 |
373 |
374 |
375 |
376 |
--------------------------------------------------------------------------------
/src/main/assembly/module-assembly.xml:
--------------------------------------------------------------------------------
1 |
17 |
18 |
21 | module
22 |
23 | zip
24 |
25 | false
26 |
27 |
28 | ${project.basedir}/target/
29 | modules/system/layers/base/org/rhq/metrics/wildfly-monitor/main
30 |
31 | wildfly-monitor.jar
32 |
33 |
34 |
35 | ${project.basedir}/src/main/resources/module/main
36 | modules/system/layers/base/org/rhq/metrics/wildfly-monitor/main
37 |
38 | module.xml
39 |
40 |
41 |
42 | ${project.basedir}/src/main/resources/config
43 | standalone/configuration/
44 |
45 | standalone-monitor.xml
46 |
47 |
48 |
49 | ${project.basedir}/src/main/resources/config
50 | domain/configuration/
51 |
52 | monitor-domain.xml
53 | monitor-host.xml
54 |
55 |
56 |
57 |
58 |
59 | true
60 | true
61 | modules/system/layers/base/org/rhq/metrics/wildfly-monitor/main
62 |
63 | io.dropwizard.metrics:metrics-core
64 | com.google.guava:guava
65 | org.influxdb:influxdb-java
66 | com.squareup.retrofit
67 | com.google.code.gson
68 | com.google.guava:guava
69 | com.squareup.okhttp:okhttp
70 | com.squareup.okio:okio
71 | com.squareup.okhttp:okhttp-urlconnection
72 | org.apache.httpcomponents:httpclient
73 | org.apache.httpcomponents:httpcore
74 | commons-logging:commons-logging
75 | commons-codec:commons-codec
76 | org.rhq.metrics:clients-common
77 |
78 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/src/main/java/org/rhq/wfly/monitor/extension/DiagnosticsAdd.java:
--------------------------------------------------------------------------------
1 | package org.rhq.wfly.monitor.extension;
2 |
3 | import org.jboss.as.controller.AbstractAddStepHandler;
4 | import org.jboss.as.controller.AttributeDefinition;
5 | import org.jboss.as.controller.OperationContext;
6 | import org.jboss.as.controller.OperationFailedException;
7 | import org.jboss.as.controller.PathAddress;
8 | import org.jboss.as.controller.ServiceVerificationHandler;
9 | import org.jboss.as.controller.registry.Resource;
10 | import org.jboss.dmr.ModelNode;
11 | import org.jboss.msc.service.ServiceController;
12 |
13 | import java.util.List;
14 |
15 | import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR;
16 |
17 | /**
18 | * Add a metric to the system
19 | * @author Heiko W. Rupp
20 | */
21 | public class DiagnosticsAdd extends AbstractAddStepHandler {
22 |
23 | public static final DiagnosticsAdd INSTANCE = new DiagnosticsAdd();
24 |
25 | private DiagnosticsAdd() {
26 |
27 | }
28 |
29 | @Override
30 | protected void populateModel(ModelNode operation, ModelNode model) throws OperationFailedException {
31 | for (AttributeDefinition def : DiagnosticsDefinition.ATTRIBUTES) {
32 | def.validateAndSet(operation, model);
33 | }
34 | }
35 |
36 | @Override
37 | protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model,
38 | ServiceVerificationHandler verificationHandler,
39 | List> newControllers) throws OperationFailedException {
40 |
41 | final PathAddress address = PathAddress.pathAddress(operation.get(OP_ADDR));
42 | ModelNode fullTree = Resource.Tools.readModel(context.readResource(PathAddress.EMPTY_ADDRESS));
43 |
44 |
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/org/rhq/wfly/monitor/extension/DiagnosticsDefinition.java:
--------------------------------------------------------------------------------
1 | package org.rhq.wfly.monitor.extension;
2 |
3 | import java.util.Arrays;
4 | import java.util.Collection;
5 |
6 | import org.jboss.as.controller.AttributeDefinition;
7 | import org.jboss.as.controller.PathElement;
8 | import org.jboss.as.controller.PersistentResourceDefinition;
9 | import org.jboss.as.controller.SimpleAttributeDefinition;
10 | import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
11 | import org.jboss.as.controller.registry.ManagementResourceRegistration;
12 | import org.jboss.dmr.ModelType;
13 |
14 | /**
15 | * Definition of a diagnostics handler
16 | * @author Heiko W. Rupp
17 | */
18 | public class DiagnosticsDefinition extends PersistentResourceDefinition {
19 |
20 | public static final DiagnosticsDefinition INSTANCE = new DiagnosticsDefinition();
21 |
22 | public static final String DIAGNOSTICS = "diagnostics";
23 |
24 | static final SimpleAttributeDefinition ENABLED = new SimpleAttributeDefinitionBuilder("enabled", ModelType.BOOLEAN,false)
25 | .build();
26 |
27 | static final SimpleAttributeDefinition SECONDS = new SimpleAttributeDefinitionBuilder("seconds", ModelType.INT,true)
28 | .build();
29 |
30 | static final SimpleAttributeDefinition MINUTES = new SimpleAttributeDefinitionBuilder("minutes", ModelType.INT,true)
31 | .build();
32 |
33 | static AttributeDefinition[] ATTRIBUTES = {
34 | ENABLED, SECONDS, MINUTES
35 | };
36 |
37 | private DiagnosticsDefinition() {
38 | super(PathElement.pathElement(DIAGNOSTICS),
39 | SubsystemExtension.getResourceDescriptionResolver(DIAGNOSTICS),
40 | DiagnosticsAdd.INSTANCE,
41 | DiagnosticsRemove.INSTANCE
42 | );
43 | }
44 |
45 | @Override
46 | public void registerAttributes(ManagementResourceRegistration resourceRegistration) {
47 | DiagnosticsWriteAttributeHandler handler = new DiagnosticsWriteAttributeHandler(ATTRIBUTES);
48 |
49 | for (AttributeDefinition attr : ATTRIBUTES) {
50 | resourceRegistration.registerReadWriteAttribute(attr, null, handler);
51 | }
52 |
53 | }
54 |
55 | @Override
56 | public Collection getAttributes() {
57 | return Arrays.asList(ATTRIBUTES);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/org/rhq/wfly/monitor/extension/DiagnosticsRemove.java:
--------------------------------------------------------------------------------
1 | package org.rhq.wfly.monitor.extension;
2 |
3 | import org.jboss.as.controller.AbstractRemoveStepHandler;
4 | import org.jboss.as.controller.OperationContext;
5 | import org.jboss.as.controller.OperationFailedException;
6 | import org.jboss.as.controller.PathAddress;
7 | import org.jboss.dmr.ModelNode;
8 |
9 | import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR;
10 |
11 | /**
12 | * StepHandler for removing a metric
13 | * @author Heiko W. Rupp
14 | */
15 | public class DiagnosticsRemove extends AbstractRemoveStepHandler {
16 |
17 | public static final DiagnosticsRemove INSTANCE = new DiagnosticsRemove();
18 |
19 | private DiagnosticsRemove() {
20 |
21 | }
22 |
23 | @Override
24 | protected void performRuntime(OperationContext context, ModelNode operation,
25 | ModelNode model) throws OperationFailedException {
26 | final PathAddress address = PathAddress.pathAddress(operation.get(OP_ADDR));
27 |
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/org/rhq/wfly/monitor/extension/DiagnosticsWriteAttributeHandler.java:
--------------------------------------------------------------------------------
1 | package org.rhq.wfly.monitor.extension;
2 |
3 | import org.jboss.as.controller.AttributeDefinition;
4 | import org.jboss.as.controller.OperationContext;
5 | import org.jboss.as.controller.OperationFailedException;
6 | import org.jboss.as.controller.PathAddress;
7 | import org.jboss.as.controller.RestartParentWriteAttributeHandler;
8 | import org.jboss.as.controller.ServiceVerificationHandler;
9 | import org.jboss.dmr.ModelNode;
10 | import org.jboss.msc.service.ServiceName;
11 | import org.rhq.wfly.monitor.service.RhqMetricsService;
12 |
13 | /**
14 | * Handler that restarts the service on attribute changes
15 | * @author Heiko W. Rupp
16 | */
17 | public class DiagnosticsWriteAttributeHandler extends RestartParentWriteAttributeHandler {
18 |
19 | public DiagnosticsWriteAttributeHandler(AttributeDefinition... definitions) {
20 | super(DiagnosticsDefinition.DIAGNOSTICS, definitions);
21 | }
22 |
23 | @Override
24 | protected void recreateParentService(OperationContext context, PathAddress parentAddress, ModelNode parentModel,
25 | ServiceVerificationHandler verificationHandler) throws OperationFailedException {
26 |
27 | }
28 |
29 | @Override
30 | protected ServiceName getParentServiceName(PathAddress parentAddress) {
31 | return RhqMetricsService.SERVICE_NAME.append(parentAddress.getLastElement().getValue());
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/org/rhq/wfly/monitor/extension/InputAdd.java:
--------------------------------------------------------------------------------
1 | package org.rhq.wfly.monitor.extension;
2 |
3 | import org.jboss.as.controller.AbstractAddStepHandler;
4 | import org.jboss.as.controller.AttributeDefinition;
5 | import org.jboss.as.controller.OperationContext;
6 | import org.jboss.as.controller.OperationFailedException;
7 | import org.jboss.as.controller.ServiceVerificationHandler;
8 | import org.jboss.dmr.ModelNode;
9 | import org.jboss.msc.service.ServiceController;
10 |
11 | import java.util.List;
12 |
13 | /**
14 | * Add a metric to the system
15 | * @author Heiko W. Rupp
16 | */
17 | public class InputAdd extends AbstractAddStepHandler {
18 |
19 | public static final InputAdd INSTANCE = new InputAdd();
20 |
21 | private InputAdd() {
22 |
23 | }
24 |
25 | @Override
26 | protected void populateModel(ModelNode operation, ModelNode model) throws OperationFailedException {
27 | for (AttributeDefinition def : InputDefinition.ATTRIBUTES) {
28 | def.validateAndSet(operation, model);
29 | }
30 | }
31 |
32 | @Override
33 | protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model,
34 | ServiceVerificationHandler verificationHandler,
35 | List> newControllers) throws OperationFailedException {
36 |
37 |
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/org/rhq/wfly/monitor/extension/InputDefinition.java:
--------------------------------------------------------------------------------
1 | package org.rhq.wfly.monitor.extension;
2 |
3 | import java.util.Arrays;
4 | import java.util.Collection;
5 |
6 | import org.jboss.as.controller.AttributeDefinition;
7 | import org.jboss.as.controller.PathElement;
8 | import org.jboss.as.controller.PersistentResourceDefinition;
9 | import org.jboss.as.controller.SimpleAttributeDefinition;
10 | import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
11 | import org.jboss.as.controller.registry.ManagementResourceRegistration;
12 | import org.jboss.dmr.ModelType;
13 |
14 | /**
15 | * Definition of a single metric
16 | * @author Heiko W. Rupp
17 | */
18 | public class InputDefinition extends PersistentResourceDefinition {
19 |
20 | public static final InputDefinition INSTANCE = new InputDefinition();
21 |
22 | public static final String DATA_INPUT = "data-input";
23 |
24 | static final SimpleAttributeDefinition RESOURCE = new SimpleAttributeDefinitionBuilder("resource", ModelType.STRING,false)
25 | .build();
26 |
27 | static final SimpleAttributeDefinition ATTRIBUTE = new SimpleAttributeDefinitionBuilder("attribute", ModelType.STRING,false)
28 | .build();
29 |
30 | static final SimpleAttributeDefinition SECONDS = new SimpleAttributeDefinitionBuilder("seconds", ModelType.INT,true)
31 | .build();
32 |
33 | static final SimpleAttributeDefinition MINUTES = new SimpleAttributeDefinitionBuilder("minutes", ModelType.INT,true)
34 | .build();
35 |
36 | static final SimpleAttributeDefinition HOURS = new SimpleAttributeDefinitionBuilder("hours", ModelType.INT,true)
37 | .build();
38 |
39 | static AttributeDefinition[] ATTRIBUTES = {
40 | RESOURCE,
41 | ATTRIBUTE,
42 | SECONDS,
43 | MINUTES,
44 | HOURS
45 | };
46 |
47 | private InputDefinition() {
48 | super(PathElement.pathElement(DATA_INPUT),
49 | SubsystemExtension.getResourceDescriptionResolver(MonitorDefinition.MONITOR, DATA_INPUT),
50 | InputAdd.INSTANCE,
51 | InputRemove.INSTANCE
52 | );
53 | }
54 |
55 | @Override
56 | public void registerAttributes(ManagementResourceRegistration resourceRegistration) {
57 | InputWriteAttributeHandler handler = new InputWriteAttributeHandler(ATTRIBUTES);
58 |
59 | for (AttributeDefinition attr : ATTRIBUTES) {
60 | resourceRegistration.registerReadWriteAttribute(attr, null, handler);
61 | }
62 |
63 | }
64 |
65 | @Override
66 | public Collection getAttributes() {
67 | return Arrays.asList(ATTRIBUTES);
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/main/java/org/rhq/wfly/monitor/extension/InputRemove.java:
--------------------------------------------------------------------------------
1 | package org.rhq.wfly.monitor.extension;
2 |
3 | import org.jboss.as.controller.AbstractRemoveStepHandler;
4 | import org.jboss.as.controller.OperationContext;
5 | import org.jboss.as.controller.OperationFailedException;
6 | import org.jboss.as.controller.PathAddress;
7 | import org.jboss.dmr.ModelNode;
8 |
9 | import org.rhq.wfly.monitor.service.RhqMetricsService;
10 |
11 | import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR;
12 |
13 | /**
14 | * StepHandler for removing a metric
15 | * @author Heiko W. Rupp
16 | */
17 | public class InputRemove extends AbstractRemoveStepHandler {
18 |
19 | public static final InputRemove INSTANCE = new InputRemove();
20 |
21 | private InputRemove() {
22 |
23 | }
24 |
25 | @Override
26 | protected void performRuntime(OperationContext context, ModelNode operation,
27 | ModelNode model) throws OperationFailedException {
28 | final PathAddress address = PathAddress.pathAddress(operation.get(OP_ADDR));
29 |
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/org/rhq/wfly/monitor/extension/InputWriteAttributeHandler.java:
--------------------------------------------------------------------------------
1 | package org.rhq.wfly.monitor.extension;
2 |
3 | import org.jboss.as.controller.AttributeDefinition;
4 | import org.jboss.as.controller.OperationContext;
5 | import org.jboss.as.controller.OperationFailedException;
6 | import org.jboss.as.controller.PathAddress;
7 | import org.jboss.as.controller.RestartParentWriteAttributeHandler;
8 | import org.jboss.as.controller.ServiceVerificationHandler;
9 | import org.jboss.dmr.ModelNode;
10 | import org.jboss.msc.service.ServiceName;
11 | import org.rhq.wfly.monitor.service.RhqMetricsService;
12 |
13 | /**
14 | * Handler that restarts the service on attribute changes
15 | * @author Heiko W. Rupp
16 | */
17 | public class InputWriteAttributeHandler extends RestartParentWriteAttributeHandler {
18 |
19 | public InputWriteAttributeHandler(AttributeDefinition... definitions) {
20 | super(InputDefinition.DATA_INPUT, definitions);
21 | }
22 |
23 | @Override
24 | protected void recreateParentService(
25 | OperationContext context, PathAddress parentAddress, ModelNode parentModel,
26 | ServiceVerificationHandler verificationHandler) throws OperationFailedException {
27 |
28 | }
29 |
30 | @Override
31 | protected ServiceName getParentServiceName(PathAddress parentAddress) {
32 | return RhqMetricsService.SERVICE_NAME.append(parentAddress.getLastElement().getValue());
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/org/rhq/wfly/monitor/extension/MonitorAdd.java:
--------------------------------------------------------------------------------
1 | package org.rhq.wfly.monitor.extension;
2 |
3 | import org.jboss.as.controller.AbstractAddStepHandler;
4 | import org.jboss.as.controller.AttributeDefinition;
5 | import org.jboss.as.controller.OperationContext;
6 | import org.jboss.as.controller.OperationFailedException;
7 | import org.jboss.as.controller.PathAddress;
8 | import org.jboss.as.controller.ServiceVerificationHandler;
9 | import org.jboss.as.controller.registry.Resource;
10 | import org.jboss.dmr.ModelNode;
11 | import org.jboss.msc.service.ServiceController;
12 |
13 | import java.util.List;
14 |
15 | import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR;
16 |
17 | /**
18 | * Adds a monitor to the system
19 | * @author Heiko Braun
20 | */
21 | public class MonitorAdd extends AbstractAddStepHandler {
22 |
23 | public static final MonitorAdd INSTANCE = new MonitorAdd();
24 |
25 | private MonitorAdd() {
26 |
27 | }
28 |
29 | @Override
30 | protected void populateModel(ModelNode operation, ModelNode model) throws OperationFailedException {
31 | for (AttributeDefinition def : MonitorDefinition.ATTRIBUTES) {
32 | def.validateAndSet(operation, model);
33 | }
34 | }
35 |
36 | @Override
37 | protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model,
38 | ServiceVerificationHandler verificationHandler,
39 | List> newControllers) throws OperationFailedException {
40 |
41 | final PathAddress address = PathAddress.pathAddress(operation.get(OP_ADDR));
42 | ModelNode fullTree = Resource.Tools.readModel(context.readResource(PathAddress.EMPTY_ADDRESS));
43 |
44 |
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/org/rhq/wfly/monitor/extension/MonitorDefinition.java:
--------------------------------------------------------------------------------
1 | package org.rhq.wfly.monitor.extension;
2 |
3 | import java.util.Arrays;
4 | import java.util.Collection;
5 | import java.util.List;
6 |
7 | import org.jboss.as.controller.AttributeDefinition;
8 | import org.jboss.as.controller.PathElement;
9 | import org.jboss.as.controller.PersistentResourceDefinition;
10 | import org.jboss.as.controller.SimpleAttributeDefinition;
11 | import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
12 | import org.jboss.as.controller.registry.ManagementResourceRegistration;
13 | import org.jboss.dmr.ModelType;
14 |
15 | /**
16 | * Definition of a monitor
17 | * @author Heiko Braun
18 | */
19 | public class MonitorDefinition extends PersistentResourceDefinition {
20 |
21 | public static final MonitorDefinition INSTANCE = new MonitorDefinition();
22 |
23 | public static final String MONITOR = "server-monitor";
24 |
25 | static final SimpleAttributeDefinition ENABLED = new SimpleAttributeDefinitionBuilder("enabled", ModelType.BOOLEAN,false)
26 | .build();
27 |
28 | static final SimpleAttributeDefinition THREADS = new SimpleAttributeDefinitionBuilder("num-threads", ModelType.INT,false)
29 | .build();
30 |
31 |
32 | static AttributeDefinition[] ATTRIBUTES = {
33 | ENABLED, THREADS
34 | };
35 |
36 | private MonitorDefinition() {
37 | super(PathElement.pathElement(MONITOR),
38 | SubsystemExtension.getResourceDescriptionResolver(MONITOR),
39 | MonitorAdd.INSTANCE,
40 | MonitorRemove.INSTANCE
41 | );
42 | }
43 |
44 | @Override
45 | protected List extends PersistentResourceDefinition> getChildren() {
46 | return Arrays.asList(InputDefinition.INSTANCE);
47 | }
48 |
49 | @Override
50 | public void registerAttributes(ManagementResourceRegistration resourceRegistration) {
51 | MonitorWriteAttributeHandler handler = new MonitorWriteAttributeHandler(ATTRIBUTES);
52 |
53 | for (AttributeDefinition attr : ATTRIBUTES) {
54 | resourceRegistration.registerReadWriteAttribute(attr, null, handler);
55 | }
56 |
57 | }
58 |
59 | @Override
60 | public Collection getAttributes() {
61 | return Arrays.asList(ATTRIBUTES);
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/main/java/org/rhq/wfly/monitor/extension/MonitorLogger.java:
--------------------------------------------------------------------------------
1 | package org.rhq.wfly.monitor.extension;
2 |
3 | /**
4 | * @author Heiko Braun
5 | * @since 05/11/14
6 | */
7 |
8 | import org.jboss.logging.BasicLogger;
9 | import org.jboss.logging.Logger;
10 | import org.jboss.logging.MessageLogger;
11 |
12 | /**
13 | * Log messages for WildFly cassandra module
14 | * @author Heiko Braun
15 | */
16 | @MessageLogger(projectCode = "<>")
17 | public interface MonitorLogger extends BasicLogger {
18 | /**
19 | * A logger with the category {@code org.rhq.wfly.monitor}.
20 | */
21 | MonitorLogger LOGGER = Logger.getMessageLogger(MonitorLogger.class, "org.rhq.wfly.monitor");
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/org/rhq/wfly/monitor/extension/MonitorRemove.java:
--------------------------------------------------------------------------------
1 | package org.rhq.wfly.monitor.extension;
2 |
3 | import org.jboss.as.controller.AbstractRemoveStepHandler;
4 | import org.jboss.as.controller.OperationContext;
5 | import org.jboss.as.controller.OperationFailedException;
6 | import org.jboss.as.controller.PathAddress;
7 | import org.jboss.dmr.ModelNode;
8 |
9 |
10 | import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR;
11 |
12 | /**
13 | * Removes a monitor from the system
14 | * @author Heiko Braun
15 | */
16 | public class MonitorRemove extends AbstractRemoveStepHandler {
17 |
18 | public static final MonitorRemove INSTANCE = new MonitorRemove();
19 |
20 | private MonitorRemove() {
21 |
22 | }
23 |
24 | @Override
25 | protected void performRuntime(OperationContext context, ModelNode operation,
26 | ModelNode model) throws OperationFailedException {
27 | final PathAddress address = PathAddress.pathAddress(operation.get(OP_ADDR));
28 |
29 | /*String metricName = address.getLastElement().getValue();
30 | RhqMonitorsService service = (RhqMonitorsService) context.getServiceRegistry(true).getService(RhqMonitorsService.SERVICE_NAME).getService();
31 | service.removeMonitor(metricName);*/
32 |
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/org/rhq/wfly/monitor/extension/MonitorWriteAttributeHandler.java:
--------------------------------------------------------------------------------
1 | package org.rhq.wfly.monitor.extension;
2 |
3 | import org.jboss.as.controller.AttributeDefinition;
4 | import org.jboss.as.controller.OperationContext;
5 | import org.jboss.as.controller.OperationFailedException;
6 | import org.jboss.as.controller.PathAddress;
7 | import org.jboss.as.controller.RestartParentWriteAttributeHandler;
8 | import org.jboss.as.controller.ServiceVerificationHandler;
9 | import org.jboss.dmr.ModelNode;
10 | import org.jboss.msc.service.ServiceName;
11 | import org.rhq.wfly.monitor.service.RhqMetricsService;
12 |
13 | /**
14 | * Handler that restarts the service on attribute changes
15 | * @author Heiko W. Rupp
16 | */
17 | public class MonitorWriteAttributeHandler extends RestartParentWriteAttributeHandler {
18 |
19 | public MonitorWriteAttributeHandler(AttributeDefinition... definitions) {
20 | super(MonitorDefinition.MONITOR, definitions);
21 | }
22 |
23 | @Override
24 | protected void recreateParentService(
25 | OperationContext context, PathAddress parentAddress, ModelNode parentModel,
26 | ServiceVerificationHandler verificationHandler) throws OperationFailedException {
27 |
28 | }
29 |
30 | @Override
31 | protected ServiceName getParentServiceName(PathAddress parentAddress) {
32 | return RhqMetricsService.SERVICE_NAME.append(parentAddress.getLastElement().getValue());
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/org/rhq/wfly/monitor/extension/RootDefinition.java:
--------------------------------------------------------------------------------
1 | package org.rhq.wfly.monitor.extension;
2 |
3 | import java.util.Arrays;
4 | import java.util.Collection;
5 | import java.util.Collections;
6 | import java.util.List;
7 |
8 | import org.jboss.as.controller.AttributeDefinition;
9 | import org.jboss.as.controller.PersistentResourceDefinition;
10 | import org.jboss.as.controller.ReloadRequiredRemoveStepHandler;
11 |
12 | /**
13 | * Definition of the >subsystem element with one attribute
14 | * @author Heiko W. Rupp
15 | */
16 | public class RootDefinition extends PersistentResourceDefinition {
17 |
18 | public static final RootDefinition INSTANCE = new RootDefinition();
19 |
20 |
21 | static PersistentResourceDefinition[] CHILDREN = {
22 | StorageDefinition.INSTANCE
23 | };
24 |
25 |
26 | private RootDefinition() {
27 | super(SubsystemExtension.SUBSYSTEM_PATH,
28 | SubsystemExtension.getResourceDescriptionResolver(),
29 | SubsystemAdd.INSTANCE,
30 | ReloadRequiredRemoveStepHandler.INSTANCE
31 | );
32 | }
33 |
34 |
35 |
36 | @Override
37 | public Collection getAttributes() {
38 | return Collections.emptySet();
39 | }
40 |
41 | @Override
42 | protected List extends PersistentResourceDefinition> getChildren() {
43 | return Arrays.asList(CHILDREN);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/org/rhq/wfly/monitor/extension/StorageAdd.java:
--------------------------------------------------------------------------------
1 | package org.rhq.wfly.monitor.extension;
2 |
3 | import java.util.List;
4 |
5 | import org.jboss.as.controller.AbstractAddStepHandler;
6 | import org.jboss.as.controller.AttributeDefinition;
7 | import org.jboss.as.controller.OperationContext;
8 | import org.jboss.as.controller.OperationFailedException;
9 | import org.jboss.as.controller.PathAddress;
10 | import org.jboss.as.controller.ServiceVerificationHandler;
11 | import org.jboss.as.controller.registry.Resource;
12 | import org.jboss.dmr.ModelNode;
13 | import org.jboss.msc.service.ServiceController;
14 |
15 | import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR;
16 |
17 | /**
18 | * Add a server node
19 | * @author Heiko W. Rupp
20 | */
21 | class StorageAdd extends AbstractAddStepHandler {
22 |
23 | static final StorageAdd INSTANCE = new StorageAdd();
24 |
25 | private StorageAdd() {
26 | }
27 |
28 | @Override
29 | protected void populateModel(ModelNode operation, ModelNode model) throws OperationFailedException {
30 | for (AttributeDefinition def : StorageDefinition.ATTRIBUTES) {
31 | def.validateAndSet(operation, model);
32 | }
33 |
34 | }
35 |
36 | @Override
37 | protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model,
38 | ServiceVerificationHandler verificationHandler,
39 | List> newControllers) throws OperationFailedException {
40 |
41 | final PathAddress address = PathAddress.pathAddress(operation.get(OP_ADDR));
42 | ModelNode fullTree = Resource.Tools.readModel(context.readResource(PathAddress.EMPTY_ADDRESS));
43 |
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/org/rhq/wfly/monitor/extension/StorageDefinition.java:
--------------------------------------------------------------------------------
1 | package org.rhq.wfly.monitor.extension;
2 |
3 | import java.util.Arrays;
4 | import java.util.Collection;
5 |
6 | import org.jboss.as.controller.AttributeDefinition;
7 | import org.jboss.as.controller.PathElement;
8 | import org.jboss.as.controller.PersistentResourceDefinition;
9 | import org.jboss.as.controller.SimpleAttributeDefinition;
10 | import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
11 | import org.jboss.as.controller.registry.AttributeAccess;
12 | import org.jboss.as.controller.registry.ManagementResourceRegistration;
13 | import org.jboss.dmr.ModelType;
14 |
15 | /**
16 | * storage adapter configuration.
17 | *
18 | * @author Heiko W. Rupp
19 | */
20 | public class StorageDefinition extends PersistentResourceDefinition {
21 |
22 | public static final StorageDefinition INSTANCE = new StorageDefinition();
23 |
24 | public static final String STORAGE_ADAPTER = "storage-adapter";
25 |
26 | private StorageDefinition() {
27 | super(PathElement.pathElement(STORAGE_ADAPTER),
28 | SubsystemExtension.getResourceDescriptionResolver(STORAGE_ADAPTER),
29 | StorageAdd.INSTANCE,
30 | StorageRemove.INSTANCE
31 | );
32 |
33 | }
34 |
35 | static final SimpleAttributeDefinition URL = new SimpleAttributeDefinitionBuilder("url", ModelType.STRING,false)
36 | .addFlag(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
37 | .setAllowExpression(true)
38 | .build();
39 |
40 | static final SimpleAttributeDefinition USER = new SimpleAttributeDefinitionBuilder("user", ModelType.STRING,true)
41 | .addFlag(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
42 | .setAllowExpression(true)
43 | .build();
44 |
45 | static final SimpleAttributeDefinition PASSWORD = new SimpleAttributeDefinitionBuilder("password", ModelType.STRING,true)
46 | .addFlag(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
47 | .setAllowExpression(true)
48 | .build();
49 |
50 | static final SimpleAttributeDefinition TOKEN = new SimpleAttributeDefinitionBuilder("token", ModelType.STRING,true)
51 | .addFlag(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
52 | .build();
53 |
54 | static final SimpleAttributeDefinition DB = new SimpleAttributeDefinitionBuilder("db", ModelType.STRING,true)
55 | .addFlag(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
56 | .build();
57 |
58 |
59 | static final AttributeDefinition[] ATTRIBUTES = {
60 | URL,
61 | USER, PASSWORD,
62 | TOKEN, DB
63 | };
64 |
65 | @Override
66 | public void registerAttributes(ManagementResourceRegistration resourceRegistration) {
67 |
68 | StorageWriteAttributeHandler handler = new StorageWriteAttributeHandler(ATTRIBUTES);
69 |
70 | for (AttributeDefinition attr : ATTRIBUTES) {
71 | resourceRegistration.registerReadWriteAttribute(attr, null, handler);
72 | }
73 | }
74 |
75 | @Override
76 | public Collection getAttributes() {
77 | return Arrays.asList(ATTRIBUTES);
78 | }
79 |
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/src/main/java/org/rhq/wfly/monitor/extension/StorageRemove.java:
--------------------------------------------------------------------------------
1 | package org.rhq.wfly.monitor.extension;
2 |
3 | import org.jboss.as.controller.AbstractRemoveStepHandler;
4 | import org.jboss.as.controller.OperationContext;
5 | import org.jboss.as.controller.OperationFailedException;
6 | import org.jboss.dmr.ModelNode;
7 |
8 | import org.rhq.wfly.monitor.service.RhqMetricsService;
9 |
10 | /**
11 | * Handler responsible for removing the subsystem resource from the model
12 | *
13 | * @author Kabir Khan
14 | */
15 | class StorageRemove extends AbstractRemoveStepHandler {
16 |
17 | static final StorageRemove INSTANCE = new StorageRemove();
18 |
19 |
20 | private StorageRemove() {
21 | }
22 |
23 | @Override
24 | protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException {
25 | //Remove any services installed by the corresponding add handler here
26 | context.removeService(RhqMetricsService.SERVICE_NAME);
27 | }
28 |
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/org/rhq/wfly/monitor/extension/StorageWriteAttributeHandler.java:
--------------------------------------------------------------------------------
1 | package org.rhq.wfly.monitor.extension;
2 |
3 | import org.jboss.as.controller.AttributeDefinition;
4 | import org.jboss.as.controller.OperationContext;
5 | import org.jboss.as.controller.OperationFailedException;
6 | import org.jboss.as.controller.PathAddress;
7 | import org.jboss.as.controller.RestartParentWriteAttributeHandler;
8 | import org.jboss.as.controller.ServiceVerificationHandler;
9 | import org.jboss.dmr.ModelNode;
10 | import org.jboss.msc.service.ServiceName;
11 | import org.rhq.wfly.monitor.service.RhqMetricsService;
12 |
13 | /**
14 | * Handler that restarts the service on attribute changes
15 | * @author Heiko W. Rupp
16 | */
17 | public class StorageWriteAttributeHandler extends RestartParentWriteAttributeHandler {
18 |
19 | public StorageWriteAttributeHandler(AttributeDefinition... definitions) {
20 | super(StorageDefinition.STORAGE_ADAPTER, definitions);
21 | }
22 |
23 | @Override
24 | protected void recreateParentService(OperationContext context, PathAddress parentAddress, ModelNode parentModel,
25 | ServiceVerificationHandler verificationHandler) throws OperationFailedException {
26 |
27 | }
28 |
29 | @Override
30 | protected ServiceName getParentServiceName(PathAddress parentAddress) {
31 | return RhqMetricsService.SERVICE_NAME.append(parentAddress.getLastElement().getValue());
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/org/rhq/wfly/monitor/extension/SubsystemAdd.java:
--------------------------------------------------------------------------------
1 | package org.rhq.wfly.monitor.extension;
2 |
3 |
4 | import org.jboss.as.controller.AbstractAddStepHandler;
5 | import org.jboss.as.controller.OperationContext;
6 | import org.jboss.as.controller.OperationFailedException;
7 | import org.jboss.as.controller.PathAddress;
8 | import org.jboss.as.controller.ServiceVerificationHandler;
9 | import org.jboss.as.controller.registry.Resource;
10 | import org.jboss.dmr.ModelNode;
11 | import org.jboss.msc.service.ServiceController;
12 | import org.rhq.wfly.monitor.service.RhqMetricsService;
13 |
14 | import java.util.List;
15 |
16 | /**
17 | * Handler responsible for adding the subsystem resource to the model.
18 | * In fact there is nothing to do here.
19 | *
20 | * Created by the archetype.
21 | * @author Kabir Khan
22 | */
23 | class SubsystemAdd extends AbstractAddStepHandler {
24 |
25 | static final SubsystemAdd INSTANCE = new SubsystemAdd();
26 |
27 | private SubsystemAdd() {
28 | }
29 |
30 | /**
31 | * {@inheritDoc}
32 | */
33 | @Override
34 | protected void populateModel(ModelNode operation, ModelNode model) throws OperationFailedException {
35 | model.setEmptyObject();
36 | }
37 |
38 |
39 | @Override
40 | protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model, ServiceVerificationHandler verificationHandler, List> newControllers) throws OperationFailedException {
41 |
42 | ModelNode subsystemConfig = Resource.Tools.readModel(context.readResource(PathAddress.EMPTY_ADDRESS));
43 |
44 | // TODO: the root resource doesn't inlcude the runtime paramters, hence we cannot depict the host/server name & launch-type from it.
45 | //ModelNode systemConfig = Resource.Tools.readModel(context.readResourceFromRoot(PathAddress.EMPTY_ADDRESS, false));
46 |
47 | // Add the service
48 | newControllers.add(
49 | RhqMetricsService.createService(
50 | context.getServiceTarget(),
51 | verificationHandler,
52 | subsystemConfig
53 | )
54 | );
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/java/org/rhq/wfly/monitor/extension/SubsystemDefinition.java:
--------------------------------------------------------------------------------
1 | package org.rhq.wfly.monitor.extension;
2 |
3 | import java.util.Arrays;
4 | import java.util.Collection;
5 | import java.util.Collections;
6 | import java.util.List;
7 |
8 | import org.jboss.as.controller.AttributeDefinition;
9 | import org.jboss.as.controller.PersistentResourceDefinition;
10 | import org.jboss.as.controller.ReloadRequiredRemoveStepHandler;
11 | import org.jboss.as.controller.registry.ManagementResourceRegistration;
12 |
13 | /**
14 | * @author Heiko W. Rupp
15 | */
16 | public class SubsystemDefinition extends PersistentResourceDefinition {
17 |
18 | public static final SubsystemDefinition INSTANCE = new SubsystemDefinition();
19 |
20 | private SubsystemDefinition() {
21 | super(SubsystemExtension.SUBSYSTEM_PATH,
22 | SubsystemExtension.getResourceDescriptionResolver(),
23 | //We always need to add an 'add' operation
24 | SubsystemAdd.INSTANCE,
25 | //Every resource that is added, normally needs a remove operation
26 | ReloadRequiredRemoveStepHandler.INSTANCE);
27 | }
28 |
29 | @Override
30 | protected List extends PersistentResourceDefinition> getChildren() {
31 | return Arrays.asList(StorageDefinition.INSTANCE, MonitorDefinition.INSTANCE, DiagnosticsDefinition.INSTANCE);
32 | }
33 |
34 | @Override
35 | public void registerOperations(ManagementResourceRegistration resourceRegistration) {
36 | super.registerOperations(resourceRegistration);
37 | //you can register additional operations here
38 | }
39 |
40 | @Override
41 | public void registerAttributes(ManagementResourceRegistration resourceRegistration) {
42 | //you can register attributes here
43 | }
44 |
45 | @Override
46 | public Collection getAttributes() {
47 | return Collections.emptyList();
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/org/rhq/wfly/monitor/extension/SubsystemExtension.java:
--------------------------------------------------------------------------------
1 | package org.rhq.wfly.monitor.extension;
2 |
3 | import org.jboss.as.controller.Extension;
4 | import org.jboss.as.controller.ExtensionContext;
5 | import org.jboss.as.controller.PathElement;
6 | import org.jboss.as.controller.SubsystemRegistration;
7 | import org.jboss.as.controller.descriptions.StandardResourceDescriptionResolver;
8 | import org.jboss.as.controller.operations.common.GenericSubsystemDescribeHandler;
9 | import org.jboss.as.controller.parsing.ExtensionParsingContext;
10 | import org.jboss.as.controller.registry.ManagementResourceRegistration;
11 |
12 | import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SUBSYSTEM;
13 |
14 |
15 | /**
16 | * @author Kabir Khan
17 | */
18 | public class SubsystemExtension implements Extension {
19 |
20 | /**
21 | * The name space used for the {@code subsystem} element
22 | */
23 | public static final String NAMESPACE = "urn:org.rhq.metrics:wildfly-monitor:1.0";
24 |
25 | /**
26 | * The name of our subsystem within the model.
27 | */
28 | public static final String SUBSYSTEM_NAME = "wildfly-monitor";
29 |
30 | /**
31 | * The parser used for parsing our subsystem.
32 | * See below
33 | */
34 |
35 | protected static final PathElement SUBSYSTEM_PATH = PathElement.pathElement(SUBSYSTEM, SUBSYSTEM_NAME);
36 | private static final String RESOURCE_NAME = SubsystemExtension.class.getPackage().getName() + ".LocalDescriptions";
37 |
38 | static StandardResourceDescriptionResolver getResourceDescriptionResolver(final String... keyPrefix) {
39 | StringBuilder prefix = new StringBuilder(SUBSYSTEM_NAME);
40 | if (keyPrefix!=null) {
41 | for (String kp : keyPrefix) {
42 | prefix.append('.').append(kp);
43 | }
44 | }
45 | return new StandardResourceDescriptionResolver(prefix.toString(), RESOURCE_NAME, SubsystemExtension.class.getClassLoader(), true, false);
46 | }
47 |
48 | @Override
49 | public void initializeParsers(ExtensionParsingContext context) {
50 | context.setSubsystemXmlMapping(SUBSYSTEM_NAME, NAMESPACE, SubsystemParser.INSTANCE);
51 | }
52 |
53 |
54 | @Override
55 | public void initialize(ExtensionContext context) {
56 | final SubsystemRegistration subsystem = context.registerSubsystem(SUBSYSTEM_NAME, 1, 0);
57 | final ManagementResourceRegistration registration = subsystem.registerSubsystemModel(SubsystemDefinition.INSTANCE);
58 | registration.registerOperationHandler(GenericSubsystemDescribeHandler.DEFINITION,
59 | GenericSubsystemDescribeHandler.INSTANCE);
60 |
61 | subsystem.registerXMLElementWriter(SubsystemParser.INSTANCE);
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/src/main/java/org/rhq/wfly/monitor/extension/SubsystemParser.java:
--------------------------------------------------------------------------------
1 | package org.rhq.wfly.monitor.extension;
2 |
3 | import java.util.List;
4 |
5 | import javax.xml.stream.XMLStreamConstants;
6 | import javax.xml.stream.XMLStreamException;
7 |
8 | import org.jboss.as.controller.PathAddress;
9 | import org.jboss.as.controller.PersistentResourceXMLDescription;
10 | import org.jboss.as.controller.persistence.SubsystemMarshallingContext;
11 | import org.jboss.dmr.ModelNode;
12 | import org.jboss.staxmapper.XMLElementReader;
13 | import org.jboss.staxmapper.XMLElementWriter;
14 | import org.jboss.staxmapper.XMLExtendedStreamReader;
15 | import org.jboss.staxmapper.XMLExtendedStreamWriter;
16 |
17 | import static org.jboss.as.controller.PersistentResourceXMLDescription.builder;
18 |
19 | /**
20 | * The subsystem parser, which uses stax to read and write to and from xml
21 | *
22 | * @author Heiko W. Rupp
23 | */
24 | class SubsystemParser
25 | implements XMLStreamConstants, XMLElementReader>, XMLElementWriter {
26 |
27 | public static final SubsystemParser INSTANCE = new SubsystemParser();
28 |
29 | private final static PersistentResourceXMLDescription xmlDescription;
30 |
31 | static {
32 | xmlDescription = builder(RootDefinition.INSTANCE)
33 | .addChild(
34 | builder(StorageDefinition.INSTANCE)
35 | .addAttributes(StorageDefinition.ATTRIBUTES)
36 | )
37 | .addChild(
38 |
39 | builder(MonitorDefinition.INSTANCE)
40 | .setXmlElementName(MonitorDefinition.MONITOR)
41 | .addAttributes(MonitorDefinition.ATTRIBUTES)
42 | .addChild(
43 | builder(InputDefinition.INSTANCE)
44 | .setXmlElementName(InputDefinition.DATA_INPUT)
45 | .addAttributes(InputDefinition.ATTRIBUTES)
46 | )
47 | )
48 | .addChild(
49 | builder(DiagnosticsDefinition.INSTANCE)
50 | .addAttributes(DiagnosticsDefinition.ATTRIBUTES)
51 | )
52 | .build();
53 |
54 | }
55 |
56 |
57 | private SubsystemParser() {
58 |
59 | }
60 |
61 | /**
62 | * {@inheritDoc}
63 | */
64 | @Override
65 | public void writeContent(XMLExtendedStreamWriter writer, SubsystemMarshallingContext context) throws XMLStreamException {
66 |
67 | ModelNode model = new ModelNode();
68 | model.get(RootDefinition.INSTANCE.getPathElement().getKeyValuePair()).set(context.getModelNode());//this is bit of workaround for SPRD to work properly
69 | xmlDescription.persist(writer, model, SubsystemExtension.NAMESPACE);
70 | }
71 |
72 | /**
73 | * {@inheritDoc}
74 | */
75 | @Override
76 | public void readElement(XMLExtendedStreamReader reader, List list) throws XMLStreamException {
77 | xmlDescription.parse(reader, PathAddress.EMPTY_ADDRESS, list);
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/src/main/java/org/rhq/wfly/monitor/extension/SubsystemRemove.java:
--------------------------------------------------------------------------------
1 | package org.rhq.wfly.monitor.extension;
2 |
3 | import org.jboss.as.controller.AbstractRemoveStepHandler;
4 | import org.jboss.as.controller.OperationContext;
5 | import org.jboss.as.controller.OperationFailedException;
6 | import org.jboss.dmr.ModelNode;
7 |
8 | /**
9 | * Handler responsible for removing the subsystem resource from the model
10 | *
11 | * @author Kabir Khan
12 | */
13 | class SubsystemRemove extends AbstractRemoveStepHandler {
14 |
15 | static final SubsystemRemove INSTANCE = new SubsystemRemove();
16 |
17 |
18 | private SubsystemRemove() {
19 | }
20 |
21 | @Override
22 | protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException {
23 | //Remove any services installed by the corresponding add handler here
24 | //context.removeService(ServiceName.of("some", "name"));
25 | }
26 |
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/org/rhq/wfly/monitor/service/RhqMetricsService.java:
--------------------------------------------------------------------------------
1 | package org.rhq.wfly.monitor.service;
2 |
3 | import org.jboss.as.controller.ControlledProcessState;
4 | import org.jboss.as.controller.ControlledProcessStateService;
5 | import org.jboss.as.controller.ModelController;
6 | import org.jboss.as.controller.PathAddress;
7 | import org.jboss.as.controller.ServiceVerificationHandler;
8 | import org.jboss.as.controller.client.ModelControllerClient;
9 | import org.jboss.as.server.ServerEnvironment;
10 | import org.jboss.as.server.ServerEnvironmentService;
11 | import org.jboss.as.server.Services;
12 | import org.jboss.dmr.ModelNode;
13 | import org.jboss.dmr.Property;
14 | import org.jboss.msc.service.Service;
15 | import org.jboss.msc.service.ServiceController;
16 | import org.jboss.msc.service.ServiceName;
17 | import org.jboss.msc.service.ServiceTarget;
18 | import org.jboss.msc.service.StartContext;
19 | import org.jboss.msc.service.StartException;
20 | import org.jboss.msc.service.StopContext;
21 | import org.jboss.msc.value.InjectedValue;
22 | import org.jboss.threads.JBossThreadFactory;
23 | import org.rhq.wfly.monitor.extension.MonitorLogger;
24 | import org.wildfly.metrics.scheduler.ModelControllerClientFactory;
25 | import org.wildfly.metrics.scheduler.config.Configuration;
26 | import org.wildfly.metrics.scheduler.config.ConfigurationInstance;
27 | import org.wildfly.metrics.scheduler.config.Interval;
28 | import org.wildfly.metrics.scheduler.config.ResourceRef;
29 | import org.wildfly.security.manager.action.GetAccessControlContextAction;
30 |
31 | import java.beans.PropertyChangeEvent;
32 | import java.beans.PropertyChangeListener;
33 | import java.io.IOException;
34 | import java.util.List;
35 | import java.util.concurrent.ExecutorService;
36 | import java.util.concurrent.Executors;
37 | import java.util.concurrent.ThreadFactory;
38 | import java.util.concurrent.TimeUnit;
39 |
40 | import static java.security.AccessController.doPrivileged;
41 | import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.*;
42 |
43 | /**
44 | * A service that gathers values from the system and sends them to a RHQ Metrics Server
45 | * @author Heiko W. Rupp
46 | */
47 | public class RhqMetricsService implements Service {
48 |
49 | private static final String LAUNCH_TYPE = "launch-type";
50 | private static final String DOMAIN = "domain";
51 | private static final String HOST = "host";
52 | private static final String NAME = "name";
53 | private static final String RESULT = "result";
54 |
55 | private Interval diagnosticsInterval;
56 | private boolean diagnosticsEnabled = false;
57 | private boolean enabled = false;
58 |
59 | private ConfigurationInstance schedulerConfig;
60 | private org.wildfly.metrics.scheduler.Service schedulerService;
61 |
62 | private final InjectedValue modelControllerValue = new InjectedValue<>();
63 | private final InjectedValue serverEnvironmentValue = new InjectedValue<>();
64 | private final InjectedValue processStateValue = new InjectedValue<>();
65 |
66 | public static final ServiceName SERVICE_NAME = ServiceName.JBOSS.append("rhq", "wildfly-monitor");
67 | private PropertyChangeListener serverStateListener;
68 |
69 |
70 | public RhqMetricsService(ModelNode config) {
71 |
72 | // the actual scheduler config
73 | this.schedulerConfig = new ConfigurationInstance();
74 |
75 | Property storageAdapter = config.get("storage-adapter").asPropertyList().get(0);
76 | List monitors = config.get("server-monitor").asPropertyList();
77 | Property diagnostics = config.get("diagnostics").asPropertyList().get(0);
78 |
79 | if(monitors.size()==1)
80 | {
81 | Property monitor = monitors.get(0);
82 | ModelNode monitorCfg = monitor.getValue();
83 | if(monitorCfg.get("enabled").asBoolean())
84 | {
85 | this.enabled = true;
86 |
87 | // parse storage adapter
88 | ModelNode storageAdapterCfg = storageAdapter.getValue();
89 | schedulerConfig.setStorageAdapter(Configuration.Storage.valueOf(storageAdapter.getName().toUpperCase()));
90 | schedulerConfig.setStorageUrl(storageAdapterCfg.get("url").asString());
91 | schedulerConfig.setStorageDb(storageAdapterCfg.get("db").asString());
92 |
93 | if(storageAdapterCfg.hasDefined("user"))
94 | schedulerConfig.setStorageUser(storageAdapterCfg.get("user").asString());
95 |
96 | if(storageAdapterCfg.hasDefined("password"))
97 | schedulerConfig.setStoragePassword(storageAdapterCfg.get("password").asString());
98 |
99 | if(storageAdapterCfg.hasDefined("token"))
100 | schedulerConfig.setStorageToken(storageAdapterCfg.get("token").asString());
101 |
102 | // monitoring setup
103 | schedulerConfig.setSchedulerThreads(monitorCfg.get("num-threads").asInt());
104 |
105 | List metrics = monitorCfg.get("data-input").asPropertyList();
106 | for (Property metric : metrics) {
107 | ModelNode metricCfg = metric.getValue();
108 |
109 | Interval interval = null;
110 | if (metricCfg.hasDefined("seconds")) {
111 | interval = new Interval(metricCfg.get("seconds").asInt(), TimeUnit.SECONDS);
112 | }
113 | else if (metricCfg.hasDefined("minutes"))
114 | {
115 | interval = new Interval(metricCfg.get("minutes").asInt(), TimeUnit.MINUTES);
116 | }
117 | else if(metricCfg.hasDefined("hours"))
118 | {
119 | interval = new Interval(metricCfg.get("hours").asInt(), TimeUnit.HOURS);
120 | }
121 |
122 |
123 | ResourceRef ref = new ResourceRef(
124 | metricCfg.get("resource").asString(),
125 | metricCfg.get("attribute").asString(),
126 | interval
127 | );
128 |
129 | schedulerConfig.addResourceRef(ref);
130 |
131 | }
132 |
133 | // diagnostics
134 | ModelNode diagnosticsCfg = diagnostics.getValue();
135 | schedulerConfig.setDiagnostics(Configuration.Diagnostics.valueOf(diagnostics.getName().toUpperCase()));
136 |
137 | if(diagnosticsCfg.hasDefined("seconds"))
138 | {
139 | this.diagnosticsEnabled = diagnosticsCfg.get("enabled").asBoolean();
140 | this.diagnosticsInterval = new Interval(diagnosticsCfg.get("seconds").asInt(), TimeUnit.SECONDS);
141 | }
142 | else if(diagnosticsCfg.hasDefined("minutes"))
143 | {
144 | this.diagnosticsEnabled = diagnosticsCfg.get("enabled").asBoolean();
145 | this.diagnosticsInterval = new Interval(diagnosticsCfg.get("minutes").asInt(), TimeUnit.MINUTES);
146 | }
147 |
148 | }
149 | }
150 |
151 | }
152 |
153 | public static ServiceController createService(final ServiceTarget target,
154 | final ServiceVerificationHandler verificationHandler,
155 | ModelNode config) {
156 |
157 | RhqMetricsService service = new RhqMetricsService(config);
158 |
159 | return target.addService(SERVICE_NAME, service)
160 | .addDependency(ServerEnvironmentService.SERVICE_NAME, ServerEnvironment.class,
161 | service.serverEnvironmentValue)
162 | .addDependency(Services.JBOSS_SERVER_CONTROLLER, ModelController.class,
163 | service.modelControllerValue)
164 | .addDependency(ControlledProcessStateService.SERVICE_NAME, ControlledProcessStateService.class,
165 | service.processStateValue)
166 | .addListener(verificationHandler)
167 | .setInitialMode(ServiceController.Mode.ACTIVE)
168 | .install();
169 | }
170 |
171 |
172 | @Override
173 | public void start(final StartContext startContext) throws StartException {
174 |
175 |
176 | if (this.enabled) {
177 |
178 |
179 | // deferred startup: we have to wait until the server is running before we can monitor the subsystems (parallel service startup)
180 | ControlledProcessStateService stateService = processStateValue.getValue();
181 | serverStateListener = new PropertyChangeListener() {
182 | @Override
183 | public void propertyChange(PropertyChangeEvent evt) {
184 | if (ControlledProcessState.State.RUNNING.equals(evt.getNewValue())) {
185 |
186 | MonitorLogger.LOGGER.infof("Starting monitoring subsystem");
187 | startScheduler(startContext);
188 | }
189 | }
190 | };
191 | stateService.addPropertyChangeListener(serverStateListener);
192 |
193 | }
194 |
195 | }
196 |
197 | private void startScheduler(StartContext startContext) {
198 |
199 | final ThreadFactory threadFactory = new JBossThreadFactory(
200 | new ThreadGroup("RHQ-Metrics-threads"),
201 | Boolean.FALSE, null, "%G - %t", null, null,
202 | doPrivileged(GetAccessControlContextAction.getInstance()));
203 |
204 | final ExecutorService executorService = Executors.newCachedThreadPool(threadFactory);
205 | final ModelControllerClient client = modelControllerValue.getValue().createClient(executorService);
206 |
207 |
208 | // create scheduler service
209 | schedulerService = new org.wildfly.metrics.scheduler.Service(schedulerConfig, new ModelControllerClientFactory() {
210 | @Override
211 | public ModelControllerClient createClient() {
212 | return modelControllerValue.getValue().createClient(executorService);
213 | }
214 | });
215 |
216 | // Get the server name from the runtime model
217 | // TODO: this should be changed to OperationContext.readResourceFromRoot(...)
218 | boolean isDomainMode = getAttribute(client, LAUNCH_TYPE).equalsIgnoreCase(DOMAIN);
219 |
220 | String hostName = null;
221 | String serverName = null;
222 |
223 | if(isDomainMode)
224 | {
225 | hostName = getAttribute(client, HOST);
226 | serverName = getAttribute(client, NAME);
227 | }
228 | else
229 | {
230 | hostName = "";
231 | serverName = getAttribute(client, NAME);
232 | }
233 |
234 | // Create a http client
235 | schedulerService.start(hostName, serverName);
236 |
237 | // enabled diagnostics if needed
238 | if(diagnosticsEnabled) {
239 | schedulerService.reportEvery(diagnosticsInterval.getVal(), diagnosticsInterval.getUnit());
240 | }
241 |
242 | }
243 |
244 | @Override
245 | public void stop(StopContext stopContext) {
246 |
247 | MonitorLogger.LOGGER.infof("Stopping monitoring subsystem");
248 |
249 | // shutdown scheduler
250 | if(schedulerService!=null)
251 | schedulerService.stop();
252 |
253 | // cleanup the state listener
254 | if(serverStateListener!=null)
255 | processStateValue.getValue().removePropertyChangeListener(serverStateListener);
256 |
257 | }
258 |
259 | @Override
260 | public RhqMetricsService getValue() throws IllegalStateException, IllegalArgumentException {
261 | return this;
262 | }
263 |
264 | private String getStringAttribute(ModelControllerClient client, String attributeName, PathAddress path) {
265 | ModelNode result = getModelNode(client, attributeName, path);
266 | return result.asString();
267 | }
268 |
269 | private ModelNode getModelNode(ModelControllerClient client, String attributeName, PathAddress address){
270 | try {
271 | ModelNode request = new ModelNode();
272 |
273 | if (address !=null) {
274 |
275 | request.get(ADDRESS).set(address.toModelNode());
276 | }
277 |
278 | request.get(OP).set(READ_ATTRIBUTE_OPERATION);
279 | request.get(NAME).set(attributeName);
280 | ModelNode resultNode = client.execute(request);
281 | // get the inner "result" -- should check for failure and so on...
282 | resultNode = resultNode.get(RESULT);
283 | return resultNode;
284 | } catch (IOException e) {
285 | throw new RuntimeException(e);
286 | }
287 | }
288 |
289 | private String getAttribute(ModelControllerClient client, String attributeName) {
290 | try {
291 | ModelNode request = new ModelNode();
292 | request.get(ADDRESS).setEmptyList();
293 | request.get(OP).set(READ_ATTRIBUTE_OPERATION);
294 | request.get(NAME).set(attributeName);
295 | ModelNode resultNode = client.execute(request);
296 | // get the inner "result" -- should check for failure and so on...
297 | resultNode = resultNode.get(RESULT);
298 | return resultNode.asString();
299 | } catch (IOException e) {
300 | throw new RuntimeException(e);
301 | }
302 | }
303 |
304 | }
305 |
--------------------------------------------------------------------------------
/src/main/java/org/wildfly/metrics/scheduler/ModelControllerClientFactory.java:
--------------------------------------------------------------------------------
1 | package org.wildfly.metrics.scheduler;
2 |
3 | import org.jboss.as.controller.client.ModelControllerClient;
4 |
5 | /**
6 | * @author Heiko Braun
7 | * @since 17/10/14
8 | */
9 | public interface ModelControllerClientFactory {
10 | ModelControllerClient createClient();
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/org/wildfly/metrics/scheduler/SchedulerLogger.java:
--------------------------------------------------------------------------------
1 | package org.wildfly.metrics.scheduler;
2 |
3 | /**
4 | * @author Heiko Braun
5 | * @since 05/11/14
6 | */
7 |
8 | import org.jboss.logging.BasicLogger;
9 | import org.jboss.logging.Logger;
10 | import org.jboss.logging.MessageLogger;
11 |
12 | /**
13 | * Log messages for WildFly cassandra module
14 | * @author Heiko Braun
15 | */
16 | @MessageLogger(projectCode = "<>")
17 | public interface SchedulerLogger extends BasicLogger {
18 | /**
19 | * A logger with the category {@code org.wildfly.metrics.scheduler}.
20 | */
21 | SchedulerLogger LOGGER = Logger.getMessageLogger(SchedulerLogger.class, "org.wildfly.metrics.scheduler");
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/org/wildfly/metrics/scheduler/Service.java:
--------------------------------------------------------------------------------
1 | package org.wildfly.metrics.scheduler;
2 |
3 | import com.codahale.metrics.ConsoleReporter;
4 | import com.codahale.metrics.Counter;
5 | import com.codahale.metrics.Meter;
6 | import com.codahale.metrics.MetricRegistry;
7 | import com.codahale.metrics.ScheduledReporter;
8 | import com.codahale.metrics.Timer;
9 | import org.wildfly.metrics.scheduler.config.Address;
10 | import org.wildfly.metrics.scheduler.config.Configuration;
11 | import org.wildfly.metrics.scheduler.config.ResourceRef;
12 | import org.wildfly.metrics.scheduler.diagnose.Diagnostics;
13 | import org.wildfly.metrics.scheduler.diagnose.StorageReporter;
14 | import org.wildfly.metrics.scheduler.polling.ClientFactoryImpl;
15 | import org.wildfly.metrics.scheduler.polling.IntervalBasedScheduler;
16 | import org.wildfly.metrics.scheduler.polling.Scheduler;
17 | import org.wildfly.metrics.scheduler.polling.Task;
18 | import org.wildfly.metrics.scheduler.storage.BufferedStorageDispatcher;
19 | import org.wildfly.metrics.scheduler.storage.InfluxStorageAdapter;
20 | import org.wildfly.metrics.scheduler.storage.RHQStorageAdapter;
21 | import org.wildfly.metrics.scheduler.storage.StorageAdapter;
22 |
23 | import java.util.ArrayList;
24 | import java.util.List;
25 | import java.util.concurrent.TimeUnit;
26 |
27 | import static com.codahale.metrics.MetricRegistry.name;
28 | import static java.util.concurrent.TimeUnit.MILLISECONDS;
29 |
30 | /**
31 | * The core service that creates task lists from a {@link org.wildfly.metrics.scheduler.config.Configuration}
32 | * and schedules work through a {@link org.wildfly.metrics.scheduler.polling.Scheduler}.
33 | * The resulting data will be pushed to a {@link org.wildfly.metrics.scheduler.storage.StorageAdapter}
34 | *
35 | * @author Heiko Braun
36 | * @since 10/10/14
37 | */
38 | public class Service implements TopologyChangeListener {
39 |
40 | private final StorageAdapter storageAdapter;
41 | private Configuration configuration;
42 | private Scheduler scheduler;
43 | private Diagnostics diagnostics;
44 | private ScheduledReporter reporter;
45 | private boolean started = false;
46 | private BufferedStorageDispatcher completionHandler;
47 |
48 | /**
49 | *
50 | * @param configuration
51 | */
52 | public Service(Configuration configuration) {
53 | this(configuration, new ClientFactoryImpl(
54 | configuration.getHost(),
55 | configuration.getPort(),
56 | configuration.getUsername(),
57 | configuration.getPassword())
58 | );
59 | }
60 |
61 | /**
62 | *
63 | * @param configuration
64 | * @param clientFactory
65 | */
66 | public Service(Configuration configuration, ModelControllerClientFactory clientFactory) {
67 |
68 | this.configuration = configuration;
69 |
70 | final MetricRegistry metrics = new MetricRegistry();
71 |
72 | this.diagnostics = createDiagnostics(metrics);
73 |
74 | if(Configuration.Storage.RHQ == configuration.getStorageAdapter())
75 | {
76 | this.storageAdapter = new RHQStorageAdapter();
77 | }
78 | else
79 | {
80 | this.storageAdapter = new InfluxStorageAdapter();
81 | }
82 |
83 | this.storageAdapter.setConfiguration(configuration);
84 | this.storageAdapter.setDiagnostics(diagnostics);
85 |
86 | if(Configuration.Diagnostics.CONSOLE == configuration.getDiagnostics()) {
87 |
88 | this.reporter = ConsoleReporter.forRegistry(metrics)
89 | .convertRatesTo(TimeUnit.SECONDS)
90 | .convertDurationsTo(MILLISECONDS)
91 | .build();
92 | }
93 | else
94 | {
95 | this.reporter = StorageReporter.forRegistry(metrics, storageAdapter)
96 | .convertRatesTo(TimeUnit.SECONDS)
97 | .convertDurationsTo(MILLISECONDS)
98 | .build();
99 | }
100 |
101 | this.completionHandler = new BufferedStorageDispatcher(storageAdapter, diagnostics);
102 |
103 | this.scheduler = new IntervalBasedScheduler(
104 | clientFactory,
105 | diagnostics,
106 | configuration.getSchedulerThreads()
107 | );
108 | }
109 |
110 | private Diagnostics createDiagnostics(final MetricRegistry metrics) {
111 | return new Diagnostics() {
112 |
113 | private final Timer requestTimer = metrics.timer(name("dmr-request-timer"));
114 | private final Meter delayCounter = metrics.meter(name("task-delay-rate"));
115 | private final Meter taskErrorCounter = metrics.meter(name("task-error-rate"));
116 | private final Meter storageError = metrics.meter(name("storage-error-rate"));
117 | private final Counter storageBuffer = metrics.counter(name("storage-buffer-size"));
118 |
119 | @Override
120 | public Timer getRequestTimer() {
121 | return requestTimer;
122 | }
123 |
124 | @Override
125 | public Meter getDelayedRate() {
126 | return delayCounter;
127 | }
128 |
129 | @Override
130 | public Meter getErrorRate() {
131 | return taskErrorCounter;
132 | }
133 |
134 | @Override
135 | public Meter getStorageErrorRate() {
136 | return storageError;
137 | }
138 |
139 | @Override
140 | public Counter getStorageBufferSize() {
141 | return storageBuffer;
142 | }
143 | };
144 | }
145 |
146 | public void start(String host, String server) {
147 |
148 | // turn ResourceRef into Tasks (relative to absolute addresses ...)
149 | List tasks = createTasks(host, server, configuration.getResourceRefs());
150 | this.completionHandler.start();
151 | this.scheduler.schedule(tasks, completionHandler);
152 | }
153 |
154 | private List createTasks(String host, String server, List resourceRefs) {
155 | List tasks = new ArrayList<>();
156 | for (ResourceRef ref : resourceRefs) {
157 |
158 | // parse sub references (complex attribute support)
159 | String attribute = ref.getAttribute();
160 | String subref = null;
161 | int i = attribute.indexOf("#");
162 | if(i>0) {
163 | subref = attribute.substring(i+1, attribute.length());
164 | attribute = attribute.substring(0, i);
165 | }
166 |
167 | tasks.add(new Task(host, server, Address.apply(ref.getAddress()), attribute, subref, ref.getInterval()));
168 | }
169 | return tasks;
170 | }
171 |
172 | public void stop() {
173 | this.completionHandler.shutdown();
174 | this.scheduler.shutdown();
175 | this.reporter.stop();
176 | this.reporter.report();
177 | }
178 |
179 | @Override
180 | public void onChange() {
181 | // shutdown scheduler
182 | // recalculate tasks
183 | // restart scheduler
184 | }
185 |
186 | public void reportEvery(int period, TimeUnit unit) {
187 | if(!started)
188 | reporter.start(period, unit);
189 | }
190 |
191 |
192 |
193 |
194 |
195 | }
196 |
--------------------------------------------------------------------------------
/src/main/java/org/wildfly/metrics/scheduler/TopologyChangeListener.java:
--------------------------------------------------------------------------------
1 | package org.wildfly.metrics.scheduler;
2 |
3 | /**
4 | * The service rebuilds the task list when the topology of a domain changes.
5 | *
6 | * @author Heiko Braun
7 | * @since 10/10/14
8 | */
9 | public interface TopologyChangeListener {
10 | void onChange();
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/org/wildfly/metrics/scheduler/config/Address.java:
--------------------------------------------------------------------------------
1 | /*
2 | * JBoss, Home of Professional Open Source.
3 | * Copyright 2010, Red Hat, Inc., and individual contributors
4 | * as indicated by the @author tags. See the copyright.txt file in the
5 | * distribution for a full listing of individual contributors.
6 | *
7 | * This is free software; you can redistribute it and/or modify it
8 | * under the terms of the GNU Lesser General Public License as
9 | * published by the Free Software Foundation; either version 2.1 of
10 | * the License, or (at your option) any later version.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * Lesser General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public
18 | * License along with this software; if not, write to the Free
19 | * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 | * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 | */
22 | package org.wildfly.metrics.scheduler.config;
23 |
24 | import com.google.common.base.CharMatcher;
25 | import com.google.common.base.Joiner;
26 | import com.google.common.base.Splitter;
27 | import com.google.common.collect.Iterators;
28 |
29 | import java.util.ArrayList;
30 | import java.util.Collections;
31 | import java.util.Iterator;
32 | import java.util.List;
33 |
34 | /**
35 | * @author Harald Pehl
36 | */
37 | public class Address implements Iterable {
38 |
39 | public static Address apply(String address) {
40 | List tokens = address == null ? Collections.emptyList() :
41 | Splitter.on(CharMatcher.anyOf("/="))
42 | .trimResults()
43 | .omitEmptyStrings()
44 | .splitToList(address);
45 |
46 | List tuples = new ArrayList<>(tokens.size() / 2 + 1);
47 | for (Iterator iterator = tokens.iterator(); iterator.hasNext(); ) {
48 | String type = iterator.next();
49 | String name = iterator.hasNext() ? iterator.next() : "";
50 | tuples.add(new Tuple(type, name));
51 | }
52 |
53 | return new Address(tuples);
54 | }
55 |
56 |
57 | private final List tuples;
58 |
59 | private Address(final List tuples) {
60 | this.tuples = new ArrayList<>();
61 | if (tuples != null) {
62 | this.tuples.addAll(tuples);
63 | }
64 | }
65 |
66 | @Override
67 | public boolean equals(final Object o) {
68 | if (this == o) { return true; }
69 | if (!(o instanceof Address)) { return false; }
70 |
71 | Address address = (Address) o;
72 |
73 | if (!tuples.equals(address.tuples)) { return false; }
74 |
75 | return true;
76 | }
77 |
78 | @Override
79 | public int hashCode() {
80 | return tuples.hashCode();
81 | }
82 |
83 | @Override
84 | public String toString() {
85 | return Joiner.on('/').join(tuples);
86 | }
87 |
88 | @Override
89 | public Iterator iterator() {
90 | return Iterators.unmodifiableIterator(tuples.iterator());
91 | }
92 |
93 | public boolean isEmpty() {return tuples.isEmpty();}
94 |
95 | public boolean isBalanced() {
96 | for (Tuple tuple : this) {
97 | if (tuple.getValue() == null || tuple.getValue().length() == 0) {
98 | return false;
99 | }
100 | }
101 | return true;
102 | }
103 |
104 | public boolean startsWith(Tuple tuple) {
105 | return !tuples.isEmpty() && tuples.get(0).equals(tuple);
106 | }
107 |
108 |
109 | /**
110 | * @author Harald Pehl
111 | */
112 | public static class Tuple {
113 |
114 | public static Tuple apply(String tuple) {
115 | if (tuple == null) {
116 | throw new IllegalArgumentException("Tuple must not be null");
117 | }
118 | List tuples = Splitter.on('=')
119 | .omitEmptyStrings()
120 | .trimResults()
121 | .splitToList(tuple);
122 | if (tuples.isEmpty() || tuples.size() != 2) {
123 | throw new IllegalArgumentException("Malformed tuple: " + tuple);
124 | }
125 | return new Tuple(tuples.get(0), tuples.get(1));
126 | }
127 |
128 | private final String key;
129 | private final String value;
130 |
131 | private Tuple(final String key, final String value) {
132 | this.key = key;
133 | this.value = value;
134 | }
135 |
136 | @Override
137 | public boolean equals(final Object o) {
138 | if (this == o) { return true; }
139 | if (!(o instanceof Tuple)) { return false; }
140 |
141 | Tuple that = (Tuple) o;
142 |
143 | if (!value.equals(that.value)) { return false; }
144 | if (!key.equals(that.key)) { return false; }
145 |
146 | return true;
147 | }
148 |
149 | @Override
150 | public int hashCode() {
151 | int result = key.hashCode();
152 | result = 31 * result + value.hashCode();
153 | return result;
154 | }
155 |
156 | @Override
157 | public String toString() {
158 | return key + "=" + value;
159 | }
160 |
161 | public String getKey() {
162 | return key;
163 | }
164 |
165 | public String getValue() {
166 | return value;
167 | }
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/src/main/java/org/wildfly/metrics/scheduler/config/ConfigLoader.java:
--------------------------------------------------------------------------------
1 | package org.wildfly.metrics.scheduler.config;
2 |
3 | /**
4 | * @author Heiko Braun
5 | * @since 10/10/14
6 | */
7 | public interface ConfigLoader {
8 | Configuration load();
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/java/org/wildfly/metrics/scheduler/config/Configuration.java:
--------------------------------------------------------------------------------
1 | package org.wildfly.metrics.scheduler.config;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * @author Heiko Braun
7 | * @since 13/10/14
8 | */
9 | public interface Configuration {
10 |
11 | public enum Diagnostics {STORAGE, CONSOLE};
12 | public enum Storage {RHQ, INFLUX}
13 |
14 | /**
15 | * The host controller host.
16 | * @return
17 | */
18 | String getHost();
19 |
20 | /**
21 | * The host controller port.
22 | *
23 | * @return
24 | */
25 | int getPort();
26 |
27 | /**
28 | * Host controller user
29 | * @return
30 | */
31 | String getUsername();
32 |
33 | /**
34 | * Host controller password
35 | * @return
36 | */
37 | String getPassword();
38 |
39 | /**
40 | * Number of threads the scheduler uses to poll for new data.
41 | *
42 | * @return
43 | */
44 | int getSchedulerThreads();
45 |
46 | /**
47 | * The resources that are to be monitored.
48 | * {@link org.wildfly.metrics.scheduler.config.ResourceRef}'s use relative addresses.
49 | * The core {@link org.wildfly.metrics.scheduler.Service} will resolve it against absolute address within a Wildfly domain.
50 | *
51 | * @return
52 | */
53 | List getResourceRefs();
54 |
55 | Storage getStorageAdapter();
56 |
57 | String getStorageUrl();
58 |
59 | String getStorageUser();
60 |
61 | String getStoragePassword();
62 |
63 | String getStorageDBName();
64 |
65 | String getStorageToken();
66 |
67 | Diagnostics getDiagnostics();
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/src/main/java/org/wildfly/metrics/scheduler/config/ConfigurationInstance.java:
--------------------------------------------------------------------------------
1 | /*
2 | * JBoss, Home of Professional Open Source.
3 | * Copyright 2010, Red Hat, Inc., and individual contributors
4 | * as indicated by the @author tags. See the copyright.txt file in the
5 | * distribution for a full listing of individual contributors.
6 | *
7 | * This is free software; you can redistribute it and/or modify it
8 | * under the terms of the GNU Lesser General Public License as
9 | * published by the Free Software Foundation; either version 2.1 of
10 | * the License, or (at your option) any later version.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * Lesser General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public
18 | * License along with this software; if not, write to the Free
19 | * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 | * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 | */
22 | package org.wildfly.metrics.scheduler.config;
23 |
24 | import java.util.ArrayList;
25 | import java.util.Collections;
26 | import java.util.List;
27 |
28 | /**
29 | * A collection of {@link ResourceRef}s with a unique id.
30 | *
31 | * @author Harald Pehl
32 | */
33 | public class ConfigurationInstance implements Configuration {
34 |
35 | private final List resourceRefs;
36 | private int schedulerThreads = 2;
37 |
38 | private String host;
39 | private int port;
40 | private String user;
41 | private String password;
42 |
43 | private String storageUrl = null;
44 | private String storageUser = null;
45 | private String storagePassword = null;
46 | private String storageDb = null;
47 | private String storageToken = null;
48 | private Storage storageAdapter = Storage.INFLUX;
49 |
50 | private Diagnostics diagnostics = Diagnostics.CONSOLE;
51 |
52 | public ConfigurationInstance() {
53 | this("localhost", 9990, new ArrayList());
54 | }
55 |
56 | public ConfigurationInstance(String host, int port) {
57 | this(host, port, new ArrayList());
58 | }
59 |
60 | public ConfigurationInstance(String host, int port, final List resourceRefs) {
61 | this.host = host;
62 | this.port = port;
63 | this.resourceRefs = resourceRefs;
64 | }
65 |
66 | public List getResourceRefs() {
67 | return Collections.unmodifiableList(resourceRefs);
68 | }
69 |
70 | @Override
71 | public String getHost() {
72 | return host;
73 | }
74 |
75 | @Override
76 | public int getPort() {
77 | return port;
78 | }
79 |
80 | @Override
81 | public String getUsername() {
82 | return this.user;
83 | }
84 |
85 | @Override
86 | public String getPassword() {
87 | return this.password;
88 | }
89 |
90 | public void setUser(String user) {
91 | this.user = user;
92 | }
93 |
94 | public void setPassword(String password) {
95 | this.password = password;
96 | }
97 |
98 | public void setHost(String host) {
99 | this.host = host;
100 | }
101 |
102 | public void setPort(int port) {
103 | this.port = port;
104 | }
105 |
106 | public void setSchedulerThreads(int schedulerThreads) {
107 | this.schedulerThreads = schedulerThreads;
108 | }
109 |
110 | @Override
111 | public int getSchedulerThreads() {
112 | return schedulerThreads;
113 | }
114 |
115 | @Override
116 | public String getStorageUrl() {
117 | return this.storageUrl;
118 | }
119 |
120 | @Override
121 | public String getStorageUser() {
122 | return storageUser;
123 | }
124 |
125 | @Override
126 | public String getStoragePassword() {
127 | return storagePassword;
128 | }
129 |
130 | @Override
131 | public String getStorageDBName() {
132 | return storageDb;
133 | }
134 |
135 |
136 | @Override
137 | public Storage getStorageAdapter() {
138 | return storageAdapter;
139 | }
140 |
141 | public void setStorageAdapter(Storage storageAdapter) {
142 | this.storageAdapter = storageAdapter;
143 | }
144 |
145 | public void setStorageUrl(String storageUrl) {
146 | this.storageUrl = storageUrl;
147 | }
148 |
149 | public void setStorageUser(String storageUser) {
150 | this.storageUser = storageUser;
151 | }
152 |
153 | public void setStoragePassword(String storagePassword) {
154 | this.storagePassword = storagePassword;
155 | }
156 |
157 | public void setStorageDb(String storageDb) {
158 | this.storageDb = storageDb;
159 | }
160 |
161 | public void addResourceRef(ResourceRef ref) {
162 | resourceRefs.add(ref);
163 | }
164 |
165 | public String getStorageDb() {
166 | return storageDb;
167 | }
168 |
169 | public String getStorageToken() {
170 | return storageToken;
171 | }
172 |
173 | public void setStorageToken(String storageToken) {
174 | this.storageToken = storageToken;
175 | }
176 |
177 | public String getUser() {
178 | return user;
179 | }
180 |
181 | public Diagnostics getDiagnostics() {
182 | return diagnostics;
183 | }
184 |
185 | public void setDiagnostics(Diagnostics diagnostics) {
186 | this.diagnostics = diagnostics;
187 | }
188 | }
189 |
190 |
--------------------------------------------------------------------------------
/src/main/java/org/wildfly/metrics/scheduler/config/Interval.java:
--------------------------------------------------------------------------------
1 | /*
2 | * JBoss, Home of Professional Open Source.
3 | * Copyright 2010, Red Hat, Inc., and individual contributors
4 | * as indicated by the @author tags. See the copyright.txt file in the
5 | * distribution for a full listing of individual contributors.
6 | *
7 | * This is free software; you can redistribute it and/or modify it
8 | * under the terms of the GNU Lesser General Public License as
9 | * published by the Free Software Foundation; either version 2.1 of
10 | * the License, or (at your option) any later version.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * Lesser General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public
18 | * License along with this software; if not, write to the Free
19 | * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 | * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 | */
22 | package org.wildfly.metrics.scheduler.config;
23 |
24 | import java.util.concurrent.TimeUnit;
25 |
26 | import static java.util.concurrent.TimeUnit.*;
27 |
28 | /**
29 | * @author Harald Pehl
30 | */
31 | public class Interval{
32 |
33 | public final static Interval EACH_SECOND = new Interval(1, SECONDS);
34 | public final static Interval TWENTY_SECONDS = new Interval(20, SECONDS);
35 | public final static Interval EACH_MINUTE = new Interval(1, MINUTES);
36 | public final static Interval TWENTY_MINUTES = new Interval(20, MINUTES);
37 | public final static Interval EACH_HOUR = new Interval(1, HOURS);
38 | public final static Interval FOUR_HOURS = new Interval(4, HOURS);
39 | public final static Interval EACH_DAY = new Interval(24, HOURS);
40 |
41 | private final int val;
42 | private final TimeUnit unit;
43 |
44 | public Interval(int val, TimeUnit unit) {
45 | this.val = val;
46 | this.unit = unit;
47 | }
48 |
49 | public long millis() {
50 | return MILLISECONDS.convert(val, unit);
51 | }
52 |
53 | public int getVal() {
54 | return val;
55 | }
56 |
57 | public TimeUnit getUnit() {
58 | return unit;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/org/wildfly/metrics/scheduler/config/ResourceRef.java:
--------------------------------------------------------------------------------
1 | /*
2 | * JBoss, Home of Professional Open Source.
3 | * Copyright 2010, Red Hat, Inc., and individual contributors
4 | * as indicated by the @author tags. See the copyright.txt file in the
5 | * distribution for a full listing of individual contributors.
6 | *
7 | * This is free software; you can redistribute it and/or modify it
8 | * under the terms of the GNU Lesser General Public License as
9 | * published by the Free Software Foundation; either version 2.1 of
10 | * the License, or (at your option) any later version.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * Lesser General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public
18 | * License along with this software; if not, write to the Free
19 | * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 | * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 | */
22 | package org.wildfly.metrics.scheduler.config;
23 |
24 | /**
25 | * A resource reference that is to be monitored.
26 | *
27 | * @author Harald Pehl
28 | */
29 | public class ResourceRef {
30 |
31 | private final String address;
32 | private final String attribute;
33 | private final Interval interval;
34 |
35 | public ResourceRef(final String address, final String attribute, final Interval interval) {
36 | this.address = address;
37 | this.attribute = attribute;
38 | this.interval = interval;
39 | }
40 |
41 | @Override
42 | public String toString() {
43 | return "Task(" + address + ":" + attribute + ", " + interval + ")";
44 | }
45 |
46 | public String getAddress() {
47 | return address;
48 | }
49 |
50 | public String getAttribute() {
51 | return attribute;
52 | }
53 |
54 | public Interval getInterval() {
55 | return interval;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/org/wildfly/metrics/scheduler/diagnose/Diagnostics.java:
--------------------------------------------------------------------------------
1 | package org.wildfly.metrics.scheduler.diagnose;
2 |
3 | import com.codahale.metrics.Counter;
4 | import com.codahale.metrics.Meter;
5 | import com.codahale.metrics.Timer;
6 |
7 | /**
8 | * @author Heiko Braun
9 | * @since 13/10/14
10 | */
11 | public interface Diagnostics {
12 | Timer getRequestTimer();
13 | Meter getErrorRate();
14 | Meter getDelayedRate();
15 |
16 | Meter getStorageErrorRate();
17 | Counter getStorageBufferSize();
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/org/wildfly/metrics/scheduler/diagnose/StorageReporter.java:
--------------------------------------------------------------------------------
1 | package org.wildfly.metrics.scheduler.diagnose;
2 |
3 | import com.codahale.metrics.Clock;
4 | import com.codahale.metrics.Counter;
5 | import com.codahale.metrics.Gauge;
6 | import com.codahale.metrics.Histogram;
7 | import com.codahale.metrics.Meter;
8 | import com.codahale.metrics.MetricFilter;
9 | import com.codahale.metrics.MetricRegistry;
10 | import com.codahale.metrics.ScheduledReporter;
11 | import com.codahale.metrics.Timer;
12 | import org.wildfly.metrics.scheduler.config.Address;
13 | import org.wildfly.metrics.scheduler.config.Interval;
14 | import org.wildfly.metrics.scheduler.polling.Task;
15 | import org.wildfly.metrics.scheduler.storage.DataPoint;
16 | import org.wildfly.metrics.scheduler.storage.StorageAdapter;
17 |
18 | import java.io.PrintStream;
19 | import java.text.DateFormat;
20 | import java.util.HashSet;
21 | import java.util.Locale;
22 | import java.util.Map;
23 | import java.util.Set;
24 | import java.util.SortedMap;
25 | import java.util.TimeZone;
26 | import java.util.concurrent.TimeUnit;
27 |
28 | /**
29 | * @author Heiko Braun
30 | * @since 14/10/14
31 | */
32 | public class StorageReporter extends ScheduledReporter {
33 |
34 | private static StorageAdapter storageAdapter;
35 | private final Locale locale;
36 | private final Clock clock;
37 | private final DateFormat dateFormat;
38 |
39 | private StorageReporter(MetricRegistry registry,
40 | Locale locale,
41 | Clock clock,
42 | TimeZone timeZone,
43 | TimeUnit rateUnit,
44 | TimeUnit durationUnit,
45 | MetricFilter filter, StorageAdapter storageAdapter) {
46 | super(registry, "storage-reporter", filter, rateUnit, durationUnit);
47 | this.locale = locale;
48 | this.clock = clock;
49 | this.storageAdapter = storageAdapter;
50 | this.dateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT,
51 | DateFormat.MEDIUM,
52 | locale);
53 | dateFormat.setTimeZone(timeZone);
54 | }
55 |
56 |
57 | @Override
58 | public void report(
59 | SortedMap gauges,
60 | SortedMap counters,
61 | SortedMap histograms,
62 | SortedMap meters,
63 | SortedMap timers) {
64 |
65 | if (!gauges.isEmpty()) {
66 |
67 | Set samples = new HashSet<>(gauges.size());
68 | for (Map.Entry entry : gauges.entrySet()) {
69 | Gauge gauge = entry.getValue();
70 |
71 | samples.add(
72 | new DataPoint(
73 | new Task("foo", "bar", Address.apply("service=metric-scheduler"), entry.getKey(), null, Interval.EACH_SECOND),
74 | gauge.getValue()
75 | )
76 | );
77 | }
78 | storageAdapter.store(samples);
79 | }
80 |
81 | if (!counters.isEmpty()) {
82 |
83 | Set samples = new HashSet<>(counters.size());
84 | for (Map.Entry entry : counters.entrySet()) {
85 | samples.add(
86 | new DataPoint(
87 | new Task("foo", "bar", Address.apply("service=metric-scheduler"), entry.getKey(), null, Interval.EACH_SECOND),
88 | entry.getValue().getCount()
89 | )
90 | );
91 | }
92 |
93 | storageAdapter.store(samples);
94 |
95 | }
96 |
97 | /*if (!histograms.isEmpty()) {
98 |
99 | Set samples = new HashSet<>(histograms.size());
100 | for (Map.Entry entry : histograms.entrySet()) {
101 | Histogram hist = entry.getValue();
102 | samples.add(
103 | new Sample(
104 | new Task(Address.apply("service=metric-scheduler"), entry.getKey(), null, Interval.EACH_SECOND),
105 | 0 // TODO
106 | )
107 | );
108 | }
109 | storageAdapter.store(samples);
110 | }*/
111 |
112 | if (!meters.isEmpty()) {
113 |
114 | Set samples = new HashSet<>(meters.size());
115 | for (Map.Entry entry : meters.entrySet()) {
116 | Meter meter = entry.getValue();
117 | samples.add(
118 | new DataPoint(
119 | new Task("foo", "bar", Address.apply("service=metric-scheduler"), entry.getKey(), null, Interval.EACH_SECOND),
120 | meter.getOneMinuteRate()
121 | )
122 | );
123 | }
124 | storageAdapter.store(samples);
125 | }
126 |
127 | if (!timers.isEmpty()) {
128 |
129 | Set samples = new HashSet<>(timers.size());
130 |
131 | for (Map.Entry entry : timers.entrySet()) {
132 | Timer timer = entry.getValue();
133 |
134 | samples.add(
135 | new DataPoint(
136 | new Task("foo", "bar", Address.apply("service=metric-scheduler"), entry.getKey(), null, Interval.EACH_SECOND),
137 | timer.getSnapshot().get75thPercentile()
138 | )
139 | );
140 | }
141 |
142 | storageAdapter.store(samples);
143 | }
144 |
145 | }
146 |
147 | public static Builder forRegistry(MetricRegistry registry, StorageAdapter storageAdapter) {
148 | return new Builder(registry, storageAdapter);
149 | }
150 |
151 | public static class Builder {
152 | private final MetricRegistry registry;
153 | private final StorageAdapter storageAdapter;
154 | private PrintStream output;
155 | private Locale locale;
156 | private Clock clock;
157 | private TimeZone timeZone;
158 | private TimeUnit rateUnit;
159 | private TimeUnit durationUnit;
160 | private MetricFilter filter;
161 |
162 | private Builder(MetricRegistry registry, StorageAdapter storageAdapter) {
163 | this.registry = registry;
164 | this.storageAdapter = storageAdapter;
165 | this.locale = Locale.getDefault();
166 | this.clock = Clock.defaultClock();
167 | this.timeZone = TimeZone.getDefault();
168 | this.rateUnit = TimeUnit.SECONDS;
169 | this.durationUnit = TimeUnit.MILLISECONDS;
170 | this.filter = MetricFilter.ALL;
171 | }
172 |
173 | /**
174 | * Write to the given {@link PrintStream}.
175 | *
176 | * @param output a {@link PrintStream} instance.
177 | * @return {@code this}
178 | */
179 | public Builder outputTo(PrintStream output) {
180 | this.output = output;
181 | return this;
182 | }
183 |
184 | /**
185 | * Format numbers for the given {@link Locale}.
186 | *
187 | * @param locale a {@link Locale}
188 | * @return {@code this}
189 | */
190 | public Builder formattedFor(Locale locale) {
191 | this.locale = locale;
192 | return this;
193 | }
194 |
195 | /**
196 | * Use the given {@link Clock} instance for the time.
197 | *
198 | * @param clock a {@link Clock} instance
199 | * @return {@code this}
200 | */
201 | public Builder withClock(Clock clock) {
202 | this.clock = clock;
203 | return this;
204 | }
205 |
206 | /**
207 | * Use the given {@link TimeZone} for the time.
208 | *
209 | * @param timeZone a {@link TimeZone}
210 | * @return {@code this}
211 | */
212 | public Builder formattedFor(TimeZone timeZone) {
213 | this.timeZone = timeZone;
214 | return this;
215 | }
216 |
217 | /**
218 | * Convert rates to the given time unit.
219 | *
220 | * @param rateUnit a unit of time
221 | * @return {@code this}
222 | */
223 | public Builder convertRatesTo(TimeUnit rateUnit) {
224 | this.rateUnit = rateUnit;
225 | return this;
226 | }
227 |
228 | /**
229 | * Convert durations to the given time unit.
230 | *
231 | * @param durationUnit a unit of time
232 | * @return {@code this}
233 | */
234 | public Builder convertDurationsTo(TimeUnit durationUnit) {
235 | this.durationUnit = durationUnit;
236 | return this;
237 | }
238 |
239 | /**
240 | * Only report metrics which match the given filter.
241 | *
242 | * @param filter a {@link MetricFilter}
243 | * @return {@code this}
244 | */
245 | public Builder filter(MetricFilter filter) {
246 | this.filter = filter;
247 | return this;
248 | }
249 |
250 | public StorageReporter build() {
251 | return new StorageReporter(registry,
252 | locale,
253 | clock,
254 | timeZone,
255 | rateUnit,
256 | durationUnit,
257 | filter, storageAdapter
258 | );
259 | }
260 | }
261 |
262 | }
263 |
--------------------------------------------------------------------------------
/src/main/java/org/wildfly/metrics/scheduler/polling/AbstractScheduler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * JBoss, Home of Professional Open Source.
3 | * Copyright 2010, Red Hat, Inc., and individual contributors
4 | * as indicated by the @author tags. See the copyright.txt file in the
5 | * distribution for a full listing of individual contributors.
6 | *
7 | * This is free software; you can redistribute it and/or modify it
8 | * under the terms of the GNU Lesser General Public License as
9 | * published by the Free Software Foundation; either version 2.1 of
10 | * the License, or (at your option) any later version.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * Lesser General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public
18 | * License along with this software; if not, write to the Free
19 | * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 | * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 | */
22 | package org.wildfly.metrics.scheduler.polling;
23 |
24 | /**
25 | * @author Harald Pehl
26 | */
27 | public abstract class AbstractScheduler implements Scheduler {
28 |
29 | private State state = State.STOPPED;
30 |
31 | protected void pushState(State state) {
32 | this.state = state;
33 | }
34 |
35 | protected void verifyState(State state) throws IllegalStateException {
36 | if (this.state != state) {
37 | throw new IllegalStateException("Expected state " + state + ", but got " + this.state);
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/org/wildfly/metrics/scheduler/polling/ClientFactoryImpl.java:
--------------------------------------------------------------------------------
1 | package org.wildfly.metrics.scheduler.polling;
2 |
3 | import org.jboss.as.controller.client.ModelControllerClient;
4 | import org.wildfly.metrics.scheduler.ModelControllerClientFactory;
5 |
6 | import javax.security.auth.callback.Callback;
7 | import javax.security.auth.callback.CallbackHandler;
8 | import javax.security.auth.callback.NameCallback;
9 | import javax.security.auth.callback.PasswordCallback;
10 | import javax.security.auth.callback.UnsupportedCallbackException;
11 | import javax.security.sasl.RealmCallback;
12 | import java.io.IOException;
13 | import java.net.InetAddress;
14 | import java.net.UnknownHostException;
15 |
16 | /**
17 | * @author Heiko Braun
18 | * @since 17/10/14
19 | */
20 | public class ClientFactoryImpl implements ModelControllerClientFactory {
21 |
22 | private String host;
23 | private int port;
24 | private String username;
25 | private String password;
26 |
27 | public ClientFactoryImpl(String host, int port, String username, String password) {
28 | this.host = host;
29 | this.port = port;
30 | this.username = username;
31 | this.password = password;
32 | }
33 |
34 | @Override
35 | public ModelControllerClient createClient() {
36 |
37 | final CallbackHandler callbackHandler = new CallbackHandler() {
38 |
39 | public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
40 | for (Callback current : callbacks) {
41 | if (current instanceof NameCallback) {
42 | NameCallback ncb = (NameCallback) current;
43 | ncb.setName(username);
44 | } else if (current instanceof PasswordCallback) {
45 | PasswordCallback pcb = (PasswordCallback) current;
46 | pcb.setPassword(password.toCharArray());
47 | } else if (current instanceof RealmCallback) {
48 | RealmCallback rcb = (RealmCallback) current;
49 | rcb.setText(rcb.getDefaultText());
50 | } else {
51 | throw new UnsupportedCallbackException(current);
52 | }
53 | }
54 | }
55 | };
56 |
57 | try {
58 | return ModelControllerClient.Factory.create(InetAddress.getByName(host), port, callbackHandler);
59 | } catch (UnknownHostException e) {
60 | throw new RuntimeException("Failed ot create controller client", e);
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/main/java/org/wildfly/metrics/scheduler/polling/IntervalBasedScheduler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * JBoss, Home of Professional Open Source.
3 | * Copyright 2010, Red Hat, Inc., and individual contributors
4 | * as indicated by the @author tags. See the copyright.txt file in the
5 | * distribution for a full listing of individual contributors.
6 | *
7 | * This is free software; you can redistribute it and/or modify it
8 | * under the terms of the GNU Lesser General Public License as
9 | * published by the Free Software Foundation; either version 2.1 of
10 | * the License, or (at your option) any later version.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * Lesser General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public
18 | * License along with this software; if not, write to the Free
19 | * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 | * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 | */
22 | package org.wildfly.metrics.scheduler.polling;
23 |
24 | import com.codahale.metrics.Timer;
25 | import org.jboss.as.controller.client.ModelControllerClient;
26 | import org.jboss.dmr.ModelNode;
27 | import org.jboss.dmr.Property;
28 | import org.rhq.wfly.monitor.extension.MonitorLogger;
29 | import org.wildfly.metrics.scheduler.ModelControllerClientFactory;
30 | import org.wildfly.metrics.scheduler.SchedulerLogger;
31 | import org.wildfly.metrics.scheduler.diagnose.Diagnostics;
32 | import org.wildfly.metrics.scheduler.storage.DataPoint;
33 |
34 | import java.io.IOException;
35 | import java.util.LinkedList;
36 | import java.util.List;
37 | import java.util.concurrent.ConcurrentLinkedQueue;
38 | import java.util.concurrent.Executors;
39 | import java.util.concurrent.ScheduledExecutorService;
40 | import java.util.concurrent.ScheduledFuture;
41 | import java.util.concurrent.ThreadFactory;
42 | import java.util.concurrent.TimeUnit;
43 |
44 | import static java.util.concurrent.TimeUnit.MILLISECONDS;
45 | import static org.wildfly.metrics.scheduler.polling.Scheduler.State.RUNNING;
46 | import static org.wildfly.metrics.scheduler.polling.Scheduler.State.STOPPED;
47 |
48 | /**
49 | * @author Harald Pehl
50 | * @author Heiko Braun
51 | */
52 | public class IntervalBasedScheduler extends AbstractScheduler {
53 |
54 | private final ScheduledExecutorService executorService;
55 | private final List jobs;
56 | private final int poolSize;
57 |
58 | private final ModelControllerClientFactory clientFactory;
59 | private final Diagnostics monitor;
60 |
61 | private ConcurrentLinkedQueue connectionPool = new ConcurrentLinkedQueue<>();
62 |
63 | public IntervalBasedScheduler(ModelControllerClientFactory clientFactory, Diagnostics monitor, final int poolSize) {
64 | this.clientFactory = clientFactory;
65 | this.monitor = monitor;
66 | this.poolSize = poolSize;
67 |
68 | this.executorService = Executors.newScheduledThreadPool(poolSize, new ThreadFactory() {
69 | @Override
70 | public Thread newThread(Runnable r) {
71 | SchedulerLogger.LOGGER.debug("Creating new executor thread");
72 | return new Thread(r);
73 | }
74 | });
75 |
76 | this.jobs = new LinkedList<>();
77 |
78 | }
79 |
80 | @Override
81 | public void schedule(List tasks, final CompletionHandler completionHandler) {
82 | verifyState(STOPPED);
83 |
84 | // optimize task groups
85 | List groups = new IntervalGrouping().apply(tasks);
86 |
87 | SchedulerLogger.LOGGER.infof("Number of tasks: %s", tasks.size());
88 | SchedulerLogger.LOGGER.infof("Number of task groups: %s", groups.size());
89 |
90 | // populate connection pool
91 | for (int i = 0; i < poolSize; i++) {
92 | try {
93 | connectionPool.add(
94 | clientFactory.createClient()
95 | );
96 | } catch (Throwable e) {
97 | e.printStackTrace();
98 | }
99 | }
100 |
101 | // schedule IO
102 | for (TaskGroup group : groups) {
103 | jobs.add(
104 |
105 | // schedule tasks
106 | executorService.scheduleWithFixedDelay(
107 | new IO(group, completionHandler),
108 | group.getOffsetMillis(), group.getInterval().millis(),
109 | MILLISECONDS
110 | )
111 | );
112 | }
113 |
114 | pushState(RUNNING);
115 | }
116 |
117 | @Override
118 | public void shutdown() {
119 | verifyState(RUNNING);
120 |
121 |
122 | try {
123 | for (ScheduledFuture job : jobs) {
124 | job.cancel(false);
125 | }
126 | executorService.shutdown();
127 | executorService.awaitTermination(5, TimeUnit.SECONDS);
128 |
129 | } catch (InterruptedException e) {
130 | e.printStackTrace();
131 | } finally {
132 |
133 | // cleanup pool
134 | for (ModelControllerClient client : connectionPool) {
135 | try {
136 | client.close();
137 | } catch (IOException e) {
138 | e.printStackTrace();
139 | }
140 | };
141 |
142 | pushState(STOPPED);
143 | }
144 | }
145 |
146 | private class IO implements Runnable {
147 |
148 | private static final String OUTCOME = "outcome";
149 | private static final String RESULT = "result";
150 | private static final String FAILURE_DESCRIPTION = "failure-description";
151 | private static final String SUCCESS = "success";
152 |
153 | private final TaskGroup group;
154 | private final CompletionHandler completionHandler;
155 | private final ModelNode operation;
156 |
157 | private IO(TaskGroup group, CompletionHandler completionHandler) {
158 | this.group = group;
159 | this.completionHandler = completionHandler;
160 |
161 | // for the IO lifetime the operation is immutable and can be re-used
162 | this.operation = new ReadAttributeOperationBuilder().createOperation(group);
163 | }
164 |
165 | @Override
166 | public void run() {
167 |
168 | if(connectionPool.isEmpty())
169 | throw new IllegalStateException("Connection pool expired!");
170 | final ModelControllerClient client = connectionPool.poll();
171 |
172 | try {
173 |
174 | Timer.Context requestContext = monitor.getRequestTimer().time();
175 |
176 | // execute request
177 | ModelNode response = client.execute(operation);
178 |
179 | long durationMs = requestContext.stop() / 1000000;
180 |
181 | String outcome = response.get(OUTCOME).asString();
182 | if (SUCCESS.equals(outcome))
183 | {
184 |
185 | if (durationMs > group.getInterval().millis()) {
186 | monitor.getDelayedRate().mark(1);
187 | }
188 |
189 | List steps = response.get(RESULT).asPropertyList();
190 | assert steps.size() == group.size() : "group structure doesn't match actual response structure";
191 |
192 | int i=0;
193 | for (Property step : steps) {
194 | Task task = group.getTask(i);
195 |
196 | // deconstruct model node
197 | ModelNode data = step.getValue();
198 | Double value = null;
199 | if(task.getSubref()!=null)
200 | {
201 | value = data.get(RESULT).get(task.getSubref()).asDouble();
202 | }
203 | else
204 | {
205 | value = data.get(RESULT).asDouble();
206 | }
207 |
208 | completionHandler.onCompleted(new DataPoint(task, value));
209 | i++;
210 | }
211 |
212 |
213 | } else {
214 | monitor.getErrorRate().mark(1);
215 | completionHandler.onFailed(new RuntimeException(response.get(FAILURE_DESCRIPTION).asString()));
216 | }
217 |
218 | } catch (Throwable e) {
219 | monitor.getErrorRate().mark(1);
220 | completionHandler.onFailed(e);
221 | } finally {
222 |
223 | // return to pool
224 | connectionPool.add(client);
225 |
226 | }
227 | }
228 |
229 | }
230 |
231 | }
232 |
--------------------------------------------------------------------------------
/src/main/java/org/wildfly/metrics/scheduler/polling/IntervalGrouping.java:
--------------------------------------------------------------------------------
1 | /*
2 | * JBoss, Home of Professional Open Source.
3 | * Copyright 2010, Red Hat, Inc., and individual contributors
4 | * as indicated by the @author tags. See the copyright.txt file in the
5 | * distribution for a full listing of individual contributors.
6 | *
7 | * This is free software; you can redistribute it and/or modify it
8 | * under the terms of the GNU Lesser General Public License as
9 | * published by the Free Software Foundation; either version 2.1 of
10 | * the License, or (at your option) any later version.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * Lesser General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public
18 | * License along with this software; if not, write to the Free
19 | * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 | * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 | */
22 | package org.wildfly.metrics.scheduler.polling;
23 |
24 | import org.wildfly.metrics.scheduler.config.Interval;
25 |
26 | import java.util.ArrayList;
27 | import java.util.Collections;
28 | import java.util.Comparator;
29 | import java.util.List;
30 |
31 | /**
32 | * @author Harald Pehl
33 | */
34 | public class IntervalGrouping implements TaskGrouping {
35 |
36 | @Override
37 | public List apply(final List tasks) {
38 |
39 | Collections.sort(tasks, new Comparator() {
40 | @Override
41 | public int compare(Task t1, Task t2) {
42 | return new Long(t1.getInterval().millis()).compareTo(t2.getInterval().millis());
43 | }
44 | });
45 |
46 |
47 | List groups = new ArrayList<>();
48 | Interval interval = tasks.get(0).getInterval();
49 | TaskGroup taskGroup = new TaskGroup(interval);
50 | groups.add(taskGroup);
51 |
52 | for (Task task : tasks) {
53 |
54 | if(!task.getInterval().equals(interval)) {
55 | // new group
56 | interval = task.getInterval();
57 | groups.add(new TaskGroup(task.getInterval()));
58 | }
59 |
60 | groups.get(groups.size()-1).addTask(task);
61 | }
62 |
63 | return groups;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/main/java/org/wildfly/metrics/scheduler/polling/OperationBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * JBoss, Home of Professional Open Source.
3 | * Copyright 2010, Red Hat, Inc., and individual contributors
4 | * as indicated by the @author tags. See the copyright.txt file in the
5 | * distribution for a full listing of individual contributors.
6 | *
7 | * This is free software; you can redistribute it and/or modify it
8 | * under the terms of the GNU Lesser General Public License as
9 | * published by the Free Software Foundation; either version 2.1 of
10 | * the License, or (at your option) any later version.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * Lesser General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public
18 | * License along with this software; if not, write to the Free
19 | * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 | * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 | */
22 | package org.wildfly.metrics.scheduler.polling;
23 |
24 |
25 | import org.jboss.dmr.ModelNode;
26 |
27 | /**
28 | * An interface to create operations ({@link ModelNode}'s) from {@link TaskGroup}s.
29 | *
30 | * @author Harald Pehl
31 | */
32 | public interface OperationBuilder {
33 |
34 | ModelNode createOperation(TaskGroup group);
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/org/wildfly/metrics/scheduler/polling/ReadAttributeOperationBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * JBoss, Home of Professional Open Source.
3 | * Copyright 2010, Red Hat, Inc., and individual contributors
4 | * as indicated by the @author tags. See the copyright.txt file in the
5 | * distribution for a full listing of individual contributors.
6 | *
7 | * This is free software; you can redistribute it and/or modify it
8 | * under the terms of the GNU Lesser General Public License as
9 | * published by the Free Software Foundation; either version 2.1 of
10 | * the License, or (at your option) any later version.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * Lesser General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public
18 | * License along with this software; if not, write to the Free
19 | * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 | * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 | */
22 | package org.wildfly.metrics.scheduler.polling;
23 |
24 | import org.jboss.dmr.ModelNode;
25 | import org.wildfly.metrics.scheduler.config.Address;
26 |
27 | import java.util.ArrayList;
28 | import java.util.List;
29 |
30 | /**
31 | * Creates a {@code read-attribute} operation of the given {@link TaskGroup}.
32 | *
33 | * @author Harald Pehl
34 | */
35 | public class ReadAttributeOperationBuilder implements OperationBuilder {
36 |
37 | @Override
38 | public ModelNode createOperation(final TaskGroup group) {
39 |
40 | if (group.isEmpty()) {
41 | throw new IllegalArgumentException("Empty groups are not allowed");
42 | }
43 |
44 | ModelNode comp = new ModelNode();
45 | List steps = new ArrayList<>();
46 | comp.get("address").setEmptyList();
47 | comp.get("operation").set("composite");
48 | for (Task task : group) {
49 | steps.add(readAttribute(task));
50 | }
51 | comp.get("steps").set(steps);
52 |
53 | return comp;
54 |
55 | }
56 |
57 | private ModelNode readAttribute(Task task) {
58 | ModelNode node = new ModelNode();
59 | Address address = task.getAddress();
60 | for (Address.Tuple tuple : address) {
61 | node.get("address").add(tuple.getKey(), tuple.getValue());
62 | }
63 | node.get("operation").set("read-attribute");
64 | node.get("name").set(task.getAttribute());
65 | return node;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/main/java/org/wildfly/metrics/scheduler/polling/Scheduler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * JBoss, Home of Professional Open Source.
3 | * Copyright 2010, Red Hat, Inc., and individual contributors
4 | * as indicated by the @author tags. See the copyright.txt file in the
5 | * distribution for a full listing of individual contributors.
6 | *
7 | * This is free software; you can redistribute it and/or modify it
8 | * under the terms of the GNU Lesser General Public License as
9 | * published by the Free Software Foundation; either version 2.1 of
10 | * the License, or (at your option) any later version.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * Lesser General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public
18 | * License along with this software; if not, write to the Free
19 | * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 | * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 | */
22 | package org.wildfly.metrics.scheduler.polling;
23 |
24 | import org.wildfly.metrics.scheduler.storage.DataPoint;
25 |
26 | import java.util.List;
27 |
28 | /**
29 | * Performs the actual work collecting the data from the monitored resources.
30 | * Used by the main {@link org.wildfly.metrics.scheduler.Service}
31 | *
32 | * @author Harald Pehl
33 | */
34 | public interface Scheduler {
35 |
36 | public enum State {RUNNING, STOPPED}
37 |
38 | void schedule(List operations, CompletionHandler completionHandler);
39 |
40 | void shutdown();
41 |
42 | /**
43 | * Callback for completed tasks
44 | */
45 | interface CompletionHandler {
46 | void onCompleted(DataPoint sample);
47 | void onFailed(Throwable e);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/org/wildfly/metrics/scheduler/polling/Task.java:
--------------------------------------------------------------------------------
1 | package org.wildfly.metrics.scheduler.polling;
2 |
3 | import org.wildfly.metrics.scheduler.config.Address;
4 | import org.wildfly.metrics.scheduler.config.Interval;
5 |
6 | /**
7 | * Represents a monitoring task. Represents and absolute address within a domain.
8 | *
9 | * @author Heiko Braun
10 | * @since 10/10/14
11 | */
12 | public class Task {
13 |
14 | private final String host;
15 | private final String server;
16 | private final Address address;
17 | private final String attribute;
18 | private final String subref;
19 | private final Interval interval;
20 |
21 | public Task(
22 | String host, String server,
23 | Address address,
24 | String attribute,
25 | String subref,
26 | Interval interval
27 | ) {
28 | this.host = host;
29 | this.server = server;
30 | this.address = address;
31 | this.attribute = attribute;
32 | this.subref = subref;
33 | this.interval = interval;
34 | }
35 |
36 | public Address getAddress() {
37 | return address;
38 | }
39 |
40 | public String getAttribute() {
41 | return attribute;
42 | }
43 |
44 | public Interval getInterval() {
45 | return interval;
46 | }
47 |
48 | public String getSubref() {
49 | return subref;
50 | }
51 |
52 | public String getHost() {
53 | return host;
54 | }
55 |
56 | public String getServer() {
57 | return server;
58 | }
59 |
60 | @Override
61 | public String toString() {
62 | return "Task{" +
63 | "address=" + address +
64 | ", attribute='" + attribute + '\'' +
65 | '}';
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/main/java/org/wildfly/metrics/scheduler/polling/TaskGroup.java:
--------------------------------------------------------------------------------
1 | /*
2 | * JBoss, Home of Professional Open Source.
3 | * Copyright 2010, Red Hat, Inc., and individual contributors
4 | * as indicated by the @author tags. See the copyright.txt file in the
5 | * distribution for a full listing of individual contributors.
6 | *
7 | * This is free software; you can redistribute it and/or modify it
8 | * under the terms of the GNU Lesser General Public License as
9 | * published by the Free Software Foundation; either version 2.1 of
10 | * the License, or (at your option) any later version.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * Lesser General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public
18 | * License along with this software; if not, write to the Free
19 | * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 | * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 | */
22 | package org.wildfly.metrics.scheduler.polling;
23 |
24 | import com.google.common.collect.Iterators;
25 | import org.wildfly.metrics.scheduler.config.Interval;
26 |
27 | import java.util.Collection;
28 | import java.util.Iterator;
29 | import java.util.LinkedList;
30 | import java.util.UUID;
31 |
32 | /**
33 | * @author Harald Pehl
34 | */
35 | public class TaskGroup implements Iterable {
36 |
37 | private final String id; // to uniquely reference this group
38 | private final Interval interval; // impacts thread scheduling
39 | private final long offsetMillis;
40 | private final LinkedList tasks;
41 |
42 | public TaskGroup(final Interval interval) {
43 | this.offsetMillis = 0;
44 | this.id = UUID.randomUUID().toString();
45 | this.interval = interval;
46 | this.tasks = new LinkedList<>();
47 | }
48 |
49 | public void addTask(Task task) {
50 | verifyInterval(task);
51 | tasks.add(task);
52 | }
53 |
54 | public boolean addTasks(final Collection extends Task> collection) {
55 | for (Task t: collection) {
56 | verifyInterval(t);
57 | }
58 | return tasks.addAll(collection);
59 | }
60 |
61 | private void verifyInterval(final Task task) {
62 | if (task.getInterval() != interval) {
63 | throw new IllegalArgumentException("Wrong interval: Expected " + interval + ", but got " + task.getInterval());
64 | }
65 | }
66 |
67 | public int size() {return tasks.size();}
68 |
69 | public boolean isEmpty() {return tasks.isEmpty();}
70 |
71 | @Override
72 | public Iterator iterator() {
73 | return Iterators.unmodifiableIterator(tasks.iterator());
74 | }
75 |
76 | public String getId() {
77 | return id;
78 | }
79 |
80 | public Interval getInterval() {
81 | return interval;
82 | }
83 |
84 | public long getOffsetMillis() {
85 | return offsetMillis;
86 | }
87 |
88 | public Task getTask(int i) {
89 | return tasks.get(i);
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/main/java/org/wildfly/metrics/scheduler/polling/TaskGrouping.java:
--------------------------------------------------------------------------------
1 | /*
2 | * JBoss, Home of Professional Open Source.
3 | * Copyright 2010, Red Hat, Inc., and individual contributors
4 | * as indicated by the @author tags. See the copyright.txt file in the
5 | * distribution for a full listing of individual contributors.
6 | *
7 | * This is free software; you can redistribute it and/or modify it
8 | * under the terms of the GNU Lesser General Public License as
9 | * published by the Free Software Foundation; either version 2.1 of
10 | * the License, or (at your option) any later version.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * Lesser General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public
18 | * License along with this software; if not, write to the Free
19 | * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 | * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 | */
22 | package org.wildfly.metrics.scheduler.polling;
23 |
24 | import java.util.List;
25 |
26 | /**
27 | * @author Harald Pehl
28 | */
29 | public interface TaskGrouping {
30 |
31 | List apply(List tasks);
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/org/wildfly/metrics/scheduler/storage/BufferedStorageDispatcher.java:
--------------------------------------------------------------------------------
1 | package org.wildfly.metrics.scheduler.storage;
2 |
3 | import org.wildfly.metrics.scheduler.diagnose.Diagnostics;
4 | import org.wildfly.metrics.scheduler.polling.Scheduler;
5 |
6 | import java.util.HashSet;
7 | import java.util.Set;
8 | import java.util.concurrent.ArrayBlockingQueue;
9 | import java.util.concurrent.BlockingQueue;
10 |
11 | /**
12 | * @author Heiko Braun
13 | * @since 13/10/14
14 | */
15 | public class BufferedStorageDispatcher implements Scheduler.CompletionHandler {
16 |
17 | private static final int MAX_BATCH_SIZE = 24;
18 | private static final int BUFFER_SIZE = 100;
19 | private final StorageAdapter storageAdapter;
20 | private final Diagnostics diagnostics;
21 | private final BlockingQueue queue;
22 | private final Worker worker;
23 |
24 | public BufferedStorageDispatcher(StorageAdapter storageAdapter, Diagnostics diagnostics) {
25 | this.storageAdapter = storageAdapter;
26 | this.diagnostics = diagnostics;
27 | this.queue = new ArrayBlockingQueue(BUFFER_SIZE);
28 | this.worker = new Worker(queue);
29 | }
30 |
31 | public void start() {
32 | worker.start();
33 | }
34 |
35 | public void shutdown() {
36 | worker.setKeepRunnig(false);
37 | }
38 |
39 | @Override
40 | public void onCompleted(DataPoint sample) {
41 | if(queue.remainingCapacity()>0) {
42 | //System.out.println(sample.getTask().getAttribute()+" > "+sample.getValue());
43 | diagnostics.getStorageBufferSize().inc();
44 | queue.add(sample);
45 | }
46 | else {
47 | throw new RuntimeException("buffer capacity exceeded");
48 | }
49 | }
50 |
51 | @Override
52 | public void onFailed(Throwable e) {
53 | e.printStackTrace();
54 | }
55 |
56 | public class Worker extends Thread {
57 | private final BlockingQueue queue;
58 | private boolean keepRunning = true;
59 |
60 | public Worker(BlockingQueue queue) {
61 | this.queue = queue;
62 | }
63 |
64 | public void run() {
65 | try {
66 | while ( keepRunning ) {
67 |
68 | // batch processing
69 | DataPoint sample = queue.take();
70 | Set samples = new HashSet<>();
71 | queue.drainTo(samples, MAX_BATCH_SIZE);
72 | samples.add(sample);
73 |
74 | diagnostics.getStorageBufferSize().dec(samples.size());
75 |
76 | // dispatch
77 | storageAdapter.store(samples);
78 | }
79 | }
80 | catch ( InterruptedException ie ) {
81 | // just terminate
82 | }
83 | }
84 |
85 | public void setKeepRunnig(boolean keepRunning) {
86 | this.keepRunning = keepRunning;
87 | }
88 | }
89 | }
90 |
91 |
--------------------------------------------------------------------------------
/src/main/java/org/wildfly/metrics/scheduler/storage/DataPoint.java:
--------------------------------------------------------------------------------
1 | package org.wildfly.metrics.scheduler.storage;
2 |
3 | import org.wildfly.metrics.scheduler.polling.Task;
4 |
5 | /**
6 | * @author Heiko Braun
7 | * @since 13/10/14
8 | */
9 | public final class DataPoint {
10 | private Task task;
11 | private long timestamp;
12 | private double value;
13 |
14 | public DataPoint(Task task, double value) {
15 | this.task = task;
16 | this.timestamp = System.currentTimeMillis();
17 | this.value = value;
18 | }
19 |
20 | public Task getTask() {
21 | return task;
22 | }
23 |
24 | public long getTimestamp() {
25 | return timestamp;
26 | }
27 |
28 | public double getValue() {
29 | return value;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/org/wildfly/metrics/scheduler/storage/DefaultKeyResolution.java:
--------------------------------------------------------------------------------
1 | package org.wildfly.metrics.scheduler.storage;
2 |
3 | import org.wildfly.metrics.scheduler.polling.Task;
4 |
5 | /**
6 | * Resolve data input attributes to final metric (storage) names.
7 | *
8 | * @author Heiko Braun
9 | * @since 24/10/14
10 | */
11 | public class DefaultKeyResolution implements KeyResolution {
12 | @Override
13 | public String resolve(Task task) {
14 | if(task.getHost()!=null && !task.getHost().equals(""))
15 | {
16 | // domain
17 | return task.getHost()+"."+task.getServer()+"."+task.getAttribute();
18 | }
19 | else
20 | {
21 | // standalone
22 | return task.getServer()+"."+task.getAttribute();
23 | }
24 |
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/org/wildfly/metrics/scheduler/storage/InfluxStorageAdapter.java:
--------------------------------------------------------------------------------
1 | package org.wildfly.metrics.scheduler.storage;
2 |
3 | import org.influxdb.InfluxDB;
4 | import org.influxdb.InfluxDBFactory;
5 | import org.influxdb.dto.Serie;
6 | import org.wildfly.metrics.scheduler.config.Configuration;
7 | import org.wildfly.metrics.scheduler.diagnose.Diagnostics;
8 | import org.wildfly.metrics.scheduler.polling.Task;
9 |
10 | import java.util.Set;
11 | import java.util.concurrent.TimeUnit;
12 |
13 | /**
14 | * Pushes the data to Influx.
15 | *
16 | * @author Heiko Braun
17 | * @since 13/10/14
18 | */
19 | public class InfluxStorageAdapter implements StorageAdapter {
20 |
21 | private InfluxDB influxDB;
22 | private String dbName;
23 | private Diagnostics diagnostics;
24 | private Configuration config;
25 | private DefaultKeyResolution keyResolution;
26 |
27 | @Override
28 | public void setConfiguration(Configuration config) {
29 | this.config = config;
30 | this.influxDB = InfluxDBFactory.connect(
31 | config.getStorageUrl(),
32 | config.getStorageUser(),
33 | config.getStoragePassword()
34 | );
35 | this.dbName = config.getStorageDBName();
36 |
37 | this.keyResolution = new DefaultKeyResolution();
38 | }
39 |
40 | @Override
41 | public void setDiagnostics(Diagnostics diag) {
42 | this.diagnostics = diag;
43 | }
44 |
45 | @Override
46 | public void store(Set datapoints) {
47 |
48 | try {
49 |
50 | Serie[] series = new Serie[datapoints.size()];
51 | int i=0;
52 | for (DataPoint datapoint : datapoints) {
53 |
54 | Task task = datapoint.getTask();
55 | String key = keyResolution.resolve(task);
56 | Serie dataPoint = new Serie.Builder(key)
57 | .columns("datapoint")
58 | .values(datapoint.getValue())
59 | .build();
60 |
61 | series[i] = dataPoint;
62 | i++;
63 | }
64 |
65 | this.influxDB.write(this.dbName, TimeUnit.MILLISECONDS, series);
66 |
67 | } catch (Throwable t) {
68 | diagnostics.getStorageErrorRate().mark(1);
69 | t.printStackTrace();
70 | }
71 |
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/main/java/org/wildfly/metrics/scheduler/storage/KeyResolution.java:
--------------------------------------------------------------------------------
1 | package org.wildfly.metrics.scheduler.storage;
2 |
3 | import org.wildfly.metrics.scheduler.polling.Task;
4 |
5 | /**
6 | * @author Heiko Braun
7 | * @since 24/10/14
8 | */
9 | public interface KeyResolution {
10 | String resolve(Task task);
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/org/wildfly/metrics/scheduler/storage/RHQStorageAdapter.java:
--------------------------------------------------------------------------------
1 | package org.wildfly.metrics.scheduler.storage;
2 |
3 | import org.apache.http.HttpResponse;
4 | import org.apache.http.StatusLine;
5 | import org.apache.http.client.HttpClient;
6 | import org.apache.http.client.methods.HttpPost;
7 | import org.apache.http.entity.StringEntity;
8 | import org.apache.http.impl.client.DefaultHttpClient;
9 | import org.rhq.metrics.client.common.Batcher;
10 | import org.rhq.metrics.client.common.SingleMetric;
11 | import org.wildfly.metrics.scheduler.config.Configuration;
12 | import org.wildfly.metrics.scheduler.diagnose.Diagnostics;
13 | import org.wildfly.metrics.scheduler.polling.Task;
14 |
15 | import java.util.ArrayList;
16 | import java.util.List;
17 | import java.util.Set;
18 |
19 | /**
20 | * Pushes the data to RHQ metrics.
21 | *
22 | * @author Heiko Braun
23 | * @since 13/10/14
24 | */
25 | public class RHQStorageAdapter implements StorageAdapter {
26 |
27 | private Configuration config;
28 | private Diagnostics diagnostics;
29 | private final HttpClient httpclient;
30 | private final DefaultKeyResolution keyResolution;
31 |
32 | public RHQStorageAdapter() {
33 | this.httpclient = new DefaultHttpClient();
34 | this.keyResolution = new DefaultKeyResolution();
35 | }
36 |
37 | @Override
38 | public void setConfiguration(Configuration config) {
39 | this.config = config;
40 | }
41 |
42 | @Override
43 | public void setDiagnostics(Diagnostics diag) {
44 | this.diagnostics = diag;
45 | }
46 |
47 | @Override
48 | public void store(Set datapoints) {
49 | HttpPost post = new HttpPost(config.getStorageUrl());
50 | try {
51 | List metrics = new ArrayList<>();
52 |
53 | for (DataPoint datapoint : datapoints) {
54 | Task task = datapoint.getTask();
55 | String key = keyResolution.resolve(task);
56 | metrics.add(new SingleMetric(key, datapoint.getTimestamp(), datapoint.getValue()));
57 | }
58 |
59 |
60 | // If we have data, send it to the RHQ Metrics server
61 |
62 | if (metrics.size()>0) {
63 | post.setHeader("Content-Type", "application/json;charset=utf-8");
64 | post.setEntity(new StringEntity(Batcher.metricListToJson(metrics)));
65 |
66 | HttpResponse httpResponse = httpclient.execute(post);
67 | StatusLine statusLine = httpResponse.getStatusLine();
68 |
69 | if (statusLine.getStatusCode() != 200) {
70 | throw new Exception("HTTP Status "+statusLine.getStatusCode()+": "+statusLine);
71 | }
72 |
73 |
74 | }
75 | } catch (Throwable t) {
76 | t.printStackTrace();
77 | diagnostics.getStorageErrorRate().mark(1);
78 | }
79 | finally {
80 | post.releaseConnection();
81 | }
82 |
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/main/java/org/wildfly/metrics/scheduler/storage/StorageAdapter.java:
--------------------------------------------------------------------------------
1 | package org.wildfly.metrics.scheduler.storage;
2 |
3 | import org.wildfly.metrics.scheduler.config.Configuration;
4 | import org.wildfly.metrics.scheduler.diagnose.Diagnostics;
5 |
6 | import java.util.Set;
7 |
8 | /**
9 | * @author Heiko Braun
10 | * @since 10/10/14
11 | */
12 | public interface StorageAdapter {
13 | void store(Set datapoints);
14 | void setConfiguration(Configuration config);
15 | void setDiagnostics(Diagnostics diag);
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/resources/META-INF/services/org.jboss.as.controller.Extension:
--------------------------------------------------------------------------------
1 | org.rhq.wfly.monitor.extension.SubsystemExtension
2 |
--------------------------------------------------------------------------------
/src/main/resources/config/monitor-host.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
94 |
95 |
96 |
98 |
99 |
100 |
101 |
103 |
104 |
105 |
106 |
107 |
--------------------------------------------------------------------------------
/src/main/resources/config/standalone-monitor.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
85 |
86 |
87 |
88 |
92 |
93 |
97 |
98 |
102 |
103 |
104 |
105 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 | jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
169 | h2
170 |
171 | sa
172 | sa
173 |
174 |
175 |
176 |
177 | org.h2.jdbcx.JdbcDataSource
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 | false
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 | ${jboss.bind.address:127.0.0.1}
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
--------------------------------------------------------------------------------
/src/main/resources/module/main/module.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/src/main/resources/org/rhq/wfly/monitor/extension/LocalDescriptions.properties:
--------------------------------------------------------------------------------
1 | wildfly-monitor=Monitor subsystem
2 | wildfly-monitor.add=Adds the subsystem
3 | wildfly-monitor.remove=Removes the subsystem
4 |
5 | wildfly-monitor.server-monitor=A server monitor
6 | wildfly-monitor.server-monitor.add=Adds a monitor
7 | wildfly-monitor.server-monitor.remove=Removes a monitor
8 | wildfly-monitor.server-monitor.enabled=Enable monitoring (requires reload/restart)
9 | wildfly-monitor.server-monitor.num-threads=Thread pool size for the scheduler
10 |
11 | wildfly-monitor.storage-adapter=The storage adapter to persist the data points
12 | wildfly-monitor.storage-adapter.add=Adds a storage adapter
13 | wildfly-monitor.storage-adapter.remove=Removes a storage adapter
14 | wildfly-monitor.storage-adapter.url=The url of the remote storage system
15 | wildfly-monitor.storage-adapter.user=Access token of the storage system
16 | wildfly-monitor.storage-adapter.password=Access token of the storage system
17 | wildfly-monitor.storage-adapter.token=Access token of the storage system
18 | wildfly-monitor.storage-adapter.name=Name of the storage adapter type (rhq|influx)
19 | wildfly-monitor.storage-adapter.db=Name of the database to write to
20 |
21 | wildfly-monitor.server-monitor.data-input=Definition of a single resource attribute to monitor
22 | wildfly-monitor.server-monitor.data-input.add=Adds a data input
23 | wildfly-monitor.server-monitor.data-input.remove=Removes a data input
24 | wildfly-monitor.server-monitor.data-input.resource=DMR path of the management resource
25 | wildfly-monitor.server-monitor.data-input.name=(Display) name of the Metric
26 | wildfly-monitor.server-monitor.data-input.attribute=Name of the desired attribute inside the management resource
27 | wildfly-monitor.server-monitor.data-input.seconds=Schedule interval in seconds
28 | wildfly-monitor.server-monitor.data-input.minutes=Schedule interval in minutes
29 | wildfly-monitor.server-monitor.data-input.hours=Schedule interval in hours
30 |
31 | wildfly-monitor.diagnostics=Subsystem diagnostics
32 | wildfly-monitor.diagnostics.add=Adds a diagnostics element
33 | wildfly-monitor.diagnostics.remove=Removes a diagnostics element
34 | wildfly-monitor.diagnostics.enabled=Enables diagnostics reporting
35 | wildfly-monitor.diagnostics.seconds=Report interval in seconds
36 | wildfly-monitor.diagnostics.minutes=Report interval in minutes
37 |
38 |
--------------------------------------------------------------------------------
/src/main/resources/schema/wildfly-monitor-subsystem.xsd:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/src/main/resources/subsystem.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
10 |
14 |
15 |
19 |
20 |
24 |
25 |
26 |
27 |
30 |
31 |
--------------------------------------------------------------------------------
/src/test/java/org/rhq/wfly/monitor/extension/SubsystemBaseParsingTestCase.java:
--------------------------------------------------------------------------------
1 | package org.rhq.wfly.monitor.extension;
2 |
3 | import org.jboss.as.subsystem.test.AbstractSubsystemBaseTest;
4 |
5 | import java.io.IOException;
6 |
7 | /**
8 | * This is the bare bones test example that tests subsystem
9 | * It does same things that {@link SubsystemParsingTestCase} does but most of internals are already done in AbstractSubsystemBaseTest
10 | * If you need more control over what happens in tests look at {@link SubsystemParsingTestCase}
11 | * @author Tomaz Cerar
12 | */
13 | public class SubsystemBaseParsingTestCase extends AbstractSubsystemBaseTest {
14 |
15 | public SubsystemBaseParsingTestCase() {
16 | super(SubsystemExtension.SUBSYSTEM_NAME, new SubsystemExtension());
17 | }
18 |
19 |
20 | @Override
21 | protected String getSubsystemXml() throws IOException {
22 | return readResource("subsystem.xml");
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/test/java/org/rhq/wfly/monitor/extension/SubsystemParsingTestCase.java:
--------------------------------------------------------------------------------
1 | package org.rhq.wfly.monitor.extension;
2 |
3 |
4 | import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADD;
5 | import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP;
6 | import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR;
7 | import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SUBSYSTEM;
8 |
9 | import java.util.List;
10 |
11 | import org.jboss.as.controller.PathAddress;
12 | import org.jboss.as.controller.PathElement;
13 | import org.jboss.as.subsystem.test.KernelServices;
14 | import org.jboss.dmr.ModelNode;
15 |
16 | import org.junit.After;
17 | import org.junit.Assert;
18 | import org.junit.Before;
19 | import org.junit.Test;
20 |
21 |
22 | /**
23 | * Tests all management expects for subsystem, parsing, marshaling, model definition and other
24 | * Here is an example that allows you a fine grained controler over what is tested and how. So it can give you ideas what can be done and tested.
25 | * If you have no need for advanced testing of subsystem you look at {@link SubsystemBaseParsingTestCase} that testes same stuff but most of the code
26 | * is hidden inside of test harness
27 | *
28 | * @author Kabir Khan
29 | */
30 | public class SubsystemParsingTestCase extends SubsystemBaseParsingTestCase {
31 |
32 | @Override
33 | @Before
34 | public void initializeParser() throws Exception {
35 | super.initializeParser();
36 | }
37 |
38 | @Override
39 | @After
40 | public void cleanup() throws Exception {
41 | super.cleanup();
42 | }
43 | /**
44 | * Tests that the xml is parsed into the correct operations
45 | */
46 | @Test
47 | public void testParseSubsystem() throws Exception {
48 | //Parse the subsystem xml into operations
49 | String subsystemXml = getSubsystemXml();
50 | List operations = super.parse(subsystemXml);
51 |
52 | ///Check that we have the expected number of operations
53 | Assert.assertEquals(7, operations.size());
54 |
55 | //Check that each operation has the correct content
56 | ModelNode addSubsystem = operations.get(0);
57 | Assert.assertEquals(ADD, addSubsystem.get(OP).asString());
58 | PathAddress addr = PathAddress.pathAddress(addSubsystem.get(OP_ADDR));
59 | Assert.assertEquals(1, addr.size());
60 | PathElement element = addr.getElement(0);
61 | Assert.assertEquals(SUBSYSTEM, element.getKey());
62 | Assert.assertEquals(SubsystemExtension.SUBSYSTEM_NAME, element.getValue());
63 |
64 | }
65 |
66 | /**
67 | * Test that the model created from the xml looks as expected
68 | */
69 | @Test
70 | public void testInstallIntoController() throws Exception {
71 | //Parse the subsystem xml and install into the controller
72 | String subsystemXml =getSubsystemXml();
73 | KernelServices services = super.createKernelServicesBuilder(null).setSubsystemXml(subsystemXml).build();
74 |
75 | //Read the whole model and make sure it looks as expected
76 | ModelNode model = services.readWholeModel();
77 | Assert.assertTrue(model.get(SUBSYSTEM).hasDefined(SubsystemExtension.SUBSYSTEM_NAME));
78 | }
79 |
80 | /**
81 | * Starts a controller with a given subsystem xml and then checks that a second
82 | * controller started with the xml marshalled from the first one results in the same model
83 | */
84 | @Test
85 | public void testParseAndMarshalModel() throws Exception {
86 | //Parse the subsystem xml and install into the first controller
87 | String subsystemXml = getSubsystemXml();
88 | KernelServices servicesA = super.createKernelServicesBuilder(null).setSubsystemXml(subsystemXml).build();
89 | //Get the model and the persisted xml from the first controller
90 | ModelNode modelA = servicesA.readWholeModel();
91 | String marshalled = servicesA.getPersistedSubsystemXml();
92 |
93 | //Install the persisted xml from the first controller into a second controller
94 | KernelServices servicesB = super.createKernelServicesBuilder(null).setSubsystemXml(marshalled).build();
95 | ModelNode modelB = servicesB.readWholeModel();
96 |
97 | //Make sure the models from the two controllers are identical
98 | super.compare(modelA, modelB);
99 | }
100 |
101 | /**
102 | * Tests that the subsystem can be removed
103 | */
104 | @Test
105 | public void testSubsystemRemoval() throws Exception {
106 | //Parse the subsystem xml and install into the first controller
107 | String subsystemXml = getSubsystemXml();
108 | KernelServices services = super.createKernelServicesBuilder(null).setSubsystemXml(subsystemXml).build();
109 | //Checks that the subsystem was removed from the model
110 | super.assertRemoveSubsystemResources(services);
111 |
112 | //TODO Check that any services that were installed were removed here
113 | }
114 |
115 | }
116 |
--------------------------------------------------------------------------------
/src/test/resources/org/rhq/wfly/monitor/extension/subsystem.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
13 |
14 |
18 |
19 |
23 |
24 |
25 |
26 |
29 |
--------------------------------------------------------------------------------