I developed a service, using resttemplate and using this service(clientproject) in another project(server), I am trying to throw the exception from resttemplate and handle at server project,but it is not working.
Here is my code:
public class UserService{
public long createUser(Long servcieId){
long userId =0L;
try
{
response = restTemplate.exchange(url,HttpMethod.POST, request, Object.class);
userId = response.getBody().getUser().getId();
}
catch(RestClientException e){
throw e;
}
return userId;
}
}
Here is my service code:
public Long createUserInPortal(Long serviceId){
try
{
Long userId=userService.createUser(serviceId);
}
catch(RestClientException e){
if(e instanceof HttpStatusCodeException){
String errorResponse=((HttpStatusCodeException)e).getResponseBodyAsString();
logger.error("the error in user service is:"+errorResponse);
}
}
I am getting the following error,"resulted in 422 (Unprocessable Entity); invoking error handler".
I am trying to see the response string in the catch block but it is not reaching this catch block.
well may be its getting inside catch block but gets filtered by
if(e instanceof HttpStatusCodeException){ condition
May be e instance is not of type HttpStatusCodeException there are other possibilities like
} catch (HttpClientErrorException e) {
success = false;
Log.e(TAG, command+" was rejected for URL: "+url, e);
resultCode = e.getStatusCode().value();
response = e.getResponseBodyAsString();
} catch (HttpServerErrorException e) {
success = false;
Log.e(TAG, command+" could not be completed for URL: "+url, e);
resultCode = e.getStatusCode().value();
response = e.getResponseBodyAsString();
} catch (ResourceAccessException e) {
if (attemptsLeft > 0) {
Log.w(TAG, command+" failed I/O, retrying.", e);
return simplePut(baseUrl, url, b, command, payload, attemptsLeft);
}
success = false;
Log.e(TAG, command+" failed I/O for URL: "+url, e);
resultCode = 499;
} catch (RestClientException e) {
success = false;
Log.e(TAG, command+" failed for URL: "+url, e);
resultCode = 599;
}
How do I test that the following code will perform the logging statement when Exception is thrown, using Mockito?
public void cleanUp() {
for (Map.Entry<String, Connection> connection : dbConnectionMap.entrySet()) {
try {
if (connection.getValue() != null) {
connection.getValue().close();
}
}catch (Exception e) {
LOGGER.log(Level.WARNING, "Exception when closing database connection: ", e);
}
}
reset();
}
I have a socket listener thread in the client side which receives data from the server. Currently I'm just getting the data input stream from socket and reading data from the stream. I want to modify my listener thread in such way that processing of that thread is blocked until data is received in the socket instead of checking my input stream always.
My socket listener thread is given below
public void run() {
listenFlag = true;
try {
//instream is a global variable
inStream = new DataInputStream(clientSocket.getInputStream());
while (listenFlag) {
messageType = -1;
if (readHeader()) {// Check for correct header
Application.getLogger().log(Level.SEVERE, "<<< passed readHeader() ----");
if (readType()) {// Check for valid Type
Application.getLogger().log(Level.SEVERE, "<<< passed readType ----");
readAndProcessMessage();// Read and process the correct message
Application.getLogger().log(Level.SEVERE, "<<< passed readAndProcessMessage ----");
}
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
}
} catch (InterruptedException e) {
Application.getLogger().log(Level.SEVERE, "Interrupted socket communication - closing socket" + e.getMessage());
} catch (InterruptedIOException e) {
Application.getLogger().log(Level.SEVERE, "Interrupted IOException socket communication - closing socket" + e.getMessage());
} catch (IOException ioe) {
Application.getLogger().log(Level.SEVERE, "Socket read error : " + ioe.getMessage());
} catch (Exception e) {
Application.getLogger().log(Level.SEVERE, "Unknown exception on SocketListenThread:"+ e.getMessage());
} finally {
Application.getLogger().log(Level.SEVERE, "SocketListenThread: listenFlag : "+ listenFlag);
Application.getLogger().log(Level.SEVERE, "Quiting SocketListnerThread Thread");
DRISMCMStatus.socketListenerStatus = DRISMCMStatus.NOT_ALIVE;
closeInputStream();
}
}
//Read header called from above.
private boolean readHeader() throws Exception {
Application.getLogger().log(Level.INFO, "Reading header..");
DRISMCMStatus.socketListenerStatus = DRISMCMStatus.WAITING;
int val = inStream.read();
DRISMCMStatus.socketListenerStatus = DRISMCMStatus.RUNNING;
Application.getLogger().log(Level.INFO, "[READ]: " + val);
if (val == -1) {
throw new IOException();
}
if ( val == SYNCCHAR) {
return true;
}
return false;
}
I am bit curious to know in the below code snippet, is there any chances of database connection not being closed. I am getting an issue in the SonarQube telling "Method may fail to close database resource"
try {
con = OracleUtil.getConnection();
pstmtInsert = con.prepareStatement(insertUpdateQuery);
pstmtInsert.setString(++k, categoryCode);
pstmtInsert.clearParameters();
pstmtInsert = con.prepareStatement(updateQuery);
for (i = 0; i < userList.size(); i++) {
pstmtInsert.setString(1, p_setId);
addCount = pstmtInsert.executeUpdate();
if (addCount == 1) {
con.commit();
usercount++;
} else {
con.rollback();
}
}
}
catch (SQLException sqle) {
_log.error(methodName, "SQLException " + sqle.getMessage());
sqle.printStackTrace();
EventHandler.handle();//calling event handler
throw new BTSLBaseException(this, "addInterfaceDetails", "error.general.sql.processing");
}
catch (Exception e) {
_log.error(methodName, " Exception " + e.getMessage());
e.printStackTrace();
EventHandler.handle();//calling event handler
throw new BTSLBaseException(this, "addInterfaceDetails", "error.general.processing");
}
finally {
try {
if (pstmtInsert != null) {
pstmtInsert.close();
}
} catch (Exception e) {
_log.errorTrace(methodName, e);
}
try {
if (con != null) {
con.close();
}
} catch (Exception e) {
_log.errorTrace(methodName, e);
}
if (_log.isDebugEnabled()) {
_log.debug("addRewardDetails", " Exiting addCount " + addCount);
}
}
Thanks in advance
If you are using Java 7+, I suggest you use try-with-resources. It ensures the resources are closed after the operation is completed.
Issue has been resolved when I closed the first prepare statement before starting the another one.
added below code snippet after the line pstmtInsert.clearParameters();
try {
if (pstmtInsert != null) {
pstmtInsert.close();
}
} catch (Exception e) {
_log.errorTrace(methodName, e);
}
I having a problem with the RabbitMQ Work Queue implementation. im current running it in Tomcat, and i have the following class constantly listerning to new task in the queue. But after a day or two, sudden it behaving strangely, where by the object DeliveryOK return by channel.queueDeclare(taskQueueName, isDurable, false, false, null); is always zero. (i print out this in the log below mentioning "Current poolSize").
But in Rabbit admin (./rabbitmqadmin list queues or the RabbitMq Admin portal) it always return a number greater than zero (say 1267 messages in the queue). And it will not reduce to zero until i restart the tomcat, the class below only able to detect that there are actually some messages in the queue.
Initially i thought that this class was terminated somehow, but it is able to consume those messages that newly arrive. It will not consume those 1267 messages that is left hanging inside the queue. For example messages 1267 in the queue, will not be consume until i restart tomcat.
From the code below, is it because buggy implementation or is there a better way to implement a queue consumer specifically for RabbitMQ? i have read a related stack post(Producer/Consumer threads using a Queue), but im not sure if it helps.
Also, is it true that this consumer implementation below will not survive a RunTimeException?
MqConsumer Class:
#Service
public class MqConsumer implements Runnable{
private static final Logger logger = LoggerFactory.getLogger(MqConsumer.class);
private final int MAX_ALERT_THRESHOLD = 10000;
#Autowired
private AsynchSystemConnections asynchSystemConnections;
public MqConsumer(){
}
#PostConstruct
private void init() {
(new Thread(new MqConsumer(asynchSystemConnections))).start();
}
public MqConsumer(AsynchSystemConnections asynchSystemConnections){
this.asynchSystemConnections = asynchSystemConnections;
}
#Override
public void run() {
logger.info("Execute Consumer instance...");
while (true) { // infinite loop until it die due server restart
boolean toSleep = consume(asynchSystemConnections);
if (toSleep){
logger.error("Sleeping for 1 second...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
logger.error("", e);
}
}
}
}
private boolean consume(AsynchSystemConnections asynchSystemConnections) {
com.rabbitmq.client.Connection mqConnection = null;
Channel mqChannel = null;
DatasiftMq dMq = null;
try {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost(asynchSystemConnections.getMqServerHost());
mqConnection = factory.newConnection();
mqChannel = mqConnection.createChannel();
//consumePushInteractionJob method will forward to AsynchTwService.consume(connection, channel, AsynchTwService.PUSH_INTERACTION_QUEUE )
dMq = asynchSystemConnections.getAsynchService().consumePushInteractionJob(mqConnection, mqChannel);
int poolSize = asynchSystemConnections.getAsynchService().getPushInteractionQueueSize();
logger.info("Current poolSize: " + poolSize);
} catch(NullPointerException e) {
logger.error("", e);
if (dMq != null) {
try {
logger.error("Removing JSON with" + dMq.getLogHeader(dMq));
asynchSystemConnections.getAsynchService().ack(mqChannel, dMq.getDelivery());
logger.error("Removed JSON with" + dMq.getLogHeader(dMq));
} catch (IOException e1) {
logger.error("Remove JSON Failed: ", e);
}
}
return true;
} catch (IOException e) {
logger.error("Unable to create new MQ Connection from factory.", e);
return true;
} catch (InterruptedException e) {
logger.error("", e);
return true;
} catch (ClassNotFoundException e) {
logger.error("", e);
return true;
} catch (Exception e) {
logger.error("Big problem, better solve this fast!!", e);
asynchSystemConnections.getNotificationService().notifySystemException(null, e);
return true;
} finally {
try {
asynchSystemConnections.getAsynchService().ack(mqChannel, dMq.getDelivery());
asynchSystemConnections.getAsynchService().disconnect(mqConnection, mqChannel);
} catch (IOException e) {
logger.error("", e);
}
}
return false;
}
AsynchTwService Class:
#Service("asynchTwService")
public class AsynchTwService implements AsynchService {
static final String FAVOURITE_COUNT_QUEUE = "favourite_count_queue";
static final String FRIENDS_FOLLOWERS_QUEUE = "friends_followers_queue";
static final String DIRECT_MESSAGE_RECEIVE_QUEUE = "direct_message_receive_queue";
static final String PUSH_INTERACTION_QUEUE = "push_interaction_queue";
private static String mqServerHost;
private static final Logger logger = LoggerFactory.getLogger(AsynchTwService.class);
private static final boolean isDurable = true;
private boolean autoAck = false;
private ConcurrentHashMap<String, Integer> currentQueueSize = new ConcurrentHashMap<String, Integer>();
#Override
public Connection getConnection() throws IOException{
ConnectionFactory factory = new ConnectionFactory();
factory.setHost(mqServerHost);
return factory.newConnection();
}
#Override
public void produce(Connection connection, Channel channel, Object object, String taskQueueName) throws IOException {
sendToQueue(connection, channel, object, taskQueueName);
}
#Override
public QueueItem consume(Connection connection, Channel channel, String taskQueueName) throws IOException, InterruptedException, ClassNotFoundException{
Serializer serializer = new Serializer();
try {
Delivery delivery = listenFromQueue(connection, channel, taskQueueName);
Object messageObj = serializer.toObject(delivery.getBody());
QueueItem queueItem = (QueueItem)messageObj;
queueItem.setDelivery(delivery);
return queueItem;
} catch (InterruptedException e) {
throw e;
} catch (ClassNotFoundException e) {
logger.error("Unable to serialize the message to QueueItem object", e);
throw e;
}
}
#Override
public int getQueueSize(String taskQueueName){
return this.currentQueueSize.get(taskQueueName);
}
private Delivery listenFromQueue(Connection connection, Channel channel, String taskQueueName) throws IOException, InterruptedException, ClassNotFoundException{
try {
DeclareOk ok = channel.queueDeclare(taskQueueName, isDurable, false, false, null);
currentQueueSize.put(taskQueueName, ok.getMessageCount());
logger.info("Queue ("+ taskQueueName + ") has items: " +ok.getMessageCount());
} catch (IOException e) {
// TODO Auto-generated catch block
}
logger.info(" [*] Consuming "+taskQueueName+" message...");
QueueingConsumer consumer = new QueueingConsumer(channel);
try {
channel.basicConsume(taskQueueName, autoAck, consumer);
} catch (IOException e) {
logger.error("", e);
}
try {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
return delivery;
} catch (ShutdownSignalException e) {
logger.error("Unable to retrieve message from Queue", e);
throw e;
} catch (ConsumerCancelledException e) {
logger.error("Unable to retrieve message from Queue", e);
throw e;
} catch (InterruptedException e) {
logger.error("Unable to retrieve message from Queue", e);
throw e;
}
}
private void sendToQueue(Connection connection, Channel channel, Object object, String taskQueueName) throws IOException{
//Initialization, create Message Queue broker connection
try{
channel.queueDeclare(taskQueueName, isDurable, false, false, null);
}catch(IOException e) {
logger.error(e.getMessage());
logger.error("Error create Message Queue connection for queue name:" + taskQueueName, e);
throw e;
}
//send message to broker
try {
long start = System.currentTimeMillis();
Serializer serializer = new Serializer();
logger.info("Sending Twitter QueueItem to Message Queue...");
channel.basicPublish("", taskQueueName, MessageProperties.PERSISTENT_TEXT_PLAIN,
serializer.toBytes(object));
logger.info("Queue successfully sent, process took: " + (System.currentTimeMillis()-start)+ "ms");
} catch (IOException e) {
logger.error("Error while sending object to queue : " + taskQueueName, e);
throw e;
}
}
public static String getMqServerHost() {
return mqServerHost;
}
public static void setMqServerHost(String mqServerHost) {
AsynchTwService.mqServerHost = mqServerHost;
}
#Override
public void disconnect(Connection connection, Channel channel) throws IOException{
try {
if (channel != null){
if (channel.isOpen()){
channel.close();
}
}
if (connection != null){
if (connection.isOpen()){
connection.close();
}
}
logger.debug("MQ Channel Disconnected");
} catch (IOException e) {
throw e;
}
}
#Override
public void ack(Channel channel, QueueingConsumer.Delivery delivery) throws IOException {
// this is made as another method call is to avoid Ack too fast un intentionally
try {
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
logger.info("[x] acked" );
} catch (IOException e) {
logger.error("Unable Acknowledge Queue Message", e);
throw e;
}
}
#Override
public DatasiftMq consumeDatasiftInteraction(Connection connection, Channel channel,
String taskQueueName) throws IOException, InterruptedException, ClassNotFoundException {
Serializer serializer = new Serializer();
try {
Delivery delivery = listenFromQueue(connection, channel, taskQueueName);
Object messageObj = serializer.toObject(delivery.getBody());
DatasiftMq dto = (DatasiftMq)messageObj;
dto.setDelivery(delivery);
return dto;
} catch (InterruptedException e) {
throw e;
} catch (ClassNotFoundException e) {
logger.error("Unable to serialize the message to DatasiftDTO object", e);
throw e;
}
}
#Override
public void reQueue(Channel channel, Delivery delivery) throws IOException {
try {
channel.basicNack(delivery.getEnvelope().getDeliveryTag(), false, true);
logger.info("[x] Nacked" );
} catch (IOException e) {
logger.error("Unable Acknowledge Queue Message", e);
throw e;
}
}
}
Seems like you are missing some basics here.
Taken from here and some code of mine.
Setting up the connection outside of the consumer thread:
//executed once
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("someHost");
factory.setUsername("user");
factory.setPassword("pass");
Connection connection = factory.newConnection();
What you have to do inside your thread:
//Consumer - executed in a Thread
QueueingConsumer consumer = new QueueingConsumer(connection.createChannel());
boolean autoAck = false;
channel.basicConsume("hello", autoAck, consumer);
while (!Thread.current().isInterrupted())) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
//...
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
}
In general I do still recommand you check out the spring-amqp library it integrates perfectly.