ace-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Marcel Offermans <marcel.offerm...@luminis.nl>
Subject Dynamically debugging services with aspects...
Date Sat, 22 Jan 2011 14:18:35 GMT
For ACE-112 [1] I had to debug the events flowing through the system to see if the events being
sent were created and received correctly. Most events (in ACE) are being sent asynchronously,
which makes debugging by setting breakpoints a bit more difficult, as setting breakpoints
in handleEvent() will not reveal the sender.

One way to get more information is to "intercept" all calls to EventAdmin, and the technique
to do this is what I wanted to share with you in this e-mail.

What we can do is use the Dependency Manager to create an aspect service on top of EventAdmin.
An aspect can intercept all calls to services and in your interceptor you can still delegate
the calls to the original service. Technically, this is being implemented using service rankings,
which means that consumers will automatically react to aspects.

What I did was add the following to the Activator of the VaadinClient:

        manager.add(createAspectService(EventAdmin.class, null, 10, null)
            .setImplementation(new EventAdmin() {
                volatile EventAdmin m_eventAdmin;
                
                private String print(Event event) {
                    StringBuffer result = new StringBuffer();
                    result.append("Event[ ");
                    String[] names = event.getPropertyNames();
                    for (String name : names) {
                        result.append(name);
                        result.append('=');
                        result.append(event.getProperty(name));
                        result.append(' ');
                    }
                    result.append(']');
                    return result.toString();
                }
                
                public void postEvent(Event event) {
                    System.out.println("postEvent: " + print(event));
                    m_eventAdmin.postEvent(event);
                }
    
                public void sendEvent(Event event) {
                    System.out.println("sendEvent: " + print(event));
                    m_eventAdmin.sendEvent(event);
                }
            }));

When we create the aspect service, the first two parameters are the service class and a filter
condition (null here) we want to create aspects on top of. For each service that matches the
service name and filter, and aspect will be instantiated of the class specified below. The
third parameters is the service ranking for this aspect. This is there because you can also
chain aspects on top of each other. The final option (null here) is the name of the member
that should be injected into the aspect service (null means any member of the right class).

The implementation is just one that intercepts all calls, prints the event, and then delegates
them to the real EventAdmin (which is injected automatically).

So it's quite easy to debug a service this way, and it's fully dynamic. Even in a running
production system, you can install a new bundle that adds an aspect on top of an existing
service and you can instantly intercept all calls, and stop or uninstall the bundle again
once you're done.

Greetings, Marcel

[1] https://issues.apache.org/jira/browse/ACE-112


Mime
View raw message