The need for monitor extension came as a requirement, to have a customized exception handling on Tuscany runtime especially when the user input errors are determined while reading, resolving and building phase of the contribution within the Tuscany runtime. Here different users/vendors using Tuscany with their products wanted to ignore some of the user input errors and allow the runtime to proceed further, while the others wanted to stop processing when a error is determined at the end of each phase. Another important need for a monitor extension is to validate the user inputs (via contributions) and report all the issues identified in one go (Example: As how the java compiler does for java code). Understanding message conversion using monitor1) Errors and warnings are logged with the monitor as problems and the processing continues. Exceptions won't be thrown, where ever possible. Processing here covers any processing of user input, i.e. contributions and the artifacts they contain. 2) After each phase namely read, resolve and build contribution, the problems are read from the monitor for display to the user (currently this will have already happened as our current monitor will just log errors and warnings as it receives them but you can imagine more capable monitors). 3) The controlling logic may look at the errors and warnings it is reporting to the user and prevent further processing occurring. Or it may allow processing to continue. This depends on which bit of processing we are talking about and what errors have been reported. Sample for the controlling logic is shown below Code Block |
---|
private void analyseProblems() throws Exception {
for (Problem problem : monitor.getProblems()){
// look for any reported errors. Schema errors are filtered
// out as there are several that are generally reported at the
// moment and we don't want to stop
if ((problem.getSeverity() == Severity.ERROR) && (!problem.getMessageId().equals("SchemaError"))) {
if (problem.getCause() != null){
throw new Exception(problem.getCause());
} else {
throw new Exception(problem.toString());
}
}
}
}
|
Creating a new monitor extensionNOTE: Please have a look at the interface design of Monitor, Problem and MonitorFactory from monitor module in the Tuscany source code. Step 1) Create a class MyMonitorImpl.java which implements the Monitor interface. Code Block |
---|
public class MyMonitorImpl implements Monitor {
private static final Logger logger = Logger.getLogger(DefaultMonitorImpl.class.getName());
// Cache all the problem reported to monitor for further analysis
private List<Problem> problemCache = new ArrayList<Problem>();
public void problem(Problem problem) {
// Your custom code to handle the problem
}
// Returns a list of reported problems.
public List<Problem> getProblems(){
return problemCache;
}
}
|
Step 2) Create a class MyMonitorFactoryImpl.java which implements the MonitorFactory interface. Code Block |
---|
public class MyMonitorFactoryImpl implements MonitorFactory {
private Monitor monitor = null;
public Monitor createMonitor() {
if (monitor == null) {
monitor = new MyMonitorImpl();
}
return monitor ;
}
}
|
Step 3) Create a plain text file named as "META- INF/services/org.apache.tuscany.sca.monitor.MonitorFactory" Register the extension by adding a line in this file as (org.apache.tuscany.sca.monitor.impl.MyMonitorFactoryImpl) Initialize and create an instance of the monitorMonitors can be initialized using the utility extensions as shown below. Code Block |
---|
UtilityExtensionPoint utilities = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class);
MonitorFactory monitorFactory = utilities.getUtility(MonitorFactory.class);
monitor = monitorFactory.createMonitor();
|
Anchor |
---|
| general guide |
---|
| general guide |
---|
|
Background Color |
---|
| General guide for developing extensions |
- Familiarize yourself with SCA 1.0 Assembly and the SCA Java 1.0 programming model. Specifications can be found at www.osoa.org.
- Never reference any classes in core. These classes are implementation-specific and subject to change; they are not part of the public SPI contract.
- Use autowire when assembling extension components.
- Do not play with classloaders such as setting the current context classloader unless it is absolutely necessary, i.e. a library used by an extension makes assumptions about context classloaders. Ideally the library can be refactored to not make these assumptions. If not, make sure the extension properly resets the current context classloader.
Background Color |
---|
| Detail on extension architecture |
The ExtensionPointRegistry Code Block |
---|
package org.apache.tuscany.sca.core;
/**
* The registry for the Tuscany core extension points. As the point of contact
* for all extension artifacts this registry allows loaded extensions to find
* all other parts of the system and register themselves appropriately.
*
* @version $Rev: 539355 $ $Date: 2007-05-18 03:05:14 -0700 (Fri, 18 May 2007) $
*/
public interface ExtensionPointRegistry {
/**
* Add an extension point to the registry
* @param extensionPoint The instance of the extension point
*/
void addExtensionPoint(Object extensionPoint);
/**
* Get the extension point by the interface
* @param extensionPointType The lookup key (extension point interface)
* @return The instance of the extension point
*/
|
|