QueueingConsumer consumer = new QueueingConsumer(channel);
System.out.println(consumer.getConsumerTag());
channel.basicConsume("queue1", consumer);
channel.basicConsume("queue3", consumer);
Is it possible to stop consuming the messages from the queue "queue3" alone dynamically?
Yes you can, using channel.basicCancel(consumerTag);
EDIT
For example:
String tag3 = channel.basicConsume("queue3", consumer);
channel.basicCancel(tag3)
Here you can find a code that unsubscribe a consumer after 5 seconds:
String tag1 = channel.basicConsume(myQueue, autoAck, consumer);
String tag2 = channel.basicConsume(myQueue2, autoAck, consumer);
executorService.execute(new Runnable() {
#Override
public void run() {
while (true) {
Delivery delivery;
try {
delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println("Received: " + message);
} catch (Exception ex) {
Logger.getLogger(TestMng.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
});
System.out.println("Consumers Ready");
try {
Thread.sleep(5000);
} catch (InterruptedException ex) {
Logger.getLogger(TestMng.class.getName()).log(Level.SEVERE, null, ex);
}
channel.basicCancel(tag2); /// here you remove only the Myqueue2
I hope it can be useful.
Related
I've a very simple application that adds messages to a queue and reads them using a MessagerListener.
Edit: I was testing this on a single instance of Artemis that had been setup as part of a two instance cluster on docker.
I want to create the ConnectionFactory once and reuse it for all producers and consumers in the application.
I have created the ConnectionFactory and stored it in a static variable (singleton) so it can be accessed from anywhere.
The aim is that the client use this shared connection factory to create a new connection when required.
However, I have noticed that doing this causes a "Failed to create session factory" when trying to create a new connection.
javax.jms.JMSException: Failed to create session factory
at org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory.createConnectionInternal(ActiveMQConnectionFactory.java:886)
at org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory.createConnection(ActiveMQConnectionFactory.java:299)
at com.test.artemistest.jms.QueueTest2.getMessagesFromQueue(QueueTest2.java:137)
at com.test.artemistest.jms.QueueTest2.access$000(QueueTest2.java:61)
at com.test.artemistest.jms.QueueTest2$1.run(QueueTest2.java:75)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:830)
Caused by: ActiveMQNotConnectedException[errorType=NOT_CONNECTED message=AMQ219007: Cannot connect to server(s). Tried with all available servers.]
at org.apache.activemq.artemis.core.client.impl.ServerLocatorImpl.createSessionFactory(ServerLocatorImpl.java:690)
at org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory.createConnectionInternal(ActiveMQConnectionFactory.java:884)
If I create a connection factory per call this error does not occur.
Doing this seems very inefficient.
I've recreated a similar issue below.
If I create the connection factory in the main method the error occurs.
However if created just before use in a method it works as expected.
If I add two listeners the error occurs even though they are in separate threads. Could it be linked to the fact the connections are not closed in the consumers but are in the producers?
Why is this the case and do you recommend sharing the connection factory?
Thanks
public class QueueTest2 {
private static boolean shutdown = false;
private static ConnectionFactory cf;
public static void main(String[] args) {
// uncomment below for error to occur
// QueueTest2.getConnectionFactory("localhost", 61616);
ExecutorService executor = Executors.newCachedThreadPool();
executor.execute(new Runnable() {
#Override
public void run() {
getMessagesFromQueue("localhost", 61616);
while (!shutdown) {
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("getMessagesFromQueue shutdown");
}
});
addMessagesToQueue("localhost", 61616);
// uncommenting below also causes the issue
// executor.execute(new Runnable() {
// #Override
// public void run() {
// getMessagesFromQueue("localhost", 61616);
// while (!shutdown) {
// try {
// Thread.sleep(1000L);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
// System.out.println("getMessagesFromQueue shutdown");
// }
// });
addMessagesToQueue("localhost", 61616);
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
shutdown = true;
executor.shutdownNow();
}
private static void addMessagesToQueue(String host, int port) {
ConnectionFactory cf2 = getConnectionFactory(host, port);
Connection connection = null;
Session sessionQueue = null;
try {
connection = cf2.createConnection("artemis", "password");
connection.setClientID("Producer");
sessionQueue = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
Queue orderQueue = sessionQueue.createQueue("exampleQueue");
MessageProducer producerQueue = sessionQueue.createProducer(orderQueue);
connection.start();
// send 100 messages
for (int i = 0; i < 100; i++) {
TextMessage message = sessionQueue.createTextMessage("This is an order: " + i);
producerQueue.send(message);
}
} catch (JMSException ex) {
Logger.getLogger(QueueTest2.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
if (sessionQueue != null) {
sessionQueue.close();
}
} catch (JMSException ex) {
Logger.getLogger(QueueTest2.class.getName()).log(Level.SEVERE, null, ex);
}
try {
if (connection != null) {
connection.close();
}
} catch (JMSException ex) {
Logger.getLogger(QueueTest2.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
private static void getMessagesFromQueue(String host, int port) {
ConnectionFactory cf2 = getConnectionFactory(host, port);
Connection connection2 = null;
Session sessionQueue2;
try {
connection2 = cf2.createConnection("artemis", "password");
connection2.setClientID("Consumer2");
sessionQueue2 = connection2.createSession(false, Session.CLIENT_ACKNOWLEDGE);
Queue orderQueue = sessionQueue2.createQueue("exampleQueue");
MessageConsumer consumerQueue = sessionQueue2.createConsumer(orderQueue);
consumerQueue.setMessageListener(new MessageHandlerTest2());
connection2.start();
Thread.sleep(5000);
} catch (JMSException ex) {
Logger.getLogger(QueueTest2.class.getName()).log(Level.SEVERE, null, ex);
} catch (InterruptedException ex) {
Logger.getLogger(QueueTest2.class.getName()).log(Level.SEVERE, null, ex);
}
}
private static ConnectionFactory getConnectionFactory(String host, int port) {
if (cf == null) {
Map<String, Object> connectionParams2 = new HashMap<String, Object>();
connectionParams2.put(TransportConstants.PORT_PROP_NAME, port);
connectionParams2.put(TransportConstants.HOST_PROP_NAME, host);
TransportConfiguration transportConfiguration = new TransportConfiguration(NettyConnectorFactory.class
.getName(), connectionParams2);
cf = ActiveMQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF, transportConfiguration);
}
return cf;
}
}
class MessageHandlerTest2 implements MessageListener {
#Override
public void onMessage(Message message) {
try {
System.out.println("new message: " + ((TextMessage) message).getText());
message.acknowledge();
} catch (JMSException ex) {
Logger.getLogger(MessageHandlerTest2.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
I've run your code, but I don't see any errors. My guess is that there may be a timing issue related to concurrency. Try adding synchronized to your getConnectionFactory method since it can theoretically be called concurrently by multiple threads in your application, e.g.:
private synchronized static ConnectionFactory getConnectionFactory(String host, int port)
I have found a solution that works on a clustered environment and docker.
It involves using the "pooled-jms" connection pool. Something I had planned to use anyway.
Although it does not explain the issues I was seeing above, it is at least a work around until I can investigate further.
The "WARN: AMQ212064: Unable to receive cluster topology " mentioned above appears to have been a red herring as it went away as quickly as it appeared.
This is my code :
There is two condition is happening :
1.Not getting chat continued when i received pending message form other side:
2.When internet goes when i disconnecting the XMPP connection then pending message has not coming but chat will continued
public void init(String userId, String pwd) {
Log.i("XMPP", "Initializing!");
mPassword = DatabaseManager.Session.getClientPassword(this);
HOST = "xm3.conversity.net";
xMppUserName = DatabaseManager.Session.getXmppUserName(this);
xMppOnlyUserName = xMppUserName.split("#")[0];
agentId = DatabaseManager.Session.getAgentNameId(this);
PORT = DatabaseManager.Session.getPortNumber(this);
Log.e("xmpp", "mPassword:" + mPassword);
Log.e("xmpp", "HOST:" + HOST);
Log.e("xmpp", "xMppOnlyUserName:" + xMppOnlyUserName);
Log.e("xmpp", "xMppUserName:" + xMppUserName);
Log.e("xmpp", "agentId:" + agentId);
Log.e("xmpp", "PORT:" + String.valueOf(PORT));
XMPPTCPConnectionConfiguration.Builder configBuilder = XMPPTCPConnectionConfiguration.builder();
configBuilder.setUsernameAndPassword(xMppUserName, passWord);
configBuilder.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
configBuilder.setResource("Android");
configBuilder.setServiceName(DOMAIN);
configBuilder.setHost(HOST);
configBuilder.setPort(PORT);
configBuilder.setSendPresence(true);
configBuilder.setDebuggerEnabled(true);
configBuilder.setCompressionEnabled(true);
connection = new XMPPTCPConnection(configBuilder.build());
connection.addConnectionListener(connectionListener);
// ReconnectionManager.getInstanceFor(connection).enableAutomaticReconnection();
// connection.setPacketReplyTimeout(10000);
// PingManager.setDefaultPingInterval(600);
// PingManager.getInstanceFor(connection).registerPingFailedListener((PingFailedListener) this);
chatmanager = ChatManager.getInstanceFor(connection);
chatmanager.addChatListener(new ChatManagerListener() {
#Override
public void chatCreated(Chat chat, boolean createdLocally) {
chat.addMessageListener(new ChatMessageListener() {
#Override
public void processMessage(Chat chat, final Message message) {
Log.e("Xmpp", String.valueOf(chat) + " === " + message.toString() + "MESSAGE: " + message.getBody());
Handler refresh = new Handler(Looper.getMainLooper());
refresh.post(new Runnable() {
public void run() {
Log.e("Xmpp", "RECIVE MESSAGE: " + message.getBody() + message.getFrom() + "StanzaID: " + message.getBodies());
String[] strings = {message.getBody(), "2", Utility.getCurrentTime(), message.getThread(), "A", "6", "7", DatabaseManager.Message.START_CHAT, ""};
DatabaseManager.Message.insertValues(getApplicationContext(), strings);
Intent i = new Intent(ChatActivity.CHAT_BROADCAST);
i.putExtra(ChatActivity.KEY_ACTION, ChatActivity.NEW_MESSAGE);
getApplicationContext().sendBroadcast(i);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// Do something after 5s = 5000ms
// disconnectConnection();
}
}, 3000);
}
});
}
});
}
});
}
// Disconnect Function
public void disconnectConnection() {
new Thread(new Runnable() {
#Override
public void run() {
connection.disconnect();
Log.e("xmpp", "connection.disconnect();");
}
}).start();
}
public void connectConnection() {
AsyncTask<Void, Void, Boolean> connectionThread = new AsyncTask<Void, Void, Boolean>() {
#Override
protected Boolean doInBackground(Void... arg0) {
// Create a connection
try {
connection.connect();
login();
connected = true;
final ScheduledExecutorService scheduleTaskExecutor = Executors.newSingleThreadScheduledExecutor();
scheduleTaskExecutor.scheduleWithFixedDelay(new Runnable() {
#Override
public void run() {
Log.d("xmpp", "inside run()");
Log.d("xmpp", "isconnect: " + connection.isConnected() + " Auth: " + connection.isAuthenticated());
/* if(!Utility.isNetworkAvailable(getApplicationContext())){
// disconnectConnection();
}
else */
if (connection.isConnected()) {
sendMessagesToServer();
} else {
try {
connection.connect();
login();
} catch (SmackException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (XMPPException e) {
e.printStackTrace();
}
}
}
}, 0, 2, TimeUnit.SECONDS);
} catch (IOException e) {
} catch (SmackException e) {
} catch (XMPPException e) {
}
return null;
}
};
connectionThread.execute();
}
private void sendMessagesToServer() {
try {
connection.sendPacket(new Presence(Presence.Type.available));
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
}
// Log.e(TAG,"in side sendMessagesToServer()");
DatabaseManager dbManager = new DatabaseManager(this);
dbManager.open();
Cursor c = dbManager.getMessages();
while (c.moveToNext()) {
//Read the message details
String status = c.getString(DatabaseManager.Message.INDEX_STATUS);
// Log.e("PREM", status + String.valueOf(status.equalsIgnoreCase("P")));
if (status.equalsIgnoreCase("P")) {
String message = c.getString(DatabaseManager.Message.INDEX_MESSAGE);
String id = c.getString(0);
sendMsg(message);
dbManager.updateMessageStatus(id, jid);
}
}
c.close();
dbManager.close();
}
public void sendMsg(String message) {
if (connection.isConnected() == true) {
// Assume we've created an XMPPConnection name "connection"._
chatmanager = ChatManager.getInstanceFor(connection);
newChat = chatmanager.createChat(agentId);
try {
newChat.sendMessage(message);
jid = newChat.getThreadID();
Log.i("Xmpp", "message send to server");
Log.i("Xmpp", "thread: " + newChat.getThreadID() + " Listner: " + newChat.getListeners() + " participant" + newChat.getParticipant());
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
}
}
}
public void login() {
try {
connection.login(xMppOnlyUserName, DatabaseManager.Session.getClientPassword(this));
Log.i("Xmpp", "Yey! We're connected to the Xmpp server!");
} catch (XMPPException | SmackException | IOException e) {
e.printStackTrace();
} catch (Exception e) {
}
}
your question is not clear, but from what I understood, you have to save the messages in sqlite database on android, and then load from database everytime you open the chat page
I have thousands of files generated each day which I want to stream using Kafka.
When I try to read the file, each line is taken as a separate message.
I would like to know how can I make each file's content as a single message in Kafka topic and with consumer how to write each message from Kafka topic in a separate file.
You can write your own serializer/deserializer for handling files.
For example :
Producer Props :
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, org.apache.kafka.common.serialization.StringSerializer);
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, YOUR_FILE_SERIALIZER_URI);
Consumer Props :
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, org.apache.kafka.common.serialization.StringDeserializer);
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, YOUR_FILE_DESERIALIZER_URI);
Serializer
public class FileMapSerializer implements Serializer<Map<?,?>> {
#Override
public void close() {
}
#Override
public void configure(Map configs, boolean isKey) {
}
#Override
public byte[] serialize(String topic, Map data) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutput out = null;
byte[] bytes = null;
try {
out = new ObjectOutputStream(bos);
out.writeObject(data);
bytes = bos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException ex) {
// ignore close exception
}
try {
bos.close();
} catch (IOException ex) {
// ignore close exception
}
}
return bytes;
}
}
Deserializer
public class MapDeserializer implements Deserializer<Map> {
#Override
public void close() {
}
#Override
public void configure(Map config, boolean isKey) {
}
#Override
public Map deserialize(String topic, byte[] message) {
ByteArrayInputStream bis = new ByteArrayInputStream(message);
ObjectInput in = null;
try {
in = new ObjectInputStream(bis);
Object o = in.readObject();
if (o instanceof Map) {
return (Map) o;
} else
return new HashMap<String, String>();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bis.close();
} catch (IOException ex) {
}
try {
if (in != null) {
in.close();
}
} catch (IOException ex) {
// ignore close exception
}
}
return new HashMap<String, String>();
}
}
Compose messages in the following form
final Object kafkaMessage = new ProducerRecord<String, Map>((String) <TOPIC>,Integer.toString(messageId++), messageMap);
messageMap will contain fileName as key and the file content as value.
Value can be serializable object.
Hence each message will contain a Map with File_Name versus FileContent map.Can be single value or multiple value.
I get "Invalid thread access" in below code. I am not sure where I have written wrong code. My main intention to write the code is to just display subtask (what is happening behind the scene) so I have added subtask before method called.
#Override
public void handleEvent(Event event)
{
if((event.keyCode == SWT.CR || event.keyCode == 13 || event.type == SWT.Selection) && btnAdd.isEnabled())
{
final PreferencesMO permo = new PreferencesMO();
permo.updatePreferences();
permo.updateDocumentNumber();
final ProjectMO pmo = new ProjectMO();
final CoverSheetMO csmo = new CoverSheetMO();
final CommonError cmerror = new CommonError();
final ParameterConfigurationMO pamo = new ParameterConfigurationMO();
final SnippetNew s = new SnippetNew();
final String projName = txtpname.getText();
Display.getDefault().asyncExec(new Runnable()
{
public void run()
{
try
{
new ProgressMonitorDialog(shell).run(true, true, new IRunnableWithProgress() {
#Override
public void run(final IProgressMonitor monitor) throws InvocationTargetException,
InterruptedException
{
monitor.beginTask("Import Data", IProgressMonitor.UNKNOWN);
monitor.subTask("Connecting to databse...");
for(int i=0;i<=100;i++)
{
s.method1(i);
}
//monitor.worked(1);
try { Thread.sleep(2000); } catch (Exception e) { }
monitor.subTask("Analysing Data...");
try { Thread.sleep(2000); } catch (Exception e) { }
if(!projName.equals(""))
{
monitor.subTask("Updating coversheet ...");
try { Thread.sleep(2000); } catch (Exception e) { }
cmerror.updateCoverSheetStatusforNewProject();
monitor.subTask("Inserting Project ...");
try { Thread.sleep(2000); } catch (Exception e) { }
pmo.addProjectManager(projName,"T");
monitor.subTask("Searching Project ID ...");
try { Thread.sleep(2000); } catch (Exception e) { }
String p_id = pmo.searchprojectID(projName);
permo.insertDocumentNumber(p_id);
monitor.subTask("Inserting data into coversheet ...");
try { Thread.sleep(2000); } catch (Exception e) { }
csmo.insertCoversheet(p_id);
pamo.insertParameterConfiguration(p_id);
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell().setText("Demo Tool - "+projName);
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
AuditLogs view = (AuditLogs) page.findView(AuditLogs.ID);
IEditorPart editorPart = page.getActiveEditor();
StackedLambdaChartInput input = new StackedLambdaChartInput();
AnalysisResult_MetricsChartInput metricsinput = new AnalysisResult_MetricsChartInput();
StackedLambdaChart_HorizantalInput stackedhorizantalinput = new StackedLambdaChart_HorizantalInput();
AnalysisResult_Metrics_HorizantalChartInput metricshorizantalinput = new AnalysisResult_Metrics_HorizantalChartInput();
BarChartInput inpuit = new BarChartInput();
BarChart_HorizantalInput barchart_horizantalinput = new BarChart_HorizantalInput();
AuditLogMO auditlog = new AuditLogMO();
monitor.subTask("Fetching audit logs to display ...");
try { Thread.sleep(2000); } catch (Exception e) { }
java.util.List<java.util.List<String>> auditlogs = auditlog.searchAuditLog(null,null);
view.table(auditlogs);
try
{
handlerService.executeCommand(AuditLogView.ID, new Event());
handlerService.executeCommand(ErrorLogView.ID, new Event());
handlerService.executeCommand(DesignHierarchyHandler.ID, new Event());
if(myeditor != null)
{
if(myeditor instanceof CoverSheet)
{
handlerService.executeCommand(CoverSheetHandler.ID, new Event());
}
else if(myeditor instanceof ParameterConfigurations)
{
handlerService.executeCommand(ParameterConfigurationHandler.ID, new Event());
}
}
}
catch (ExecutionException | NotDefinedException | NotEnabledException | PartInitException| NotHandledException e1)
{
e1.printStackTrace();
}
Constant con = new Constant();
con.createNewProject();
}
//shell.close();
monitor.done();
}
});
}
catch (InvocationTargetException | InterruptedException e)
{
e.printStackTrace();
}
}
});
}
}
Put your progress monitor as below :
Display.getDefault().asyncExec( new Runnable()
{
IWorkbenchWindow win = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
new ProgressMonitorDialog(shell).run(true, true, new IRunnableWithProgress() {
#Override
public void run(final IProgressMonitor monitor) throws InvocationTargetException,
InterruptedException
{
monitor.beginTask("Import Data", IProgressMonitor.UNKNOWN);
monitor.subTask("Connecting to databse...");
for(int i=0;i<=100;i++)
}
If you want the workbench page, that also has to be called inside a UI thread like above.
You can't access UI code in the background thread used for the IRunnableWithProgress code.
So you must get the values of controls in the UI thread before you run the progress dialog.
You also can't access things like IWorkbenchPage in the background thread. If you want to update UI objects from a non-UI thread, you need to use Display.asyncExec or Display.syncExec to run the updating code in the UI thread.
I have a distributed queue on Weblogic. Messages are read from the queue using JMS onMessage() function. However the messages are not purged from the queue as long as the deployment is running. The message state string is always 'receive'. How do we ensure that the message is not picked up again in case a restart of the deployment is done?
#Override
public void onMessage(Message msg) {
try {
String msgText;
if (msg instanceof TextMessage) {
msgText = ((TextMessage) msg).getText();
} else {
msgText = msg.toString();
}
System.out.println("Message Received from Message_RESPONSE_QUEUE: " + msgText + " - " + count++);
// now send the message to queue2
InitialContext ic2 = getInitialContext2();
getMsgFromQueue qs = new getMsgFromQueue();
qs.init2(ic2, QUEUE2);
qs.send(msg, null);
} catch (JMSException jmse) {
} catch (NamingException ex) {
Logger.getLogger(getMsgFromQueue.class.getName()).log(Level.SEVERE, null, ex);
}
}
The message from the JMS queue does not get removed until JMS server receives an acknowledgement.
Here's some references that you may find useful -
http://docs.oracle.com/cd/E17904_01/web.1111/e15493/prog_details.htm#i1156227
http://docs.oracle.com/cd/E17904_01/web.1111/e15493/prog_details.htm#i1152248
http://docs.oracle.com/cd/E17904_01/web.1111/e15493/prog_details.htm#i1156227