Accessing RabbitMQ from different clusters/machines - rabbitmq

I have a RabbitMQ instance deployed on a google cloud engine. I also have a hadoop instance deployed on a different google cloud engine but still in the same application. I am trying to connect to the RabbitMQ queue instance from the hadoop clusters but with no success.
I have a java application that should push items on the RabbitMQ queue and then receive them in the same application. The following is the connection java code:
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("130.211.112.37:5672");
try {
connection = factory.newConnection();
channel = connection.createChannel();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
but i get the following result:
java.net.UnknownHostException: 130.211.112.37:5672
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:178)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:579)
at com.rabbitmq.client.impl.FrameHandlerFactory.create(FrameHandlerFactory.java:32)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:615)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:639)
at de.unibonn.iai.eis.luzzu.io.impl.SparkStreamProcessorObserver.<clinit>(SparkStreamProcessorObserver.java:157)
at de.unibonn.iai.eis.luzzu.evaluation.Main.main(Main.java:87)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.spark.deploy.SparkSubmit$.launch(SparkSubmit.scala:328)
at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:75)
at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)
I tried opening port 5672 on google cloud firewall. Does anyone has some pointers to the solution please?
Best
Jeremy

As wrote to the comment:
ConnectionFactory factory = new ConnectionFactory();
//factory.setHost("130.211.112.37:5672"); <----- sethost accepts only the host!
factory.setHost("130.211.112.37");
factory.setPort(5672);
try {
connection = factory.newConnection();
channel = connection.createChannel();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
By default the port is 5672, so setPort it is not necessary.
You have to use setPort only if you change the default port.

As explained here: https://www.rabbitmq.com/api-guide.html you need to call setHost and setPort to create a connection. In your app you are passing the host and port together on the same line.

Related

How to catch error when message have been sent from JMS

I am sending an message through my standalone application that uses EJB MDB to communicate to my other application server that is running on JBOSS server.My application server is connected to a MSSQL server. In certain scenario, connection to the database is lost on application server side and we get following error -
Connection is reset.
Later , when i try to send message i don't get any error at my standalone EJB MDB logs and the process just stops executing.I get error log on application server side logs but same logs don't get propagated to my EJB MDB error logs.
As per my understanding, when db connection is lost all the ejb bean present in jboss container get nullified too.(I could be wrong here, i am new to EJB).
I tried implementing below code in my code that use to send message -
QueueConnection qcon = null;
#PostConstruct
public void initialize() {
System.out.println("In PostConstruct");
try {
qcon = qconFactory.createQueueConnection();
} catch (Exception e) {
e.printStackTrace();
}
}
#PreDestroy
public void releaseResources() {
System.out.println("In PreDestroy");
try {
if(qcon != null)
{
qcon.close();
}
if(qcon== null){
throw new Exception(" new exception occured.");
}
} catch (Exception e) {
e.printStackTrace();
}
}
I was in a impression that Queueconnection object will be nullified, when our db connection have been lost(as we are creating bean and making connection for message). But it doesn't seem to work.
I did found a way to call back my application after sending message. I used a separate temporary queue and used setJMSReplyTo method to set the reply destination. More info could be obtained from this
link. Hope this helps others.

JSSEHelper does not provide the correct SSLSocketFactory for extablishing secure connection in Websphere 8.0

I was working with 8.0 version of Websphere application server. I was trying to get SSLSocketFactory from JSSEHelper. Although
I have successfuly got the SSLSocketFactory
I have successfuly got the SSLSocket from SSLSocketFactory
I have successfuly established the secure connection,
but cipher suites provided in ClientHello message corresponded neither to
CellDefault SSL Settings/NodeDefault SSL Settings/NodeDefaultnor
nor to my own custom SSL configuration.
The solution to this problem was to avoid retrieving SSLSocketFactory from JSSEHelper. Instead of using JSSEHelper, I should use static method getDefault() from SSLSocketFactory class in whis way:
public SSLSocket getSslSocket(Properties sslProps) {
SSLSocketFactory factory = SSLSocketFactory.getDefault();
SSLSocket socket = null;
try {
socket = (SSLSocket) factory.createSocket();
} catch (IOException e) {
e.printStackTrace();
}
return socket;
}
More details can be found here:
Could anybody please clarify why this statement:
slSocketFactory = jsseHelper.getSSLSocketFactory(sslMap, sslProps)
returns incorrect 'SSL socket factory' while this statement
SSLSocketFactory.getDefault()
returns the correct one?
Moreover, in what case should I use factory retrieved from these statements respectively?
SSLSocketFactory.getDefault();
jsseHelper.getSSLSocketFactory(sslMap, sslProps)
getSSLSocketFactory(java.lang.String sslAliasName, java.util.Map connectionInfo, SSLConfigChangeListener listener)
Thank you very much
Although it is not intuitive, statement:
SSLSocketFactory factory = SSLSocketFactory.getDefault();
returns the WebSphere custom SSLSocketFactory.
Then you can enforce SSL-configuration on thread in this way:
Properties sslProperties = getProperties();
jsseHelper.setSSLPropertiesOnThread(sslProperties);
SSLSocket socket = getSslSocket();
CommonIO.writeToSocket(socket, "127.0.0.1", 1234);
jsseHelper.setSSLPropertiesOnThread(null);
Although JSSEHelper.getSSLSocketFactory(sslMap, sslConfig_XYZ) returns also factory but their sockets ignore cipher suites encapsulated in SSL-configuration sslConfig_XYZ.
On the other hand, if you want to enforce only
protocol
keystore
truststore
this method:
JSSEHelper.getSSLSocketFactory(sslMap, sslConfig_XYZ)
is sufficient enough.

Migrating from WebSphere MQ to Active MQ

There was a similar question Procedure to migrate from IBM MQ to ActiveMQ and it was closed, but I will try anyway.
Our customers want to migrate from WebSphere MQ to Active MQ. In above mentioned question it was said that as for JMS such migration in theory will consist in apps re-configuration. Our customers say that their apps use auto-generated .bindings file. So, is it possible to make apps work with Active MQ just by editing .binding file and putting active mq's .jars to java classpath, or some other configuration is required?
To check this , i tried the following
a) Create a WMQ bindings file use JMSAdmin. Once i created a QCF and Queue i was able to send a message via a JMS lookup and send a message.
b) For the AMQ set up to generate a .bindings file , IBM had some sample code to generate the bindings file.
Once this was done i used exactly the same code to send a message and the message was perfectly sent to both AMQ and WMQ
Here is the sample code that i was able to interoperate.
public void sendMessages() {
ConnectionFactory connectionFactory;
Connection con = null;
Session session = null;
MessageProducer producer = null;
//create initial context properties
Properties initialContextProperties = new Properties();
initialContextProperties.put("java.naming.factory.initial", "com.sun.jndi.fscontext.RefFSContextFactory");
initialContextProperties.put(Context.PROVIDER_URL, "file:/C:/JNDI-Directory/AMQ");
initialContextProperties.setProperty("transport.jms.security.authentication", "none");
try {
InitialContext initialContext = new InitialContext(initialContextProperties);
//create connection factory object
//ivtQCF - created connection factory object in IBM-MQ
connectionFactory = (ConnectionFactory) initialContext.lookup("confact2");
con = connectionFactory.createConnection();
con.start();
session = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
//localq - created queue in IBM-MQ
Destination destination = (Destination) initialContext.lookup("dest");
producer = session.createProducer(destination);
String msg = "SAMPLE MESSAGE PLACED TO QUEUE";
TextMessage textMessage = session.createTextMessage(msg);
producer.send(textMessage);
con.close();
session.close();
producer.close();
} catch (NamingException e) {
throw new RuntimeException("Unable to send jms messages", e);
} catch (JMSException e) {
throw new RuntimeException("Unable to send jms messages", e);
}
}

Cannot connect to redis using jedis

Redis version: 3.2.0
Jedis version: 2.8.1
Below is my java code for connecting to redis:
public class TestRedis {
public static void main(String[] args) {
String host = args[0];
int port = Integer.parseInt(args[1]);
try (Jedis jedis = new Jedis(host, port)) {
System.out.println("Connected to jedis " + jedis.ping());
} catch(Exception e){
e.printStackTrace();
}
}
}
I am running this program in the machine where redis is installed. This machine's ip address is 192.168.1.57
If I provide host="localhost" and port = "6379" as arguments, connection with redis successfully established.
However, If I give host="192.168.1.57" and port = "6379" in arguments, I end up with below exception:
redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection refused
at redis.clients.jedis.Connection.connect(Connection.java:164)
at redis.clients.jedis.BinaryClient.connect(BinaryClient.java:80)
at redis.clients.jedis.Connection.sendCommand(Connection.java:100)
at redis.clients.jedis.Connection.sendCommand(Connection.java:95)
at redis.clients.jedis.BinaryClient.ping(BinaryClient.java:93)
at redis.clients.jedis.BinaryJedis.ping(BinaryJedis.java:105)
at TestRedis.main(TestRedis.java:14)
Caused by: java.net.ConnectException: Connection refused
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:579)
at redis.clients.jedis.Connection.connect(Connection.java:158)
... 6 more
Please help...
There are a few settings that would affect this: bind and protected-mode. They work together to provide a baseline of security with new installs.
Find the following in your redis.conf file and comment it out:
bind 127.0.0.1
By adding a # in front of it:
# bind 127.0.0.1
Or, if you would rather not comment it out, you can also add the IP of your eth0/em1 interface to it, like this:
bind 127.0.0.1 192.168.1.57
Also, unless you're using password security, you'll also have to turn off protected mode by changing:
protected-mode yes
To:
protected-mode no
Make sure that you read the relevant documentation and understand the security implications of both of these changes.
After making these changes, restart redis.

Connection to remote redis server is reset

Trying the basic set operation on a redis server installed in red hat linux.
JedisPool pool = new JedisPool(new JedisPoolConfig(), HOST, PORT);
Jedis jedis = null;
try {
jedis = pool.getResource();
System.out.println(jedis.isConnected()); //prints true
jedis.set("status", "online"); //gets exception
} finally {
if (jedis != null) {
jedis.close();
}
}
pool.destroy();
Getting the following exception:
Exception in thread "main" redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketException: Connection reset
at redis.clients.util.RedisInputStream.ensureFill(RedisInputStream.java:201)
at redis.clients.util.RedisInputStream.readByte(RedisInputStream.java:40)
at redis.clients.jedis.Protocol.process(Protocol.java:132)
at redis.clients.jedis.Protocol.read(Protocol.java:196)
at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:288)
at redis.clients.jedis.Connection.getStatusCodeReply(Connection.java:187)
at redis.clients.jedis.Jedis.set(Jedis.java:66)
at com.revechat.spring.redis_test.App.main(App.java:28)
Caused by: java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at redis.clients.util.RedisInputStream.ensureFill(RedisInputStream.java:195)
... 7 more
How to resolve the issue ?
I had a similar issue. Our production Redis required an encrypted connection over TLS, whereas our test system did not. In production therefore the java.net.SocketException: Connection reset appeared when we tried to use the Jedis connection.
To fix it, use
JedisPool pool = new JedisPool(new JedisPoolConfig(), HOST, PORT, true);
for connections that require TLS.