I'm using weblogic 10.3.3, when I sends messages to Queue then its going in pending messsage which should in current message. I'm using code :
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
//.....
qSession = qConnect.createQueueSession(
false, Session.AUTO_ACKNOWLEDGE);
//.....
TextMessage tmsg= qSession.createTextMessage();
tmsg.setText(message);
QueueSender qSender = qSession.createSender(requestQ);
qSender.send(tmsg);
I have gone through google but not found the helpful solution.
To quote manual entry,
A pending message is one that has either been sent in a transaction
and not committed, or that has been received and not committed or
acknowledged.
As you're using AUTO_ACKNOWLEDGE, I guess either you're sending messages in a transaction that has not been committed or message processing takes so long that it is still in process.
Related
I have an import function that returns a message summarizing the import results upon completion. It is currently a return redirect message that thus displays the message in the import view when the import is finished.
$rows = $counter;
$updates = count($update);
$table = Str::plural($modelName);
Storage::delete('csv_import/' . $filename);
$redirect = $request->input('redirect', false);
return redirect()->to($redirect)->with('message', trans(($updates > 0 ? 'global.app_imported_rows_to_table_with_updates' : 'global.app_imported_rows_to_table'),
['rows' => $rows, 'updates' => $updates, 'table' => $table]
The import is done by a job in the background enabling a user to move around the app doing different things while the import completes. The issue is that the return message as it is currently, displays the message in the import page view but frequently the user is elsewhere in the app when the import completes and thus does not get to see the message.
How might one be able to refactor this so that the message, upon import completion, is displayed globally in any view the user might be on when the import finishes?
If you want to have a notification seen throughout your application after the import is done. You need to set up three things.
First is a job and queue. What is will do. When the import process is starting it will disrupt your main thread preventing your users to navigate to other pages or doing other actions. Import is a heavy process, you know. By running your import to a queue, you will somehow have a multi-thread scenario.
https://laravel.com/docs/8.x/queues
Second, set up a pusher or anything that will broadcast an event to your front-end to listen. For example...
You want to import 10k contacts and you run it in the queue. So it will take minutes to finish depending on the process under the hood. And in your job's logic, you will need to call a broadcast event to notify your front-end that the import process is done.
broadcast(new SomeEvent());
And in your front-end, you have to listen to that event and do something like you know. Notify the user?
Broadcast Docs
And lastly, if you want to notify users regardless of which page they are on in your app, you need to set up something, like probably in Vue, somewhere in your app.js a notifiable to notify your users that their import is done.
I didnt see enough examples on web using apache camel with websphere mq to send and receive messages. I had a example code but I got struck at the middle of code. could any one help on this..
import org.apache.camel.CamelContext;
import org.apache.camel.Endpoint;
import org.apache.camel.Exchange;
import org.apache.camel.ExchangePattern;
import org.apache.camel.Producer;
import org.apache.camel.util.IOHelper;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Client that uses the Mesage Endpoint
* pattern to easily exchange messages with the Server.
* <p/>
* Notice this very same API can use for all components in Camel, so if we were using TCP communication instead
* of JMS messaging we could just use <code>camel.getEndpoint("mina:tcp://someserver:port")</code>.
* <p/>
* Requires that the JMS broker is running, as well as CamelServer
*/
public final class CamelClientEndpoint {
private CamelClientEndpoint() {
//Helper class
}
// START SNIPPET: e1
public static void main(final String[] args) throws Exception {
System.out.println("Notice this client requires that the CamelServer is already running!");
AbstractApplicationContext context = new ClassPathXmlApplicationContext("camel-client.xml");
CamelContext camel = context.getBean("camel-client", CamelContext.class);
// get the endpoint from the camel context
Endpoint endpoint = camel.getEndpoint("jms:queue:numbers");
// create the exchange used for the communication
// we use the in out pattern for a synchronized exchange where we expect a response
Exchange exchange = endpoint.createExchange(ExchangePattern.InOut);
// set the input on the in body
// must be correct type to match the expected type of an Integer object
exchange.getIn().setBody(11);
// to send the exchange we need an producer to do it for us
Producer producer = endpoint.createProducer();
// start the producer so it can operate
producer.start();
// let the producer process the exchange where it does all the work in this oneline of code
System.out.println("Invoking the multiply with 11");
producer.process(exchange);
// get the response from the out body and cast it to an integer
int response = exchange.getOut().getBody(Integer.class);
System.out.println("... the result is: " + response);
// stopping the JMS producer has the side effect of the "ReplyTo Queue" being properly
// closed, making this client not to try any further reads for the replies from the server
producer.stop();
// we're done so let's properly close the application context
IOHelper.close(context);
}
}
I got struck at this point of code..
exchange.getIn()
Do I have to use exchange.getOut() to send message?? and How to construct message using string and add headers to it.
Welcome to stackoverflow!
I am still not sure what exactly is the problem you are stuck at and it prevents me (and possibly others as well) in helping you resolve your roadblock.
Perhaps you need to familiarize a bit more on what camel is and how it works. Camel in Action is a great book to help you with that.
If you are unable to get a copy at this point, a preview of the first few chapters of the book is available online and it should give you much better leverage. Source code repository for chapter 2 should give you some more ideas around how to process JMS messages.
In addition to it. Please don't expect full blown solutions from StackOverflow. You may read this page on how to ask a good question
Hi I am using camel to get the messages from the JMS queue, process the message store it in Hadoop using FS java API and then transfer it to another queue
Currently my JMS concurrent is 20. so at one shot camel JMS consumes 20 messages at a time. For every message, I create the fs connection and perform an operation that creates a file and writes a file.
Here is the issue
What i see is sometimes while writing the content to the file, due to some reason my namenode goes down, in this case, I want to switch my name to the active name node
Here is a log I get
[Camel (camel-1) thread #1 a failover occurred since the last call #169 ClientNamenodeProtocolTranslatorPD.getFileInfo over {name_node_address_allias/ip:port}
When I debug it I show Operation category WRITE is not supported in state standby
I want at that time to switch to the active name node
Hadoop Java API Sample code
package org.myorg;
import org.apache.hadoop.conf.*;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.FileStatus;
public class HdfsTest {
public static void main(String args[]) {
conf.addResource("path-of-core-site.xml");
conf.addResource("path-of-hdfs-site.xml");
conf.set("fs.defaultFS", "hdfs://cloudera:8020");
conf.set("hadoop.security.authentication", "kerberos");
UserGroupInformation.setConfiguration(conf);
UserGroupInformation.loginUserFromKeytab("hdfs#CLOUDERA", "/etc/hadoop/conf/hdfs.keytab");
FileSystem fs = FileSystem.get(conf);
//logic to create a file and write
//close the cfile and connection
}
}
In my application, I have a queue (HornetQ) set up on JBoss 7 AS.
I have used Spring batch to do some work once the messages is received (save values in database etc.) and then the consumer commits the JMS session.
Sometimes when there is an exception while processing the message, the excecution of consumer is aborted abruptly.
And the message remains in "in delivery" state. There are about 30 messages in this state on my production queue.
I have tried restarting the consumer but the state of these messages is not changed. The only way to remove these
messages from the queue is to restart the queue. But before doing that I want a way to read these messages so
that they can be corrected and sent to the queue again to be processed.
I have tried using QueueBrowser to read them but it does not work. I have searched a lot on Google but could not
find any way to read these messages.
I am using a Transacted session, where once the message is processed, I am calling:
session.commit();
This sends the acknowledgement.
I am implementing spring's
org.springframework.jms.listener.SessionAwareMessageListener
to recieve messages and then to process them.
While processing the messages, I am using spring batch to insert some data in database.
For a perticular case, it tries to insert data too big to be inserted in a column.
It throws an exception and transaction is aborted.
Now, I have fixed my producer and consumer not to have such data, so that this case should not happen again.
But my question is what about the 30 "in delivery" state messages that are in my production queue? I want to read them so that they can be corrected and sent to the queue again to be processed. Is there any way to read these messages? Once I know their content, I can restart the queue and submit them again (after correcting them).
Thanking you in anticipation,
Suvarna
It all depends on the Transaction mode you are using.
for instance if you use transactions:
// session here is a TX Session
MessageConsumer cons = session.createConsumer(someQueue);
session.start();
Message msg = consumer.receive...
session.rollback(); // this will make the messages to be redelivered
if you are using non TX:
// session here is auto-ack
MessageConsumer cons = session.createConsumer(someQueue);
session.start();
// this means the message is ACKed as we receive, doing autoACK
Message msg = consumer.receive...
//however the consumer here could have a buffer from the server...
// if you are not using the consumer any longer.. close it
consumer.close(); // this will release messages on the client buffer
Alternatively you could also set consumerWindowSize=0 on the connectionFactory.
This is on 2.2.5 but it never changed on following releases:
http://docs.jboss.org/hornetq/2.2.5.Final/user-manual/en/html/flow-control.html
I"m covering all the possibilities I could think of since you're not being specific on how you are consuming. If you provide me more detail then I will be able to tell you more:
You can indeed read your messages in the queue using jmx (with for example jconsole)
In Jboss As7 you can do it the following way :
MBeans>jboss.as>messaging>default>myJmsQueue>Operations
listMessagesAsJson
[edit]
Since 2.3.0 You have a dedicated method for this specific case :
listDeliveringMessages
See https://issues.jboss.org/browse/HORNETQ-763
My experimental application is quite simple, trying what can be done with Actors and Akka.
After JVM start, it creates actor system with couple of plain actors, JMS consumer (akka.camel.Consumer) and JMS producer (akka.camel.Producer). It sends couple of messages between actors and also JMS producer -> JMS server -> JMS consumer. It basically talks to itself via JMS service.
From time to time I was experiencing weird behaviour: it seemed that from time to time, first of messages which where supposed to be sent to JMS server was somehow lost. By looking at my application logs, I could see that applications is trying to send the message but it was never received by JMS server. (For each run I have to start JVM&Application again).
Akka Camel Documentation mentions that it's possible that some components may not be fully initialized at the begining: "Some Camel components can take a while to startup, and in some cases you might want to know when the endpoints are activated and ready to be used."
I tried to implement following to wait for Camel initialization
val system = ActorSystem("actor-system")
val camel = CamelExtension(system)
val jmsConsumer = system.actorOf(Props[JMSConsumer])
val activationFuture = camel.activationFutureFor(jmsConsumer)(timeout = 10 seconds, executor = system.dispatcher)
val result = Await.result(activationFuture,10 seconds)
which seems to help with this issue. (Although, when removing this step now, I'm not able to recreate this issue any more... :/).
My question is whether this is correct way to ensure all components are fully initialized?
Should I use
val future = camel.activationFutureFor(actor)(timeout = 10 seconds, executor = system.dispatcher)
Await.result(future, 10 seconds)
for each akka.camel.Producer and akka.camel.Consumer actor to be sure that everything is initialized properly?
Is that all I should to do, or something else should be done as well? Documentation is not clean on that and it's not easy to test as issue was happening only occasionaly...
You need to initialize the camel JMS component and also Producer before sending any messages.
import static java.util.concurrent.TimeUnit.SECONDS;
import scala.concurrent.Future;
import scala.concurrent.duration.Duration;
import akka.dispatch.OnComplete;
ActorRef producer = system.actorOf(new Props(SimpleProducer.class), "simpleproducer");
Timeout timeout = new Timeout(Duration.create(15, SECONDS));
Future<ActorRef> activationFuture = camel.activationFutureFor(producer,timeout, system.dispatcher());
activationFuture.onComplete(new OnComplete<ActorRef>() {
#Override
public void onComplete(Throwable arg0, ActorRef arg1)
throws Throwable {
producer.tell("First!!");
}
},system.dispatcher());