You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Jeanfrancois Arcand <jf...@apache.org> on 2003/01/13 21:29:23 UTC

[JMX hooks/handler] was Re: cvs commit: jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote BaseHook.java

Sorry for the delay....

Costin Manolache wrote:

>Jeanfrancois Arcand wrote:
>
>  
>
>>Hi Costin, (you beat me on the proposal :-) )
>>    
>>
>
>Actually - this is a different story ( JMX-enabling different componets).
>I'll check in similar additions to ValveBase, BaseContainer, 
>CoyoteConnector.
>
Humm..I would like to be able to support hooks/Valves also using one 
approach. I'm not an expert with JMX, but it seems we can do it.

>
>The idea is for each component to be aware of its name and domain, 
>and to "bridge" whatever notification/hook mechanism into JMX
>notifications.
>
>I don't think we need an additional extension mechansim - for all
>that I need I think JMX notifications are good enough. I don't
>know how hard ( or usefull ) it is to bridge all existing extension
>points, but at least the connector should be able to send JMX notifications
>and it can easily use this model for its own needs.
>
StandardPipeline and ValveBase can be ported to support JMX notification 
also. We can add support for JMX notification in ValveContext.next() or 
port that method inside StandardPipeline and then use JMX notification 
without making major design change (the Digester will register the Valve 
mostly the same way, but this time using the jmx NotificationListener 
interface ). That should "JMX"-enabled StandardPipeline and valve that 
extends ValveBase

>
>
>
>  
>
>>what about having a concept of a chain somewhere (meaning hooks chain
>>(handler :-) ). This way handler doesn't need to know which comes next
>>(or previous), but the handler chain knows it. What I was having in mind
>>was being able to define somewhere:
>>    
>>
>
>I'm ok with that too. Valves have a Next - and I assumed many people 
>preffer this model ( and it involves fewer interfaces :-).
>My only requirement is to be able to use it in iterative mode too
>( I don't like the long stack traces and I feel better with iterative).
>
It is ValveContext that have a next :-), which is similar to an 
HandlerChain (Pipeline is starting the process, ValveContext is doing 
the rest).

>
>For configuration: I would be -1 for any new API / tomcat-specific config
>format.
>  
>
Then my question is: how do we specify, as an example, that the JSR 115 
authorization valve should be invoked before, let say, JNDI 
authorization valve? We are currently doing that implicitly in 
server.xml, but all valves are associated with the same pipeline 
implementation (or I'm missing something here). I would like to be able 
to configure more that one chain (one for connector, one for valve, 
etc.). As an example, an <Engine> may have a different chain behaviour 
than a <host> element when an exception occurs.

>
>All configuration should be done using JMX. I have no doubt about
>it ( well, JMX has its limitations, but the general model of 
>manageable components with light coupling is essential ).
>
I agree.

>
>Instead of param-name/value - use JMX attributes. The handler is a JMX 
>component. For registration - I think we should use the standard JMX 
>notifications ( or your proposed API if JMX proves too complicated or
>we can't get around its limitations )
>
That's true. But where do we get the initial value of those objects?

>
>We could use a Chain MBean component where you declare ( as attributes )
>the various hooks in the chain. ActionCode will correspond to a Chain.
>That may be very nice - allowing hooks to be inserted at runtime, etc.
>
This is where I would like to go. Being able to set hooks at runtime 
using some descriptors. Or have an extension folder where JMX enabled 
hooks will be discovered and added, by default, to the end of the chain.

>
>
>
>  
>
>><handler-configuration>
>>    <module name="org.apache.coyote>
>>    
>>
>...
>  
>
>>    <handler-chain>
>><handler-configuration>
>>    
>>
>
>
>  
>
>>Using that information, an HandlerChainDispatcher can generically load
>>that information and then instanciate the proper HandlerChain/Handler.
>>In the code, that will result in
>>
>>public interface HandlerChain{
>>    public void addHandler(Handler);
>>    public void addHandler(int index, Handler);
>>    public boolean contains(Handler);
>>    public boolean  handle(HandlerChainContext);
>>// remove handler(Handler)
>>}
>>    
>>
>
>+0 - sounds good, but I would rather use NotificationBroadcaster :-)
>( or some specialized version in modeler - to get around Filters ).
>  
>
True. Filtering will certaintly be a performance hit... the question is 
do we want to be able to fully support jmx notification mechanism or 
part of it (by skipping the filter invokation). In modeler, you seems to 
have a solution for the filtering invocation. Have you make some test to 
see if it is faster?

>
>
>
>  
>
>>public interface Handler{
>>    public boolean handle(HandlerContext);
>>    public void setHandlerInfo(HandlerInfo);   // Same as ActionCode
>>    public HandlerInfo getHandlerInfo(HandlerInfo);
>>   
>>    public void init();
>>    public void destroy()
>>    public void recycle();
>>}
>>    
>>
>
>Again - I would rather use 
>
>interface javax.management.NotificationListener {
>  handleNotification( Notification n, Object handBack );
>}
>  
>
I agree. The concept stay the same, but we should use JMX 
NotifcationListener for implementing the concept.

>And normal JMX for init/destroy/etc. 
>
>
>  
>
>>public interface HandlerContext(){
>>    public Object putAttribute(String,Object);
>>    public Object getAttribute(String);
>>    public Map getAttributes();
>>    public void removeAttribute(String);
>>    public void clear();
>>}
>>    
>>
>
>That's a tricky one - besides String-based attributes 
>I think we need to use the "notes" ( i.e. index based ).
>But I think the HandlerContext should just be an instance
>of Notification ( with added notes and an int notification
>code for faster dispatch ).
>
What about using the setUserData/getUserData for doing that?

>
>  
>
>>Finally, that looks like a small proposal ;-)
>>    
>>
>
>My preference is to try to just use JMX.
>
I agree. I will try to speak in term of jmx next time :-)

-- Jeanfrancois

>
>It is not perfect - but I think it's good enough and we'll
>benefit more by using a standard and well-known API.
>  
>
>
>Costin
>
>
>
>
>
>--
>To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
>For additional commands, e-mail: <ma...@jakarta.apache.org>
>
>
>  
>

Re: [JMX hooks/handler] was Re: cvs commit: jakarta-tomcat-connectors/coyote/src/java/org/apache/coyote BaseHook.java

Posted by Costin Manolache <cm...@yahoo.com>.
Jeanfrancois Arcand wrote:

>>Actually - this is a different story ( JMX-enabling different componets).
>>I'll check in similar additions to ValveBase, BaseContainer,
>>CoyoteConnector.
>>
> Humm..I would like to be able to support hooks/Valves also using one
> approach. I'm not an expert with JMX, but it seems we can do it.

Regardless of the hook type - all components should know their name and
domain and should know when they are registered - so MBeanRegistration must
be implemented in all root components.


> StandardPipeline and ValveBase can be ported to support JMX notification
> also. We can add support for JMX notification in ValveContext.next() or
> port that method inside StandardPipeline and then use JMX notification
> without making major design change (the Digester will register the Valve
> mostly the same way, but this time using the jmx NotificationListener
> interface ). That should "JMX"-enabled StandardPipeline and valve that
> extends ValveBase

The main problem - the notification in JMX works in the same way as 
Event/Listener - i.e. iterate over listeners and call each one. 
Valves are recursive, each valve calls the next. I don't want to reopen
the discussion on what's better - we ( tomcat-dev) know both are valid and 
we agreed to disagree on this :-) That's why I added the recursive 
mechansim in BaseHook.

We could register Vavles using addNotification - and even modify modeler
to support both models ( right now it supports none - notification doesn't
seem to be completely implemented ). Not sure it's a big priority - but
if you have the time it would be great to at least see how it looks.


>>I'm ok with that too. Valves have a Next - and I assumed many people
>>preffer this model ( and it involves fewer interfaces :-).
>>My only requirement is to be able to use it in iterative mode too
>>( I don't like the long stack traces and I feel better with iterative).
>>
> It is ValveContext that have a next :-), which is similar to an
> HandlerChain (Pipeline is starting the process, ValveContext is doing
> the rest).

I have a bad habbit to try to simplify some things :-) ( bad because 
sometimes things need to be complex - and it takes a lot of time ).
Doesn't matter how many classes are involved in this procept - the
concept is that you have a list and each element calls the next.
 


>>For configuration: I would be -1 for any new API / tomcat-specific config
>>format.
>>  
>>
> Then my question is: how do we specify, as an example, that the JSR 115
> authorization valve should be invoked before, let say, JNDI
> authorization valve? We are currently doing that implicitly in
> server.xml, but all valves are associated with the same pipeline
> implementation (or I'm missing something here). I would like to be able
> to configure more that one chain (one for connector, one for valve,
> etc.). As an example, an <Engine> may have a different chain behaviour
> than a <host> element when an exception occurs.

There are 2 ( or 3 ) solutions:

- explicit Chain MBean. You configure each module as a MBean, and you have 
one Chain MBean, where you specify the names of each mbean. A variation - in 
modeler we could add some modeler-specific mbean to control the 
notification chain of each modeled mbean. 
  <mbean name="catalina:Type=Chain,id=AuthHook" >
     <attribute name="module" value="catalina:Type=Module,id=JSR115Auth" />
     <attribute name="module" value="........." />
  </mbean>

- next ( or "after" ) attribute in the valve. Something like that is done in 
jk2. You configure the JSR115 mbean, the JNDIAuth mbean - and you specify
the name of the first in the "after" attribute of the second. The base class
can easily take care of this - it'll just jmx.invoke "setNext".
  <mbean name="...id=JSR115Auth" />
    <attribute name="after" value="catalina:Type=Module,id=.... />
    <attribute name="chain" value="catalina:Type=Chain,id=AuthHook" /> (???)


Of course, things get interesting if you want to insert ( or remove ) 
mbeans at runtime ( without completely stoping the server if possible ).
Both mechanisms support that ( with either sync or with a "server pause"). 


>>All configuration should be done using JMX. I have no doubt about
>>it ( well, JMX has its limitations, but the general model of
>>manageable components with light coupling is essential ).
>>
> I agree.


>>Instead of param-name/value - use JMX attributes. The handler is a JMX
>>component. For registration - I think we should use the standard JMX
>>notifications ( or your proposed API if JMX proves too complicated or
>>we can't get around its limitations )
>>
> That's true. But where do we get the initial value of those objects?

Configurable objects == mbeans.
You configure and name them, then use the reference ( name ) in the 
chain mbean configuration.


>>We could use a Chain MBean component where you declare ( as attributes )
>>the various hooks in the chain. ActionCode will correspond to a Chain.
>>That may be very nice - allowing hooks to be inserted at runtime, etc.
>>
> This is where I would like to go. Being able to set hooks at runtime
> using some descriptors. Or have an extension folder where JMX enabled
> hooks will be discovered and added, by default, to the end of the chain.

I like discovery - but for the server I preffer some explicit configuration.
Either Chain MBean or a "next"/"after" attributes are fine.

( a third option - each module can register itself explicitely during 
pre/post notifications or in start. ).


>>+0 - sounds good, but I would rather use NotificationBroadcaster :-)
>>( or some specialized version in modeler - to get around Filters ).
>>  
>>
> True. Filtering will certaintly be a performance hit... the question is
> do we want to be able to fully support jmx notification mechanism or
> part of it (by skipping the filter invokation). In modeler, you seems to
> have a solution for the filtering invocation. Have you make some test to
> see if it is faster?

I haven't finished the implementation - but it should be as fast as the
"non-jmx" version ( either Interceptor or Valve ). 

The main idea is simple: if you specify a o.a.c.modeler.FixedFilter as 
filter, the notification broadcaster used by modeler can see that he knows
about the filter. FixedFilter contract will say: even if I'm a filter that
needs to be invoked before each notification, I can tell you now that
I'll allways filter a particular type/attribute.

And the broadcaster can use this info to construct individual chains for
each notification emitted - with the same overhead as 3.3 Interceptor
( in 3.3 we introspect each module to find what methods/hooks are 
implemented, that's the "filter" ).

Everything else should be equal. 

BTW, the "handback" object is pretty nice, ThreadPool could work very
well with notifications/listeners :-).

>>That's a tricky one - besides String-based attributes
>>I think we need to use the "notes" ( i.e. index based ).
>>But I think the HandlerContext should just be an instance
>>of Notification ( with added notes and an int notification
>>code for faster dispatch ).
>>
> What about using the setUserData/getUserData for doing that?

I think "userData" should hold the Request or something like that.

Notification is a base class, just like Event. It is perfectly fine
to extend it with specialized methods - like 
  int getCode() 
  or getNote(). 

>>My preference is to try to just use JMX.
>>
> I agree. I will try to speak in term of jmx next time :-)

I'm not saying that JMX is the best solution or that I would -1 
if you propose something that is not JMX.

I want to have a JMX-friendly solution because it makes the whole
thing much cleaner and easier to work with. If JMX is not good 
enough for something - we use a custom solution.

Costin


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>