[rhq-metrics] Possible implementation idea for pluggable aggregators

Lukas Krejci lkrejci at redhat.com
Wed Jan 7 10:44:32 UTC 2015


On Wednesday, January 07, 2015 10:23:39 Thomas Segismont wrote:
> True. It is possible to create a module (in the sense of JBoss Module)
> which the web application depends on. Then in this module you drop an
> API JAR and implementations JARs. All these JARs need to be declared in
> the module descriptor.
> 
> If you want to add a new implementation, you need to:
> - drop the new JAR int the module directory
> - update the descriptor
> - reload the application (AFAIK, the module cannot be refreshed while a
> application depending on it is running)
> 
> That's why I find this less container friendly than adding/removing Java
> EE applications (a process which can be managed while the server is running)

Maybe we could learn from how Wildfly itself is doing the reloads of webapps - 
because these are nothing else but fancy modules.

Also I know that Furnace (a component of JBoss Forge) has customized the 
module loading such that the directory layout is different from the default.

In Revapi [1], I reused that and can load modules that are just simple jars in 
a single directory, reading their deps and such from the maven metadata 
included in the jars. I'm using java services in Revapi for everything and 
stuff seems to work.

Not sure about dynamically adding/removing jars from such module directory but 
that's easily tried out.

[1] https://github.com/revapi/revapi/blob/master/revapi-standalone/src/main/java/org/revapi/standalone/Main.java#L214

> Le 05/01/2015 15:47, Lukas Krejci a écrit :
> > AFAIK, jboss-modules supports ServiceLoader and so should Wildfly...
> > 
> > You just need to specify how you want the services treated when you
> > declare
> > your deps.
> > 
> > Not sure how this would work if your deps are dynamic / loaded at runtime
> > without a module descriptor...
> > 
> > On Friday, December 19, 2014 18:18:12 Thomas Segismont wrote:
> >> Long overdue reply, sorry.
> >> 
> >> Your proposal is certainly the most container-friendly solution.
> >> 
> >> Had we based rhq-metrics on another technology with a flat classpath
> >> paradigm, we could have use something as simple as the Service loader[1].
> >> 
> >> [1] http://docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html
> >> 
> >> Le 03/12/2014 21:56, Heiko W.Rupp a écrit :
> >>> Hey,
> >>> 
> >>> so I have been thinking on how users can write their own aggregators and
> >>> aggregation functions and deploy them in a pluggable way.
> >>> 
> >>> As we are thinking about messaging for rhq.next anyway [1] I thought
> >>> this
> >>> could be done by forwarding data and/or requests to a message queue /
> >>> topic and have listeners react on those messages. Being old-school, I
> >>> decided to use MessageDrivenBeans - especially as Mazz has already
> >>> created the necessary bits for running an ActiveMQ broker as subsystem
> >>> in
> >>> WildFly and also a ResourceAdapter [2]
> >>> 
> >>> I've implemented two kinds of things so far (don't worry, all in a
> >>> branch
> >>> in my own repo :-):
> >>> 
> >>> 1) forward all incoming data to a topic and have then MDBs work on them
> >>> [3] - this could be used in alerting, where the alert engine just picks
> >>> up those messages and works on them.
> >>> Samples via MDB look like this [4]:
> >>> 
> >>> 
> >>> 
> >>> @MessageDriven(activationConfig = {
> >>> 
> >>>       @ActivationConfigProperty(propertyName = "destinationType",
> >>>       propertyValue = "javax.jms.Topic"),
> >>>       @ActivationConfigProperty(propertyName = "destination",
> >>>       propertyValue = "metrics")>
> >>> 
> >>> }
> >>> )
> >>> @SuppressWarnings("unused")
> >>> public class MaxMdb extends AbstractMetricDrivenMDB {
> >>> 
> >>>       @Override
> >>>       void workOn(List<RawNumericMetric> metrics) {
> >>> 
> >>> /// do work here
> >>> 
> >>>     }
> >>> 
> >>> }
> >>> 
> >>> I guess the activation config could even go into the abstract superclass
> >>> 
> >>> 
> >>> 2) Adhoc aggregation worker
> >>> Those are MDBs that are triggered by this code block in the
> >>> MetricHandler
> >>> [5]>
> >>> 
> >>>     @GET
> >>>     
> >>>       @Path("/metrics/{agg}/{id}")
> >>>       public void getAggregate(@Suspended final AsyncResponse
> >>>       asyncResponse,
> >>>       
> >>>                                    @PathParam("agg")String name,
> >>>                                    @PathParam("id")String id) throws
> >>>                                    Exception {
> >>>           
> >>>           BasicMessage msg = new BasicMessage(id);
> >>>           Map<String,String> headers = new HashMap<>();
> >>>           headers.put("function",name);
> >>>           
> >>>           aggregationProcessor.sendAndListen(msg,
> >>>           
> >>>               new BasicMessageListener<BasicMessage>() {
> >>>               
> >>>                   @Override
> >>>                   protected void onBasicMessage(BasicMessage
> >>>                   basicMessage)
> >>>                   {
> >>>     
> >>>     /// Work on results - e.g  asyncResponse.resume();
> >>> 
> >>> Basically the name of the aggregation function is passed as path
> >>> parameter
> >>> and added as a header field for messaging
> >>> 
> >>> The MDB code would then look like this [6]:
> >>> 
> >>> 
> >>> @MessageDriven(activationConfig = {
> >>> 
> >>>       @ActivationConfigProperty(propertyName = "destinationType",
> >>>       propertyValue = "javax.jms.Queue"),
> >>>       @ActivationConfigProperty(propertyName = "destination",
> >>>       propertyValue = "aggregationTask"),
> >>>       @ActivationConfigProperty(propertyName = "messageSelector",
> >>>       propertyValue = "function = 'invert'")>
> >>> 
> >>> }
> >>> )
> >>> @SuppressWarnings("unused")
> >>> public class InvertAdHocAggregator extends AbstractAggregationWorkerMDB
> >>> {
> >>> 
> >>>       @Override
> >>>       BasicMessage work(BasicMessage msg) {
> >>>    
> >>>    /// compute the result here
> >>>    
> >>>     }
> >>> 
> >>> }
> >>> 
> >>> The most interesting part here is
> >>> 
> >>> @ActivationConfigProperty(propertyName = "messageSelector",
> >>> propertyValue
> >>> = "function = 'invert'")
> >>> 
> >>> where the propertyValue defines a selector that determines what messages
> >>> can reach this MDB.
> >>> 
> >>> So with above MetricHandler code
> >>> 
> >>> GET /metrics/bla/123  would not trigger this MDB but
> >>> GET /metrics/invert/123 would do.
> >>> 
> >>> I am not saying we should adopt this way for user definable
> >>> aggregations;
> >>> the beauties are though - each MDB can just be deployed into the server
> >>> as its own jar file - processing can easily be distributed onto many
> >>> compute nodes because of the message bus.
> >>> 
> >>> [1]
> >>> https://developer.jboss.org/en/rhq/blog/2014/08/14/thoughts-on-rhqnext-s
> >>> e
> >>> rver-architecture [2]
> >>> http://management-platform.blogspot.de/2014/11/messaging-infrastructure-> >>> u
> >>> sing-activemq.html [3]
> >>> https://github.com/pilhuhn/rhq-metrics/blob/msg-integration/rest-servlet
> >>> /
> >>> src/main/java/org/rhq/metrics/restServlet/MetricHandler.java#L123 [4]
> >>> https://github.com/pilhuhn/rhq-metrics/blob/msg-integration/clients/metr
> >>> i
> >>> c-driven-mdb/src/main/java/org/rhq/metrics/clients/metricDrivenMDB/MaxMd
> >>> b.
> >>> java [5]
> >>> https://github.com/pilhuhn/rhq-metrics/blob/msg-integration/rest-servlet
> >>> /
> >>> src/main/java/org/rhq/metrics/restServlet/MetricHandler.java#L251 [6]
> >>> https://github.com/pilhuhn/rhq-metrics/blob/msg-integration/clients/metr
> >>> i
> >>> c-driven-mdb/src/main/java/org/rhq/metrics/clients/metricDrivenMDB/adhoc
> >>> /I
> >>> nvertAdHocAggregator.java
> >>> _______________________________________________
> >>> rhq-devel mailing list
> >>> rhq-devel at lists.fedorahosted.org
> >>> https://lists.fedorahosted.org/mailman/listinfo/rhq-devel
> >> 
> >> _______________________________________________
> >> rhq-devel mailing list
> >> rhq-devel at lists.fedorahosted.org
> >> https://lists.fedorahosted.org/mailman/listinfo/rhq-devel
> > 
> > _______________________________________________
> > rhq-devel mailing list
> > rhq-devel at lists.fedorahosted.org
> > https://lists.fedorahosted.org/mailman/listinfo/rhq-devel
> 
> _______________________________________________
> rhq-devel mailing list
> rhq-devel at lists.fedorahosted.org
> https://lists.fedorahosted.org/mailman/listinfo/rhq-devel



More information about the rhq-devel mailing list