Two-way Apache Camel Routes - Infinite loop - apache

I have 2 endpoints that I would like to establish routes between. Due to the nature of these endpoints (JMS topics), I would like the bridging to be bidirectional.
The underlying JmsComponent for the Tibco endpoint has the pubSubNoLocal parameter enabled which ensures that a consumer does not receive messages it has itself sent as per http://camel.apache.org/jms.html
pubSubNoLocal false
Specifies whether to inhibit the delivery of messages published by its own connection.
However this has no effect since the 2 routes create separate connections to the JMS topic my.topic.
As a result, the following will create an infinite loop.
As mentioned, I need the routes to operate in both directions for "seamless integration"
<c:route>
<c:from uri="tibco:topic:my.topic"/>
<c:to uri="solace-jms:topic:mytopic" />
</c:route>
<c:route>
<c:from uri="solace-jms:topic:mytopic"/>
<c:to uri="tibco:topic:my.topic" />
</c:route>

I suggest le consideration the concepts of message selectors and headers.
The way I see it, you do 2 things:
Add a "PRODUCER" header with your Server ID (however you define it)
All your listeners must be configured with a negative selector "NOT (PRODUCER='YOUR_ID')"
Done ?
(Of course, you could also use 2 topics... but I assume it is out of the question...)

You will need to add some indication in the message that it has been sent through either bridge. You could play with existing properties (redelivery ?) or better add a new one. For example set property bridged=true when it passes your bridge. Then inside your definition you can filter out each message already bridged.

Related

RabbitMQ headers exchange routing: match all listed headers

I have a lot of consumers with different set of features, so I want route message to process to correct one. I decided use headers exchange and specify necessary features in message headers, but here fall into obstacle.
In rabbitMQ there is binding argument x-match which may take values only any and all (https://lists.rabbitmq.com/pipermail/rabbitmq-discuss/2013-July/028575.html). Each consumer instead while binds has big list of available features (most of them are true/false, but also there are strings), which I specify as binding arguments along with x-match argument. But when I publish message I wanna specify only necessary headers, for instance, feature-1 and feature-7 with specific values. I don't even know about all available consumer features when publish the message. And here is problem: if I miss some of binding argument when x-match==all, message won't be routed, and if I set x-match to any, the only matching header is enough to route message - despite another header's value may not match.
To give you example, let's consider consumer with features: country=US, f1=true, f2=true, f3=false.
Scenario 1: So I attach (create binding) its queue to headers exchange with these arguments and x-match set to all. Then I publish message and I need country to be "US" and f2 to be true. I don't know anything about other possible consumer features. Message won't be routed, because not all headers match exactly.
Scenario 2: Another use case is if I bind queue with x-match argument set to any. If I specify again country to be "US" and f2 to be true - message will be routed, but also it will be (incorrectly) routed if f2 is set to false and only country matches.
So probably I misunderstand something, but I look for easiest solution for me: how to route message to right consumer based on list of necessary features. I would like to use something like all-specified value for x-match argument which wouldn't demand list all available features but will require all given headers to match exactly.
Indeed, only own exchange may help for my purpose. If I'm succeed in erlang I'll report here.
Update
I managed to write own plugin which fits my purposes. Probably it is not perfect but works good for me for now.
https://github.com/senseysensor/rabbitmq-x-features-exchange

Is it safe to rely on session variables to store information to be shared between multiple asynchronous flows?

I have a couple of flows that rely on session variables that are generated in one flow and then passed to the other. Is it safe to rely on session variables used by two asynchronous flows? I guess I don't fully understand the scope of 'sessionVars' in a mule application or in a given mule message.
The mule session has nothing to do with the Java EE session that is shared across threads. The mule session is part of the MuleMessage and how they works is explained here, therefor if you want to share something across multiple flows processing the same message that is the way to go.
If instead you are looking into a way to store a value from a flow processing the message A and pick that value from a flow processing the message B you should consider store this value into the objectstore
I am pretty sure that session variables are returned to http endpoints that are request-response. This could expose sensitive data. I am trying to locate the original mention and official mitigation strategy but have yet to locate it again.
But an easy solution is to remove them at return point of a flow
Edit:
Found the thing I was looking for...
`
<http:connector name="NoSessionConnector">
<service-overrides sessionHandler="org.mule.session.NullSessionHandler"/>
</http:connector>
`
found here under 'HTTP Response Header'
http://www.mulesoft.org/documentation/display/current/HTTP+Transport+Reference
Or, you can also create a custom SessionHandler

Apache Camel : "direct:start" endpoint - what does it mean?

I'm new to Apache Camel. Can someone explain what "direct:start" means in Camel.
Please see
https://camel.apache.org/components/latest/http-component.html
from("direct:start")
.to("http://myhost/mypath");
Thanks.
The "direct:start" above is simply saying that the route starts with a Direct Component named "start".
The direct endpoint provides synchronous invocation of a route. If you want to send an Exchange to the direct:start endpoint you would create a ProducerTemplate and use the various send methods.
ProducerTemplate template = context.createProducerTemplate();
template.sendBody("direct:start", "This is a test message");
There is nothing special about the name start. It is simply the name you are going to use when referring to the endpoint and could have just as easily been direct:foo.
Assume like the direct route as a method with name start , so we need to call the start method /direct route to perform certain operation. The below example will help .
The first route will be triggered when an input file is available in XXXX location and when it reaches line , the actual flow will go to second route. Basically the direct route with from endpoint will be triggered by some producer endpoint.
<route id="fileRoute">
<from uri="file:XXXX">
..
<to uri="direct:start">
</route>
<route id="directStartRoute">
<from uri="direct:start">
<to uri="http://myhost/mypath">
</route>
Apache Camel direct is basically for sending Exchange from one route to another in SAME Camel context. So let’s say you are getting message from AMQ and you want to populate headers for every message you get and then send it to mail recipient list. So here you need to create new router which has following description
from(“direct:populateHeaders”)
.setHeader(“myHeader”, “myHeaderValue”)
.end()
And from any route you can send your Exchange object to this route by writing
...
.to(“direct:populateHeaders”)
...
Its important to keep in mind that this will not work out of your Camel Context.
direct:start provides synchronous ways to communicate between 2 endpoints and this is only been used if you want to communicate using camel messages and not generic file or xml messages.
Consider it like this :
There are two things whenever you are sending a message to camel route.
1. The URI scheme, which defines how your message is going to be delivered. And to which component type it is going to be delivered.
2. URI path, which defines the instance of that component.
Now, to your direct:start location.
'direct' tells that this message should send synchronously to the Direct Component.
'start' tells which instance of the Direct Component this message should be delivered.
Importance of different URI path:
Now consider if you are having to different routes. And wants to produce message from two different threads synchronously. Using 'direct:start' as start point for the routes will not work. Unless you are having some conditional processing component, forget this if you are beginner.
For, successfully deliver the messages to both the routes , you will have to add 2 entries i.e. 'direct:somename1' and 'direct:somename2'. 'start' is not a mandatory thing , you can give whatever name you like to.
I recommend you to read some chapters from Martin Fowler's EIP books. It is a wonderful resource to begin with. This will make you very easy to understand Camel.
It should be fairly easy to explain: exchange is always sent from a source to a destination. For that to happen, you need to create those 02 endpoints: one will consume (yes the start) and the other one will emit.
from("direct:start") means "directly consume the exchange from the "start" endpoint and process it anyhow.
to("direct:start") means "send" the exchange to the "start" endpoint "directly" within the same camel context.
What makes this really ambiguous is that the endpoint itself (i.e: "direct:start") is implicitly created on the fly so when writing your code, you are assuming that there is an endpoint called "direct:start" so you can retrieve exchange from it but you can also send an exchange to it.
Good luck!
forget about start. start is just a name of a halt point (direct).
Direct component can be take as a bridge between routes in same context.

asterisk load balancing using openser/opensips

I need to load balance incoming calls to asterisk. To do this, I have set up the Openser server in front of it and I loaded and configured the dispatcher modules to do so. What I want to do is that the Openser server will receive the calls and route them to the least "busy" Asterisk server which will take care of the rest (I have an IVR menu set up in each of the servers). I am using X-Lite softphone for testing. The same users are registered in both Asterisk and Openser. When I initiate the call it just goes across the Openser server, it does not get forwarded to any of the Asterisk boxes. I am wondering if I am missing any configuration or step in my set up.
Thank you in advance
The dispatcher module cannot do any type of load balancing. It is a "stateless" module, that means that it does not keep track of how many calls are sent to each box.
You can choose different types of routing logic, the available types are:
“0” - hash over callid
“1” - hash over from uri.
“2” - hash over to uri.
“3” - hash over request-uri.
“4” - round-robin (next destination).
“5” - hash over authorization-username
“6” - random (using rand()).
“7” - hash over the content of PVs string.
“X” - if the algorithm is not implemented, the first entry in set is chosen.
The one most likely to distribute the load fairly is round-robin (option 5).
To use it, call the following function in the route section of your openser.cnf:
ds_select_dst("1", "5");
The first parameter is your GW group, the second is the routing type.
For more info check this page
Hope this helps
The dispatcher module cannot do that. You'd have to use the (surprise!) load balancer module

BizTalk Dynamic WCF-WSHttp Send Port reverting to Http Adapter

I'm trying to send a message to the WCF-WSHttp adapter with a dynamic
send port from an orchestration, but BizTalk seems to always be
reverting back to the HTTP Adapter.
According to the docs that I've been able to find, I should just need
to set the transport type from my expression shape to get BizTalk to
use the WCF-WSHttp adapter, and I AM, but it still seems to be
reverting. Below is an example of my expression shape that's setting
the properties (as you can see, I've tried both
Microsoft.XLANGs.BaseTypes.TransportType and
BTS.OutboundTransportType):
Body(BTS.OutboundTransportType) = "WCF-WSHttp";
SendMessagePort(Microsoft.XLANGs.BaseTypes.Address) =
System.String.Format("{0}/Accept{1}", "http://myserver/myservice/
myservice.svc/Accept{0}", messageInfo.MessageType);
SendMessagePort(Microsoft.XLANGs.BaseTypes.TransportType) = "WCF-
WSHttp";
Probably are Craig :-)
When using a dynamic send port, BizTalk uses the "scheme" part of the url to decide which adapter to use.
When your url starts with "Http://" or "Https://" BizTalk would always use the HTTP adapter.
Similarly url's begining with ftp:// will use the FTP adapter.
Same works for custom adapaters as well - when you install the adapter's configuration you register the moniker to use; for example - the open source Scheduled Task adapter uses schedule:// (I believe).
Using dynamic send ports with WCF is slightly more involved than most other adapaters because of the various configuration that's required but you can find detailed explanation here, just scroll down to the "Dynamic Send Ports" section about half way down.
I ended up resolving my issue, but am still unsure of the reasoning for the behavior I saw.
The Expression shape mentioned in the question was located inside of an Atomic Scope. Once the Orchestration exited the scope containing the Expression shape, the Transport Type was reset back to its original value. Moving the Expression out of the atomic scope resolved the issue, in that the TransportType was set correctly.