Receive MapMessage by Consumer shows nothing - jms

Hello i am facing a strange(for me ) problemm with MapMessage in ActiveMQ. My code produces no error but it shows nothing.
Producer code:
public void sendMapMessageTopic(String topicName) throws Exception {
try {
initConnectionTopic(topicName);
mapMessage = session.createMapMessage();
mapMessage.setIntProperty("Age", 24);
mapMessage.setStringProperty("Full Name", "Konstantinos Drakonakis");
mapMessage.setStringProperty("Height", "178cm");
List<String> data = new ArrayList<String>();
data.add("Company");
data.add("Project");
mapMessage.setObject("data", data);
Map<String, Object> specs = new HashMap<String, Object>();
specs.put("data", data);
mapMessage.setObject("specs", specs);
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
producer.send(mapMessage);
} catch (Exception e) {
System.out.println("Exception while sending map message to the queue" + e.getMessage());
throw e;
} finally {
if (connection != null) {
connection.close();
if (session != null) {
session.close();
}
}
}
}
Consumer code:
public void startReceivingMapMessageTopic(String topicName) throws Exception {
try {
//get connection factory
connectionFactory = new ActiveMQConnectionFactory(username, password, brokerUrl);
//create a connection
connection = connectionFactory.createConnection();
connection.start();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//create destination(unless it already exists)
queue = session.createTopic(topicName);
consumer = session.createConsumer(queue);
messageMap = (MapMessage) consumer.receive(1000);
if (messageMap instanceof MapMessage) {
MapMessage m = messageMap;
System.out.println("The contents of MapMessage is: " + m.getStringProperty("Age"));
}
System.in.read();
consumer.close();
connection.close();
session.close();
} catch (Exception e) {
System.out.println("Exception while sending message to the queue" + e.getMessage());
throw e;
}
}
Main method for Producer:
public static void main(String[] args) {
//connect to the default broker url
ActiveMQQueueSender sender = new ActiveMQQueueSender("tcp://localhost:61616", "admin", "admin");
try {
sender.sendMapMessageTopic("Map Message Topic");
} catch (Exception ex) {
System.out.println("Exception during" + ex.getMessage());
}
}
Main method for consumer:
public static void main(String[] args) {
ActiveMQQueueReceiver receiver = new ActiveMQQueueReceiver("tcp://localhost:61616", "admin", "admin");
try {
receiver.startReceivingMapMessageTopic("Map Message Topic");
} catch (Exception ex) {
System.out.println("Exception during receival in main class" + ex.getMessage());
}
}
But still i get nothing. Any ideas?

Related

Messages not rolling back on K8s pod restarts when using Spring JMS Listener with Client Ack

We have Spring JMS application ( deployed on K8s) which processes about 100 - 400 messages/sec. The application consumes messages from IBM MQ and processes them. Off late we have started noticing messages getting dropped whenever K8s pod restarts or deployments are done even though we have message ack in place. I am looking for a solution here to resolve this issue.
Software
Version
Spring Boot
2.1.7.RELEASE
IBM MQ Client
9.1.0.5
JMS
2.0.1
Java
11
#Configuration
#EnableJms
public class MqConfiguration {
#Bean
public MQConnectionFactory mqConnectionFactory(Servers configProperties) {
MQConnectionFactory mqConnectionFactory = new MQConnectionFactory();
try {
mqConnectionFactory.setHostName(configProperties.getHost());
mqConnectionFactory.setQueueManager(configProperties.getQueueManager());
mqConnectionFactory.setPort(Integer.valueOf(configProperties.getPort()));
mqConnectionFactory.setChannel(configProperties.getChannel());
mqConnectionFactory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
mqConnectionFactory.setCCSID(1208);
mqConnectionFactory.setClientReconnectOptions(WMQConstants.WMQ_CLIENT_RECONNECT);
} catch (Exception e) {
logger.logError(mqConnectionFactory, ,
"Failed to create MQ ConnectionFactory", String.valueOf(HttpStatus.SC_BAD_REQUEST), e);
}
return mqConnectionFactory;
}
#Bean(name = "messageListenerContainerFactory")
public DefaultJmsListenerContainerFactory provideJmsListenerContainerFactory(
MQConnectionFactory connectionFactory) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE);
factory.setErrorHandler(new ErrorHandler() {
#Override
public void handleError(Throwable t) {
ServiceMetrics metrics = new ServiceMetrics();
metrics.setCorrelationId(UUID.getUUID());
logger.logError(factory, "Exception occured at JMS Factory Container Listener", String.valueOf(HttpStatus.SC_BAD_REQUEST), t);
}
});
return factory;
}
#Bean(name = "jmsQueueTemplate")
public JmsTemplate provideJmsQueueTemplate(MQConnectionFactory connectionFactory) {
return new JmsTemplate(connectionFactory);
}
}
#Configuration
public class AsyncConfiguration {
#Autowired
private Servers configProperties;
#Bean(name = "asyncTaskExecutor")
public ExecutorService getAsyncTaskExecutor() {
String THREAD_POOL = "th-pool-";
return getExecutor(THREAD_POOL, 70,true);
}
private ExecutorService getExecutor(String threadName, int maxPoolSize, boolean cached) {
final ThreadFactory threadFactory = new CustomizableThreadFactory(threadName);
if (cached) {
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(0, maxPoolSize,
60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), threadFactory);
threadPoolExecutor.setRejectedExecutionHandler((r, executor) -> {
if (!executor.isShutdown()) {
try {
executor.getQueue().put(r);
} catch (InterruptedException e) {
throw new RejectedExecutionException(e);
}
}
});
return threadPoolExecutor;
} else {
return new ThreadPoolExecutor(maxPoolSize, maxPoolSize,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(),
threadFactory);
}
}
#Component
public class InputQueueListener {
#Autowired
private ExecutorService asyncTaskExecutor;
#JmsListener(destination = "${mqserver.queue}", containerFactory = "messageListenerContainerFactory", concurrency = "1-16")
public void processXMLMessage(Message message) {
CompletableFuture.runAsync(() -> processMessage(message), asyncTaskExecutor);
}
private void processMessage(Message message) {
String inputXmlMessage = null;
boolean isSuccess = false;
try {
if (message instanceof TextMessage) {
TextMessage textMessage = (TextMessage) message;
inputXmlMessage = textMessage.getText();
} else if (message instanceof BytesMessage) {
BytesMessage byteMessage = (BytesMessage) message;
inputXmlMessage = CommonHelperUtil.getMessageFromBytes(byteMessage);
} else {
logger.logError(null, "Invalid message type received while converting Message to XML", String.valueOf(HttpStatus.SC_BAD_REQUEST));
errorQueuePublisher.publishErrorMessage(message);
try {
message.acknowledge();
} catch (JMSException jmsException) {
logger.logError(null, null, "Failed to Acknowledge XML message.",
String.valueOf(HttpStatus.SC_BAD_REQUEST), jmsException);
}
}
-
-
if (isSuccessProcessed) {
message.acknowledge();
} else {
message.acknowledge();
// Publishing back to the same queue
publishForRetry.publishMessageForRetry(message);
}
} catch (Exception e) {
if (StringUtils.isBlank(serviceMetrics.getCorrelationId())) {
serviceMetrics.setCorrelationId(UUID.getUUID());
}
logger.logError(null, null, "Exception while Converting Processing Message. Retrying to publish.",
String.valueOf(HttpStatus.SC_BAD_REQUEST), e);
// Publishing back to the same queue
publishForRetry.publishMessageForRetry(message);
try {
message.acknowledge();
} catch (JMSException jmsException) {
logger.logError(null, null,
"Failed to Acknowledge the Message when publishing" + "to Error Queue",
String.valueOf(HttpStatus.SC_BAD_REQUEST), jmsException);
}
}
}
}
}

TCP socket client using Spring Boot Web

I'm developing a web application using Spring Boot Web and I want to communicate with a TCP socket server using IP and Port (connect, send, receive and disconnect).
I'm new to Spring Boot and I searched many days in the internet without any working result and the Websocket solution will not work in this case.
UPDATE (please confirm)
I think that I can use the standard java.io.* and java.net.* in Spring Boot Web juste like any other Java Program:
try {
try (Socket clientSocket = new Socket(IP, PORT);
PrintWriter out = new PrintWriter(
clientSocket.getOutputStream(), true);
BufferedReader br = new BufferedReader(
new InputStreamReader(
clientSocket.getInputStream()))) {
System.out.println("Connected to server");
String str = "test";
out.write(str);
out.flush();
char[] cbuf = new char[size];
br.read(cbuf, 0, size);
System.out.println(cbuf);
}
} catch (IOException ex) {
ex.printStackTrace();
}
This is my own version of a simple tcp client developed for SpringBoot.
First, you have to open the connection with the openConnection() method. Then, you can send messages with sendMessage() method and receive messages with takeMessage() method.
#Service("socketClient")
public class SocketClient {
#Value("brain.connection.port")
int tcpPort;
#Value("brain.connection.ip")
String ipConnection;
private Socket clientSocket;
private DataOutputStream outToTCP;
private BufferedReader inFromTCP;
private PriorityBlockingQueue<String> incomingMessages = new PriorityBlockingQueue<>();
private PriorityBlockingQueue<String> outcomingMessages = new PriorityBlockingQueue<>();
private final Logger log = LoggerFactory.getLogger(this.getClass());
private Thread sendDataToTCP = new Thread(){
public void run(){
String sentence = "";
log.info("Starting Backend -> TCP communication thread");
while(true){
try {
sentence = incomingMessages.take();
outToTCP.writeBytes(sentence + '\n');
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
};
private Thread getDataFromTCP = new Thread(){
public void run(){
log.info("Starting TCP -> Backend communication thread");
while(true){
String response = "";
try {
response = inFromTCP.readLine();
if (response == null)
break;
outcomingMessages.put(response);
} catch (IOException e) {
e.printStackTrace();
}
}
}
};
public void openConnection(){
try {
this.clientSocket = new Socket(ipConnection, tcpPort);
outToTCP = new DataOutputStream(clientSocket.getOutputStream());
inFromTCP = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
getDataFromTCP.start();
sendDataToTCP.start();
} catch (IOException e) {
e.printStackTrace();
}
}
//Send messages to Socket.
public void sendMessage(String message) throws InterruptedException {
incomingMessages.put(message);
}
//Take Message from Socket
public String takeMessage() throws InterruptedException {
return outcomingMessages.take();
}
}

Mockito doThrow for JMS Client not throwing Exception

I am writing unit test case for my JMS client. But doThrow is not throwing any error. Looks like it is because my sendMessage method has return type as void and I have finally block to close the connection.
Is anyone facing the same issue?
doThrow(new JMSException("Expected")).when(messageSubmitter).sendMessage(message);
Here's the sendMessage method:
public void sendMessage(String message) throws JMSException,Exception {
Connection connection = connectionFactory.createConnection();
try {
connection.start();
try {
Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
try {
MessageProducer messageProducer =session.createProducer(messageQueue);
try {
TextMessage message = session.createTextMessage();
message.setText(messageQueue);
messageProducer.send(message);
}
} finally {
JmsUtils.closeProducer(messageProducer);
}
} finally {
JmsUtils.closeSession(session);
}
} finally {
JmsUtils.closeConnection(connection);
}
} catch (JMSException ex) {
throw ex;
} catch(Exception ex) {
throw ex;
}
}
This is my test method and above is my jms client method.
#Test
public void myAction_should_return_failure_result_in_case_of_JMS_excepti‌​on() throws Exception {
// given
String message ="Test";
doThrow(exception).when(MessageSubmitter.sendMessage(message‌​);
//when
ActionResult processingResult = Submitter.myActionOn("123");
//then
assertFalse(processingResult.isProcessedSuccessfully());
assertEquals(exception, processingResult.getException());
}

weblogic.net.http.HttpUnauthorizedException: Proxy or Server Authentication Required

I am trying to connect to a REST API in an application deployed on weblogic 10.3.6. The sample code works fine when run independently (outside weblogic server). But when I deploy the same code it starts giving me this error
Failed to communicate with proxy: proxy.xxx.xxx/xxxx. Will try connection api.forecast.io/443 now.
weblogic.net.http.HttpUnauthorizedException: Proxy or Server Authentication Required
at weblogic.net.http.HttpURLConnection.getAuthInfo(HttpURLConnection.java:297)
at weblogic.net.http.HttpsClient.makeConnectionUsingProxy(HttpsClient.java:440)
at weblogic.net.http.HttpsClient.openServer(HttpsClient.java:351)
at weblogic.net.http.HttpsClient.New(HttpsClient.java:527)
at weblogic.net.http.HttpsURLConnection.connect(HttpsURLConnection.java:239)
Code that we are running is as below
try {
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, new X509TrustManager[] { new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
} }, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
} catch (Exception e) { // should never happen
e.printStackTrace();
}
try {
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("proxy.xxxx.xxxx", xxxx));
URL url = new URL("https://api.forecast.io/forecast/xxxxxxxxx/12.9667,77.5667");
HttpURLConnection conn = (HttpURLConnection)url.openConnection(proxy);
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}
conn.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "";
Our proxy is a company proxy and doesn't have any username/password. We are stuck on this issue for sometime now. Any suggestions/pointers will be really appreciated.

How to subscribe to an existing advisory topic?

I have activemq5.3.2 running and I wanted to subscribe existing advisory topics using my java program. while, `jndi` lookup I am getting following error:
javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:
java.naming.factory.initial
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:657)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:259)
at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:296)
at javax.naming.InitialContext.lookup(InitialContext.java:363)
at jmsclient.Consumer.<init>(Consumer.java:38)
at jmsclient.Consumer.main(Consumer.java:74)
Exception occurred: javax.jms.InvalidDestinationException: Don't understand null destinations
Please suggest where the problem is, or how could I use my topic name to look for?
package jmsclient;
import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.apache.activemq.ActiveMQConnectionFactory;
public class Consumer implements MessageListener {
private static int ackMode;
private static String clientTopicName;
private boolean transacted = false;
//private MessageConsumer messageConsumer;
static {
clientTopicName = "ActiveMQ.Advisory.Consumer.Queue.example.A";
ackMode = Session.AUTO_ACKNOWLEDGE;
}
#SuppressWarnings("null")
public Consumer()
{// TODO Auto-generated method stub
TextMessage message = null;
Context jndiContext;
//TopicConnectionFactory topicConnectionFactory = null;
TopicConnection topicConnection = null;
TopicSession topicSession = null;
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://usaxwas012ccxra.ccmp.ibm.lab:61616");
try{
Topic myTopic = null;
try { jndiContext = new InitialContext();
myTopic = (Topic) jndiContext.lookup(clientTopicName);
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
topicConnection = connectionFactory.createTopicConnection();
topicConnection.start();
topicSession = topicConnection.createTopicSession(transacted, ackMode);
TopicSubscriber topicSubscriber = topicSession.createSubscriber(myTopic);
Message m = topicSubscriber.receive(1000);
if (m != null) {
if (m instanceof TextMessage) {
message = (TextMessage) m;
System.out.println("Reading message: " + message.getText());
}
}
} //try ends
catch (JMSException e) {
System.out.println("Exception occurred: " + e.toString());
} finally {
if (topicConnection != null) {
try {
topicConnection.close();
} catch (JMSException e) {}
}}}
public void onMessage(Message arg0) {
// TODO Auto-generated method stub
}
public static void main(String[] args) {
new Consumer();
}
}

Resources