Hi Ryan

thanks for this update, please see comments inline.

On Tue, May 3, 2011 at 7:58 AM, Ryan Zoerner <ryanzoer...@gmail.com> wrote:
> Dear Sergey,
>
> I would like to update you and the team about the Integrating CXF JAX-RS
> with EJB project.
>
> Starting with the Server.java file in the "basic" http demo, found at
>
> http://svn.apache.org/viewvc/cxf/trunk/distribution/src/main/release/samples/jax_rs/
>
> I have been doing some codetracing starting with JAXRSServerFactoryBean.
>
> I have taken a hint from the Spring setup files (beans.xml) shown in the
> JAX-RS guide,
> which starts, and branches out from, here:
>
> http://cxf.apache.org/docs/jax-rs.html
>
> The hint is that most of the setup involved in implementing a CXF webservice
> is making
> sure that all of the necessary attributes have been defined. When you look
> at the source
> code and see a bunch of fields, it does not make the situation as plain as
> when you look
> at the beans.xml file and see that the logger that we need is this logger,
> etc.
>

I agree...

> So, I have come to view the application as primarily setting up a list of
> properties that
> we need to have defined in order to run the service. In other words, we need
> to define
> what should be attached to the application in order to have a working app.
> For instance,
> you wouldn't want to have a house without attaching a door.
>
> Ok. So, from that I have been doing method tracing from the
> JAXRSServerFactoryBean and
> have come up with the following list of files, which I have saved copies of,
> into a
> sub-folder of the 'basic' demo, in order to go over them. The list of files
> looks like
> this:
>
> S:.
> ├───exchange
> │       ArrayList.java
> │       Exchange.java
> │       ExchangeImpl.java
> │       Map.java
> │       MessageContentsList.java
> │       Response.java
> │       StringMap.java
> │
> ├───invoker
> │       AbstractInvoker.java
> │       Invoker.java
> │       JAXRSInvoker.java
> │       ResourceProvider.java
> │
> ├───log
> │       LogUtils.java
> │
> ├───resourceInfo
> │       AbstractResourceInfo.java
> │       ClassResourceInfo.java
> │       OperationResourceInfo.java
> │
> ├───server
> │       AbstractJAXRSFactoryBean.java
> │       JAXRSInInterceptor.java
> │       JAXRSServerFactoryBean.java
> │
> ├───service
> │       AbstractAttributedInterceptorProvider.java
> │       AbstractServiceFactoryBean.java
> │       Configurable.java
> │       HashMap.java
> │       InterceptorProvider.java
> │       JAXRSServiceFactoryBean.java
> │       JAXRSServiceImpl.java
> │       Service.java
> │
> └───utils
>        InjectionUtils.java
>        SingletonResourceProvider.java
>
> The key files that I find so far, in regards to a new invoker are:
> │       AbstractInvoker.java
> │       Invoker.java
> │       JAXRSInvoker.java
>
> │       AbstractResourceInfo.java
> │       ClassResourceInfo.java
> │       OperationResourceInfo.java
>

You've listed all the key resources here.
JAXRSServerFactoryBean is used directly or indirectly (when Spring is
used) to create a running JAX-RS endpoint.
JAXRSServerFactoryBean delegates to JAXRSServiceFactoryBean for
analyzing root resource classes and building a collection of
ClassResourceInfo objects (where each ClassResourceInfo object
corresponds to a root or sub resource class). Each ClassResourceInfo
has a collection of OperationResourceInfo object, each of them
corresponding to a particular JAX-RS resource method.

When the invocation is processed, JAXRSInInterceptor finds a matching
ClassResourceInfo and OperationResourceInfo, converts payload and URI
path and query parameters into method parameter objects, and saves it
all on the current Exchange or Message.

JAXRSInvoker proceeds with the actual lnvocation...

> Apparently, the invoker gets some of the info that it needs about what
> Object and Method to invoke upon,
> from the exchange Object. [Not completely sure that this is correct].
>

Yes

> Then, apparently, the ClassResourceInfo class finds out about the
> annotations of the class that needs
> to be invoked upon. [Not completely sure that this is correct]
>

JAXRSInInterceptor does all of that initially; JAXRSInvoker may also
do it but only of a current method which is being invoked is a
subresource locator.

> The second part is one of two key operations necessary to implement JAX-RS
> in general. The requirements
> to create a resource are as follows:
>
> Resources-
> A new resource class is created for each request to that resource.
> 1. The constructor is called.
> 2. Any requested dependencies are injected.
> 3. The appropriate method is **invoked**.
>

Yes, that is correct. Note that no new resource is necessarily created
on every request. JAXRSInvoker asks ResourceProvider to give an
instance back, and if it is a singleton provider then the same
instance is returned back every time.

> The second item here may require some custom coding because of the unique
> annotations that are associated
> with EJB. Second, The ClassResourceInfo file may automatically deal with the
> annotations already, since it
> uses reflection to obtain a list of annotations associated with the fields
> of the class. It also does so
> for the methods in the class and also, with the superclasses associated with
> the class.
> [Not completely sure that this is correct]
>
> Apparently, though, the ResourceInfo classes are the key to obtaining the
> necessary information about the
> class upon which to be invoked.
>

Yes. I think for this project we will just explicitly configure
jaxrs:server endpoint with the name of EJB classes which have been
annotated with JAX-RS resources. That will help us to get started
fast. I'm thinking that the package scanning feature would be nice but
we have to prioritize. The other thing we need to do is to provide a a
custom ResourceProvider implementation which will handle the lifecycle
of EJB beans.

> On another note, I am familiar with the Enterprise Service Bus from SOA. The
> Enterprise Service Bus may be
> seen as a large set of cables banded together.

That is a nice definition, something new :-)

> The job of the Enterprise
> Service Bus is to be the connections
> between various services connected to the bus. In a typical SOA system,
> message passing might be done more
> formally using SOAP messages and WSDL files, which I think, are a subset of
> SOAP? but I am unsure. The SOAP
> messages enable the bus, and all of the legacy applications attached to it,
> to communicate: bus-to-app, and
> app-to-bus, according to a common message format. The message typically says
> something like: I need these
> parameters answered with this information. This means that an application
> can pass a message, via the bus,
> to another application connected to the bus.
>
> I see that CXF is designed in the same way. What seems to be the case is
> that there are messages and
> Interceptors to deal with messages. I think that this is the main way that
> CXF allows various services
> attached to the bus, to communicate with one another. For instance, if you
> have a customer service and
> a customer associated purchases system, and they are on two different urls,
> then you might be able to
> interface between the two services utilizing the message passing system of
> CXF [If this is incorrect,
> please let me know]. I already see that most of the Interceptor duties seem
> to be related to delivering
> unexpected situations that arise, to some other place in the form of a
> message. If I am wrong about this,
> does CXF provide some mechanism for services to communicate with each other
> through it, or is that simply
> the job of the service implementor, to create all of this themselves?
>

It's a pretty fundamental analysis that you do, good effort.

> In using the http demo, it occurred to me that it might be better to have a
> ComplexEntity<T> class,
> instead of a Customer class and a ComplexEntityService<T> class instead of a
> CustomerService class.
> This would enable the user to pass any ComplexEntity to these classes, and
> using reflection, obtain
> the same result every time. The other thing that I thought of here is that
> it might be a good idea
> to have a PrimaryIdentifier annotation for the xml field that you would like
> to use as the primary
> key for locating the ComplexEntity. For instance, with Customers, the
> PrimaryIdentifier would be
> the long value: id. I have seen the ClientFactory and am impressed with the
> utility of it, given
> that you can supply only the basic necessary details and obtain a client.
> However, taking away
> the need to code individual files to deal with a Customer, or an Order,
> might be a nice addition.
>

That would be a nice addition. However it's more about refactoring the
actual java resource as opposed to
experimenting with JAX-RS. Here is  what I'd like to suggest, for us
to be on track with getting up to speed with JAX-RS.
Update jaxrs/basic demo as follows:
- register a custom ResourceProvider implementation which will just
print the current invocation number; we will need a custom
implementation for the project too, so, registering a simple custom
provider will help you to see and debug how JAXRSInvoker interacts
with ResourceProvider
- update CustomerService to throw an exception for a certain customer
name/id and register a custom ExceptionMapper implementation which
will convert this exception into 400 status
- register a custom invoker which extends JAXRSInvoker and prints the
name of the method to be invoked before delegating to JAXRSInvoker
- add another resource method to CustomerService with some new @Path
value and @GET method and invoke on it from the browser
- add another sub-resource method to CustomerService with some new
@Path value and invoke on it from the browser

I feel it can help you with getting up to speed real fast. If you can
get it working by Monday/Tuesday next week or earlier then it would be
a very good progress IMHO and then we can move on to seeing how CXF
(JAX-WS) works with EJB and then finalizing it with providing a custom
ResourceProvider and/or invoker

> The other thing that I note here is that I see that there is a code-gen
> mechanism and I think that
> there is a xsd2java mechanism, but whether or not this can create a Customer
> class from a superClass
> such as turning ComplexEntity into Customer by substituting Customer in
> place of the appearance
> of ComplexEntity, I do not know. In theory, it might be nice to make an xsd
> generator that would
> set "one or more" by default, and certain other, potentially configurable,
> default values, so
> that java classes for complex entities could be created from a simple xml
> file and a corresponding
> xsd file might also be created, or at least a template, from the xml.
>

At the moment the only way to get code generated from a schema and
make it JAX-RS aware is to use a jaxb plugin which can generate
classes from a schema and  then apply an external model to those
classes or manually add JAX-RS annotations. We'll have a WADL
generator too. Lets chat about it a bit later on.

> Ok. So, back to the project. The files that I am now focusing on are the 5
> that I named above. I think
> that this is the key to invoking upon EJB beans, and that everything else in
> the process might be
> taken for granted as being not part of the properties mapped to the Server
> (or? Client) that involve
> instantiating, injecting depencies upon, and invoking upon, the ejb and ejb
> method. I say mapped
> to the server, but I mean it in regards to the xml-idea that I mentioned
> above. That there are a
> set of classes attached to the Server, like trees, with the trunk ending up
> in the ServerFactory, or
> one of the classes that it calls. Just basic programming, I guess, but it
> helps me eliminate, in my
> mind the things that I won't need to look at in order to make this work
> (hopefully).
>
> If I've said anything in all of this that doesn't make any sense, or if you
> have any corrections
> to the things that I've said, or if you have any questions about what I
> said, or if you have
> any suggestions. Please feel free to comment.
>

Please experiment with the jaxrs/basic demo as suggested above. Next
week we can start with looking at how CXF JAXWS handles EJB
invocations

Thanks, Sergey

> Thank you.
>
> Ryan Zoerner
>



-- 
Sergey Beryozkin

Application Integration Division of Talend
http://sberyozkin.blogspot.com

Reply via email to