Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. mvn exec:java@HSMART_SMS_CONSUMERS_1000 -Dhsmart-config-path=/home/vibhor/installs/HSMART2/config */ package com.netcore.hsmart.smsconsumers; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.hazelcast.core.IMap; import com.netcore.hsmart.AppConstants; import com.netcore.hsmart.InsecureHostnameVerifier; import com.netcore.hsmart.InsecureTrustManager; import com.netcore.hsmart.Utilities; import com.rabbitmq.client.AMQP; import com.rabbitmq.client.Connection; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Consumer; import com.rabbitmq.client.DefaultConsumer; import com.rabbitmq.client.Envelope; import com.rabbitmq.client.Method; import com.rabbitmq.client.ShutdownListener; import com.rabbitmq.client.ShutdownSignalException; import java.io.IOException; import java.math.BigInteger; import java.net.URI; import java.net.URLDecoder; import java.net.URLEncoder; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Random; import java.util.concurrent.TimeoutException; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.Invocation; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.Response; import org.glassfish.jersey.client.ClientConfig; import org.glassfish.jersey.client.ClientProperties; import javax.ws.rs.ProcessingException; import java.util.logging.Level; import java.text.SimpleDateFormat; import java.util.Date; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import org.apache.commons.configuration2.ex.ConfigurationException; import org.apache.logging.log4j.ThreadContext; import org.json.JSONObject; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadLocalRandom; import org.glassfish.jersey.grizzly.connector.GrizzlyConnectorProvider; /** * * @author root */ public class SmsConsumer561 { private static final int COUNTERS = ((System.getProperty("thread-count") != null) ? Integer.parseInt(System.getProperty("thread-count")) : 1); public static void main(String args[]) throws Exception { ExecutorService executor = Executors.newCachedThreadPool(); for (int i = 1; i <= COUNTERS; i++) { Runnable worker = new SmsConsumer561Runnable(Integer.toString(i)); executor.execute(worker); } } /** * *******worker class******** */ public static class SmsConsumer561Runnable implements Runnable { private final static String GATEWAY_ID = "561"; // private final String GATEWAY_URL = // "https://s-esms.maxis.net.my:8443/servlet/smsdirect.jsp"; // private final String GATEWAY_URL = // "http://192.168.104.89:4000/api/dlr"; // private final String API_SUCCESS_CALL_STATUS_VAL = "01010"; // private Map<String, String> API_CALL_STATS = new HashMap<>(); private Map<String, String> DATA_POSTED = new HashMap<>(); private final String threadId; // private final static String NULLSTR = "null"; // private ClientConfig CLIENT_CONFIG = new // ClientConfig().connectorProvider(new GrizzlyConnectorProvider()); // private Client CLIENT = null; // private static IMap<String, String> refIdMap = null; // custom members private final static int MAX_LENGTH_PER_PART_ENGLISH = 153; private final static int MAX_LENGTH_PER_PART_NON_ENGLISH = 67; private final static String MESSAGE_PREFIX = "RM0.00 "; // with space public SmsConsumer561Runnable(String str) { threadId = str; } /** * @param args * the command line arguments * @throws java.lang.Exception */ @Override public void run() { ThreadContext.put("gatewayId", GATEWAY_ID); try { AppConstants.loadAppConfig(); } catch (ConfigurationException ex) { java.util.logging.Logger.getLogger(this.getClass().getSimpleName()).log(Level.SEVERE, null, ex); } Logger logger = LoggerFactory.getLogger(this.getClass()); try { // Connection connection = // AppConstants.getRabbitMqObject().newConnection(); AppConstants.getRabbitMqConnection().addShutdownListener(new ShutdownListener() { @Override public void shutdownCompleted(ShutdownSignalException cause) { // throw new UnsupportedOperationException("Not // supported yet."); if (cause.isHardError()) { Connection conn; conn = (Connection) cause.getReference(); if (!cause.isInitiatedByApplication()) { Method reason = cause.getReason(); logger.info("REASON:" + reason.toString()); } } else { Channel ch = (Channel) cause.getReference(); logger.info("NO HARDSHUTDOWN"); } } }); Channel channel = AppConstants.getRabbitMqConnection().createChannel(); channel.exchangeDeclare(AppConstants.getSmsReceiverExchangeName(), "direct"); channel.queueDeclare(AppConstants.getSmsReceiverQueuePrefix() + GATEWAY_ID, true, false, false, null); channel.queueBind(AppConstants.getSmsReceiverQueuePrefix() + GATEWAY_ID, AppConstants.getSmsReceiverExchangeName(), GATEWAY_ID); channel.basicQos(1000); // channel.addShutdownListener(listener); logger.info(" [*] Waiting for messages from gateway " + GATEWAY_ID + ". To exit press CTRL+C"); Consumer consumer; consumer = new DefaultConsumer(channel) { @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { ThreadContext.put("gatewayId", GATEWAY_ID); String payload = new String(body, "UTF-8"); String payloadParts[] = payload.split(AppConstants.getPayloadGroupSeparator()); for (String payloadPart : payloadParts) { String s[] = payloadPart.split(AppConstants.getPayloadKVSeparator()); DATA_POSTED.put(s[0], s[1]); } logger.info("REF_ID:" + DATA_POSTED.get("ref_id") + "|START+++++++++++++++"); logger.info("REF_ID:" + DATA_POSTED.get("ref_id") + "|PAYLOAD:" + payload); long deliveryTag = envelope.getDeliveryTag(); // for multipart SMS check logger.info("REF_ID:" + DATA_POSTED.get("ref_id") + "|CHECKING_FOR_MULTIPART"); boolean isMultipartSms = checkForMultipartSms(); if (isMultipartSms) { channel.basicAck(deliveryTag, false); } else { channel.basicNack(deliveryTag, false, true); } /** * release memory */ logger.info("REF_ID:" + DATA_POSTED.get("ref_id") + "|END-----------------"); DATA_POSTED.clear(); payloadParts = null; } }; String cTag = channel.basicConsume(AppConstants.getSmsReceiverQueuePrefix() + GATEWAY_ID, false, consumer); logger.info("CONSUMER TAG : " + cTag); } catch (IOException e) { logger.error("RMQ_ERROR:" + e.getMessage()); } } private boolean checkForMultipartSms() { ThreadContext.put("gatewayId", GATEWAY_ID); Logger logger = LoggerFactory.getLogger(this.getClass()); // check message length for multipart SMS after prefixing 'RM0.00' try { String msgWithPrefix = MESSAGE_PREFIX + URLDecoder.decode(DATA_POSTED.get("message"), "UTF-8"); Integer lengthOfMsgWithPrefix = msgWithPrefix.length(); byte[] bytesOfMsgWithPrefix = msgWithPrefix.getBytes("UTF-8"); Channel channel = AppConstants.getRabbitMqConnection().createChannel(); channel.exchangeDeclare(AppConstants.getSmsReceiverExchangeName() + "_after_multipart_check", "direct"); channel.queueDeclare( AppConstants.getSmsReceiverQueuePrefix() + GATEWAY_ID + "_after_multipart_check", true, false, false, null); channel.queueBind(AppConstants.getSmsReceiverQueuePrefix() + GATEWAY_ID + "_after_multipart_check", AppConstants.getSmsReceiverExchangeName() + "_after_multipart_check", GATEWAY_ID); if (("1".equals(DATA_POSTED.get("message_type")) && lengthOfMsgWithPrefix > MAX_LENGTH_PER_PART_ENGLISH) || ("2".equals(DATA_POSTED.get("message_type")) && lengthOfMsgWithPrefix > MAX_LENGTH_PER_PART_NON_ENGLISH)) { logger.info("REF_ID:" + DATA_POSTED.get("ref_id") + "|FOUND_MULTIPART_SMS"); logger.info("REF_ID:" + DATA_POSTED.get("ref_id") + "|PUBLISHING_IN_QUEUE_IN_PARTS"); // we have multipart SMS // break original message into parts List<String> multiParts = splitMessageParts(msgWithPrefix, ("1".equals(DATA_POSTED.get("message_type")) ? MAX_LENGTH_PER_PART_ENGLISH : MAX_LENGTH_PER_PART_NON_ENGLISH)); logger.info("REF_ID:" + DATA_POSTED.get("ref_id") + "|MESSAGE_STATS|LENGTH:" + lengthOfMsgWithPrefix + "|BYTES:" + bytesOfMsgWithPrefix.length + "|PARTS_COUNT:" + multiParts.size() + "|PARTS_MSGS:" + multiParts.toString()); Iterator<String> iterator = multiParts.iterator(); logger.info("REF_ID:" + DATA_POSTED.get("ref_id") + "|PREPARING_MULTIPART_PAYLOAD"); int iteratorCount = 1; int randomNum = ThreadLocalRandom.current().nextInt(10, 255 + 1); String hexNumber = Integer.toHexString(randomNum); while (iterator.hasNext()) { // publish in separate queue. Long REF_ID = null; // if first iterator use the current ref id else // generate new for other chunks REF_ID = (iteratorCount == 1) ? Long.parseLong(DATA_POSTED.get("ref_id")) : AppConstants.refIdCounter().getAndIncrement(); final String payload = "ref_id" + AppConstants.getPayloadKVSeparator() + REF_ID + AppConstants.getPayloadGroupSeparator() + "gateway_id" + AppConstants.getPayloadKVSeparator() + GATEWAY_ID + AppConstants.getPayloadGroupSeparator() + "message" + AppConstants.getPayloadKVSeparator() + URLEncoder.encode(URLDecoder.decode(iterator.next(), "UTF-8"), "UTF-8") + AppConstants.getPayloadGroupSeparator() + "msisdn" + AppConstants.getPayloadKVSeparator() + DATA_POSTED.get("msisdn") + AppConstants.getPayloadGroupSeparator() + "sender_id" + AppConstants.getPayloadKVSeparator() + DATA_POSTED.get("sender_id") + AppConstants.getPayloadGroupSeparator() + "message_type" + AppConstants.getPayloadKVSeparator() + DATA_POSTED.get("message_type") + AppConstants.getPayloadGroupSeparator() + "is_multipart_msg" + AppConstants.getPayloadKVSeparator() + "1" + AppConstants.getPayloadGroupSeparator() + "part_identifier" + AppConstants.getPayloadKVSeparator() + "050003" + hexNumber + String.format("%02d", multiParts.size()) + String.format("%02d", iteratorCount); logger.info("REF_ID:" + DATA_POSTED.get("ref_id") + "|MULTIPART_CALL_" + iteratorCount + ":" + payload); channel.basicPublish(AppConstants.getSmsReceiverExchangeName() + "_after_multipart_check", GATEWAY_ID, null, payload.getBytes()); iteratorCount++; } } else { logger.info("REF_ID:" + DATA_POSTED.get("ref_id") + "|FOUND_SINGLE_SMS"); final String payload = "ref_id" + AppConstants.getPayloadKVSeparator() + DATA_POSTED.get("ref_id") + AppConstants.getPayloadGroupSeparator() + "gateway_id" + AppConstants.getPayloadKVSeparator() + GATEWAY_ID + AppConstants.getPayloadGroupSeparator() + "message" + AppConstants.getPayloadKVSeparator() + URLEncoder.encode(URLDecoder.decode(msgWithPrefix, "UTF-8"), "UTF-8") + AppConstants.getPayloadGroupSeparator() + "msisdn" + AppConstants.getPayloadKVSeparator() + DATA_POSTED.get("msisdn") + AppConstants.getPayloadGroupSeparator() + "sender_id" + AppConstants.getPayloadKVSeparator() + DATA_POSTED.get("sender_id") + AppConstants.getPayloadGroupSeparator() + "message_type" + AppConstants.getPayloadKVSeparator() + DATA_POSTED.get("message_type"); logger.info("REF_ID:" + DATA_POSTED.get("ref_id") + "|SINGLE_SMS_PAYLOAD:" + payload); channel.basicPublish(AppConstants.getSmsReceiverExchangeName() + "_after_multipart_check", GATEWAY_ID, null, payload.getBytes()); } channel.close(); return true; } catch (ProcessingException | IOException | TimeoutException e) { logger.error("REF_ID: " + DATA_POSTED.get("ref_id") + "|MULTIPART_SMS_CHECK_ERROR:" + e.getMessage() + Arrays.toString(e.getStackTrace())); return false; } } private static List<String> splitMessageParts(String text, int size) { // Give the list the right capacity to start with. You could use an // array // instead if you wanted. List<String> ret = new ArrayList<String>((text.length() + size - 1) / size); for (int start = 0; start < text.length(); start += size) { ret.add(text.substring(start, Math.min(text.length(), start + size))); } return ret; } } }