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

Java tutorial

Introduction

Here is the source code for com.netcore.hsmart.smsconsumers.SmsConsumer1000.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.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.net.URI;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
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.grizzly.connector.GrizzlyConnectorProvider;
import javax.ws.rs.ProcessingException;
import java.util.logging.Level;

import com.netcore.hsmart.hibernate.HibernateUtil;
import com.netcore.hsmart.hibernate.entities.SmsRequestData;
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.glassfish.jersey.media.multipart.MultiPartFeature;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.json.JSONArray;
import org.json.JSONObject;

/**
 *
 * @author root
 */
public class SmsConsumer1000 {

    private final static String GATEWAY_ID = "557";

    private final static String GATEWAY_URL = "https://rest.nexmo.com/sms/json";

    private static final Map<String, String> API_CALL_STATS = new HashMap<String, String>();

    private static final String API_SUCCESS_CALL_STATUS_VAL = "0";

    private static String encRefId = null;

    /**
     * @param args the command line arguments
     * @throws java.lang.Exception
     */
    public static void main(String[] args) throws Exception {

        /**
         * Set properties at runtime
         */
        System.setProperty("smsconsumer_logfile", GATEWAY_ID + "_sms_consumer.log");
        AppConstants.loadAppConfig();

        final String queueName = AppConstants.getSmsReceiverQueuePrefix() + GATEWAY_ID;
        final String exchangeName = AppConstants.getSmsReceiverExchangeName();
        final String routingKey = GATEWAY_ID;

        Logger logger = LoggerFactory.getLogger(SmsConsumer1000.class);

        try {

            Connection connection = AppConstants.getRabbitMqObject().newConnection();

            connection.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 = connection.createChannel();

            channel.exchangeDeclare(exchangeName, "direct");
            channel.queueDeclare(queueName, true, false, false, null);
            channel.queueBind(queueName, exchangeName, routingKey);
            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 {

                    Map<String, String> dataToPost = new HashMap<>();
                    String payload = new String(body, "UTF-8");

                    String payloadParts[] = payload.split(AppConstants.getPayloadGroupSeparator());

                    for (String payloadPart : payloadParts) {
                        String s[] = payloadPart.split(AppConstants.getPayloadKVSeparator());
                        dataToPost.put(s[0], s[1]);
                    }
                    logger.info("REF_ID:" + dataToPost.get("ref_id") + "|START+++++++++++++++");
                    logger.info("REF_ID:" + dataToPost.get("ref_id") + "|PAYLOAD:" + payload);

                    long deliveryTag = envelope.getDeliveryTag();

                    if (invokeApiCall(dataToPost)) {
                        if (saveRequestData()) {

                            channel.basicAck(deliveryTag, false);
                        } else {
                            channel.basicNack(deliveryTag, false, true);
                        }

                    } else {
                        channel.basicNack(deliveryTag, false, true);
                    }

                    /**
                     * release memory
                     */
                    logger.info("REF_ID:" + dataToPost.get("ref_id") + "|END-----------------");
                    API_CALL_STATS.clear();
                    dataToPost.clear();
                    payloadParts = null;

                }
            };

            String cTag = channel.basicConsume(queueName, false, consumer);
            logger.info("CONSUMER TAG : " + cTag);

        } catch (IOException | TimeoutException e) {
            logger.error("RMQ_ERROR:" + e.getMessage());
        }
    }

    private static boolean invokeApiCall(Map<String, String> dataToPost) {
        Logger logger = LoggerFactory.getLogger(SmsConsumer1000.class);

        try {

            encRefId = Utilities.encrypt(dataToPost.get("ref_id") + "_" + dataToPost.get("gateway_id"));

            SSLContext sc = SSLContext.getInstance("TLSv1");//Java 8
            System.setProperty("https.protocols", "TLSv1");//Java 8

            TrustManager[] trustAllCerts = { new InsecureTrustManager() };
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            HostnameVerifier allHostsValid = new InsecureHostnameVerifier();

            Client client = ClientBuilder.newBuilder().sslContext(sc).hostnameVerifier(allHostsValid).build();

            //             HttpAuthenticationFeature feature = HttpAuthenticationFeature.universalBuilder()
            //                    .credentialsForBasic(username, password).credentials(username, password).build();
            //             client.register(feature);
            //            ClientConfig clientConfig = new ClientConfig();
            //            clientConfig.connectorProvider(new GrizzlyConnectorProvider());
            //Client client = ClientBuilder.newClient(clientConfig);
            WebTarget webTarget = client.target(GATEWAY_URL);

            WebTarget apiKeyParam = webTarget.queryParam("api_key", "6bcc2766");
            WebTarget apiSecretParam = apiKeyParam.queryParam("api_secret", "8d9792b11b6aa2c4");
            WebTarget refIdParam = apiSecretParam.queryParam("ref_id", encRefId);
            WebTarget fromParam = refIdParam.queryParam("from", dataToPost.get("sender_id"));
            WebTarget toParam = fromParam.queryParam("to", dataToPost.get("msisdn"));
            WebTarget msgParam = toParam.queryParam("text", dataToPost.get("message"));
            WebTarget dlrFlag = msgParam.queryParam("status-report-req", dataToPost.get("1"));
            WebTarget callbackParam = dlrFlag.queryParam("callback", AppConstants.getHttpProtocol()
                    + "://59.163.11.67:" + AppConstants.getDlrrecvServerPort() + "/publishDlr?ref_id=" + encRefId);

            URI u = callbackParam.getUri();

            Invocation.Builder invocationBuilder = callbackParam.request().header("Content-Length",
                    u.getQuery().length());
            long startTime = System.currentTimeMillis();
            Response response = invocationBuilder.get();
            long elapsedTime = System.currentTimeMillis() - startTime;
            String responseText = response.readEntity(String.class);
            Integer responseStatus = response.getStatus();

            response.close();
            client.close();

            logger.info("REF_ID:" + dataToPost.get("ref_id") + "|ENC_TEXT:" + encRefId);
            logger.info("REF_ID:" + dataToPost.get("ref_id") + "|URI:" + u.toString() + "|LENGTH:"
                    + u.getQuery().length());
            logger.info("REF_ID:" + dataToPost.get("ref_id") + "|LATENCY:" + elapsedTime + "ms");

            API_CALL_STATS.put("ref_id", dataToPost.get("ref_id"));
            API_CALL_STATS.put("gateway_id", dataToPost.get("gateway_id"));
            API_CALL_STATS.put("enc_text", encRefId);
            API_CALL_STATS.put("uri", u.toString());
            API_CALL_STATS.put("latency", String.valueOf(elapsedTime));

            return parseVendorApiResponse(responseStatus, responseText, dataToPost);

        } catch (ProcessingException e) {
            logger.error("ERROR:" + e.getMessage() + Arrays.toString(e.getStackTrace()));
            return false;

        } catch (Exception ex) {

            java.util.logging.Logger.getLogger(SmsConsumer1000.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }

    }

    private static boolean parseVendorApiResponse(Integer responseStatus, String responseText,
            Map<String, String> dataPosted) {

        Logger logger = LoggerFactory.getLogger(SmsConsumer1000.class);

        String nullStr = "NULL";
        JSONObject jsonObj = new JSONObject(responseText);
        JSONArray messagesJsonArray = jsonObj.getJSONArray("messages");
        JSONObject messageJsonObj = messagesJsonArray.getJSONObject(0);

        logger.info("REF_ID:" + dataPosted.get("ref_id") + "|HTTP_STATUS:" + responseStatus);
        logger.info("REF_ID:" + dataPosted.get("ref_id") + "|RESPONSE_TEXT:" + responseText);
        logger.info("REF_ID:" + dataPosted.get("ref_id") + "|MSG_COUNT:" + jsonObj.get("message-count"));
        logger.info(
                "REF_ID:" + dataPosted.get("ref_id") + "|API_CALL_STATUS:" + messageJsonObj.getString("status"));

        API_CALL_STATS.put("http_status", responseStatus.toString());
        API_CALL_STATS.put("response_text", responseText);
        API_CALL_STATS.put("msg_count", jsonObj.getString("message-count"));
        API_CALL_STATS.put("api_call_status", messageJsonObj.getString("status"));

        /**
         * If http status other than 200 - fail if response status string not
         * equal to success status - fail Action: build DLR API url with
         * instant_dlr=true param and post to DLR receiver server
         */
        if ((messageJsonObj.getString("status") == null ? API_SUCCESS_CALL_STATUS_VAL != null
                : !messageJsonObj.getString("status").equals(API_SUCCESS_CALL_STATUS_VAL))
                || !"200".equals(responseStatus.toString())) {

            logger.info("REF_ID:" + dataPosted.get("ref_id") + "|MSG_ID:" + nullStr);
            logger.info("REF_ID:" + dataPosted.get("ref_id") + "|PRICE:" + nullStr);
            logger.info("REF_ID:" + dataPosted.get("ref_id") + "|BALANCE:" + nullStr);
            logger.info("REF_ID:" + dataPosted.get("ref_id") + "|API_CALL_ERROR_TEXT:"
                    + messageJsonObj.getString("error-text"));

            API_CALL_STATS.put("msg_id", nullStr);
            API_CALL_STATS.put("price", nullStr);
            API_CALL_STATS.put("balance", nullStr);
            API_CALL_STATS.put("api_call_error_text", messageJsonObj.getString("error-text"));

            logger.info("REF_ID:" + dataPosted.get("ref_id") + "|API_CALL_FAIL");

            callDlrApi();

        } else {

            logger.info("REF_ID:" + dataPosted.get("ref_id") + "|MSG_ID:" + messageJsonObj.get("message-id"));
            logger.info("REF_ID:" + dataPosted.get("ref_id") + "|PRICE:" + messageJsonObj.get("message-price"));
            logger.info(
                    "REF_ID:" + dataPosted.get("ref_id") + "|BALANCE:" + messageJsonObj.get("remaining-balance"));
            logger.info("REF_ID:" + dataPosted.get("ref_id") + "|API_CALL_STATUS:"
                    + messageJsonObj.getString("status"));
            logger.info("REF_ID:" + dataPosted.get("ref_id") + "|API_CALL_ERROR_TEXT:" + nullStr);

            API_CALL_STATS.put("msg_id", messageJsonObj.getString("message-id"));
            API_CALL_STATS.put("price", messageJsonObj.getString("message-price"));
            API_CALL_STATS.put("balance", messageJsonObj.getString("remaining-balance"));
            API_CALL_STATS.put("api_call_error_text", nullStr);

            logger.info("REF_ID:" + dataPosted.get("ref_id") + "|API_CALL_SUCCESS");
        }

        return true;

    }

    /**
     * Call and capture response
     */
    private static void callDlrApi() {
        Logger logger = LoggerFactory.getLogger(SmsConsumer1000.class);

        logger.info("REF_ID:" + API_CALL_STATS.get("ref_id") + "|SENDING_INSTANT_DLR");
        ClientConfig clientConfig = new ClientConfig();
        clientConfig.register(MultiPartFeature.class);
        clientConfig.connectorProvider(new GrizzlyConnectorProvider());
        Client client = ClientBuilder.newClient(clientConfig);
        WebTarget webTarget = client.target(AppConstants.getHttpProtocol() + "://"
                + AppConstants.getDlrrecvServerHost() + ":" + AppConstants.getDlrrecvServerPort() + "/publishDlr");

        WebTarget refParam = webTarget.queryParam("ref_id", API_CALL_STATS.get("enc_text"));
        WebTarget statusParam = refParam.queryParam("status", API_CALL_STATS.get("api_call_status"));
        WebTarget errorParam = statusParam.queryParam("err-code", API_CALL_STATS.get("api_call_error_text"));

        WebTarget dlrTypeParam = errorParam.queryParam("dlr_type", "instant");
        Date d = new Date();
        String dlrTime = new SimpleDateFormat("yyMMddhhmm").format(d);
        WebTarget dlrTimeParam = dlrTypeParam.queryParam("scts", dlrTime);

        URI u = dlrTimeParam.getUri();

        logger.info("REF_ID:" + API_CALL_STATS.get("ref_id") + "|INSTANT_DLR_URL:" + u.toString());

        Invocation.Builder invocationBuilder = dlrTimeParam.request();
        long startTime = System.currentTimeMillis();
        Response response = invocationBuilder.get();
        long elapsedTime = System.currentTimeMillis() - startTime;
        String responseText = response.readEntity(String.class);
        Integer responseStatus = response.getStatus();

        logger.info("REF_ID:" + API_CALL_STATS.get("ref_id") + "|INSTANT_DLR_CALL_STATUS:" + responseText
                + "|HTTP_STATUS:" + responseStatus + "|DELAY:" + elapsedTime + "ms");

        response.close();
        client.close();

        //logger.info("SIZE:" + API_CALL_STATS.size());
    }

    private static boolean saveRequestData() {
        Logger logger = LoggerFactory.getLogger(SmsConsumer1000.class);

        logger.info("REF_ID:" + API_CALL_STATS.get("ref_id") + "|DB operation started");
        SessionFactory factory = HibernateUtil.getSessionFactory();
        try (Session session = factory.getCurrentSession()) {
            session.getTransaction().begin();
            SmsRequestData req = new SmsRequestData();
            req.setRefId(API_CALL_STATS.get("ref_id"));
            req.setGatewayId(GATEWAY_ID);
            //req.setEncText(encRefId);
            req.setUri(API_CALL_STATS.get("uri"));
            req.setHttpStatus(API_CALL_STATS.get("http_status"));
            req.setResponseText(API_CALL_STATS.get("response_text"));
            req.setLatency(API_CALL_STATS.get("latency"));
            req.setApiCallStatus(API_CALL_STATS.get("api_call_status"));
            req.setMsgCount(API_CALL_STATS.get("msg_count"));
            req.setMsgId(API_CALL_STATS.get("msg_id"));
            req.setPrice(API_CALL_STATS.get("price"));
            req.setBalance(API_CALL_STATS.get("balance"));
            req.setApiCallErrorText(API_CALL_STATS.get("api_call_error_text"));

            Date now = new Date();
            req.setCreatedTime(now);
            session.save(req);
            session.getTransaction().commit();

            logger.info("REF_ID:" + API_CALL_STATS.get("ref_id") + "|DATA_SAVED");
            return true;
        } catch (Exception e) {
            logger.info("REF_ID:" + API_CALL_STATS.get("ref_id") + "|DB_ERROR:" + e.getMessage());
            return false;
        }

    }

}