Holger, in JBoss 3.0 we have client interceptors, and pluggable transports.
The invocation has been totally decoupled from the EJB container. The EJB
Container is now just an MBean and all EJB invocations go across the JMX
bus.
JBoss 3.1 takes things a bit further. In 3.1 you can now define multiple
invokers (transports) per EJB container. So an EJB container can be
configured to receive requests from RMI, IIOP, SOAP, HTTP, whatever all at
the same time. We'll want to hook your HTTP invoker into this architecture.
The files and java packages you'll want to look at are as follows, There's
also a detail email I sent out 2 months ago that is copied later on in this
email:
In server module:
Packages org.jboss.invocation, org.jboss.proxy
org.jboss.invocation.jrmp.server.JRMPInvoker.java is the main entry point on
the server side. It accepts invocation requests and routes them across the
JMX bus. I think your HTTP POST protocol can be very simple. Just marshall
an Invocation and send it across the wire. The JRMPInvoker is stateless and
can route any Invocation.
For the client side, you'll need to implement a new
org.jboss.invocation.jrmp.interfaces.JRMPInvokerProxy. This is really the
"Transport" on the client side. You'll also need to implement a
org.jboss.proxy.ejb.ProxyFactory. The JBoss clustering can be used as an
example since it has extended JRMPInvokerProxy, ProxyFactory and has its own
Invoker. see the cluster module. All classes under the above packages.
What sucks is that even if you've implemented this stuff, its not very
helpful because JNDI does not have pluggable transports. This is something
we wanted to work on for JBoss 4.0. Make JNDI an MBean, as well as rewrite
client-interceptors/server-interceptors/proxy factories and their
configurations all in terms of MBeans and MBean invocations and MBean xml
descriptors. This is the major vision Marc has put forth. To make JBoss a
Unified architecture that can describe any distributed object framework as a
set of MBeans and MBean configurations. The classes are there, the
configuration isn't.
But, just get the HTTP invoker with EJB working, then we can work on JNDI
later.
Here's what I wrote back in April on the subject:
"JBoss 3.1 (CVS-HEAD) now has the ability to bind multiple invokers per EJB
container. This means that one EJB container can serve up requests from
IIOP, RMI, SOAP, <your-protocol-here> all at the same time. Also, if your
EJBs are configured correctly in jboss.xml Beans accessed through bean
ejb-refs will automatically and transparently use the correct protocol.
Meaning, if you start off on IIOP, you'll stay on IIOP (unless the call is
colocated).
There have been some fundamental changes to configuration:
1. <container-configuration> no longer has client-interceptors defined
within it. A new invoker to proxy factory binding has the
client-interceptor definitions for each proxyfactory/invoker binding combo.
2. Also, <container-invoker> configuration tag has been removed from
<container-configuration>.
3. jdk1.2.2 support has been removed from standardjboss.xml
4. THere are no more Clustered <container-configuration> definitions in
standardjboss.xml. They're no longer needed
Let's take a look at the new standardjboss.xml:
<jboss>
<invoker-proxy-bindings>
<invoker-proxy-binding>
<name>entity-rmi-invoker</name>
<invoker-mbean>jboss:service=invoker,type=jrmp</invoker-mbean>
<proxy-factory>org.jboss.proxy.ejb.ProxyFactory</proxy-factory>
<proxy-factory-config>
<client-interceptors>
<home>
<interceptor>org.jboss.proxy.ejb.HomeInterceptor</interceptor>
<interceptor>org.jboss.proxy.SecurityInterceptor</interceptor>
<interceptor>org.jboss.proxy.TransactionInterceptor</interceptor>
<interceptor>org.jboss.invocation.InvokerInterceptor</interceptor>
</home>
<bean>
<interceptor>org.jboss.proxy.ejb.EntityInterceptor</interceptor>
<interceptor>org.jboss.proxy.SecurityInterceptor</interceptor>
<interceptor>org.jboss.proxy.TransactionInterceptor</interceptor>
<interceptor>org.jboss.invocation.InvokerInterceptor</interceptor>
</bean>
<list-entity>
<interceptor>org.jboss.proxy.ejb.ListEntityInterceptor</interceptor>
<interceptor>org.jboss.proxy.SecurityInterceptor</interceptor>
<interceptor>org.jboss.proxy.TransactionInterceptor</interceptor>
<interceptor>org.jboss.invocation.InvokerInterceptor</interceptor>
</list-entity>
</client-interceptors>
</proxy-factory-config>
</invoker-proxy-binding>
...
The invoker-proxy-binding is a description of the binding between an Invoker
and the EJB proxy factory. It also contains the Proxy Factory's
configuration. For RMI ejbs, proxy-factory-config contains a list of
client-interceptors. If you look at the message-driven-bean
invoker-proxy-factory binding, you'll see that the proxy-factory-config
contains configuration for setting up JMS.
<invoker-proxy-binding>
<name>message-driven-bean</name>
<invoker-mbean>default</invoker-mbean>
<proxy-factory>org.jboss.ejb.plugins.jms.JMSContainerInvoker</proxy-factory>
<proxy-factory-config>
<JMSProviderAdapterJNDI>DefaultJMSProvider</JMSProviderAdapterJNDI>
<ServerSessionPoolFactoryJNDI>StdJMSPool</ServerSessionPoolFactoryJNDI>
<MaximumSize>15</MaximumSize>
<MaxMessages>1</MaxMessages>
<Optimized>True</Optimized>
<MDBConfig>
<ReconnectIntervalSec>10</ReconnectIntervalSec>
<DLQConfig>
<DestinationQueue>queue/DLQ</DestinationQueue>
<MaxTimesRedelivered>10</MaxTimesRedelivered>
<TimeToLive>0</TimeToLive>
</DLQConfig>
</MDBConfig>
</proxy-factory-config>
</invoker-proxy-binding>
Now, to actually see what the new multi-invokers can do, take a look at
.../testsuite/src/main/org/jboss/test/invokers and
.../testsuite/src/resources/invokers/META-INF.
Let's examine the ejb-jar.xml file and jboss.xml file for this test in the
testsuite.
ejb-jar.xml:
<entity>
<description>a simple bean managed entity bean</description>
<ejb-name>SimpleBMP</ejb-name>
<home>org.jboss.test.invokers.interfaces.SimpleBMPHome</home>
<remote>org.jboss.test.invokers.interfaces.SimpleBMP</remote>
<ejb-class>org.jboss.test.invokers.ejb.SimpleBMPBean</ejb-class>
<prim-key-class>java.lang.Integer</prim-key-class>
<persistence-type>Bean</persistence-type>
<transaction-type>Container</transaction-type>
<reentrant>false</reentrant>
</entity>
<session>
<description>A trival echo stateless session bean</description>
<ejb-name>StatelessSession</ejb-name>
<home>org.jboss.test.invokers.interfaces.StatelessSessionHome</home>
<remote>org.jboss.test.invokers.interfaces.StatelessSession</remote>
<ejb-class>org.jboss.test.invokers.ejb.StatelessSessionBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
<ejb-ref>
<ejb-ref-name>ejb/SimpleBMP</ejb-ref-name>
<ejb-ref-type>Entity</ejb-ref-type>
<home>org.jboss.test.invokers.interfaces.SimpleBMPHome</home>
<remote>org.jboss.test.invokers.interfaces.SimpleBMP</remote>
</ejb-ref>
</session>
You see that there are 2 beans defined. A BMP entity bean "SimpleBMP" and a
stateless session EJB "StatelessSession" that has an <ejb-ref> to the
"SimpleBMP"
Let's now look at jboss.xml.
<invoker-proxy-bindings>
<invoker-proxy-binding>
<name>entity-compression-invoker</name>
<invoker-mbean>jboss:service=invoker,type=jrmp,socketType=CompressionSocketF
actory</invoker-mbean>
<proxy-factory>org.jboss.proxy.ejb.ProxyFactory</proxy-factory>
<proxy-factory-config>
<client-interceptors>
<home>
<interceptor>org.jboss.proxy.ejb.HomeInterceptor</interceptor>
<interceptor>org.jboss.proxy.SecurityInterceptor</interceptor>
<interceptor>org.jboss.proxy.TransactionInterceptor</interceptor>
<interceptor>org.jboss.invocation.InvokerInterceptor</interceptor>
</home>
<bean>
<interceptor>org.jboss.proxy.ejb.EntityInterceptor</interceptor>
<interceptor>org.jboss.proxy.SecurityInterceptor</interceptor>
<interceptor>org.jboss.proxy.TransactionInterceptor</interceptor>
<interceptor>org.jboss.invocation.InvokerInterceptor</interceptor>
</bean>
</client-interceptors>
</proxy-factory-config>
</invoker-proxy-binding>
<invoker-proxy-binding>
<name>stateless-compression-invoker</name>
<invoker-mbean>jboss:service=invoker,type=jrmp,socketType=CompressionSocketF
actory</invoker-mbean>
<proxy-factory>org.jboss.proxy.ejb.ProxyFactory</proxy-factory>
<proxy-factory-config>
<client-interceptors>
<home>
<interceptor>org.jboss.proxy.ejb.HomeInterceptor</interceptor>
<interceptor>org.jboss.proxy.SecurityInterceptor</interceptor>
<interceptor>org.jboss.proxy.TransactionInterceptor</interceptor>
<interceptor>org.jboss.invocation.InvokerInterceptor</interceptor>
</home>
<bean>
<interceptor>org.jboss.proxy.ejb.StatelessSessionInterceptor</interceptor>
<interceptor>org.jboss.proxy.SecurityInterceptor</interceptor>
<interceptor>org.jboss.proxy.TransactionInterceptor</interceptor>
<interceptor>org.jboss.invocation.InvokerInterceptor</interceptor>
</bean>
</client-interceptors>
</proxy-factory-config>
</invoker-proxy-binding>
</invoker-proxy-bindings>
First in jboss.xml you'll see 2 new invoker-proxy-bindings defined.
"entity-compression-invoker" and "stateless-compression-invoker". THese are
bindings to a new JRMPInvoker "CompressionSocketFactory". Basically the
invoker is a RMI server with Customer sockets. THe custom sockets gzip the
request before sending it across the wire. jboss.xml continues to define
the EJBs and the relationships these beans have to various invokers:
<enterprise-beans>
<entity>
<ejb-name>SimpleBMP</ejb-name>
<invoker-bindings>
<invoker>
<invoker-proxy-binding-name>entity-compression-invoker</invoker-proxy-bindin
g-name>
<jndi-name>CompressionSimpleBMP</jndi-name>
</invoker>
<invoker>
<invoker-proxy-binding-name>entity-rmi-invoker</invoker-proxy-binding-name>
<jndi-name>SimpleBMP</jndi-name>
</invoker>
</invoker-bindings>
</entity>
The configuration above shows how you can allow an EJB to be served up by
multiple different invokers. You must describe each invoker the EJB will
deploy with. For each invoker-binding you define, a HOME proxy will be
created that is attached to the invoker under the jndi-name for each invoker
you define. 2 homes will be bound to JNDI "CompressionSimpleBMP" and
"SimpleBMP"
Let's continue:
<session>
<ejb-name>StatelessSession</ejb-name>
<invoker-bindings>
<invoker>
<invoker-proxy-binding-name>stateless-compression-invoker</invoker-proxy-bin
ding-name>
<jndi-name>CompressionStatelessSession</jndi-name>
<ejb-ref>
<ejb-ref-name>ejb/SimpleBMP</ejb-ref-name>
<jndi-name>CompressionSimpleBMP</jndi-name>
</ejb-ref>
</invoker>
<invoker>
<invoker-proxy-binding-name>stateless-rmi-invoker</invoker-proxy-binding-nam
e>
<jndi-name>StatelessSession</jndi-name>
<ejb-ref>
<ejb-ref-name>ejb/SimpleBMP</ejb-ref-name>
<jndi-name>SimpleBMP</jndi-name>
</ejb-ref>
</invoker>
</invoker-bindings>
</session>
The "StatelessSession" bean works basically the same as the SimpleBMP as far
as describing multiple invokers. You'll see <ejb-ref>s can be described for
each invoker binding. So, if you invoke on a Compression StatelessSession
and access a SimpleBMP, the SimpleBMP you get back will be a Compression
SimpleBMP. All seemless. If you do not have to define <ejb-ref> for each
invoker, for instance, you could do this instead:
<session>
<ejb-name>StatelessSession</ejb-name>
<invoker-bindings>
<ejb-ref>
<ejb-ref-name>ejb/SimpleBMP</ejb-ref-name>
<jndi-name>CompressionSimpleBMP</jndi-name>
</ejb-ref>
<invoker>
<invoker-proxy-binding-name>stateless-compression-invoker</invoker-proxy-bin
ding-name>
<jndi-name>CompressionStatelessSession</jndi-name>
</invoker>
<invoker>
<invoker-proxy-binding-name>stateless-rmi-invoker</invoker-proxy-binding-nam
e>
<jndi-name>StatelessSession</jndi-name>
</invoker>
</invoker-bindings>
</session>
Also, you do not have to define <invoker-bindings> for all your EJBs now.
There is a default for each entity bean type. This applies to clustering as
well.
Some class name changes:
ContainerInvoker.java -> EJBProxyFactory.java
ContainerInvokerContainer.java -> EJBProxyFactoryContainer.java
LocalContainerInvoker.java -> LocalProxyFactory.java
BasicLocalContainerInvoker.java -> BasicLocalProxyFactory.java
Well, that's about it. Hope you like it! Hope it doesn't cause too many
new problems :)
Regards,
Bill"
> -----Original Message-----
> From: [EMAIL PROTECTED]
> [mailto:[EMAIL PROTECTED]]On Behalf Of
> Holger Engels
> Sent: Friday, June 21, 2002 5:00 AM
> To: [EMAIL PROTECTED]
> Subject: [JBoss-dev] http transport
>
>
>
> I try to understand, how a http transport can be implemented within jboss
> .. so what do I need?
>
>
> on the server side:
>
> o a connector servlet / extra http deamon, that accepts invocations
> embedded in http posts. the result of a home invocation is a handle.
> subsequent invocations (remote interface) contain the handle to identify
> the target ejb. the servlet is completely stateless.
> o an mbean service, that manages the servlet / http deamon
>
>
> on the client:
>
> o some interceptor (the last one in the chain), that marshalls the
> invocation as an http post request and demarshalls results / throwables.
> I call it the 'Transport'
> o is a special handle implementation required?
> o usertransaction handling is transparent (part of Invocation)?
>
>
> configuration:
>
> o it's the server's job to provide the connector servlet. the servlet
> doesn't need to be configured. the invocations carry all the information
> that is required to perform home-/ remote-invocations.
>
> o the client will do a lookup first (coded name, declared in the
> application-client descriptor). it then gets a dynamic proxy passing on
> the java style invocation to the invocation handler. the invocation
> handler feeds the invocation into the interceptor chain. this chain has
> to be configured somehow (during deployment of the application-client
> jar).
>
> o afaik there's no application client deployment at the moment and the
> client side interceptors are configured from the server, right?
>
>
> so what makes up the whole interceptor chain? we distinguish:
>
> o client side interceptors
> o server side interceptors (synchronization, pooling / caching, security)
> o symmetric interceptors (encryption / decryption for instance)
>
> the overall configuration of the (ordered) interceptor chain is made of
> component aspects and reference aspects. transport is just another aspect
> of the reference.
>
>
> authentication:
>
> in the smartcc, using the http transport requires a http login module
> (basic/digest auth) to be configured. the authentication task is
> performed
> by the servlet container. the container cares about setting up the
> security association.
>
>
> dain asked for an http plugin for jndi. my question: why do I need the
> server side's jndi content on the client if I don't lookup homes? what
> does a java client need beside what's configured in the
> application client
> descriptor. what am i missing?
>
> holger
>
>
>
> -------------------------------------------------------
> Sponsored by:
> ThinkGeek at http://www.ThinkGeek.com/
> _______________________________________________
> Jboss-development mailing list
> [EMAIL PROTECTED]
> https://lists.sourceforge.net/lists/listinfo/jboss-development
-------------------------------------------------------
Sponsored by:
ThinkGeek at http://www.ThinkGeek.com/
_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-development