Using java application, I'm trying to create a durable subscription on a jms uniform distributed topic.
The jms server is running on weblogic 10.3.5 and the topic is distributed on 2 servers.
If I'm developping a message driven bean, it's working. I have a durable subscription on both servers with the same subscription name.
With a standalone java application, I can do the job with a normal topic (not distributed). But can't manage it to work with distributed topic.
InitialContext ic = new InitialContext();
TopicConnectionFactory connectionFactory = (TopicConnectionFactory) ic.lookup("myConnectionFactory");
TopicConnection connection = connectionFactory.createTopicConnection();
connection.setClientID("testclient");
TopicSession session = connection.createTopicSession(false,Session.AUTO_ACKNOWLEDGE);
TopicSubscriber subscriber;
Topic topic1 = (Topic) ic.lookup("jmsserver1#myTopic");
Topic topic2 = (Topic) ic.lookup("jmsserver2#myTopic");
subscriber = session.createDurableSubscriber(topic1,"testSubscription","",false);
subscriber = session.createDurableSubscriber(topic2,"testSubscription","",false);
Gives me
Exception in thread "main" weblogic.jms.common.JMSException: [JMSClientExceptions:055037]Subscription testSubscription is in use
In the weblogic console the first subscription testSubscription on myJmsModule!jmsserver1#myTopic is created not the second.
What can I do ?
You will have to remove the durable subscription manually and WLS will not remove to automatically
https://docs.oracle.com/cd/E17904_01/web.1111/e15493/dist_topics.htm#WLMDB10013
Setting Automatic Deletion of Durable Subscriptions :-
You can configure an MDB to automatically delete a durable topic subscription when the MDB is undeployed or deleted from a server. To configure an MDB to automatically delete durable topic subscriptions, set durable-subscription-deletion to True. By default, durable-subscription-deletion is set to False
By default it is false and thus it will not clear the durable subscriber automatically.
You need to change the ConnectionFactory via the weblogic admin console to create shareable connections
Client ID Policy: CLIENT_ID_POLICY_UNRESTRICTED
Subscription Sharing Policy:Sharable
https://docs.oracle.com/cd/E57014_01/wls/WLACH/pagehelp/JMSjmsconnectionjmsconnectionfactoryconfigclientparamstitle.html
Related
I have an ActiveMQ queue that does seem not seem to be supported by Quarkus. When I try to use the Quarkus JMS implementation described here I get the following error:
AMQP SASL header mismatch value 0, expecting 41. In state: HEADER0
I assume that this is because the ActiveMQ server does not support AMQP. The code I wrote to try and connect to the ActiveMQ server.
ConnectionFactory connectionFactory = new ConnectionFactory();
connection = connectionFactory.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue("inQue");
producer = session.createProducer(destination);
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
messageMap = session.createMapMessage();
While the above does not work. If i change it to using
ActiveMQConnectionFactory from ActiveMQ it works just fine:
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616");
connection = connectionFactory.createConnection("admin", "admin");
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue("inQue");
producer = session.createProducer(destination);
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
messageMap = session.createMapMessage();
But if i change to the Quarkus version of ConnectionFactory it no longer works and I get the error above. So is it possible to solve this somehow? Or do I need to use ActiveMQConnectionFactory? If so, how can I get Quarkus to register my MessageListener? Right now, just to test, I write:
MessageListener listener = new MyListener();
consumer.setMessageListener(listener);
But I would like Quarkus to do this when the application starts. But I'm not sure how to do it.
Depending on which version of ActiveMQ you are using you should be able to use the Quarkus JMS extension which is based on Qpid JMS and speaks AMQP. The trick is that you need to connect to the transport connector that was configured to speak AMQP and not one that uses the native Openwire protocol which normally resides on port 61616.
The ActiveMQ documentation defines how this is done. Essentially in your broker configuration you need a definition similar to this:
<transportConnectors>
<transportConnector name="amqp" uri="amqp://0.0.0.0:5672"/>
</transportConnectors>
Of course if using ActiveMQ Artemis this configuration would be different but you didn't specify which specific version of ActiveMQ you are running.
The error message you provided (If it is from the server logs) indicates that the client did indeed connect to an AMQP endpoint but it got something that it did not expect which implies something else strange is going on such as you are not using Qpid JMS but some other client since the initial byte of the expected AMQP header is reported to have been zero which is definitely wrong since an AMQP header always starts with the letter 'A'.
NOTE: Given the comments the error message in the question is likely from the client which would indicate the client read the normally sent Openwire header meaning the transport connector in play was an Openwire variant.
I am creating a program to send messages to ActiveMQ. This server is in active/passive configuration with one active and two standby nodes.
My code for creating connections as follows:
String furl = "failover:(tcp://aa.myamq-01:61616:tcp://aa.myamq-02:61616:tcp://aa.myamq-03:61616");
ConnectionFactory = new ActiveMQConnectionFactory(furl);
Connection connection = ConnectionFactory.createConnection();
connection.start();
Everything works as expected. However I get the following output in the console.
ERROR | Connect fail to tcp://aa.myamq-01:61616, error message : Connection refused:Connect
ERROR | Connect fail to tcp://aa.myamq-02:61616, error message : Connection refused:Connect
INFO |Successfully connected to tcp://aa.myamq-03:61616
Is there a way the active server can be identified and connection attempted to it only? Alternatively, can the error messages be suppressed?
AFAIK there isn't in this scenario. Inactive ActiveMQ nodes are actually not accepting connections. Therefor they look like they are down.
But if you would need to find out which node is master you can find that in DB if you use DB backend in ActiveMQ.
Regarding suppressing this message I would not even try to do that because if there would be a regular failure you will not notice it.
I am using Spring AMQP and this is my connection factory code:
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setAcknowledgeMode(AcknowledgeMode.AUTO);<br/>
factory.setDefaultRequeueRejected(false);
During consuming the message if RabbitMQ server restarts or there is a connection lost I will get the below exception:
org.springframework.amqp.rabbit.connection.AutoRecoverConnectionNotCurrentlyOpenException: Auto recovery connection is not currently open
If server comes up my application will be connected again
but with a new connection and there will be an unacked messsage.
How to handle this? I want the message to be requeued and my old connection should be killed.
Consider to use the latest Spring AMQP 1.7.2 which turns off that:
connectionFactory.setAutomaticRecoveryEnabled(false);
on the target com.rabbitmq.client.ConnectionFactory in favor of its own recovery mechanism.
I am looking for a solution using Java and Redis (currently using the Jedis library) of having a cold standby redis server. I am looking for an intermediate solution to a single server, and a cluster of servers. Specifically, I want to have two servers setup, each standalone, and have my application only use the first Redis server if it is available, and fail over to the second server, only if the first server is not available - a standard cold standby scenario - no replication.
The current connection factory is setup as
public JedisConnectionFactory redisConnectionFactory() {
JedisConnectionFactory redisConnectionFactory = new JedisConnectionFactory();
redisConnectionFactory.setHostName(redisUrl);
redisConnectionFactory.setPort(redisPort);
redisConnectionFactory.setDatabase(redisDbIndex);
return redisConnectionFactory;
}
where redisUrl resolves to something like 'my-redis-server.some-domain.com'. I would like to be able to specify the redis host name something like 'my-redis-server-1.some-domain.com,my-redis-server-2.some-domain.com' and have the second server used as the cold standby.
I am using MQexplorer to handle queue manager, and when I connect to MQ using JMS with JNDI lookup, using qcf.createQueueConnection(); I am getting JMSWMQ2013: The security authentication was not valid that was supplied for QueueManager error. All posts/blogs mention about this error, but they say to remove CHAUTH for queuemanager and so on... How do I work this out using MQExplorer? Please help me on this!
I am using MQ client(with JNDI on LDAP) connection which can connect remote machine(not bindings).
Actually disabling CHLAUTH is NOT advised as doing so opens up your queue manager to the world. It's OK if this is a test queue manager. Using runmqsc you can disable channel authentication. In runmqsc issue "ALTER QMGR CHLAUTH(DISABLED)" command to disable channel authentication.
Please read WMQ InfoCenter or Chapter 20 of this redbook or just search for T.Rob's posts in this forum on CHLAUTH. Few links here, this one