Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current Restore this Version View Page History

« Previous Version 2 Next »

One of the main benefits of Fabric3 is it enables developers to write more manageable applications. This chapter covers how to expose components as part of the Management Resource Famework and as JMX MBeans.

Publishing Components as MBeans


Composite scoped components (and system extension components) can be exposed as JMX MBeans using the org.fabric3.api.annotations.management.Management the org.fabric3.api.annotations.management.ManagementOperation annotations. The following is an example that publishes an MBean with an attribute and two management operations:
@Scope("COMPOSITE")
@Management(description = "A calculator component")
public class HelloServiceImpl implements HelloService{
@ManagementOperation(description = "The greeting text")
public void setGreeting(String greeting){
//...
}
@ManagementOperation(description = "The greeting text")
public String getGreeting(){
//...
}
@ManagementOperation(description = "Start auditing")
public void startAudit() {
// ...
}
@ManagementOperation(description = "Stop auditing")
public void stopAudit() {
// ..
}
}
It is also possible to set the JMX group on the @Management attribute, which is used to display MBeans in a common hierarchy in a JMX client:
@Scope("COMPOSITE")
@Management(group = "Hello Components",
description = "A calculator component")
public class HelloServiceImpl implements HelloService{
//...
}

JMX Security


JMX authorization can be enabled at an MBean or operation level using the readRoles and writeRoles parameters for @Management and the rolesAllowed parameter for @ManagementOperation. By default on system components, readRoles is set to ROLE_FABRIC3_ADMIN and ROLE_FABRIC3_OBSERVER while writeRoles is set to ROLE_FABRIC3_ADMIN. The following example enables custom authorization:
@Scope("COMPOSITE")
@Management(readRoles={"ROLE_OPERATIONS", "ROLE_ADMIN"},
writeRoles={"ROLE_ADMIN"})
public class HelloServiceImpl implements HelloService{
@ManagementOperation(rolesAllowed={"ROLE_SUPER_ADMIN"})
public void setSecretGreeting(String greeting){
//...
}
@ManagementOperation(rolesAllowed={"ROLE_SUPER_ADMIN"})
public String getSecretGreeting(){
//...
}
@ManagementOperation
public void startAudit() {
// ...
}
@ManagementOperation
public void stopAudit() {
// ..
}
}

Monitoring


In place of traditional logging, Fabric3 provides facilities for application code to emit events to channels. This provides added flexibility by allowing component consumers to subscribe to receive events in addition to logging operations.
Fabric3 uses LogBack (http://logback.qos.ch/) to log events sent to the default application channel (for details on the default application channel, see "Monitoring and Logging" in Chapter 19, "Running and Managing the Fabric3 Server").
The org.fabric3.annotations.monitor.Monitor annotation is used to inject a monitor proxy, which is responsible for dispatching application events to a channel. The monitor proxy is defined using an interface supplied by the application:
public class CalculatorImpl implements Calculator{
private CalculatorMonitor monitor;
public CalculatorImpl(@Monitor monitor){
this.monitor = monitor;
}
public double add(double n1, double n2) {
monitor.add(n1,n2);
return n1+n2;
}
//...
}
Fabric3 will search for a resource bundle named f3.properties in the classpath by converting the monitor interface package to a directory hierarchy. The properties file can be used to provide internationalized text output in a log message. An example f3.properties file is shown below:
org.fabric3.samples.CalculatorMonitor#add=Added: {0} and {1}
org.fabric3.samples.CalculatorMonitor#add=An error occured:\n {0}


Segregating Monitor Events


It is also possible to defile custom channels to send events. This allows application events to be segregated. Below is an example of a configuring a channel. Note that the channel is set as synchronous, which means events will be dispatched to listeners synchronously. This ensures log events are recorded in order:
<composite
xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
xmlns:f3="urn:fabric3.org"...>
<channel name="CustomMonitorChannel"
requires="f3:synchronous"/>
</composite>
To attach a logger to the channel, use implementation.monitor:
<composite ...>
<component name="TestChannelMonitor">
<implementation.monitor/>
<consumer name="monitor" source="CustomMonitorChannel"/>
</component>
</composite>
XXXXXXXXXXXXX
Example of configuring a file-based appender:
<implementation.monitor>
<configuration>
<appender name="CUSTOM" class="ch.qos.logback.core.RollingFileAppender">
<file>application.log</file>
<encoder>
<pattern>[%level %thread %d{YY:MM:DD HH:mm:ss.SSS}] [%logger] %msg%n%ex</pattern>
</encoder>
</appender>
</configuration>
</implementation.monitor>

An event can be dispatched to a custom channel by specifying the channel name on the @Monitor annotation:
public class CalculatorImpl implements Calculator{
private CalculatorMonitor monitor;
public CalculatorImpl(@Monitor("CustomMonitorChannel" monitor){
this.monitor = monitor;
}
public double add(double n1, double n2) {
monitor.add(n1,n2);
return n1+n2;
}
//...
}