I am trying to connect to rabbitmq-c in centos 5.6 and test its function in c client following the steps of the website: http://www.rabbitmq.com/tutorials/tutorial-one-java.html.
However, it fails when I use the default exchange.
For example, I want to send a message, "Hello world", to a queue named "myqueue" via the default exchange whose name is "(AMQP default)".
In java, here is the code:
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
But in c, when I run rmq_new_task.c (almost the same as amqp_sendstring.c) as the examples on https://github.com/liuhaobupt/rabbitmq_work_queues_demo-with-rabbit-c-client-lib.
queuename="myqueue";
......
die_on_error(amqp_basic_publish(conn, amqp_cstring_bytes(exchange),
amqp_cstring_bytes(routingkey), &props, amqp_cstring_bytes("Hello world")),
"Publishing");
In the java client, we just set the parameter "exchange" to "" to tell the server that we'd send the message to a specified queue named the same as routingkey via the default exchange.
So what value should I give the second parameter "exchange" in c client (using the default exchange)? I tried to set it to "" or "amq.direct". It didnot show any error while running and seemed working well.
However, when I checked in the rabbitmq-management(http://localhost:55672/#/queues), the queue named "myqueue" did not exist!
Would someone please point me to the right direction? I'd really appreciate!
Take a look at http://www.rabbitmq.com/tutorials/amqp-concepts.html and specifically look for the section entitled Default Exchange.
The usage of the default exchange is very simple.
In java you would do:
channel.basicPublish("", "hello", null, message.getBytes());
By specifying "" in says to use the default exchange. (There should be no need to use amq.direct)
As per the article above it states:
The default exchange is a direct exchange with no name (empty string)
pre-declared by the broker. It has one special property that makes it
very useful for simple applications: every queue that is created is
automatically bound to it with a routing key which is the same as the
queue name.
So that means publishing to the default exchange will only work if you have already created the queue that you want to publish to.
So you will need to create your queue before you can publish to the default exchange. Once you've done that you will start seeing your messages.
Related
all.
I have some route of camel.
My scenario is below.
1. file size checking on remote server
2. store the file size on header
3. get the file by sftp through pollenrich
4. compare the size of downloaded file with the size of original header value
5. if there is different, retry the download
I know that the value of old header is disappear after pollenrich.
Is there any anything to meet my scenario I can do?
Thank you.
As #burki has said, a custom aggregation strategy will work. Here is an example propagating a message header and an exchange parameter from the initial exchange to the new exchange.
.pollEnrich()
.simple("myUrl?param=${header.myUrlParameter}")
.aggregationStrategy( new AggregationStrategy() {
public Exchange aggregate( Exchange oldExchange, Exchange newExchange )
{
newExchange.getIn().setHeader( "MyHeader", oldExchange.getIn().getHeader( "MyHeader" ) );
newExchange.setProperty( "MyProperty", oldExchange.getProperty( "MyProperty" ) );
return newExchange;
} } )
I hope this helps.
You should be able to use pollEnrich with an AggregationStrategy that implements how the original message and the enrich message are merged.
I guess you are getting the merge result of the default strategy because you don't reference a strategy.
Have a look at the first example of the Enrich Options in the Camel docs (section "Using the Fluent Builders").
I think you should be able to integrate headers from the original message into the merged message so that they are still available after the enrich step.
Try as I might I cannot seem to make quickfixj take a dictionary - or indeed give any sign its registered the dictionary at all, I have no choice but to use the dictionary and it is not something I have control over. I've tried various uses of the DataDictionary property which is in the documentation and in quickfixJEndpoint class, but I really expect to set it on the endpoint, but dont seem to have any way to do that
I have an accpetor A
and an initiator B
I want to send a message from acceptor to intitiator via A->B
send an ack back from initiator to accpetor via B->A
The last place it 'works' is just before sending to the fix endpoint A->B
The initiator and acceptor connect, handshake and log-on with no problem, then the acceptor constructs its non-standard fix-message and send it, right before it sends is the last time before an exception occurs.
It includes a tag '15' which is causing a problem because the type it is being used on does not normally include 15, but with the DataDictionary it does - but it isn't loading the dictionary and quickfixj is throwing an invalidField exception because it doesn't like tag 15 being there since its not on the base-type.
I set on the exchange everything I can to make it acknowledge the datadictionary, everywhere I can
on route
in process {
TradeCaptureReport fix = new TradeCaptureReport();
fix.setString( 15, "my value" );
....
exchange.setProperty( QuickfixJEndpoint.DATA_DICTIONARY_KEY, "mydictionary.xml" )
exchange.getOut().setProperty( QuickfixJEndpoint.DATA_DICTIONARY_KEY, "mydictionary.xml" )
exchange.getOut().setBody( fix );
}
quickfix.FieldException: Tag not defined for this message type,
B->A , error> (Reject sent for Message 2: Tag not defined for this message type:15)
It never reaches the code inside the acceptor which would normally receive A->B and return B->A as a response, so although it report B->A and think that is incorrect
I hope I've given enough info here. scratching my brain for how to get quickfixj to pick up this dictionary.
Oh, the resource definietly exists, although nothing indicates it ever even tries to look for it, it definitely doesn't seem to be hitting anyything 'in the code' to indicate that it has done anything to look for a DataDictionary.
Any ideas how I can set a DataDictionary
The last place it 'works' is at A->B, I define the fix-message but it craps-out when I send it. the error message is reported on B->A - which is a bit wierd, then again, there's a LOT of stack trace, it definietly doesn't get into the code of the reciever
I solved myself by avoiding camel's mechanism to do DataDictionary, which as of 2.11.2 doesn't seem to work and just set the dictionary in the settings file. Works.
When sending emails via javamail, the following is always appended to the bottom of each message:
This email and any files transmitted with it are confidential and
intended solely for the use of the individual or entity to whom they
are addressed. If you have received this email in error please notify
the system manager. This message contains confidential information and
is intended only for the individual named. If you are not the named
addressee you should not disseminate, distribute or copy this e-mail.
Please notify the sender immediately by e-mail if you have received
this e-mail by mistake and delete this e-mail from your system. If you
are not the intended recipient you are notified that disclosing,
copying, distributing or taking any action in reliance on the contents
of this information is strictly prohibited.
How does one prevent this?
(NOTE: This problem is extremely frustrating to research on the web due to the fact that a disclaimer of this form is attached to so many indexed documents! :-(
JavaMail is not doing that, it is your outgoing SMTP server appending it to each message, probably set up by IT.
To confirm, you can use gmail's servers (with a personal account) and you will see it does not get added to the messages.
This should work. Pay attention to the form in which email body get parsed. In my case the emailBody string is on one line, so you have to put the "#Your disclaimer Here#" on one line. Answer for who will come in future.
public String deleteDisclaimer(String emailBody) {
String disclaimer = "#Your disclaimer here#";
if (emailBody.contains(disclaimer)) {
System.out.println("Deleting Disclaimer..");
return emailBody.substring(0,emailBody.indexOf(disclaimer));
}
System.out.println("DISCLAIMER NOT FOUND!");
return emailBody;
}
Solution:
int session = (int)get_env(argv, SESSION_ID); to get identifier unique to connection
US_VHOST_DATA (vhost) or US_HANDLER_DATA (listener) or US_SERVER_DATA (server) for data persistent > current connection
Missing pieces:
either persistent data for connection only
or some way to execute code when current connection is closed by client (econnreset etc.) or server (e.g. kalive_tmo reached)
This should be solvable as soon as a new HDL_BEFORE_CLOSE state for handlers is added, which makes this question answered for me.
Original Question:
Is it possible in a G-WAN handler to store information persistent to a request/connection (don't really know if "request" applies here)?
To better illustrate what I mean, this is what I got now:
Client (browser, javascript) sends websocket handshake
Handler starts, gets into:
HDL_AFTER_ACCEPT - here i call gc_init for US_REQUEST_DATA, and get no error
HDL_AFTER_READ - here i check for US_REQUEST_DATA which is not yet set, so I do websocket handshake and gc_malloc + set US_REQUEST_DATA, increase KALIVE_TMO, and then return 2 to send data
Client sees websocket connection as being established, so I (manually triggered some seconds afterwards) send a message
Handler goes to HDL_AFTER_READ again, BUT US_REQUEST_DATA is not set
What I've also tried:
returning 1 instead of 2 in HDL_AFTER_READ -> client gets 404 and handshake does not work
At the moment I'm only using US_REQUEST_DATA to identify if websocket connection is already established and next incoming data should be in websocket message format, so if there is a different (maybe better?) solution, I'm open to that as well of course.
Thanks!
Edit: Added clarification about request/connection
I am not sure why US_REQUEST_DATA does not seem to keep your allocated block of memory.
Can you try the persistence.c example to see if it works as expected for you?
Other than G-WAN persistent pointers, you can use OS services like the Linux shared memory API, etc.
But the G-WAN API should work fine once you copy & paste the example above.
Other values have different scopes:
US_VHOST_DATA (scope:vhost)
US_HANDLER_DATA (scope:listener)
US_SERVER_DATA (scope:server)
Use the session ID below which is unique to each CONNECTION:
int session = (int)get_env(argv, SESSION_ID);
I'm working with net-snmp and agentx. I have to register my enterprise OIDs for scalars and tables. For example:
netsnmp_register_read_only_scalar(...); // register my scalars
netsnmp_tdata_register(...); // register my table
Until I make those calls in my agentx code, my OIDs don't show up in snmpd.
My MIB file also has NOTIFICATION-TYPE definitions, such as:
myTrapTest NOTIFICATION-TYPE
STATUS current
DESCRIPTION "A sample trap."
::= { myNotifications 1 }
I took a look at #include <net-snmp/agent/agent_trap.h> but this file seems to be about sending traps, not registering custom ones.
My question: What do I call to register my trap definitions?
Turns out there is no registration required for traps. When I asked on the NET-SNMP mailing list, the answer I received was:
You need to 'register' variables/tables so that the master
agent knows which sub-agent to call/invoke (you versus the other guy)
when a particular OID is get/set, but...
You don't have to 'register' trap definitions, you simply have to
'send' the (correctly composed) notification (agentx-Notify-PDU).
(Source: http://permalink.gmane.org/gmane.network.net-snmp.user/35320 )