JBI provides some way to specify routing at deployment time, but not at
runtime using the jbi.xml configuration file.
If you want to do advanced routing in servicemix, there are two ways:
* either implement an EndpointChooser and set it on the activation
spec, or use it as the default one : the main problem is that
they can not be updated at runtime. We currently have very basic
policies : FirstChoicePolicy and RandomChoicePolicy.
We may be able provide more advanced policies, but it is imho quite
difficult to come up with generic policies.
If you have ideas about generic policies to implement, please tell
us so that we can discuss them.
You can also raise a jira and attach a patch when you have written
one :)
* using a service engine as a router : the main benefit is that by
undeploying / redeploying, you can change the routing policy.
This can be done using rules engines, such as drools, or xslt
routers.
We can also imagine using an external store and retrieve the
updated policies on a regular basis. The deployment would only
consist on a pointer to a set of rules in the external store.
I think that if the routing rules contains business logic, this should
be handled by a service engine and not a policy, to be able to
manage them easily using jmx. Policies imho, should be kept for simple
policies that can not fail, but this may be argued I guess.
Cheers,
Guillaume Nodet
Charles Souillard wrote:
I now well understand your explanation.
It helps me.
But I am surprised there no way to map OilProvider one time to Total
and another time to Elf...
Perhap I will work with Total for 1day and then move for 2 days to Elf
etc...
I am surprised to only have the solution to remove the SE !
I can also imagine I have many oil products and that I want to ship
15W40 oil to Elf and 15W50 to Total so I need to have both at the same
time !
What I was thinking is a way to configure JBI container to move from
one to the other very quickly. Perhaps this info could be carried in
the message sent through the NMR. Both Elf and Total implement
OilProvider...
What do you think about that ?
Regards,
Charles
Guillaume Nodet wrote:
The way to handle that is in my previous mail, but i focused on a bad
use case, i guess :)
To decouple the provider endpoint to the consumer endpoint, you
should use interfaces.
In your example, you will define an interface name (which is a
QName), for example: uri = http://com.foo.bar, name = OilProvider
When you deploy the Total SE, you will configure it so that it
implements the OilProvider interface (this can be set on the
activation spec,
or using a wsdl deployment).
When you want to call this provider, you will set the InterfaceName
of the MessageExchange to OilProvider without setting the service name
or endpoint name. In this case, the NMR will select an endpoint that
implements the given interface.
If at a later time, you want to switch to another provider, you only
have to deploy a new endpoint that implements the same interface,
and remove the old one, so that the NMR will be forced to use the new
endpoint, which is the only one implementing the OilProvider interface.
The only limitation of this approach is that the message must be
"normalized". So when you switch, you may have to put a
transformation to
speak to the new provider, but the consumer will be aware of it. The
only thing it needs is an endpoint that implements the OilProvider
interface
and that uses a defined xml schema : it can be a transformation
engine that will transform the request and route it to a binding
component (HTTP or
JMS), or whateever you can think about ...
Hope this helps,
Guillaume Nodet
Charles Souillard wrote:
Sorry, I was not clear...
I will take another example :
I am Supermarket appli (SE) and I normally deals with Elf for oil
products.
One day I decide to change my oil provider to Total.
What I want to know is if it is possible to configure a service
dynamically to now call Total ?
In fact my question is :
Does the message going out from my SE contains physical infos ?
If it is the case it means that my SE has to manage this.
Else, it means I can configure the JBI container to now associate my
logical "oil provider" to Total.
I think to be powerful, the container must offer such a feature. It
could not be a component feature as in the case I was dealing with
Elf through the JMS BC of servicemix, perhaps Total will use HTTP BC !
Is that clear ?
It is hard to explain that in a short way. I hope My abstract is
clear for you...
Thanks
Charles
Guillaume Nodet wrote:
In your example, you want a single request to be processed by
several providers and
aggregate their responses. This can not be handled automatically
by JBI : the aggregation part
must contains business logic and thus can not be done in a generic
way.
Such situations are extensively described in the EIP book
(http://www.enterpriseintegrationpatterns.com/eaipatterns.html).
Note that the EIP patterns are geared towards asynchronous
messaging, which is not always easy to map to an in-out mep,
because the patterns usually use in-only messages.
First, there are two possibilities :
* use publish / subscribe : each provider will register itself so
that it will receive messages. the main problem is for the aggregator
that has no simple way to know how many messages it will need to
aggregate
* use a recipient list
For the first case, ServiceMix offer two ways : internal publish /
subscribe (in the xml config, you specify on the activation spec
the endpoint you
want to subscribe to) or WS-Notification (servicemix-wsn2005
service engine).
Using a recipient list may be easier, as a JBI endpoints may
implement one or more interfaces. In this case, you could have a
component
which will ask jbi for endpoints implementing a known interface.
It could send an in-out to each of these endpoints, select the best
offer,
and discard the others.
JBI also defines interface base routing : when a consumer send an
exchange, it can specify the interface name that should service the
request.
The NMR will select an endpoint that implements this interface.
This can be customized using policies
(see org.apache.servicemix.jbi.resolver.EndpointChooser) on an
activation spec for example.
So to answer your question, there is a kind of mapping between
logical and physical endpoints, but this is done by interfaces.
Cheers,
Guillaume Nodet
PS: you can take a look at
http://www.enterpriseintegrationpatterns.com/RecipientList.html
http://www.enterpriseintegrationpatterns.com/PublishSubscribeChannel.html
http://www.enterpriseintegrationpatterns.com/Aggregator.html
Charles Souillard wrote:
What I mean by logical/physical endpoint is :
Let's take the example of a supermarket which deals with many food
providers.
Each time the supermarket wants to buy a product it choose the
best price between all of these food providers.
So I was thinking that we could have a logical endpoint which is
"food provider" and dynamically we can bind this logical partner
to a physical partner which could be "Danone" or "Labeyrie".
What I understand from your previous email is that to do such a
thing I will have to deploy two service assemblies (one for Danone
and one for Labeyrie) and I will have to specify (WHEN ? HOW ?)
the physical partner I want to deal with ?
About the storage, I was thinking that there was a map somewhere
containing :
* the possible mapping for a logical endpoint : all food providers
* the current mapping for a logical endpoint : Danone for example
What I think now is that I will have to give my two providers two
different names as they provides the same service (food provider)
and I will have to select one between the two when calling the JMS
binding Component for example...
If I am right on this, can you please explain me how I can
configure dynamically the partner I want to call ? How can I move
from one to one other dynamically ?
Thanks alot for your answers,
Regards,
Charles
Guillaume Nodet wrote:
What do you mean exactly by logical and physical ?
Let's take the example of jms : when deploy a wsdl with the
appropriate binding information,
the endpoints can be either consumer endpoint or provider
endpoint, in the jbi meaning.
A consumer endpoint will receive requests from the external world
and route them in the NMR.
A provider endpoint will receive requests from the NMR and route
them to the external world.
For a provider endpoint, a jbi endpoint will be activated with a
service name and an endpoint name
retrieved from the wsdl. Binding informations are used to
determine the queue / topic to use.
For a consumer endpoint, informations will be retrieved and a jms
consumer will be created.
Currently, the exchanges are routed to the jbi endpoint defined
by the service name and endpoint
name defined in the wsdl. Binding informations are used to
determine the queue / topic to
listen to.
There is no global store of this informations : each binding
component is responsible for mapping
its own protocol specific endpoints to jbi endpoints. However
all jbi endpoints can be accessed
via the jbi api and the wsdl description can be retrieved for
each jbi endpoint.
Guillaume
Charles Souillard wrote:
Guillaume,
thanks for your quick answer !
Have you got any any idea for my last 2 questions concerning :
* The way used to do the mapping logical/physical endpoint ?
* And where this map is stored ?
Regards,
Charles
Guillaume Nodet wrote:
The new BC will behave as you say.
So this is true for
* servicemix-http
* servicemix-jms
Note that these components are not finished yet, but i am
currently working on it.
When you will deploy a service unit, it contains informations
about the endpoints to create,
either consumer endpoint or provider endpoint.
Depending on the deployment model you will use (wsdl or xml),
the information is extracted
and use to create endpoints.
Cheers,
Guillaume Nodet
Charles Souillard wrote:
Hi all,
I just want to be sure of something about BCs.
My understanding is that BCs are "generic". It means the JMS
BC is deployed into SM only once and then if we want to
configure different endpoints (each partner has its own
queue/topic for example) we only have to deploy (JBI deploy)
new service assemblies containing some artifacts...
Can you just confirm this understanding or tell me if I am
wrong...
This question comes to me by thinking about JCA which is a
special case as each partner will have its own JCA connector I
think, isn't it ?
I have another question concerning endpoints. I just want to
know how the mapping is done between logical endpoints and
physical endpoints.
On the web site, I can read that UDDI is not yet supported so
where are stored these informations ?
Thanks,
Regards,
Charles