package oneapi.client.impl; import oneapi.client.SMSMessagingClient; import oneapi.config.Configuration; import oneapi.listener.*; import oneapi.model.*; import oneapi.model.RequestData.Method; import oneapi.model.common.*; import oneapi.pushserver.PushServerSimulator; import oneapi.retriever.DeliveryReportRetriever; import oneapi.retriever.InboundMessageRetriever; import java.util.ArrayList; import java.util.List; public class SMSMessagingClientImpl extends OneAPIBaseClientImpl implements SMSMessagingClient { private static final String SMS_MESSAGING_OUTBOUND_URL_BASE = "/smsmessaging/outbound"; private static final String SMS_MESSAGING_INBOUND_URL_BASE = "/smsmessaging/inbound"; private DeliveryReportRetriever deliveryReportRetriever = null; private InboundMessageRetriever inboundMessageRetriever = null; private volatile List<DeliveryReportListener> deliveryReportPullListenerList = null; private volatile List<InboundMessageListener> inboundMessagePullListenerList = null; private volatile List<DeliveryStatusNotificationsListener> deliveryStatusNotificationPushListenerList = null; private volatile List<InboundMessageNotificationsListener> inboundMessagePushListenerList = null; private PushServerSimulator dlrStatusPushServerSimulator; private PushServerSimulator inboundMessagesPushServerSimulator; //*************************SMSMessagingClientImpl Initialization****************************************************************************************************************************************************** public SMSMessagingClientImpl(Configuration configuration) { super(configuration); } //*************************SMSMessagingClientImpl public****************************************************************************************************************************************************** /** * Send an SMS over OneAPI to one or more mobile terminals using the customized 'SMSRequest' object * * @param smsRequest (mandatory) object containing data needed to be filled in order to send the SMS * @return String Request Id */ @Override public SendMessageResult sendSMS(SMSRequest smsRequest) { RequestData requestData = new RequestData(SMS_MESSAGING_OUTBOUND_URL_BASE + "/" + encodeURLParam(smsRequest.getSenderAddress()) + "/requests", Method.POST, null, smsRequest, JSON_CONTENT_TYPE); return executeMethod(requestData, SendMessageResult.class); } /** * Send an SMS asynchronously over OneAPI to one or more mobile terminals using the customized 'SMSRequest' object * * @param smsRequest (mandatory) object containing data needed to be filled in order to send the SMS * @param responseListener (mandatory) method to call after receiving sent SMS response */ public void sendSMSAsync(SMSRequest smsRequest, final ResponseListener<SendMessageResult> responseListener) { RequestData requestData = new RequestData(SMS_MESSAGING_OUTBOUND_URL_BASE + "/" + encodeURLParam(smsRequest.getSenderAddress()) + "/requests", Method.POST, null, smsRequest, JSON_CONTENT_TYPE); executeMethodAsync(requestData, SendMessageResult.class, responseListener); } /** * Query the delivery status over OneAPI for an SMS sent to one or more mobile terminals * * @param senderAddress (mandatory) is the address from which SMS messages are being sent. Do not URL encode this value prior to passing to this function * @param requestId (mandatory) contains the requestId returned from a previous call to the sendSMS function * @return DeliveryInfoList */ @Override public DeliveryInfoList queryDeliveryStatus(String senderAddress, String requestId) { RequestData requestData = new RequestData(SMS_MESSAGING_OUTBOUND_URL_BASE + "/" + encodeURLParam(senderAddress) + "/requests/" + encodeURLParam(requestId) + "/deliveryInfos", Method.GET, "deliveryInfoList"); return executeMethod(requestData, DeliveryInfoList.class); } /** * Query the delivery status asynchronously over OneAPI for an SMS sent to one or more mobile terminals * * @param senderAddress (mandatory) is the address from which SMS messages are being sent. Do not URL encode this value prior to passing to this function * @param requestId (mandatory) contains the requestId returned from a previous call to the sendSMS function * @param responseListener (mandatory) method to call after receiving delivery status */ public void queryDeliveryStatusAsync(String senderAddress, String requestId, final ResponseListener<DeliveryInfoList> responseListener) { StringBuilder urlBuilder = (new StringBuilder(SMS_MESSAGING_OUTBOUND_URL_BASE)).append("/"); urlBuilder.append(encodeURLParam(senderAddress)); urlBuilder.append("/requests/"); urlBuilder.append(encodeURLParam(requestId)); urlBuilder.append("/deliveryInfos"); RequestData requestData = new RequestData(urlBuilder.toString(), Method.GET, "deliveryInfoList"); executeMethodAsync(requestData, DeliveryInfoList.class, responseListener); } /** * Convert JSON to Delivery Info Notification * * @return DeliveryInfoNotification */ public DeliveryInfoNotification convertJsonToDeliveryInfoNotification(String json) { return convertJSONToObject(json.getBytes(), DeliveryInfoNotification.class, "deliveryInfoNotification"); } /** * Start subscribing to delivery status notifications over OneAPI for all your sent SMS * * @param subscribeToDeliveryNotificationsRequest (mandatory) contains delivery notifications subscription data * @return String Subscription Id */ @Override public String subscribeToDeliveryStatusNotifications(SubscribeToDeliveryNotificationsRequest subscribeToDeliveryNotificationsRequest) { StringBuilder urlBuilder = new StringBuilder(SMS_MESSAGING_OUTBOUND_URL_BASE).append("/"); if (null != subscribeToDeliveryNotificationsRequest.getSenderAddress()) { urlBuilder.append(encodeURLParam(subscribeToDeliveryNotificationsRequest.getSenderAddress())).append("/"); } urlBuilder.append("subscriptions"); RequestData requestData = new RequestData(urlBuilder.toString(), Method.POST, "deliveryReceiptSubscription", subscribeToDeliveryNotificationsRequest, JSON_CONTENT_TYPE); DeliveryReceiptSubscription deliveryReceiptSubscription = executeMethod(requestData, DeliveryReceiptSubscription.class); return getIdFromResourceUrl(deliveryReceiptSubscription.getResourceURL()); } /** * Get delivery notifications subscriptions by sender address * * @return DeliveryReportSubscription[] */ @Override public DeliveryReportSubscription[] getDeliveryNotificationsSubscriptionsBySender(String senderAddress) { StringBuilder urlBuilder = new StringBuilder(SMS_MESSAGING_OUTBOUND_URL_BASE).append("/"); urlBuilder.append(encodeURLParam(senderAddress)); urlBuilder.append("/subscriptions"); RequestData requestData = new RequestData(urlBuilder.toString(), Method.GET, "deliveryReceiptSubscriptions"); return executeMethod(requestData, DeliveryReportSubscription[].class); } /** * Get delivery notifications subscriptions by subscription id * * @return DeliveryReportSubscription */ @Override public DeliveryReportSubscription getDeliveryNotificationsSubscriptionById(String subscriptionId) { StringBuilder urlBuilder = new StringBuilder(SMS_MESSAGING_OUTBOUND_URL_BASE).append("/subscriptions/"); urlBuilder.append(encodeURLParam(subscriptionId)); RequestData requestData = new RequestData(urlBuilder.toString(), Method.GET, "deliveryReceiptSubscription"); return executeMethod(requestData, DeliveryReportSubscription.class); } /** * Get delivery notifications subscriptions by for the current user * * @return DeliveryReportSubscription[] */ @Override public DeliveryReportSubscription[] getDeliveryNotificationsSubscriptions() { RequestData requestData = new RequestData(SMS_MESSAGING_OUTBOUND_URL_BASE + "/subscriptions", Method.GET, "deliveryReceiptSubscriptions"); return executeMethod(requestData, DeliveryReportSubscription[].class); } /** * Stop subscribing to delivery status notifications over OneAPI for all your sent SMS * * @param subscriptionId (mandatory) contains the subscriptionId of a previously created SMS delivery receipt subscription */ @Override public void removeDeliveryNotificationsSubscription(String subscriptionId) { StringBuilder urlBuilder = new StringBuilder(SMS_MESSAGING_OUTBOUND_URL_BASE).append("/subscriptions/"); urlBuilder.append(encodeURLParam(subscriptionId)); RequestData requestData = new RequestData(urlBuilder.toString(), Method.DELETE); executeMethod(requestData); } /** * Get SMS messages sent to your Web application over OneAPI using default 'maxBatchSize' = 100 * * @return InboundSMSMessageList */ @Override public InboundSMSMessageList getInboundMessages() { return this.getInboundMessages(100); } /** * Get SMS messages sent to your Web application over OneAPI * * @param maxBatchSize (optional) is the maximum number of messages to get in this request * @return InboundSMSMessageList */ @Override public InboundSMSMessageList getInboundMessages(int maxBatchSize) { //Registration ID is obsolete so any string can be put: e.g. INBOUND RequestData requestData = new RequestData(SMS_MESSAGING_INBOUND_URL_BASE + "/registrations/INBOUND/messages" + "?maxBatchSize=" + encodeURLParam(String.valueOf(maxBatchSize)), Method.GET, "inboundSMSMessageList"); return executeMethod(requestData, InboundSMSMessageList.class); } /** * Get asynchronously SMS messages sent to your Web application over OneAPI * * @param responseListener (mandatory) method to call after receiving inbound messages */ public void getInboundMessagesAsync(final ResponseListener<InboundSMSMessageList> responseListener) { this.getInboundMessagesAsync(100, responseListener); } /** * Get asynchronously SMS messages sent to your Web application over OneAPI * * @param maxBatchSize (optional) is the maximum number of messages to get in this request * @param responseListener (mandatory) method to call after receiving inbound messages */ public void getInboundMessagesAsync(int maxBatchSize, final ResponseListener<InboundSMSMessageList> responseListener) { //Registration ID is obsolete so any string can be put: e.g. INBOUND RequestData requestData = new RequestData(SMS_MESSAGING_INBOUND_URL_BASE + "/registrations/INBOUND/messages" + "?maxBatchSize=" + encodeURLParam(String.valueOf(maxBatchSize)), Method.GET, "inboundSMSMessageList"); executeMethodAsync(requestData, InboundSMSMessageList.class, responseListener); } /** * Convert JSON to Inbound SMS Message Notification * * @return InboundSMSMessageList */ public InboundSMSMessageList convertJsonToInboundSMSMessageNotificationExample(String json) { return convertJSONToObject(json.getBytes(), InboundSMSMessageList.class); } /** * Start subscribing to notifications of SMS messages sent to your application over OneAPI * * @param subscribeToInboundMessagesRequest (mandatory) contains inbound messages subscription data * @return String Subscription Id */ @Override public String subscribeToInboundMessagesNotifications(SubscribeToInboundMessagesRequest subscribeToInboundMessagesRequest) { RequestData requestData = new RequestData(SMS_MESSAGING_INBOUND_URL_BASE + "/subscriptions", Method.POST, "resourceReference", subscribeToInboundMessagesRequest, JSON_CONTENT_TYPE); ResourceReference resourceReference = executeMethod(requestData, ResourceReference.class); return getIdFromResourceUrl(resourceReference.getResourceURL()); } /** * Get inbound messages notifications subscriptions for the current user * * @return MoSubscription[] */ @Override public MoSubscription[] getInboundMessagesNotificationsSubscriptions(int page, int pageSize) { RequestData requestData = new RequestData(SMS_MESSAGING_INBOUND_URL_BASE + "/subscriptions" + "?page=" + encodeURLParam(String.valueOf(page)) + "&pageSize=" + encodeURLParam(String.valueOf(pageSize)), Method.GET, "subscriptions"); return executeMethod(requestData, MoSubscription[].class); } /** * Get inbound messages notifications subscriptions for the current user * * @return MoSubscription[] */ @Override public MoSubscription[] getInboundMessagesNotificationsSubscriptions() { return getInboundMessagesNotificationsSubscriptions(1, 10); } /** * Stop subscribing to message receipt notifications for all your received SMS over OneAPI * * @param subscriptionId (mandatory) contains the subscriptionId of a previously created SMS message receipt subscription */ @Override public void removeInboundMessagesSubscription(String subscriptionId) { StringBuilder urlBuilder = new StringBuilder(SMS_MESSAGING_INBOUND_URL_BASE).append("/subscriptions/"); urlBuilder.append(encodeURLParam(subscriptionId)); RequestData requestData = new RequestData(urlBuilder.toString(), Method.DELETE); executeMethod(requestData); } /** * Get MO Number Types */ @Override public MoNumberType[] getMoNumberTypes() { StringBuilder urlBuilder = new StringBuilder(SMS_MESSAGING_INBOUND_URL_BASE).append("/numberTypes"); RequestData requestData = new RequestData(urlBuilder.toString(), Method.GET, "moNoTypes"); return executeMethod(requestData, MoNumberType[].class); } /** * Get delivery reports * * @return DeliveryReport[] */ @Override public DeliveryReportList getDeliveryReports(int limit) { StringBuilder urlBuilder = new StringBuilder(SMS_MESSAGING_OUTBOUND_URL_BASE).append("/requests/deliveryReports"); urlBuilder.append("?limit="); urlBuilder.append(encodeURLParam(String.valueOf(limit))); RequestData requestData = new RequestData(urlBuilder.toString(), Method.GET); return executeMethod(requestData, DeliveryReportList.class); } /** * Get delivery reports asynchronously * * @param responseListener (mandatory) method to call after receiving delivery reports */ public void getDeliveryReportsAsync(int limit, final ResponseListener<DeliveryReportList> responseListener) { StringBuilder urlBuilder = (new StringBuilder(SMS_MESSAGING_OUTBOUND_URL_BASE)).append("/requests/deliveryReports"); urlBuilder.append("?limit="); urlBuilder.append(encodeURLParam(String.valueOf(limit))); RequestData requestData = new RequestData(urlBuilder.toString(), Method.GET); executeMethodAsync(requestData, DeliveryReportList.class, responseListener); } /** * Get delivery reports */ @Override public DeliveryReportList getDeliveryReports() { return getDeliveryReports(0); } /** * Get delivery reports asynchronously * * @param responseListener (mandatory) method to call after receiving delivery reports */ public void getDeliveryReportsAsync(final ResponseListener<DeliveryReportList> responseListener) { this.getDeliveryReportsAsync(0, responseListener); } /** * Get delivery reports by Request Id * * @return DeliveryReportList */ @Override public DeliveryReportList getDeliveryReportsByRequestId(String requestId, int limit) { StringBuilder urlBuilder = new StringBuilder(SMS_MESSAGING_OUTBOUND_URL_BASE).append("/requests/"); urlBuilder.append(encodeURLParam(requestId)); urlBuilder.append("/deliveryReports"); urlBuilder.append("?limit="); urlBuilder.append(encodeURLParam(String.valueOf(limit))); RequestData requestData = new RequestData(urlBuilder.toString(), Method.GET); return executeMethod(requestData, DeliveryReportList.class); } /** * Get delivery reports by Request Id * * @return DeliveryReportList */ @Override public DeliveryReportList getDeliveryReportsByRequestId(String requestId) { return getDeliveryReportsByRequestId(requestId, 0); } /** * Add OneAPI PULL 'Delivery Reports' listener * * @param listener - (new DeliveryReportListener) */ @Override public void addPullDeliveryReportListener(DeliveryReportListener listener) { if (listener == null) { return; } if (deliveryReportPullListenerList == null) { deliveryReportPullListenerList = new ArrayList<DeliveryReportListener>(); } this.deliveryReportPullListenerList.add(listener); this.startDeliveryReportRetriever(); } /** * Add OneAPI PULL 'INBOUND Messages' listener * Messages are pulled automatically depending on the 'inboundMessagesRetrievingInterval' client configuration parameter * * @param listener - (new InboundMessageListener) */ @Override public void addPullInboundMessageListener(InboundMessageListener listener) { if (listener == null) { return; } if (inboundMessagePullListenerList == null) { inboundMessagePullListenerList = new ArrayList<InboundMessageListener>(); } this.inboundMessagePullListenerList.add(listener); this.startInboundMessageRetriever(); } /** * Returns INBOUND Message PULL Listeners list */ @Override public List<InboundMessageListener> getInboundMessagePullListeners() { return inboundMessagePullListenerList; } /** * Returns Delivery Reports PULL Listeners list */ @Override public List<DeliveryReportListener> getDeliveryReportPullListeners() { return deliveryReportPullListenerList; } /** * Remove PULL Delivery Reports listeners and stop retriever */ @Override public void removePullDeliveryReportListeners() { stopDeliveryReportRetriever(); deliveryReportPullListenerList = null; if (LOGGER.isInfoEnabled()) { LOGGER.info("PULL Delivery Report Listeners are successfully released."); } } /** * Remove PULL INBOUND Messages listeners and stop retriever */ @Override public void removePullInboundMessageListeners() { stopInboundMessagesRetriever(); inboundMessagePullListenerList = null; if (LOGGER.isInfoEnabled()) { LOGGER.info("PULL Inbound Message Listeners are successfully released."); } } /** * Add OneAPI PUSH 'Delivery Status' Notifications listener and start push server simulator */ public void addPushDeliveryStatusNotificationListener(DeliveryStatusNotificationsListener listener) { if (listener == null) { return; } if (deliveryStatusNotificationPushListenerList == null) { deliveryStatusNotificationPushListenerList = new ArrayList<DeliveryStatusNotificationsListener>(); } deliveryStatusNotificationPushListenerList.add(listener); StartDlrStatusPushServerSimulator(); if (LOGGER.isInfoEnabled()) { LOGGER.info("Listener is successfully added, push server is started and is waiting for Delivery Status Notifications"); } } /** * Add OneAPI PUSH 'INBOUND Messages' Notifications listener and start push server simulator */ public void addPushInboundMessageListener(InboundMessageNotificationsListener listener) { if (listener == null) { return; } if (inboundMessagePushListenerList == null) { inboundMessagePushListenerList = new ArrayList<InboundMessageNotificationsListener>(); } inboundMessagePushListenerList.add(listener); startInboundMessagesPushServerSimulator(); if (LOGGER.isInfoEnabled()) { LOGGER.info("Listener is successfully added, push server is started and is waiting for Inbound Messages Notifications"); } } /** * Returns Delivery Status Notifications PUSH Listeners list */ public List<DeliveryStatusNotificationsListener> getDeliveryStatusNotificationPushListeners() { return deliveryStatusNotificationPushListenerList; } /** * Returns INBOUND Message Notifications PUSH Listeners list */ public List<InboundMessageNotificationsListener> getInboundMessagePushListeners() { return inboundMessagePushListenerList; } /** * Remove PUSH Delivery Reports Notifications listeners and stop server */ public void removePushDeliveryStatusNotificationListeners() { stopDlrStatusPushServerSimulator(); deliveryStatusNotificationPushListenerList = null; if (LOGGER.isInfoEnabled()) { LOGGER.info("Delivery Status Notification Listeners are successfully removed."); } } /** * Remove PUSH Delivery Reports Notifications listeners and stop server */ public void removePushInboundMessageListeners() { stopInboundMessagesPushServerSimulator(); inboundMessagePushListenerList = null; if (LOGGER.isInfoEnabled()) { LOGGER.info("Inbound Message Listeners are successfully removed."); } } //*************************SMSMessagingClientImpl private****************************************************************************************************************************************************** /** * START DLR Retriever */ private void startDeliveryReportRetriever() { if (this.deliveryReportRetriever != null) { return; } this.deliveryReportRetriever = new DeliveryReportRetriever(); int intervalMs = getConfiguration().getDlrRetrievingInterval(); this.deliveryReportRetriever.start(intervalMs, this); } /** * STOP DLR Retriever and dispose listeners */ private void stopDeliveryReportRetriever() { if (deliveryReportRetriever == null) { return; } deliveryReportRetriever.stop(); deliveryReportRetriever = null; } /** * START INBOUND Messages Retriever */ private void startInboundMessageRetriever() { if (this.inboundMessageRetriever != null) { return; } this.inboundMessageRetriever = new InboundMessageRetriever(); int intervalMs = getConfiguration().getInboundMessagesRetrievingInterval(); this.inboundMessageRetriever.start(intervalMs, this); } /** * STOP INBOUND Messages Retriever and dispose listeners */ private void stopInboundMessagesRetriever() { if (inboundMessageRetriever == null) { return; } inboundMessageRetriever.stop(); inboundMessageRetriever = null; } private void StartDlrStatusPushServerSimulator() { if (dlrStatusPushServerSimulator == null) { dlrStatusPushServerSimulator = new PushServerSimulator(this, getConfiguration().getDlrStatusPushServerSimulatorPort()); dlrStatusPushServerSimulator.start(); } } private void stopDlrStatusPushServerSimulator() { if (dlrStatusPushServerSimulator != null) { dlrStatusPushServerSimulator.stop(); } } private void startInboundMessagesPushServerSimulator() { if (inboundMessagesPushServerSimulator == null) { inboundMessagesPushServerSimulator = new PushServerSimulator(this, getConfiguration().getInboundMessagesPushServerSimulatorPort()); inboundMessagesPushServerSimulator.start(); } } private void stopInboundMessagesPushServerSimulator() { if (inboundMessagesPushServerSimulator != null) { inboundMessagesPushServerSimulator.stop(); } } }