Cannot read message on ActiveMQ-queue when implemented in WSO2: "Cannot display ObjectMessage body" - wso2

I've just successfully implemented a JMS-message-processor in my WSO2-process. However, when logged in as an admin on the ActiveMQ console, I can view the stats of the queue but I cannot access the contents of the pending message. Instead, I see this error:
Cannot display ObjectMessage body. Reason: Failed to build body from content. Serializable class not available to broker. Reason: java.lang.ClassNotFoundException: org.apache.synapse.message.store.impl.commons.StorableMessage
Accessing the contents of a pending message is possible when using the RabbitMQ, so I figured it should also be possible with this message broker.
I've found solutions online, but they don't seem to be working, or perhaps they're out of date. Can somebody point me to the correct answer to solve this? I'm on WSO2 Integration Studio 8.1.0 and am using ActiveMQ 5.17.1.

It appears that WSO2 is using javax.jms.ObjectMessage despite the fact that there's a long list of reasons why doing so is a bad idea, including the issue you're currently facing, but I digress.
The problem here is that the implementation of the javax.jms.ObjectMessage (i.e. org.apache.synapse.message.store.impl.commons.StorableMessage in this case) must be on the classpath of any application which wants to deserialize that message. This class is not, in fact, on the classpath of ActiveMQ therefore the ActiveMQ web console cannot deserialize the message and display its contents (assuming those contents are human-readable in the first place). That's why a ClassNotFoundException is thrown.
You may be able to resolve the issue by putting org.apache.synapse.message.store.impl.commons.StorableMessage on ActiveMQ's classpath. Aside from that there's really nothing to be done.
I assume this is different for RabbitMQ because in that case WSO2 doesn't use the JMS API and uses the AMQP protocol which is not Java-centric like JMS.

Justin has explained the cause of the issue and as suggested you can try adding the class to ActiveMQ runtime and see whether it resolves the issue. This class is located in the Synapse-Core(synapse-core_2.x.x.wso2vXXX.jar). But remember although this may resolve the ActiveMQ UI issue, this message is not consumable by other systems unless they know how to deserialize it.
Let me add more details on why the message is serialized. Message serialization happens when you use the Store mediator, and when you store a message with Store Mediator it is intended to be only read by a Message Processor. Simply the serialized message can only be consumed by WSO2 Message Processors. In other words, Store Mediator and the Message processors are tightly coupled.
If message serialization is an issue for you. For example, if other systems are consuming the messages that WSO2 publishes you can try using the JMS transport to produce and to consume messages from ActiveMQ. Other than that you can also consider using JMS Inbound Endpoint to consume messages, which all use standard media types when storing the message.

Related

Akka.NET - Is it possible to mix AtLeastOnceDeliveryReceiveActor with Publish/Subscribe pattern?

I'd like to ask whether it's possible to implement publish/subscribe pattern (http://getakka.net/articles/clustering/distributed-publish-subscribe.html) where subscriber is an AtLeastOnceDeliveryReceiveActor (http://getakka.net/articles/persistence/at-least-once-delivery.html)
I cannot make it working due to fact that AtLeastOnceDeliveryReceiveActor doesn't have Receive method, but just Command. When I get reference to an actor and using Tell method send a message then Command receive it, but if I'd like to use mediator with Publish method then Command doesn't receive that message.
Thanks in advance.
ReceivePersistentActor's Command works just like Receive handler (the only distinction is acknowledgement of persistence/recovery lifecycle of an actor). That being said, you could potentially build an at-least-once-delivery publish/subscribe bus... however I'd advise to simply integrate your actors logic with an existing persistent queue/log (like Kafka, RabbitMQ, Azure Service Bus, whatever) instead of trying to recreate it in Akka. I guess it will be less painful for most of the people.

Qpid receive message by correlation id (using c++ application)

Qpid offers responses to the received message. For parallel processing purposes we have multiple instances of the application that are listening to the same queue. The problem is that I would like that exactly the same instance receives the response. I believe that this can be done using correlation ids, but I cannot find an example how to do that with Qpid.
I searched the web and found discussion from 2009 (http://qpid.2158936.n2.nabble.com/get-message-by-correlationId-td3440876.html) where they aimed to add selectors shortly. This is probably the associated ticket (https://issues.apache.org/jira/browse/QPID-4558). There is finished subtask "Initial selector implementation", so I belive that this is implemented.
I was searching the API documentation and found methods getCorrelationId() and setCorrelationId(), but I cannot find an example how to filter the messages from queue.
Thanks.

Can we Consume the Messages using wso2esb Jms

I am using wso2esb4.7.0 and ActiveMQ 5.8.0 versions
i followed wso2esb docs they provided store and forward message store policy
But i dont want store i just want to consume those messages which is already has been store
by my client application i wish to pool that messages for every 5 sec
Is it possible in wso2esb jms using ActiveMq
will you write sample code of proxy
<messageProcessor name="Duplicate5" class="org.apache.synapse.message.processors.forward.ScheduledMessageForwardingProcessor" messageStore="Duplicate" xmlns="http://ws.apache.org/ns/synapse">
<parameter name="interval">1000</parameter>
<parameter name="message.processor.reply.sequence">fault</parameter>
</messageProcessor>
i tried with this but its not working
To pull messages from the queue, you need to use JMS transport..Check JMS proxy for the samples..
The message store persists the messages in the form of serializable Java objects. This might contain certain underlying information(E.g.: Properties) which is not visible in the message when you view message details in the ActiveMQ console. The message processor uses such information stored by the store when processing the message. Therefore, as far as I understand, the message store and message processor should be used together if you want to make things functional.
If you're straightaway storing the received messages in ActiveMQ queue, you might have to configure the message consumer manually. Check this usecase [1].
And also look in to this blogpost example to get an idea [2].
[1] http://docs.wso2.org/wiki/display/ESB470/ESB+as+a+JMS+Consumer
[2] http://nuwanwimalasekara.blogspot.com/2013/04/jms-proxy-service-using-wso2-esb.html
Hope this helps.
You can not use the Message-processor alone, You must have combination of Message Store and message processor. if you want to understand the behavior of the Message Store and Message processor refer the blog some time back.
If you want to use listen/pull from the JMS using ESB you have to use ESB as a JMS Consumer. Please refer further on document to implementation detail.

How to connect ActiveMQ to CXF with Apache Camel

does anyone know a working example that bridges ActiveMQ to CXF? I saw many examples that connect a WebService to a message queue, but I need it the other way round. Messages from a JMS queue shall be forwarded to a web service and the result returned to the caller.
My first approach is only working for web services that expose one single method:
from("activemq:wsa").to("cxf:bean:webServiceA");
Status msg = producerTemplate.requestBody("activemq:wsa", params, Status.class);
But for web services that have more than one method, a similar call results in a ExchangeTimedOutException.
Map<String, Object> header = new HashMap<String, Object>();
header.put(CxfConstants.OPERATION_NAME, "doSomething");
header.put(CxfConstants.OPERATION_NAMESPACE, "http://.../");
Status msg = producerTemplate.requestBodyAndHeaders("activemq:wsb", params, header, Status.class);
Nevertheless, I can see that the request is forward to the web service and the correct answer is returned. But unfortunately then it gets lost on its way back.
Any hints or links to external resources are appreciated.
Many regards,
Jakob
ActiveMQ and JMS calls are one way default, you may want to specify it to be synchronous.
http://camel.apache.org/jms.html#JMS-RequestreplyoverJMS
Other than that, it should be no different to use ActiveMQ as a starter for CXF producers.
A suggestion is to download the Camel source and look into this folder:
\components\camel-cxf\src\test\java\org\apache\camel\component\cxf
(or by Web: http://svn.apache.org/viewvc/camel/trunk/components/camel-cxf/src/test/)
You will have a huge amount of CXF producer test cases, to look at as reference material.
The problem occurs when a web service returns objects of classes that don't implement the serializable interface, even if these classes are serializable.
Implementing the serializable interface solves the problem.

API Design: How should distinct classes of errors be handled from an asynchronous XMLHTTP call?

I have a legacy VB6 application that needs to make asynchronous calls to a web service. The web service provides a search method allows end-users to query a central database and view the results from within the application. I'm using the MSXML2.XMLHTTP to make the requests, and have written a SearchWebService class that encapsulates the web service call and code to handle the response asychronously.
Currently, the SearchWebService raises one of two events to the caller: SearchCompleted and SearchFailed. A SearchCompleted event is raised that contains the search results in a parameter to the event if the call completes successfully. A SearchFailed is raised when any type of failure is detected, which can be anything from an improperly-formatted URL (this is possible because the URL is user-configurable), to low-level network errors such as "Host not found", to HTTP errors such as internal server errors. It returns a error message string to the end-user (which is extracted from the web service response body, if present, or from the HTTP status code text if the response has no body, or translated from the network error code if a network error occurs).
Because of various security requirements, the calling application does not access the web service directly, but instead accesses it through a proxy web server running at the customer site, which in turn accesses the actual web service through via a VPN. However, the SearchWebService doesn't know that the calling application is accessing the web service through a proxy: it's just given a URL and told to make the request. The existence of the proxy is a application-level requirement.
The problem is that from an end-user perspective, it's important that the calling application be able to distinguish between low-level network errors versus HTTP errors from the web service, and to distinguish proxy errors from remote web server errors. For example, the application needs to know if a request failed because the proxy server is down, or because the remote web service that the proxy is accessing is down. An application-specific message needs to be presented to the end-user in each case, such as "Search web service proxy server appears to be down. The proxy server may need to be restarted" versus "The proxy is currently running but the remote web server appears to be unavailable. Please contact (name of person in charge of the remote web server)." I could handle this directly in the SearchWebService class, but it seems wrong to generate these application-specific error messages from such a generic class (and the class might be used in environments that don't require a proxy, where the error messages would no longer make sense).
This distinction is important for troubleshooting: a proxy server problem can usually be resolved by the customer, but a remote web server error has to handled by a third party.
I was thinking one way to handle this would be to have the SearchWebService class detect different types of errors and raise different events in each case. For example, instead of a single SearchFailed event, I could have a NetworkError event for low-level network errors (which would indicate a problem accessing the proxy server), a ConfigurationError event for invalid properties on the SearchWebService class (such as passing an improperly-formatted URL), and a ServiceError for errors that occur on the remote web server (implying that the proxy is working properly but the remote server returned an error).
Now that I think about it, there is also an additional error scenario: it could be possible that the proxy server is running properly, but the remote web server is down, or the proxy server has been misconfigured.
Is the approach of using multiple error events to classify different classes of error a reasonable solution to this problem? For the last scenario (the proxy is running but the remote server cannot be reached), I'm guessing I may have to set up the proxy to return a specific HTTP error code so that client can detect this situation (i.e. something more specific than a 500 response).
Originally I kept the single SearchFailed event and simply added an additional errorCode parameter to the event, but that got messy quickly, especially in cases where there wasn't a logical error code to use (such as if the VB6 raises a "real" error, i.e. if the XMLHTTP class isn't registered).
I think that some ideas I've used with Java exceptions may apply here.
Having a large number of different Exceptions gets pretty messy, yet we need to give enough detail to the user so we don't want to lose information.
Hence I have a small number of specific Exceptions, which I guess would correspond to your Events:
InvalidRequestEvent: Used when the user specifies bad information
TransientErrorEvent: used when there's infrastructure issues when a retry might work.
I tend to work in environments where we have clusters of servers so if a user request hits a dying server then if he resubmits he'll probably get a good one, hence from his perspective a simple retry often works. However sometimes the error is with a service such as the Network or Database and in which case the user needs diagnostic information to report to the helpdesk. Hence we need to decide on the extra information to put into the exception. This is (if I understand you correctly) your question.
In the case of InvalidRequestException we would bet giving some information about the problems with the input. It could be on the lines of "Mismatched parenthese" or "Unknown column CUTSOMER in table ORDER". In the case of TransientErrorException it could be "Proxy server is down".
Now depending upon your exact requirments you may not actually choose to put that text in the Exception, but rather an error number which the presentation layer converts to a locale-specific string (English, French ...).
So either Exception might contain something like this (sorry for that Java syntax, but I hope the idea is clear):
BaseException {
String ErrorText; // the error text itself
// OR if you want to allow for internationaliation
int ErrorCode; // my application specific code, corresponds to text held by the UI
String[] params; // specific parameters to be substitued in the error text
// CUTSOMER and ORDER in my example above
int SystemErrorCode; // If you have an underlying error code it goes here
String SystemErrorText; // any further diagnoistic you might need to give to
// the user so that they can report the problem to the
// help desk.
// OR instead of the text (this is something I've seen done)
int SystemErrorTag; // A unique id for this particular error problem.
// This server systems will label their message in the
// server logs. Users just tell the help desk this number
// they don't need to read detailed server error text.
}