com.netcore.hsmart.smsconsumers.SmsConsumer561.java Source code

Java tutorial

Introduction

Here is the source code for com.netcore.hsmart.smsconsumers.SmsConsumer561.java

Source

/*
 * 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;
        }
    }
}