Jolokia-core as OSGi bundle?

classic Classic list List threaded Threaded
9 messages Options
rklaren rklaren
Reply | Threaded
Open this post in threaded view
|

Jolokia-core as OSGi bundle?

Hi,

First of good job on coming up with this :) Accessing JMX from non Java applications is a pain.

I had a look at integrating jolokia (0.83) in an application running in Eclipse Virgo. For this we want the configuration to be similar to the rest of our application (or better said in the same location). Also we wanted a default setting of no access.

The integration options provided are already quite nice but I'd rather not open up extra ports by using the 'big' bundle, and Virgo currently restricts us to no HTTP service (probably solved in next version, and I see we might even have native jolokia support in Virgo) So I wanted to do something simpler, just subclass AgentServlet from jolokia-core and configure it a bit.

Easier said than done in turns out... jolokia-core is not an OSGi bundle. Fixed that by rebuilding it. Then it turns out that its not possible to configure a custom restrictor on the servlet (or somehow specify the location of the configuration file). With some creativity I got what I wanted but it's not pretty...

So would it be possible to change jolokia-core to an OSGi bundle? And expose the necessary things to extend/integrate it a bit nicer:
* Expose Restrictor
* Expose a few base Restictors (AllowAll + DenyAll)
* The current restrictor (did not look at how extensible it is)
* Change the AgentServlet so one can specify a custom restrictor or RestrictorFactory (does RestrictorFactory add much in terms of flexibility in how it is used? Maybe a factory method for the restrictor on the Servlet would be an idea?)

If these ideas seem compatible then I'm willing to provide some patches.

Cheers,

Ric
roland roland
Reply | Threaded
Open this post in threaded view
|

Re: Jolokia-core as OSGi bundle?

Hi Ric,

the suggested way to integrated Jolokia as an servlet is to use org.jolokia.osgi.servlet.JolokiaServlet from the jolokia-osgi artifact (which is the 'slim' bundle).

Please refer to this post (and the whole thread around this post).

The only drawback for now is, that if the bundle is started (not only 'resolved') it will register to an OSGi HttpService as soon as one kicks in. Since Virgo doesn't comes with one, there should be no harm. But it would be best to leave it in the RESOLVED state to be sure.

However, restrictor handling is not yet covered here. To have an abstraction here would be a good thing, i.e I will consider this for the next version so that the servlet can be feed with a custom restrictor. Preparing jolokia-core as an bundle itself is unfortunately not that easy, since there are depedendencies exposed in the API, which are not for common usage. So, jolokia-osgi is meant to be the proper 'shell' around the core jar (which is embedded here as well as the json serialized used internally).

Another idea is to provide different locations for the jolokia-access.xml descriptor, e.g. via a configuration service or at least a bundle property pointing to the descriptor via an URL.

I certainly accept patches (prefered via an Github fork) if they fit, but give some a moment, so I can think about the proper direction (which I will push to github this week or so).

Thanks a lot for your input ...
... roland
rklaren rklaren
Reply | Threaded
Open this post in threaded view
|

Re: Jolokia-core as OSGi bundle?

Hi,

On 21 March 2011 12:25, roland [via Jolokia] <[hidden email]> wrote:
the suggested way to integrated Jolokia as an servlet is to use org.jolokia.osgi.servlet.JolokiaServlet from the jolokia-osgi artifact (which is the 'slim' bundle).

Please refer to this post (and the whole thread around this post).

Yes I had seen that post, but wanted to grab the smallest artifact that was closest to the config file settings I wanted to have different. Although my current solution to use a different config file would work with jolokia-osgi as well I think on 2nd thought. I'll retry with the jolokia-osgi bundle.

The only drawback for now is, that if the bundle is started (not only 'resolved') it will register to an OSGi HttpService as soon as one kicks in. Since Virgo doesn't comes with one, there should be no harm. But it would be best to leave it in the RESOLVED state to be sure.
 
However, restrictor handling is not yet covered here. To have an abstraction here would be a good thing, i.e I will consider this for the next version so that the servlet can be feed with a custom restrictor. Preparing jolokia-core as an bundle itself is unfortunately not that easy, since there are depedendencies exposed in the API, which are not for common usage. So, jolokia-osgi is meant to be the proper 'shell' around the core jar (which is embedded here as well as the json serialized used internally).

Ah my first impression was that by moving a few classes/packages combined with a little refactoring it should be doable, most likely I missed something :)

My main 'problems' are the default permissive settings (impact can be big on misconfiguration), and the config file location.

Another idea is to provide different locations for the jolokia-access.xml descriptor, e.g. via a configuration service or at least a bundle property pointing to the descriptor via an URL.

Is a setter for the config location possible or overridable getConfigLocation()? Then a subclass can just override, simple and to the point. Or pull in the Restrictor as an OSGi service, and use a DenyAllRestrictor at the times that the external Restrictor is not present?

I certainly accept patches (prefered via an Github fork) if they fit, but give some a moment, so I can think about the proper direction (which I will push to github this week or so).

I'll keep an eye on the github project. Looking forward to what you think up.

Cheers,

Ric

roland roland
Reply | Threaded
Open this post in threaded view
|

Re: Jolokia-core as OSGi bundle?

Hi,
rklaren wrote
Yes I had seen that post, but wanted to grab the smallest artifact that was closest to the config file settings I wanted to have different. Although my current solution to use a different config file would work with jolokia-osgi as well I think on 2nd thought. I'll retry with the jolokia-osgi bundle.
The jolokia-osgi bundle should be also the first choice, since the single dependency Jolokia relies on, json-simple, is not osgified yet. I submitted a patch, but it hasn't made it into the upstream yet (and I'm afraid it won't in the future since the project seems to be somewhat stalled). So, jolokia-osgi embeds this 16k library into the bundle itself which is the cleanest solution for now. This would not be the case for jolokia-core.
Ah my first impression was that by moving a few classes/packages combined with a little refactoring it should be doable, most likely I missed something :)
This is also what I thought first, but then I realized that it would take a major effort and because of the problem described above, I think the jolokia-osgi bundle is the best solution.
Is a setter for the config location possible or overridable getConfigLocation()? Then a subclass can just override, simple and to the point. Or pull in the Restrictor as an OSGi service, and use a DenyAllRestrictor at the times that the external Restrictor is not present?
yes these are all good ideas. A restrictor 'whiteboard' service would be a nice addition, too. But probably the default setup will be a bit more permissive to allow for a quick startup, which is important, too. Maybe a property will switch on/off whether all/none is allowed by default.
I'll keep an eye on the github project. Looking forward to what you think up.
Thanks, I will let you know as soon as I have some roadmap ;-)
... roland
roland roland
Reply | Threaded
Open this post in threaded view
|

Re: Jolokia-core as OSGi bundle?

Hi,

I just pushed my first suggestion for an extended restrictor handling, both to github (branch: "restrictor") and as 0.90-SNAPSHOT to our maven repository.

It contains the following additions:

* The AgentServlet now knows about an init param 'policyLocation', which can be a plain URL which is readable via URL.getInputStream() or a location specifier in the format 'classpath:...'. Default is 'classpath:/jolokia-access.xml'. If a classpath location was specified, and the descriptor could not be found, than a warning is logged and no access restrictions apply (same as before). If it is another URL, which has been explicitely specified as an init parameter, an error is logged and no access is granted globally.

* All restrictor related stuff has been moved to org.jolokia.restrictor, which is exported in the OSGi Bundles. Three default restrictors are provided out of the box: PolicyRestrictor, AllowAllRestrictor and DenyAllRestrictor.

* The JolokiaServlet can take an implementation of an Restrictor as constructor parameter, which then is used.

* For the OSGi Bundles, if the bundle property "org.jolokia.useRestrictorService" is set to true (default: false) and the bundle activator registers the servlet on its own at an OSGi HttpService, then a delegating restrictor is used, which uses a registered Restrictor service. If no such service is available, access is denied globally. A sample maven project for such a Restrictor service can be found in agent/osgi/restrictor-sample
BTW, if the bundle property "org.jolokia.listenForHttpService" is set to "false" (default: "true"), the bundle will never register an agent servlet itself. This property is useful, if the JolokiaServlet is to be registered manually.

I hope this strategy will cover most use cases and it is backwards compatible. Please let me know, whether it fits your needs and I'm looking forward to your comments ;-)
... roland
rklaren rklaren
Reply | Threaded
Open this post in threaded view
|

Re: Jolokia-core as OSGi bundle?

Hi,

On 22 March 2011 22:51, roland [via Jolokia]
<[hidden email]> wrote:
> I just pushed my first suggestion for an extended restrictor handling, both to github (branch: "restrictor") and as 0.90-SNAPSHOT to our maven repository.

Thank you for the changes :) Finally got to looking at it.

> It contains the following additions:
>
> * The AgentServlet now knows about an init param 'policyLocation', which can be a plain URL which is readable via URL.getInputStream() or a location specifier in the format 'classpath:...'. Default is 'classpath:/jolokia-access.xml'. If a classpath location was specified, and the descriptor could not be found, than a warning is logged and no access restrictions apply (same as before). If it is another URL, which has been explicitely specified as an init parameter, an error is logged and no access is granted globally.

An initParameter is not completely practical at least I don't see how
I can put the value of a spring bean in there (and maybe do some extra
concat operations in the process). On 2nd look I could make a
ServletConfig delegating utility that fakes the initParameter, not
exactly elegant though. With spring HttpServletBean you get some of
that stuff for free, but that's an annoying extra dependency. Or I can
use the extra restrictor constructor parameter.

I see that createRestrictor in AgentServlet is protected, yet that
org.jolokia.util is not exported so LogHandler/ConfigKey are not
available? For the restrictor interface HttpMethod is not exported
either.

If LogHandler were exported I could also use setLogHandler before the
JolokiaServlet init, so I can log to SLF4J (so virgo can pick it up in
it's consolidated logging via its medic service).

> * All restrictor related stuff has been moved to org.jolokia.restrictor, which is exported in the OSGi Bundles. Three default restrictors are provided out of the box: PolicyRestrictor, AllowAllRestrictor and DenyAllRestrictor.

Looks great. Except that org.jolokia.request.RequestType is not
visible in OSGi, so one cannot effectively subclass PolicyRestrictor
(if that is the intend).

> * The JolokiaServlet can take an implementation of an Restrictor as constructor parameter, which then is used.

Nice extra options.

> * For the OSGi Bundles, if the bundle property "org.jolokia.useRestrictorService" is set to true (default: false) and the bundle activator registers the servlet on its own at an OSGi HttpService, then a delegating restrictor is used, which uses a registered Restrictor service. If no such service is available, access is denied globally. A sample maven project for such a Restrictor service can be found in agent/osgi/restrictor-sample
> BTW, if the bundle property "org.jolokia.listenForHttpService" is set to "false" (default: "true"), the bundle will never register an agent servlet itself. This property is useful, if the JolokiaServlet is to be registered manually.

Would it make sense to define constants for those properties, to make
things a bit typo/refactor friendly ?

I'm wondering if the uses clause of the org.jolokia.osgi.servlet
export will give problems if no http service is present. It looks I
cannot get things to compile and run in the time before I have to rush
off to another meeting, so I'll get back to you on that.

Cheers,

Ric
roland roland
Reply | Threaded
Open this post in threaded view
|

Re: Jolokia-core as OSGi bundle?

Hi Ric,

Thank you for the changes :) Finally got to looking at it.
Thanks for taking the time, your feedback is highly appreciated.

I see that createRestrictor in AgentServlet is protected, yet that
org.jolokia.util is not exported so LogHandler/ConfigKey are not
available? For the restrictor interface HttpMethod is not exported
either.

If LogHandler were exported I could also use setLogHandler before the
JolokiaServlet init, so I can log to SLF4J (so virgo can pick it up in
it's consolidated logging via its medic service).
In fact, createRestrictor is the proper extension point when it a custom
(or extened) Restrictor should be used. The init parameter is only useful
for configuration of the stock PolicyRestrictor to use a different policy file
location.

And you are right, there are some missing classes in the export and the signature of
createRestrictor() is not really useful.

What I did now:

* Simplified the signature to createRestrictor(String location) so only the location
   as configured (or the default location) is feed into this method. For logging
   purposes, getLogHandler() can be used in the overriden method.

* OSGi exported org.jolokia.util as well. This contains the missing enums (RequestType)
   and interface (LogHandler), so that PolicyRestrictor can be now extended as well.
   I'm not perfect happy with this package, also its classes have only dependencies to the standard
   java lib classes, its name is probably a bit to general, and RequestType is not an utility class
   but an enum for specifying the kind of JolokiaRequest (so semantically it would probably fit better into
   the "request" package).

Looks great. Except that org.jolokia.request.RequestType is not
visible in OSGi, so one cannot effectively subclass PolicyRestrictor
(if that is the intend).
This should be ok now.

Would it make sense to define constants for those properties, to make
things a bit typo/refactor friendly ?
ConfigKey is now also available in the util package and can be accessed.
It encapsulates all the known config properties.

I'm wondering if the uses clause of the org.jolokia.osgi.servlet
export will give problems if no http service is present. It looks I
cannot get things to compile and run in the time before I have to rush
off to another meeting, so I'll get back to you on that.
I just tried it with a vanilla Felix 3.0.8 and it works now as long as the bundle is not
started (only 'resolved'). It still works when started, but gives a nasty error message
since the Activator won't be able to startup properly because of the missing
dependency on the HttpService (wich is not imported with a resolution:=optional).

I'm just pushing out the next 0.90-SNAPSHOT to our maven repo.

Thanks again for your feedback and let me know, if it works better now for you. BTW,
0.90 release is scheduled for this weekend.
... roland
rklaren rklaren
Reply | Threaded
Open this post in threaded view
|

Re: Jolokia-core as OSGi bundle?

Hi,

On 29 March 2011 20:17, roland [via Jolokia] <[hidden email]> wrote:
Thanks for taking the time, your feedback is highly appreciated.

And so are the improvements :) I pulled the latest version from git (master) and built it. And redid the integration. Looks a lot cleaner now.

What I did now:

* Simplified the signature to createRestrictor(String location) so only the location
   as configured (or the default location) is feed into this method. For logging
   purposes, getLogHandler() can be used in the overriden method.

I was able to get exactly what I wanted via the createRestrictor override. So I'm happy with the new changes.

One slight issue with the getLogHandler now there's a short moment that inside AgentServlet getDefaultLogHandler is used (and the logHandler attribute is set from that). Yet I'm unable to call setLogHandler from the constructor/init methods since org.jolokia.http is not exported in OSGi. So I cannot actually set the loghandler.

If inside JolokiaServlet during backend creation, getLoghandler were used in stead of accessing the attribute directly things would work as expected. (Or some other minor refactoring)

I'm wondering if the uses clause of the org.jolokia.osgi.servlet
export will give problems if no http service is present. It looks I
cannot get things to compile and run in the time before I have to rush
off to another meeting, so I'll get back to you on that.
I just tried it with a vanilla Felix 3.0.8 and it works now as long as the bundle is not
started (only 'resolved'). It still works when started, but gives a nasty error message
since the Activator won't be able to startup properly because of the missing
dependency on the HttpService (wich is not imported with a resolution:=optional).

Things deploy and work in Eclispe Virgo as well. So things look good.
 

Thanks again for your feedback and let me know, if it works better now for you. BTW,
0.90 release is scheduled for this weekend.

Aside from the loghandler issue things look good.

Cheers,

Ric

roland roland
Reply | Threaded
Open this post in threaded view
|

Re: Jolokia-core as OSGi bundle?

Hi,

One slight issue with the getLogHandler now there's a short moment that
inside AgentServlet getDefaultLogHandler is used (and the logHandler
attribute is set from that). Yet I'm unable to call setLogHandler from the
constructor/init methods since org.jolokia.http is not exported in OSGi. So
I cannot actually set the loghandler.

If inside JolokiaServlet during backend creation, getLoghandler were used in
stead of accessing the attribute directly things would work as expected. (Or
some other minor refactoring)
Yes, that's true. I think the best solution is to get rid of setLogHandler() and getDefaultLogHandler() altogether in favor of an overidable  createLogHandler(). I changed this, so that a subclass can simply override this method for creating of a logger. This method is called early in the init() method along with the servlet config, so custom configuration options can be extracted as well.

Aside from the loghandler issue things look good.
Thanks for your help ….
... roland