I am new to JMS coding. I am trying to create message from stand-alone java client which creates and send the message to queue and message driven bean is used for further processing of the messages.
I referred the following guidelines :
http://techtipsjava.blogspot.de/2013/05/jms-on-glassfish-queue-and-topic-with.html
I am using Glassfish application server (3.1). And setup everything to create JMS message from stand-alone java client.
Here is my code:
Client
import java.util.Properties;
import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.QueueConnectionFactory;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
public class TruckMonitor {
public static void main(String args[]) {
try {
// Provide the details of remote JMS Client
Properties props = new Properties();
props.put(Context.PROVIDER_URL, "mq://localhost:7676");
// Create the initial context for remote JMS server
InitialContext cntxt = new InitialContext(props);
System.out.println("Context Created");
// JNDI Lookup for QueueConnectionFactory in remote JMS Provider
QueueConnectionFactory qFactory = (QueueConnectionFactory)cntxt.lookup("OmazanQueueConnectionFactory");
// Create a Connection from QueueConnectionFactory
Connection connection = qFactory.createConnection();
System.out.println("Connection established with JMS Provide ");
connection.start();
// Initialise the communication session
Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
// Create the message
TextMessage message = session.createTextMessage();
message.setJMSDeliveryMode(DeliveryMode.PERSISTENT);
message.setText(getMessage());
// JNDI Lookup for the Queue in remote JMS Provider
Queue queue = (Queue)cntxt.lookup("OmazanQueue");
// Create the MessageProducer for this communication
// Session on the Queue we have
MessageProducer mp = session.createProducer(queue);
// Send the message to Queue
mp.send(message);
System.out.println("Message Sent: " + getMessage());
// Make sure all the resources are released
mp.close();
session.close();
cntxt.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
private static String getMessage() {
String msg = null;
StringBuffer sbExceptionEvent = new StringBuffer("<exceptionEvent>");
sbExceptionEvent.append("</exceptionEvent>");
msg = sbExceptionEvent.toString();
return msg;
}
}
Message Driven Bean:
import java.util.Properties;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Queue;
import javax.jms.QueueConnectionFactory;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
/** * Message-Driven Bean implementation class for: OmazanMDBean*/
#MessageDriven(
activationConfig = {
#ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
#ActivationConfigProperty(propertyName = "destination", propertyValue = "OmazanQueue"),
#ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge")
},
mappedName = "OmazanQueue")
public class OmazanMDBean implements MessageListener {
/**
* Default constructor.
* #throws NamingException
* #throws JMSException
*/
public OmazanMDBean() {
super();
}
/**
* #see MessageListener#onMessage(Message)
*/
public void onMessage(Message message) {
System.out.println("Inside omMessage");
try {
message.acknowledge();
} catch (Exception e) {
e.printStackTrace();
}
TextMessage txtMessage = (TextMessage) message;
try {
System.out.println(txtMessage.getText());
} catch (Exception e) {
e.printStackTrace();
}
}
}
The problem is: onMessage() is not getting invoked. Did I miss anything? Please help me.
I guess if you remove #ActivationConfigProperty(propertyName = "destination", propertyValue = "OmazanQueue") from you MessageDrivenBean it will work since you have already used mappedName = "OmazanQueue"
Related
I have below code for Redis Configuration, i need to use RedissonClient to flush cache after regular intervals.Using timerTask to run flush code. CacheManager and Proxy Manager is used because it is connected to bucket4j Ratelimiting code.
Connection to Docker Redis Image is successful as well. Using redisson version 3.12.5.
Following this doc: https://www.freecodecamp.org/news/rate-limiting-with-bucket4j-and-redis/
import io.github.bucket4j.distributed.proxy.ProxyManager;
import io.github.bucket4j.grid.jcache.JCacheProxyManager;
import java.util.Iterator;
import java.util.Timer;
import java.util.TimerTask;
import javax.cache.CacheManager;
import javax.cache.Caching;
import javax.cache.spi.CachingProvider;
import lombok.extern.log4j.Log4j2;
import org.ehcache.jsr107.EhcacheCachingProvider;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.jcache.configuration.RedissonConfiguration;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.utility.DockerImageName;
import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.concurrent.TimeUnit.SECONDS;
#Log4j2
#Configuration
public class RedisConfig {
private static GenericContainer redis = null;
private RedissonClient redisson;
private final Timer timer = new Timer("RedisConfig", true);
private final CleanupRedis clean = new CleanupRedis(this);
public RedisConfig(){
timer.scheduleAtFixedRate(clean, SECONDS.toMillis(2), MINUTES.toMillis(2));
}
#Bean(name = "client")
public RedissonClient client() {
Config config = new Config();
if (redis == null) {
redis = new GenericContainer<>(redisImageName()).withExposedPorts(6379);
redis.start();
}
System.setProperty("spring.redis.host", redis.getHost());
System.setProperty("spring.redis.port", redis.getMappedPort(6379).toString());
config
.useSingleServer()
.setAddress("redis://" + redis.getHost() + redis.getMappedPort(6379));
RedissonClient rdson = Redisson.create(config);
return rdson;
}
#Bean
public CacheManager cacheManager(#Qualifier("client") RedissonClient redissonClient) {
Iterator<CachingProvider> iterator =
Caching.getCachingProviders(Caching.getDefaultClassLoader()).iterator();
while (iterator.hasNext()) {
CachingProvider provider = iterator.next();
if (!(provider instanceof EhcacheCachingProvider)) {
iterator.remove();
}
}
CacheManager manager = Caching.getCachingProvider().getCacheManager();
manager.createCache("cache", RedissonConfiguration.fromConfig(redissonClient.getConfig()));
return manager;
}
private static DockerImageName redisImageName() {
return DockerImageName.parse("docker.io/redis:5.0.3-alpine")
.asCompatibleSubstituteFor("redis:5.0.3-alpine");
}
#Bean
ProxyManager<String> proxyManager(CacheManager cacheManager) {
return new JCacheProxyManager<>(cacheManager.getCache("cache"));
}
protected class CleanupRedis extends TimerTask {
private RedisConfig redisConfig;
CleanupRedis(RedisConfig redisConfig) {
this.redisConfig = redisConfig;
}
#Override
public void run() {
try {
System.out.println("Redisson client call is being made");
RedissonClient redisson = Redisson.create(client().getConfig());
System.out.println("Redisson client is not working");
redisson.getKeys().flushdb();
log.debug("Successfully cleared the Redis Cache");
redisson.shutdown();
} catch (Exception e) {
log.debug("caught exception cleanup availability: {}", e.getMessage());
}
}
}
}
I have been using the rally javatoolkit for a while to add testcases, test results etc without any error. But all of a sudden it started throwing error as
" javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated" . I have referred the pages "rally rest api java toolkit sslpeerunverifiedexception : peer not authenticated" , rally rest api java toolkit sslpeerunverifiedexception : peer not authenticated but they didn't help me. Can someone help me with what I am doing wrong. Also If i need to download a certificate please help me for windows system. Thanks in advance. my code is as below:
import com.rallydev.rest.RallyRestApi;
import com.rallydev.rest.client.HttpClient;
import com.rallydev.rest.request.GetRequest;
import com.rallydev.rest.response.GetResponse;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.conn.scheme.Scheme;
public class ConnnectionTestWithHTTPClient {
public static void main(String[] args) throws URISyntaxException, IOException {
String host = "https://rally1.rallydev.com";
String apiKey = "_abc123";
String applicationName = "Connnection Test With HTTPClient";
RallyRestApi restApi = new RallyRestApi(new URI(host),apiKey);
restApi.setApplicationName(applicationName);
//restApi.setProxy(new URI("http://myproxy.mycompany.com"), "MyProxyUsername", "MyProxyPassword"); //SET PROXY SETTINS HERE
HttpClient client = restApi.getClient();
try {
SSLSocketFactory sf = new SSLSocketFactory(new TrustStrategy() {
public boolean isTrusted(X509Certificate[] certificate, String authType)
throws CertificateException {
//trust all certs
return true;
}
}, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
client.getConnectionManager().getSchemeRegistry().register(new Scheme("https", 443, sf));
String workspaceRef = "/workspace/12345"; //USE VALID WORKSPACE OID
GetRequest getRequest = new GetRequest(workspaceRef);
GetResponse getResponse = restApi.get(getRequest);
System.out.println(getResponse.getObject());
} catch (Exception e) {
System.out.println(e);
} finally {
restApi.close();
}
}
}
Also adding to the issue, i found a different error when I changed the port from 443 to 8443. i get "java.io.IOException: HTTP/1.1 522 Origin Connection Time-out" when i use 8443.
For some reason when I uncomment the line //restApi.setProxy(new URI("http://myproxy.mycompany.com"), "MyProxyUsername", "MyProxyPassword"); with correct inputs, the error goes off.
For all those who need the inputs, please put in the following:
restApi.setProxy(new URI("http://rally1.rallydev.com"), "xyz#abc.com", "rallypassword");
so the working code is as below:
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import com.rallydev.rest.RallyRestApi;
import com.rallydev.rest.client.HttpClient;
import com.rallydev.rest.request.GetRequest;
import com.rallydev.rest.response.GetResponse;
public class ConnnectionTestWithHTTPClient {
public static void main(String[] args) throws URISyntaxException, IOException {
String host = "https://rally1.rallydev.com";
String apiKey = "_apikey";
String applicationName = "Connnection Test With HTTPClient";
RallyRestApi restApi = new RallyRestApi(new URI(host),apiKey);
restApi.setApplicationName(applicationName);
restApi.setProxy(new URI("http://rally1.rallydev.com"), "abc#abc.com", "rallypassword"); //YOUR PROXY SETTINGS HERE
HttpClient client = restApi.getClient();
try {
SSLSocketFactory sf = new SSLSocketFactory(new TrustStrategy() {
public boolean isTrusted(X509Certificate[] certificate, String authType)
throws CertificateException {
//trust all certs
return true;
}
}, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
client.getConnectionManager().getSchemeRegistry().register(new Scheme("https", 443, sf));
String workspaceRef = "/workspace/1234";
GetRequest getRequest = new GetRequest(workspaceRef);
GetResponse getResponse = restApi.get(getRequest);
System.out.println(getResponse.getObject());
} catch (Exception e) {
System.out.println(e);
} finally {
restApi.close();
}
}
}
I am developing the adapter in MFP V8. Below is my code to validate username and password:
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import com.ibm.mfp.adapter.api.AdaptersAPI;
import com.ibm.mfp.adapter.api.ConfigurationAPI;
import com.ibm.mfp.security.checks.base.UserAuthenticationSecurityCheck;
import com.ibm.mfp.server.registration.external.model.AuthenticatedUser;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
#Api(value = "Sample Adapter Resource")
#Path("/resource")
public class UserValidationSecurityCheck extends UserAuthenticationSecurityCheck{
private String displayName;
private String errorMsg;
private HashMap<String,Object> adapterReponse = null;
#Context
AdaptersAPI adaptersAPI;
#Override
protected AuthenticatedUser createUser() {
return new AuthenticatedUser(displayName, displayName, this.getName(),adapterReponse);
}
#Override
protected boolean validateCredentials(Map<String, Object> credentials) {
if(credentials!=null && credentials.containsKey("username") && credentials.containsKey("password")){
if (credentials.get("username")!=null && credentials.get("password")!=null) {
String username = credentials.get("username").toString();
String password = credentials.get("password").toString();
if (username.equals(password)) {
JSONObject loginParams = new JSONObject();
loginParams.put("username", username);
loginParams.put("password", password);
HttpUriRequest httpUriRequest = adaptersAPI.createJavascriptAdapterRequest("LoginAndWeeklyCertAdapter1", "login", loginParams);
try {
HttpResponse httpResponse = adaptersAPI.executeAdapterRequest(httpUriRequest);
adapterReponse = adaptersAPI.getResponseAsJSON(httpResponse);
System.out.println(adapterReponse.toString());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
} else {
errorMsg = "Wrong Credentials";
}
}
}
else{
errorMsg = "Credentials not set properly";
}
return false;
}
public boolean isLoggedIn(){
return getState().equals(STATE_SUCCESS);
}
public AuthenticatedUser getRegisteredUser() {
return registrationContext.getRegisteredUser();
}
#Override
protected Map<String, Object> createChallenge() {
Map<String, Object> challenge = new HashMap<String, Object>();
challenge.put("errorMsg", errorMsg);
challenge.put("remainingAttempts", getRemainingAttempts());
return challenge;
}
#ApiOperation(value = "Returns 'Hello from resource'", notes = "A basic example of a resource returning a constant string.")
#ApiResponses(value = { #ApiResponse(code = 200, message = "Hello message returned") })
#GET
#Produces(MediaType.TEXT_PLAIN)
public String getResourceData() {
// log message to server log
logger.info("Logging info message...");
return "Hello from resource";
}
}
When I am submitting the challenge answer I am getting NullPointerException in following line:
HttpUriRequest httpUriRequest = adaptersAPI.createJavascriptAdapterRequest("LoginAndWeeklyCertAdapter1", "login");
because adaptersAPI is null. Do I have to do any extra configuration in order to make that work? How can I initialize AdaptersAPI object?
Note: The login method and the security check both are in same adapter.
Update
I investigated more of time into it and updated the code to given above and observed the following:
1. When validateCredentials() is getting called after submitting the challenge response then I am getting null value in AdapterAPI object.
2. Where as, when I am calling the getResourceData() using the mobilefirst swagger tool then I am getting an object of AdapterAPI.
We cannot inject the adapters API into a security check object(by design - not a bug). The only way we can go is to extract the logic from Adapter into a Java code, without using adapters API.
I have searched for the solution of my problem as much as I could.
My App runs on Glassfish v3.This app sends a message to Glassfish JMS queue and this message is supposed to be read by a standalone client on the same host but outside Glassfish JVM.
I have written standalone client java code - have included appserv-rt.jar and gf-client.jar from Glassfish installation directory.
This client code is unable to receive the message.System out statements print till "got consumer".After that nothing happens.
If I change the name of the queue-I get an error saying Queue not found.So it seems client code is able to find queue but it does not receive any messages.What do I need to include in my client code?
Here is my Java class :-
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;
import javax.annotation.Resource;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.jms.Queue;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.apache.log4j.Category;
import domain.RedirectFile;
public class ZblBulkUploadThread implements Runnable,MessageListener{
private static final Category log = Category.getInstance(ZblBulkUploadThread.class) ;
private Queue queue;
public void run()
{
try
{
System.out.println(" inside try") ;
InitialContext jndiContext = null;
MessageConsumer messageConsumer=null;
jndiContext = new InitialContext();
System.out.println(" got context ") ;
ConnectionFactory connectionFactory = (ConnectionFactory)jndiContext.
lookup("jms/SimpleConnectionFactory");
System.out.println("got connectionfactory") ;
Connection connection = connectionFactory.createConnection();
System.out.println("got connection") ;
Session session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
queue = (Queue)jndiContext.lookup("jms/SimpleQueue") ;
System.out.println("got queue"+queue.getQueueName()) ;
messageConsumer = session.createConsumer(queue);
System.out.println(" selector "+messageConsumer.getMessageSelector()) ;
System.out.println("got consumer") ;
Message message = messageConsumer.receive() ;
System.out.println("Message is "+message) ;
System.out.println("destination is "+message.getJMSDestination()) ;
ObjectMessage om = ((ObjectMessage)message) ;
try
{
RedirectFile file = (RedirectFile)om.getObject() ;
log.debug("filePath "+file.getFilePath()) ;
log.debug(" userName "+file.getUserName()) ;
log.debug(" mode is "+file.getMode()) ;
System.out.println("filePath "+file.getFilePath()) ;
System.out.println(" userName "+file.getUserName()) ;
System.out.println(" mode is "+file.getMode()) ;
}
catch(Exception ex)
{
log.error("ERROR "+ex.getMessage()) ;
ex.printStackTrace() ;
}
log.debug("session created") ;
}
catch(Exception ex)
{
ex.printStackTrace() ;
log.error("Error "+ex.getMessage()) ;
}
}
public void onMessage(Message message)
{
System.out.println("Message received "+message) ;
}
public static void main(String[] args)
{
ZblBulkUploadThread zbut = new ZblBulkUploadThread() ;
new Thread(zbut).start() ;
}
}
try: connection.start(); somewhere before the receive call.
I have solved the problem. You need to create an instance of SSLEngine and add it to the pipeline of handlers for each clinent request. I have done this by adding the handler in the channelConnected event and removing the ssl handler in the channel disconnected. This make sure for each channel connected it will be added new.
Below is the code of the handler. Is this the right approach for doing persistent socket connection with SSL support?
package server;
import static org.jboss.netty.buffer.ChannelBuffers.dynamicBuffer;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;
import org.jboss.netty.channel.group.ChannelGroup;
import org.jboss.netty.channel.group.DefaultChannelGroup;
import org.jboss.netty.handler.ssl.SslHandler;
import ssl.SslContextFactory;
import ssl.SslKeyStore;
public class ServerHandler extends SimpleChannelHandler {
private static final String ECHORES = "0057081082200000000000000400000000000000070612201399966400301";
#Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
System.out.println("Inside ServerHandler.messageReceived");
ChannelBuffer buffer = (ChannelBuffer) e.getMessage();
ChannelBuffer temp = dynamicBuffer();
temp.writeBytes(buffer);
if (temp.readableBytes() >= 4) {
byte messageLen[] = new byte[4];
temp.readBytes(messageLen);
int len = Integer.parseInt(new String(messageLen));
System.out.println("Length of the message is : " + len);
if (temp.readableBytes() >= len) {
byte[] message = new byte[len];
temp.readBytes(message);
System.out.println("Input message is : " + new String(message));
Channel channel = e.getChannel();
buffer = ChannelBuffers.copiedBuffer(ECHORES.getBytes());
ChannelFuture future = channel.write(buffer);
future.addListener(ChannelFutureListener.CLOSE);
}
}
}
#Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
e.getCause().printStackTrace();
Channel channel = e.getChannel();
channel.close();
}
#Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
String file = "test.jks";
SSLContext sslCtx = SslContextFactory.getServerContext(new SslKeyStore(file));
final SSLEngine sslEngine =sslCtx.createSSLEngine();
sslEngine.setNeedClientAuth(false);
sslEngine.setUseClientMode(false);
final SslHandler sslHandler = new SslHandler(sslEngine);
ctx.getPipeline().addFirst("ssl", sslHandler);
ChannelFuture handshakeFuture = sslHandler.handshake();
handshakeFuture.addListener(new ChannelFutureListener() {
#Override
public void operationComplete(ChannelFuture future) throws Exception {
if (future.isSuccess()) {
System.out.println("SSL/TLS session established");
System.out.println("Your session is protected by "+ sslHandler.getEngine().
getSession().getCipherSuite() + " cipher suite.\n");
} else {
future.getChannel().close();
}
}
});
}
#Override
public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
System.out.println("Inside ServerHandler.channelDisconnected");
ctx.getPipeline().remove("ssl");
}
}
I am getting the following exception while using netty with ssl. My first transaction and handshake goes fine. If I send a new message to teh server again I am getting this exception.
"javax.net.ssl.SSLException: SSLEngine is closing/closed"
What could be going wrong here. How to keep the esatablished TLS/SSL session? This error happens at org.jboss.netty.handler.ssl.SslHandler.handshake(SslHandler.java:358).
Intention is to keep the server running with a persistent TLS socket connection , so that clients can send messages.
-TK