1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.modeshape.jboss.managed;
25
26 import java.net.URL;
27 import java.util.ArrayList;
28 import java.util.Collection;
29 import java.util.Collections;
30 import java.util.Comparator;
31 import java.util.List;
32 import java.util.concurrent.TimeUnit;
33 import javax.jcr.Repository;
34 import javax.jcr.RepositoryException;
35 import net.jcip.annotations.Immutable;
36 import org.jboss.managed.api.ManagedOperation.Impact;
37 import org.jboss.managed.api.annotation.ManagementComponent;
38 import org.jboss.managed.api.annotation.ManagementObject;
39 import org.jboss.managed.api.annotation.ManagementOperation;
40 import org.jboss.managed.api.annotation.ManagementParameter;
41 import org.jboss.managed.api.annotation.ManagementProperties;
42 import org.jboss.managed.api.annotation.ManagementProperty;
43 import org.jboss.managed.api.annotation.ViewUse;
44 import org.joda.time.DateTime;
45 import org.modeshape.common.math.Duration;
46 import org.modeshape.common.statistic.Stopwatch;
47 import org.modeshape.common.util.CheckArg;
48 import org.modeshape.common.util.Logger;
49 import org.modeshape.common.util.Reflection.Property;
50 import org.modeshape.graph.connector.RepositoryConnectionPool;
51 import org.modeshape.graph.connector.RepositorySource;
52 import org.modeshape.jboss.managed.util.ManagedUtils;
53 import org.modeshape.jcr.JcrConfiguration;
54 import org.modeshape.jcr.JcrEngine;
55 import org.modeshape.jcr.JcrRepository;
56 import org.modeshape.repository.sequencer.SequencingService;
57
58
59
60
61
62 @Immutable
63 @ManagementObject(isRuntime = true, name = "ModeShapeEngine", description = "A ModeShape engine", componentType = @ManagementComponent(type = "ModeShape", subtype = "Engine"), properties = ManagementProperties.EXPLICIT)
64 public final class ManagedEngine implements ModeShapeManagedObject {
65
66
67
68
69
70 private JcrEngine engine;
71
72
73
74
75 private URL configurationUrl;
76
77 public static enum Component {
78 CONNECTOR, SEQUENCER, CONNECTIONPOOL, SEQUENCINGSERVICE, REPOSITORY
79 }
80
81 public ManagedEngine() {
82 this.engine = null;
83 }
84
85
86
87
88
89
90
91 public ManagedEngine(JcrEngine engine) {
92 CheckArg.isNotNull(engine, "engine");
93 this.engine = engine;
94 }
95
96 public void setConfigURL(URL configurationUrl) throws Exception {
97 this.configurationUrl = configurationUrl;
98
99
100 loadConfigurationAndCreateEngine();
101 }
102
103 protected synchronized void loadConfigurationAndCreateEngine()
104 throws Exception {
105 this.engine = new JcrConfiguration().loadFrom(configurationUrl).build();
106 }
107
108
109
110
111
112
113
114
115
116
117
118 protected synchronized JcrEngine getEngine() {
119 return this.engine;
120 }
121
122
123
124
125
126
127 @ManagementOperation(description = "Starts this engine", impact = Impact.Lifecycle)
128 public synchronized void start() {
129 if (!isRunning()) {
130 this.engine.start();
131 }
132 }
133
134
135
136
137
138
139
140 @ManagementOperation(description = "Indicates if this engine is running", impact = Impact.ReadOnly)
141 public synchronized boolean isRunning() {
142 if (this.engine == null)
143 return false;
144 try {
145 this.engine.getRepositoryService();
146 return true;
147 } catch (IllegalStateException e) {
148 return false;
149 }
150 }
151
152
153
154
155
156
157
158
159
160
161
162 @ManagementOperation(description = "Restarts this engine", impact = Impact.Lifecycle)
163 public synchronized void restart() throws Exception {
164
165 JcrEngine oldEngine = this.engine;
166 try {
167
168 loadConfigurationAndCreateEngine();
169 start();
170 } catch (Throwable e) {
171
172
173 this.engine = oldEngine;
174 if (e instanceof RuntimeException)
175 throw (RuntimeException) e;
176 throw (Exception) e;
177 }
178
179
180
181
182
183
184
185
186 oldEngine.shutdownAndAwaitTermination(10, TimeUnit.SECONDS);
187 }
188
189
190
191
192
193
194 @ManagementOperation(description = "Shutdowns this engine", impact = Impact.Lifecycle)
195 public synchronized void shutdown() {
196 if (isRunning()) {
197 try {
198 this.engine.shutdown();
199 } finally {
200 this.engine = null;
201 }
202 }
203 }
204
205
206
207
208
209
210
211
212 @ManagementOperation(description = "Obtains the managed connectors of this engine", impact = Impact.ReadOnly)
213 public Collection<ManagedConnector> getConnectors() {
214 if (!isRunning())
215 return Collections.emptyList();
216
217
218
219 final JcrEngine engine = getEngine();
220 assert engine != null;
221
222 Collection<ManagedConnector> connectors = new ArrayList<ManagedConnector>();
223 for (String repositoryName : engine.getRepositoryNames()) {
224 RepositorySource repositorySource = engine
225 .getRepositorySource(repositoryName);
226 assert repositorySource != null : "Repository '" + repositoryName
227 + "' does not exist";
228 connectors.add(new ManagedConnector(repositorySource));
229 }
230
231 return Collections.unmodifiableCollection(connectors);
232 }
233
234
235
236
237
238
239
240 @ManagementOperation(description = "Pings a connector by name", impact = Impact.ReadOnly)
241 public long getInUseConnections(String connectorName) {
242 if (!isRunning())
243 return 0;
244
245
246 final JcrEngine engine = getEngine();
247 assert engine != null;
248
249 long totalConnectionsInUse = 0;
250 try {
251 totalConnectionsInUse = engine.getRepositoryService()
252 .getRepositoryLibrary().getConnectionPool(connectorName)
253 .getInUseCount();
254 } catch (Exception e) {
255 Logger.getLogger(getClass()).error(e,
256 JBossManagedI18n.errorDeterminingTotalInUseConnections,
257 connectorName);
258 }
259
260 return totalConnectionsInUse;
261 }
262
263
264
265
266
267
268
269
270
271 @ManagementOperation(description = "Obtains the properties for an object", impact = Impact.ReadOnly)
272 public List<ManagedProperty> getProperties(String objectName,
273 Component objectType) {
274 if (!isRunning())
275 return Collections.emptyList();
276
277
278
279 final JcrEngine engine = getEngine();
280 assert engine != null;
281
282 List<ManagedProperty> managedProps = new ArrayList<ManagedProperty>();
283 if (objectType.equals(Component.CONNECTOR)) {
284 RepositorySource repositorySource = engine
285 .getRepositorySource(objectName);
286 assert repositorySource != null : "Connection '" + objectName
287 + "' does not exist";
288 managedProps = ManagedUtils.getProperties(objectType,
289 repositorySource);
290 } else if (objectType.equals(Component.CONNECTIONPOOL)) {
291 RepositoryConnectionPool connectionPool = engine
292 .getRepositoryService().getRepositoryLibrary()
293 .getConnectionPool(objectName);
294 assert connectionPool != null : "Repository Connection Pool for repository '"
295 + objectName + "' does not exist";
296 managedProps = ManagedUtils.getProperties(objectType,
297 connectionPool);
298 }
299
300 return managedProps;
301 }
302
303
304
305
306
307
308
309
310
311
312
313
314 @ManagementOperation(description = "Obtains the managed repositories of this engine", impact = Impact.ReadOnly)
315 public Collection<ManagedRepository> getRepositories() {
316 if (!isRunning())
317 return Collections.emptyList();
318
319
320
321 final JcrEngine engine = getEngine();
322 assert engine != null;
323
324 Collection<ManagedRepository> repositories = new ArrayList<ManagedRepository>();
325 for (String repositoryName : engine.getRepositoryNames()) {
326 repositories.add(new ManagedRepository(repositoryName));
327 }
328
329 return repositories;
330 }
331
332
333
334
335
336
337
338
339
340
341 public JcrRepository getRepository(String repositoryName) {
342 if (!isRunning())
343 return null;
344
345
346
347 final JcrEngine engine = getEngine();
348 assert engine != null;
349
350 try {
351 return engine.getRepository(repositoryName);
352 } catch (RepositoryException e) {
353 Logger.getLogger(getClass()).error(e,
354 JBossManagedI18n.errorGettingRepositoryFromEngine,
355 repositoryName);
356 return null;
357 }
358 }
359
360
361
362
363
364
365
366
367
368 @ManagementOperation(description = "The JCR version supported by this repository", impact = Impact.ReadOnly)
369 public String getRepositoryVersion(String repositoryName) {
370 String version = null;
371 JcrRepository repository = getRepository(repositoryName);
372 if (repository != null) {
373 version = repository.getDescriptor(Repository.SPEC_NAME_DESC) + " "
374 + repository.getDescriptor(Repository.SPEC_VERSION_DESC);
375 }
376 return version;
377 }
378
379 @ManagementProperty(name = "Query Activity", description = "The number of queries executed", use = ViewUse.STATISTIC)
380 public int getQueryActivity() {
381 if (!isRunning())
382 return 0;
383
384
385
386 final JcrEngine engine = getEngine();
387 assert engine != null;
388
389
390
391 return 0;
392 }
393
394 @ManagementProperty(name = "Save Activity", description = "The number of nodes saved", use = ViewUse.STATISTIC)
395 public int getSaveActivity() {
396 if (!isRunning())
397 return 0;
398
399
400
401 final JcrEngine engine = getEngine();
402 assert engine != null;
403
404
405
406 return 0;
407 }
408
409 @ManagementProperty(name = "Session Activity", description = "The number of sessions created", use = ViewUse.STATISTIC)
410 public Object getSessionActivity() {
411 if (!isRunning())
412 return null;
413
414
415
416 final JcrEngine engine = getEngine();
417 assert engine != null;
418
419
420
421 return 0;
422 }
423
424
425
426
427
428
429
430 @ManagementOperation(description = "Obtains all the managed locks sorted by the owner", impact = Impact.ReadOnly)
431 public List<ManagedLock> listLocks() {
432 return listLocks(ManagedLock.SORT_BY_OWNER);
433 }
434
435
436
437
438
439
440
441
442
443 public List<ManagedLock> listLocks(Comparator<ManagedLock> lockSorter) {
444 CheckArg.isNotNull(lockSorter, "lockSorter");
445 if (!isRunning())
446 return Collections.emptyList();
447
448
449
450 final JcrEngine engine = getEngine();
451 assert engine != null;
452
453
454 List<ManagedLock> locks = new ArrayList<ManagedLock>();
455
456
457 for (int i = 0; i < 5; ++i) {
458 locks.add(new ManagedLock("workspace-" + i, true, "sessionId-1",
459 new DateTime(), "id-" + i, "owner-" + i, true));
460 }
461
462
463 Collections.sort(locks, lockSorter);
464
465 return locks;
466 }
467
468
469
470
471
472
473
474 @ManagementOperation(description = "Obtains the managed sessions sorted by user name", impact = Impact.ReadOnly)
475 public List<ManagedSession> listSessions() {
476 return listSessions(ManagedSession.SORT_BY_USER);
477 }
478
479
480
481
482
483
484
485
486
487 public List<ManagedSession> listSessions(
488 Comparator<ManagedSession> sessionSorter) {
489 CheckArg.isNotNull(sessionSorter, "sessionSorter");
490 if (!isRunning())
491 return Collections.emptyList();
492
493
494
495 final JcrEngine engine = getEngine();
496 assert engine != null;
497
498
499 List<ManagedSession> sessions = new ArrayList<ManagedSession>();
500
501
502 for (int i = 0; i < 5; ++i) {
503 sessions.add(new ManagedSession("workspace-" + i, "userName-" + i,
504 "sessionId-1", new DateTime()));
505 }
506
507
508 Collections.sort(sessions, sessionSorter);
509
510 return sessions;
511 }
512
513
514
515
516
517
518
519
520
521 @ManagementOperation(description = "Removes the lock with the specified ID", impact = Impact.WriteOnly, params = { @ManagementParameter(name = "lockId", description = "The lock identifier") })
522 public boolean removeLock(String lockId) {
523 if (!isRunning())
524 return false;
525
526
527
528 final JcrEngine engine = getEngine();
529 assert engine != null;
530
531
532 return false;
533 }
534
535
536
537
538
539
540
541
542
543 @ManagementOperation(description = "Terminates the session with the specified ID", impact = Impact.WriteOnly, params = { @ManagementParameter(name = "sessionId", description = "The session identifier") })
544 public boolean terminateSession(String sessionId) {
545 if (!isRunning())
546 return false;
547
548
549
550 final JcrEngine engine = getEngine();
551 assert engine != null;
552
553
554 return false;
555 }
556
557
558
559
560
561
562
563
564
565
566
567 public RepositorySource getConnector(String connectorName) {
568 if (!isRunning())
569 return null;
570
571
572
573 final JcrEngine engine = getEngine();
574 assert engine != null;
575
576 RepositorySource repositorySource = engine
577 .getRepositorySource(connectorName);
578 assert (repositorySource != null) : "Connector '" + connectorName
579 + "' does not exist";
580 return repositorySource;
581 }
582
583
584
585
586
587
588
589 @ManagementOperation(description = "Pings a connector by name", impact = Impact.ReadOnly)
590 public boolean pingConnector(String connectorName) {
591 if (!isRunning())
592 return false;
593
594
595
596 final JcrEngine engine = getEngine();
597 assert engine != null;
598
599 boolean success = false;
600 String pingDuration = null;
601 try {
602 RepositoryConnectionPool pool = engine.getRepositoryService()
603 .getRepositoryLibrary().getConnectionPool(connectorName);
604 if (pool != null) {
605 Stopwatch sw = new Stopwatch();
606 sw.start();
607 success = pool.ping();
608 sw.stop();
609 pingDuration = sw.getTotalDuration().toString();
610 }
611 } catch (Exception e) {
612 Logger.getLogger(getClass()).error(e,
613 JBossManagedI18n.errorDeterminingIfConnectionIsAlive,
614 connectorName);
615 }
616 if (pingDuration == null)
617 pingDuration = new Duration(0L).toString();
618 return success;
619 }
620
621
622
623
624
625
626
627
628
629
630
631 @ManagementOperation(description = "Obtains the managed sequencing service of this engine", impact = Impact.ReadOnly)
632 public SequencingService getSequencingService() {
633 if (!isRunning())
634 return null;
635
636
637
638 return getEngine().getSequencingService();
639 }
640
641
642
643
644
645
646
647
648
649 @ManagementOperation( description = "Obtains the descriptors for a JCRRepository as ManagedProperties", impact = Impact.ReadOnly )
650 public List<ManagedProperty> getRepositoryProperties(String repositoryName) {
651 if (!isRunning()) return null;
652
653 List<ManagedProperty> propertyList = new ArrayList<ManagedProperty>();
654
655 JcrRepository repository = getRepository(repositoryName);
656
657 String[] descriptorKeys = repository.getDescriptorKeys();
658
659 for (String key: descriptorKeys){
660 String value = repository.getDescriptor(key);
661 propertyList.add(new ManagedProperty(ManagedUtils.createLabel(key),value));
662 }
663
664 return propertyList;
665 }
666
667
668
669
670
671
672
673 @ManagementOperation(description = "Obtains the version of this ModeShape instance", impact = Impact.ReadOnly)
674 public synchronized String getVersion() {
675 if (!isRunning())
676 return "";
677
678
679
680 return getEngine().getEngineVersion();
681 }
682
683 public static class ManagedProperty {
684 private static final long serialVersionUID = 1L;
685
686 private String name;
687 private String label;
688 private String description;
689 private String value;
690
691 public ManagedProperty() {
692
693 }
694
695 public ManagedProperty(String label, String currentValue) {
696 this.setLabel(label);
697 this.value = currentValue;
698 }
699
700 public ManagedProperty(Property property, String currentValue) {
701 this.setName(property.getName());
702 this.setLabel(property.getLabel());
703 this.setDescription(property.getDescription());
704 this.value = currentValue;
705 }
706
707
708
709
710 public void setDescription(String description) {
711 this.description = description;
712 }
713
714
715
716
717
718 public void setName(String name) {
719 this.name = name;
720 }
721
722
723
724
725 public String getName() {
726 return name;
727 }
728
729
730
731
732
733 public void setLabel(String label) {
734 this.label = label;
735 }
736
737
738
739
740 public String getLabel() {
741 return label;
742 }
743
744
745
746
747 public String getValue() {
748 return this.value;
749 }
750
751
752
753
754 public String getDescription() {
755 return description;
756 }
757
758 }
759 }