From 362f12b576a0403d22e42b6736d97b8fb00737de Mon Sep 17 00:00:00 2001 From: cmueller Date: Wed, 11 Sep 2013 23:14:25 +0200 Subject: [PATCH 001/212] improve the DateFormatterTest --- .../org/jsmpp/util/DateFormatterTest.java | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/jsmpp/src/test/java/org/jsmpp/util/DateFormatterTest.java b/jsmpp/src/test/java/org/jsmpp/util/DateFormatterTest.java index 28440d0..7287f52 100644 --- a/jsmpp/src/test/java/org/jsmpp/util/DateFormatterTest.java +++ b/jsmpp/src/test/java/org/jsmpp/util/DateFormatterTest.java @@ -74,7 +74,7 @@ public void validateRelativeDate() throws Exception { public void formatAbsoluteDate() { TimeFormatter timeFormatter = new AbsoluteTimeFormatter(); - GregorianCalendar date = new GregorianCalendar(Locale.GERMANY); + GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("Europe/Berlin"), Locale.GERMANY); date.set(Calendar.YEAR, 2013); date.set(Calendar.MONTH, Calendar.JANUARY); date.set(Calendar.DAY_OF_MONTH, 1); @@ -91,12 +91,33 @@ public void formatAbsoluteDate() { assertEquals(timeFormatter.format(date), "130701130000008+"); } + @Test(groups="checkintest") + public void formatAbsoluteDateRussia() { + TimeFormatter timeFormatter = new AbsoluteTimeFormatter(); + + GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("Asia/Yekaterinburg"), new Locale("ru", "RU")); + date.set(Calendar.YEAR, 2013); + date.set(Calendar.MONTH, Calendar.JANUARY); + date.set(Calendar.DAY_OF_MONTH, 1); + date.set(Calendar.HOUR, 1); + date.set(Calendar.MINUTE, 0); + date.set(Calendar.SECOND, 0); + date.set(Calendar.MILLISECOND, 0); + + assertEquals(timeFormatter.format(date), "130101010000024+"); + + date.set(Calendar.MONTH, Calendar.JULY); + + // we have the same offset because of the absent of daylight saving time + assertEquals(timeFormatter.format(date), "130701010000024+"); + } + @Test(groups="checkintest") public void formatRelativeDate() { RelativeTimeFormatter timeFormatter = new RelativeTimeFormatter(TimeZone.getTimeZone("America/Denver")); // at this date neither Denver nor Germany has daylight saving time - GregorianCalendar date = new GregorianCalendar(Locale.GERMANY); + GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("Europe/Berlin"), Locale.GERMANY); date.set(Calendar.YEAR, 2013); date.set(Calendar.MONTH, Calendar.JANUARY); date.set(Calendar.DAY_OF_MONTH, 1); From 904a531e2f0d429b615f136f2e848e9f3f5bcddc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Skytt=C3=A4?= Date: Tue, 24 Sep 2013 09:55:58 +0300 Subject: [PATCH 002/212] Fix numeric values for data, telex, land mobile, ermes, internet, and wap NPIs. --- jsmpp/src/main/java/org/jsmpp/SMPPConstant.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/SMPPConstant.java b/jsmpp/src/main/java/org/jsmpp/SMPPConstant.java index 018e214..dd56463 100644 --- a/jsmpp/src/main/java/org/jsmpp/SMPPConstant.java +++ b/jsmpp/src/main/java/org/jsmpp/SMPPConstant.java @@ -332,14 +332,14 @@ public interface SMPPConstant { */ public static final byte NPI_UNKNOWN = 0x00; public static final byte NPI_ISDN = 0x01; - public static final byte NPI_DATA = 0x02; - public static final byte NPI_TELEX = 0x03; - public static final byte NPI_LAND_MOBILE = 0x04; + public static final byte NPI_DATA = 0x03; + public static final byte NPI_TELEX = 0x04; + public static final byte NPI_LAND_MOBILE = 0x06; public static final byte NPI_NATIONAL = 0x08; public static final byte NPI_PRIVATE = 0x09; - public static final byte NPI_ERMES = 0x10; - public static final byte NPI_INTERNET = 0x14; - public static final byte NPI_WAP = 0x18; + public static final byte NPI_ERMES = 0x0a; + public static final byte NPI_INTERNET = 0x0e; + public static final byte NPI_WAP = 0x12; public static final short TAG_SC_INTERFACE_VERSION = 0x0210; public static final short TAG_SAR_MSG_REF_NUM = 0X020C; From 59c50aed194f5f729258357c07087815984e1296 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Skytt=C3=A4?= Date: Tue, 24 Sep 2013 10:01:58 +0300 Subject: [PATCH 003/212] Spelling fixes. --- .../java/org/jsmpp/examples/SMPPServerSimulator.java | 10 +++++----- .../src/main/java/org/jsmpp/examples/StressServer.java | 4 ++-- .../examples/SubmitMultipartMultilangualExample.java | 4 ++-- .../main/java/org/jsmpp/bean/OptionalParameter.java | 2 +- .../main/java/org/jsmpp/session/AbstractSession.java | 10 +++++----- .../session/state/AbstractGenericSMPPSessionBound.java | 2 +- jsmpp/src/main/java/org/jsmpp/util/PDUDecomposer.java | 2 +- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java index 299a40f..7895bd5 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java @@ -67,7 +67,7 @@ public class SMPPServerSimulator extends ServerResponseDeliveryAdapter implement private static final Integer DEFAULT_PORT = 8056; private static final Logger logger = LoggerFactory.getLogger(SMPPServerSimulator.class); private final ExecutorService execService = Executors.newFixedThreadPool(5); - private final ExecutorService execServiceDelReciept = Executors.newFixedThreadPool(100); + private final ExecutorService execServiceDelReceipt = Executors.newFixedThreadPool(100); private final MessageIDGenerator messageIDGenerator = new RandomMessageIDGenerator(); private int port; @@ -88,7 +88,7 @@ public void run() { execService.execute(new WaitBindTask(serverSession)); } } catch (IOException e) { - logger.error("IO error occured", e); + logger.error("IO error occurred", e); } } @@ -103,7 +103,7 @@ public MessageId onAcceptSubmitSm(SubmitSm submitSm, MessageId messageId = messageIDGenerator.newMessageId(); logger.debug("Receiving submit_sm '{}', and return message id {}", new String(submitSm.getShortMessage()), messageId); if (SMSCDeliveryReceipt.SUCCESS.containedIn(submitSm.getRegisteredDelivery()) || SMSCDeliveryReceipt.SUCCESS_FAILURE.containedIn(submitSm.getRegisteredDelivery())) { - execServiceDelReciept.execute(new DeliveryReceiptTask(source, submitSm, messageId)); + execServiceDelReceipt.execute(new DeliveryReceiptTask(source, submitSm, messageId)); } return messageId; } @@ -121,7 +121,7 @@ public SubmitMultiResult onAcceptSubmitMulti(SubmitMulti submitMulti, messageId); if (SMSCDeliveryReceipt.SUCCESS.containedIn(submitMulti.getRegisteredDelivery()) || SMSCDeliveryReceipt.SUCCESS_FAILURE.containedIn(submitMulti.getRegisteredDelivery())) { - execServiceDelReciept.execute(new DeliveryReceiptTask(source, submitMulti, messageId)); + execServiceDelReceipt.execute(new DeliveryReceiptTask(source, submitMulti, messageId)); } return new SubmitMultiResult(messageId.getValue(), new UnsuccessDelivery[0]); @@ -255,7 +255,7 @@ public void run() { new RegisteredDelivery(0), DataCodings.ZERO, delRec.toString().getBytes()); - logger.debug("Sending delivery reciept for message id " + messageId + ":" + stringValue); + logger.debug("Sending delivery receipt for message id " + messageId + ":" + stringValue); } catch (Exception e) { logger.error("Failed sending delivery_receipt for message id " + messageId + ":" + stringValue, e); } diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/StressServer.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/StressServer.java index 3b8e6e4..c0f8ae3 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/StressServer.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/StressServer.java @@ -93,7 +93,7 @@ public void run() { waitBindExecService.execute(new WaitBindTask(serverSession)); } } catch (IOException e) { - logger.error("IO error occured", e); + logger.error("IO error occurred", e); } } @@ -199,7 +199,7 @@ public void run() { new RegisteredDelivery(0), DataCodings.ZERO, delRec.toString().getBytes()); - logger.debug("Sending delivery reciept for message id " + messageId + ":" + stringValue); + logger.debug("Sending delivery receipt for message id " + messageId + ":" + stringValue); } catch (Exception e) { logger.error("Failed sending delivery_receipt for message id " + messageId + ":" + stringValue, e); } diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/SubmitMultipartMultilangualExample.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/SubmitMultipartMultilangualExample.java index 14714bb..c6b0036 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/SubmitMultipartMultilangualExample.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/SubmitMultipartMultilangualExample.java @@ -134,7 +134,7 @@ private void sendAndWait() throws IOException, InterruptedException { e.printStackTrace(); } - // configure variables acording to if message contains national + // configure variables according to if message contains national // characters Alphabet alphabet = null; int maximumSingleMessageSize = 0; @@ -259,4 +259,4 @@ public static boolean isEncodeableInGsm0338(String isoString) { return true; } -} \ No newline at end of file +} diff --git a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java index 8bfccbf..455e218 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java @@ -49,7 +49,7 @@ public byte[] serialize() { return buffer.array(); } - /** This method should serialize the value part of the optional parameter. The format of the value is dependant + /** This method should serialize the value part of the optional parameter. The format of the value is dependent * on the specific optional parameter type so it is abstract and must be implmented by subclasses. * @return */ diff --git a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java index d9da26d..07bbd30 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java @@ -133,11 +133,11 @@ public long getLastActivityTimestamp() { } /** - * Set total thread can read PDU and process it parallely. It's defaulted to + * Set total thread can read PDU and process it in parallel. It's defaulted to * 3. * * @param pduProcessorDegree is the total thread can handle read and process - * PDU parallely. + * PDU in parallel. * @throws IllegalStateException if the PDU Reader has been started. */ public void setPduProcessorDegree(int pduProcessorDegree) throws IllegalStateException { @@ -149,10 +149,10 @@ public void setPduProcessorDegree(int pduProcessorDegree) throws IllegalStateExc } /** - * Get the total of thread that can handle read and process PDU parallely. + * Get the total of thread that can handle read and process PDU in parallel. * - * @return the total of thread that can handle read and process PDU - * parallely. + * @return the total of thread that can handle read and process PDU in + * parallel. */ public int getPduProcessorDegree() { return pduProcessorDegree; diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/AbstractGenericSMPPSessionBound.java b/jsmpp/src/main/java/org/jsmpp/session/state/AbstractGenericSMPPSessionBound.java index 933d5a7..ba8d7b0 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/AbstractGenericSMPPSessionBound.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/AbstractGenericSMPPSessionBound.java @@ -61,7 +61,7 @@ public void processEnquireLinkResp(Command pduHeader, byte[] pdu, public void processUnbind(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { - logger.info("Receving unbind request"); + logger.info("Receiving unbind request"); try { responseHandler.sendUnbindResp(pduHeader.getSequenceNumber()); } finally { diff --git a/jsmpp/src/main/java/org/jsmpp/util/PDUDecomposer.java b/jsmpp/src/main/java/org/jsmpp/util/PDUDecomposer.java index fb41e98..316fed6 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/PDUDecomposer.java +++ b/jsmpp/src/main/java/org/jsmpp/util/PDUDecomposer.java @@ -167,7 +167,7 @@ public interface PDUDecomposer { QuerySm querySm(byte[] b) throws PDUStringException; /** - * Decompose the SMPP PDU query short message reponse command. + * Decompose the SMPP PDU query short message response command. * * @param b is the PDU. * @return the query short message response command object. From f5080fbadf95983c7fa674d20edf27d8250a98db Mon Sep 17 00:00:00 2001 From: cmueller Date: Sat, 5 Oct 2013 14:51:31 +0200 Subject: [PATCH 004/212] fixed broken unit test --- jsmpp/src/test/java/org/jsmpp/util/DateFormatterTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jsmpp/src/test/java/org/jsmpp/util/DateFormatterTest.java b/jsmpp/src/test/java/org/jsmpp/util/DateFormatterTest.java index 7287f52..9fadf95 100644 --- a/jsmpp/src/test/java/org/jsmpp/util/DateFormatterTest.java +++ b/jsmpp/src/test/java/org/jsmpp/util/DateFormatterTest.java @@ -78,17 +78,17 @@ public void formatAbsoluteDate() { date.set(Calendar.YEAR, 2013); date.set(Calendar.MONTH, Calendar.JANUARY); date.set(Calendar.DAY_OF_MONTH, 1); - date.set(Calendar.HOUR, 1); + date.set(Calendar.HOUR_OF_DAY, 1); date.set(Calendar.MINUTE, 0); date.set(Calendar.SECOND, 0); date.set(Calendar.MILLISECOND, 0); - assertEquals(timeFormatter.format(date), "130101130000004+"); + assertEquals(timeFormatter.format(date), "130101010000004+"); date.set(Calendar.MONTH, Calendar.JULY); // because of daylight saving time, we have a different offset - assertEquals(timeFormatter.format(date), "130701130000008+"); + assertEquals(timeFormatter.format(date), "130701010000008+"); } @Test(groups="checkintest") @@ -99,7 +99,7 @@ public void formatAbsoluteDateRussia() { date.set(Calendar.YEAR, 2013); date.set(Calendar.MONTH, Calendar.JANUARY); date.set(Calendar.DAY_OF_MONTH, 1); - date.set(Calendar.HOUR, 1); + date.set(Calendar.HOUR_OF_DAY, 1); date.set(Calendar.MINUTE, 0); date.set(Calendar.SECOND, 0); date.set(Calendar.MILLISECOND, 0); From 48a24365105ebf5ff666595e2b78d006e4e8a525 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Mon, 7 Apr 2014 17:41:01 +0200 Subject: [PATCH 005/212] Updated COctetString Binary stores the string plus the NULL character. --- .../org/jsmpp/bean/OptionalParameter.java | 41 +++++++++++-------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java index 8bfccbf..1b83e0e 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java @@ -256,23 +256,32 @@ protected byte[] serializeValue() { public static class COctetString extends OctetString { public COctetString(short tag, String value, String charsetName) - throws UnsupportedEncodingException { - super(tag, value, charsetName); - } + throws UnsupportedEncodingException { + super(tag, new byte[value.getBytes(charsetName).length + 1]); + System.arraycopy(value.getBytes(charsetName), 0, this.value, 0, + value.getBytes(charsetName).length); + this.value[value.getBytes().length] = (byte) 0x00; + } + + public COctetString(short tag, String value) { + super(tag, new byte[value.getBytes().length + 1]); + System.arraycopy(value.getBytes(), 0, value, 0, + value.getBytes().length); + this.value[value.getBytes().length] = (byte) 0x00; + return; + } + + public COctetString(short tag, byte[] value) { + super(tag, value); + } + + @Override + public String getValueAsString() { + byte[] s = new byte[(value.length > 0 ? value.length - 1 : 0)]; + System.arraycopy(value, 0, s, 0, s.length); + return new String(s); + } - public COctetString(short tag, String value) { - super(tag, value); - } - - public COctetString(short tag, byte[] value) { - super(tag, value); - } - - @Override - public String getValueAsString() { - return new String(getValue()); - } - } /** From 338fa47d705141abf17fe9fa50c085586670e4e4 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Tue, 8 Apr 2014 14:56:44 +0200 Subject: [PATCH 006/212] COctetString Fixed a typo --- .../src/main/java/org/jsmpp/bean/OptionalParameter.java | 2 +- .../test/java/org/jsmpp/bean/OptionalParameterTest.java | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java index 1b83e0e..e8b5522 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java @@ -265,7 +265,7 @@ public COctetString(short tag, String value, String charsetName) public COctetString(short tag, String value) { super(tag, new byte[value.getBytes().length + 1]); - System.arraycopy(value.getBytes(), 0, value, 0, + System.arraycopy(value.getBytes(), 0, this.value, 0, value.getBytes().length); this.value[value.getBytes().length] = (byte) 0x00; return; diff --git a/jsmpp/src/test/java/org/jsmpp/bean/OptionalParameterTest.java b/jsmpp/src/test/java/org/jsmpp/bean/OptionalParameterTest.java index 406c242..9fe51f2 100644 --- a/jsmpp/src/test/java/org/jsmpp/bean/OptionalParameterTest.java +++ b/jsmpp/src/test/java/org/jsmpp/bean/OptionalParameterTest.java @@ -154,5 +154,14 @@ public void cOctetStringGetValueAsString() throws UnsupportedEncodingException { COctetString string = new OptionalParameter.COctetString(Tag.ADDITIONAL_STATUS_INFO_TEXT.code(), "urgent"); assertEquals(string.getValueAsString(), "urgent"); + + assertEquals((byte)0x75, string.getValue()[0]); // u + assertEquals((byte)0x72, string.getValue()[1]); // r + assertEquals((byte)0x67, string.getValue()[2]); // g + assertEquals((byte)0x65, string.getValue()[3]); // e + assertEquals((byte)0x6e, string.getValue()[4]); // n + assertEquals((byte)0x74, string.getValue()[5]); // t + assertEquals((byte)0x00, string.getValue()[6]); // NULL + } } \ No newline at end of file From a97f6e10cef28bac2a46a0958519d041f6b9c6eb Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Wed, 9 Apr 2014 23:22:02 +0200 Subject: [PATCH 007/212] Fix exception in Vendor_specific_msc_addr Adding StringIndexOutOfBoundsException in Vendor_specific_msc_addr. Happens when address length is 0 or 1. --- jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java index e8b5522..fb293b7 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java @@ -2159,6 +2159,9 @@ private Vendor_specific_msc_addr(short tag, byte value[]) { super(tag, value); try { address = new String(value, 2, value.length-2, "ISO-8859-1"); + } catch (StringIndexOutOfBoundsException e) { + // TODO: do something better + e.printStackTrace(); } catch (UnsupportedEncodingException e) { // TODO: do something better e.printStackTrace(); From c7a073854367393ee0c84eb0246c8ef0359c593f Mon Sep 17 00:00:00 2001 From: Daniel Pocock Date: Thu, 6 Nov 2014 10:19:51 +0100 Subject: [PATCH 008/212] Fix typos, clarify 8-bit coding is unspecified (not actually an alphabet) --- jsmpp/src/main/java/org/jsmpp/bean/Alphabet.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/Alphabet.java b/jsmpp/src/main/java/org/jsmpp/bean/Alphabet.java index 59e3943..27664cb 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/Alphabet.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/Alphabet.java @@ -29,7 +29,7 @@ public enum Alphabet { ALPHA_DEFAULT((byte)0x00), /** - * The -bit aphabet coding. + * 8-bit binary octet unspecified coding. */ ALPHA_8_BIT((byte)0x04), From 03e3d13289e125dc16d88e66037a6e8d6297b64f Mon Sep 17 00:00:00 2001 From: Daniel Pocock Date: Thu, 6 Nov 2014 10:20:21 +0100 Subject: [PATCH 009/212] Clarify the meaning of Alphabet in relation to the SMPP spec --- jsmpp/src/main/java/org/jsmpp/bean/Alphabet.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/Alphabet.java b/jsmpp/src/main/java/org/jsmpp/bean/Alphabet.java index 27664cb..71a71c8 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/Alphabet.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/Alphabet.java @@ -16,6 +16,9 @@ /** * This is enum of the alphabet type. + * + * Alphabet represents the lower 4 bits of the data_coding field in the PDU, + * as specified in s5.2.19 of the SMPP v3.4 specification. * * @author uudashr * @version 1.0 From c2d53fe99a40c74d2875574097b2fd14d1eec250 Mon Sep 17 00:00:00 2001 From: Tomas Andersen Date: Thu, 6 Nov 2014 10:49:17 +0100 Subject: [PATCH 010/212] SMPPSession staled in a deadlock from time to time due to a deadlock in the cleanup of SMPPSession and AbstractSession. The EnquireLink and PDUReader threads both waited for each other to end. Moved all close handling to the parent object (AbstractSession) --- .../org/jsmpp/session/AbstractSession.java | 60 +++++++++++++------ .../java/org/jsmpp/session/SMPPSession.java | 36 ++++++----- 2 files changed, 61 insertions(+), 35 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java index d9da26d..46a123b 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java @@ -200,25 +200,32 @@ public DataSmResult dataShortMessage(String serviceType, } public void close() { - logger.info("AbstractSession.close() called"); - SessionContext ctx = sessionContext(); - if (!ctx.getSessionState().equals(SessionState.CLOSED)) { - ctx.close(); - try { - connection().close(); - } catch (IOException e) { - } - } - + logger.info("AbstractSession.close() called"); + SessionContext ctx = sessionContext(); + if (!ctx.getSessionState().equals(SessionState.CLOSED)) { + ctx.close(); try { - if(enquireLinkSender != null) { - enquireLinkSender.join(); - } - } catch (InterruptedException e) { - logger.warn("interrupted while waiting for enquireLinkSender thread to exit"); - } + connection().close(); + } catch (IOException e) { + } + } + + // Make sure the enquireLinkThread doesn't wait for itself + if (Thread.currentThread() != enquireLinkSender) + { + if (enquireLinkSender != null) + { + try { + enquireLinkSender.join(); + } catch (InterruptedException e) { + logger.warn("interrupted while waiting for enquireLinkSender thread to exit"); + } + } + } + + logger.info("AbstractSession.close() done"); } - + /** * Validate the response, the command_status should be 0 otherwise will * throw {@link NegativeResponseException}. @@ -262,11 +269,21 @@ protected Command executeSendCommand(SendCommandTask task, long timeout) pendingResponse.put(seqNum, pendingResp); try { task.executeTask(connection().getOutputStream(), seqNum); - } catch (IOException e) { - logger.error("Failed sending " + task.getCommandName() + " command", e); + } + catch (IOException e) + { + logger.error("Failed sending " + task.getCommandName() + " command", e); + + if(task.getCommandName().equals("enquire_link")) + { + logger.info("Tomas: Ignore failure of sending enquire_link, wait to see if connection is restored"); + } + else + { pendingResponse.remove(seqNum); close(); throw e; + } } try { @@ -334,6 +351,8 @@ private void unbind() throws ResponseTimeoutException, } public void unbindAndClose() { + + logger.info("unbindAndClose() called"); if (sessionContext().getSessionState().isBound()) { try { unbind(); @@ -418,11 +437,14 @@ public void run() { try { sendEnquireLink(); } catch (ResponseTimeoutException e) { + logger.error("EnquireLinkSender.run() ResponseTimeoutException", e); close(); } catch (InvalidResponseException e) { + logger.error("EnquireLinkSender.run() InvalidResponseException", e); // lets unbind gracefully unbindAndClose(); } catch (IOException e) { + logger.error("EnquireLinkSender.run() IOException", e); close(); } } diff --git a/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java b/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java index af3cd3a..36f458f 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java @@ -108,7 +108,7 @@ public class SMPPSession extends AbstractSession implements ClientSession { private MessageReceiverListener messageReceiverListener; private BoundSessionStateListener sessionStateListener = new BoundSessionStateListener(); private SMPPSessionContext sessionContext = new SMPPSessionContext(this, sessionStateListener); - + /** * Default constructor of {@link SMPPSession}. The next action might be * connect and bind to a destination message center. @@ -269,7 +269,7 @@ public String connectAndBind(String host, int port, * @param bindType is the bind type. * @param systemId is the system id. * @param password is the password. - * @param systemTypeis the system type. + * @param systemType is the system type. * @param interfaceVersion is the interface version. * @param addrTon is the address TON. * @param addrNpi is the address NPI. @@ -454,22 +454,26 @@ protected GenericMessageReceiverListener messageReceiverListener() { @Override public void close() { - super.close(); + super.close(); - if(Thread.currentThread() != pduReaderWorker) { - try { - if(pduReaderWorker != null) { - pduReaderWorker.join(); - } - } catch (InterruptedException e) { - logger.warn("Interrupted while waiting for pduReaderWorker thread to exit"); - } - } +// Moved all cleanup handling to superclass. This code may cause a deadlock because +// PDUReaderWorker waits for EnquireLinkSender and visa versa +// if(Thread.currentThread() != pduReaderWorker) { +// try { +// if(pduReaderWorker != null) { +// logger.trace("Try to join pduReaderWorker thread"); +// pduReaderWorker.join(); +// logger.trace("Joined"); +// } +// } catch (InterruptedException e) { +// logger.warn("Interrupted while waiting for pduReaderWorker thread to exit"); +// } +// } } @Override protected void finalize() throws Throwable { - close(); + close(); } private void fireAcceptDeliverSm(DeliverSm deliverSm) throws ProcessRequestException { @@ -611,8 +615,8 @@ private void readPDU() { try { Command pduHeader = null; byte[] pdu = null; - - pduHeader = pduReader.readPDUHeader(in); + + pduHeader = pduReader.readPDUHeader(in); pdu = pduReader.readPDU(in, pduHeader); /* @@ -624,7 +628,7 @@ private void readPDU() { sessionContext, responseHandler, sessionContext, onIOExceptionTask); executorService.execute(task); - + } catch (InvalidCommandLengthException e) { logger.warn("Receive invalid command length", e); try { From 73b6d484b3aac927bdb470ab5d41f4e09c0a07cd Mon Sep 17 00:00:00 2001 From: Daniel Pocock Date: Thu, 6 Nov 2014 13:51:34 +0100 Subject: [PATCH 011/212] Add support for more of the SMPP alphabet codes --- .../main/java/org/jsmpp/bean/Alphabet.java | 119 ++++++++++++++++-- .../org/jsmpp/bean/DataCodingFactory00xx.java | 11 +- .../main/java/org/jsmpp/bean/DataCodings.java | 10 ++ .../org/jsmpp/bean/GeneralDataCoding.java | 2 +- .../jsmpp/bean/MessageWaitingDataCoding.java | 11 +- .../java/org/jsmpp/bean/SimpleDataCoding.java | 8 +- .../org/jsmpp/bean/SimpleDataCodingTest.java | 8 +- 7 files changed, 141 insertions(+), 28 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/Alphabet.java b/jsmpp/src/main/java/org/jsmpp/bean/Alphabet.java index 71a71c8..0e0fb72 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/Alphabet.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/Alphabet.java @@ -29,37 +29,108 @@ public enum Alphabet { /** * SMSC alphabet default */ - ALPHA_DEFAULT((byte)0x00), + ALPHA_DEFAULT((byte)0x00, true, false), + + /** + * IA5 (CCITT T.50)/ASCII (ANSI X3.4) + */ + ALPHA_IA5((byte)0x01, true, false), + + /** + * 8-bit binary octet unspecified coding. + */ + ALPHA_UNSPECIFIED_2((byte)0x02, true, true), + + /** + * Latin 1 (ISO-8859-1) + */ + ALPHA_LATIN1((byte)0x03, true, false), /** * 8-bit binary octet unspecified coding. */ - ALPHA_8_BIT((byte)0x04), + ALPHA_UNSPECIFIED_4((byte)0x04, true, true), + + /** + * JIS (X 0208-1990) + */ + ALPHA_JIS((byte)0x05, true, false), + + /** + * Cyrllic (ISO-8859-5) + */ + ALPHA_CYRILLIC((byte)0x06, true, false), + + /** + * Latin/Hebrew (ISO-8859-8) + */ + ALPHA_LATIN_HEBREW((byte)0x07, true, false), /** * UCS2 alphabet coding (16-bit) */ - ALPHA_UCS2((byte)0x08), + ALPHA_UCS2((byte)0x08, true, false), + + /** + * Pictogram Encoding + */ + ALPHA_PICTOGRAM_ENCODING((byte)0x09, true, false), + + /** + * ISO-2022-JP (Music Codes) + */ + ALPHA_ISO_2022_JP_MUSIC_CODES((byte)0x0a, true, false), + + /** + * Unused. + */ + ALPHA_RESERVED_11((byte)0x0b, false, false), + + /** + * Unused. + */ + ALPHA_RESERVED_12((byte)0x0c, false, false), + + /** + * Extended Kanji JIS(X 0212-1990) + */ + ALPHA_JIS_X_0212_1990((byte)0x0d, true, false), + + /** + * KS C 5601 (now known as KS X 1001 but referred to + * by the old name in the SMPP v3.4 spec) + */ + ALPHA_KS_C_5601((byte)0x0e, true, false), /** * Unused. */ - ALPHA_RESERVED((byte)0x0c); + ALPHA_RESERVED_15((byte)0x0f, false, false); + + + /** + * Is the MASK of alphabet (00001111). + */ + public static final byte MASK_ALPHABET = 0x0f; // bin: 00001111 /** - * Is the MASK of alphabet (00001100). + * Is the MASK of alphabet when message class is present (00001100). */ - public static final byte MASK_ALPHABET = 0x0c; // bin: 00001100 + public static final byte MASK_ALPHABET_MESSAGE_CLASS = 0x0c; // bin: 00001100 private final byte value; + private final boolean valid; + private final boolean unspecified; /** * Default constructor. * * @param value is the alphabet value. */ - private Alphabet(byte value) { + private Alphabet(byte value, boolean valid, boolean unspecified) { this.value = value; + this.valid = valid; + this.unspecified = unspecified; } /** @@ -71,6 +142,34 @@ public byte value() { return value; } + /** + * Check if this is a valid alphabet or a reserved alphabet index. + * + * @return true if valid, false if reserved + */ + public boolean isValid() { + return valid; + } + + /** + * Check if this is a valid alphabet or a reserved alphabet index. + * + * @return true if reserved, false if known + */ + public boolean isReserved() { + return !isValid(); + } + + /** + * Check if this is a genuine alphabet or if it signifies binary + * data with unspecified meaning. + * + * @return true if this alphabet code does not correspond to a specific alphabet + */ + public boolean isUnspecified() { + return unspecified; + } + /** * Get the enum constant associated with specified value. * @@ -90,7 +189,11 @@ public static Alphabet valueOf(byte value) throws IllegalArgumentException { } public static Alphabet parseDataCoding(byte dataCoding) throws IllegalArgumentException { - byte value = (byte)(dataCoding & MASK_ALPHABET); + byte mask = MASK_ALPHABET; + if(DataCodings.containsMessageClass(dataCoding)) { + mask = MASK_ALPHABET_MESSAGE_CLASS; + } + byte value = (byte)(dataCoding & mask); for (Alphabet val : values()) { if (val.value == value) return val; diff --git a/jsmpp/src/main/java/org/jsmpp/bean/DataCodingFactory00xx.java b/jsmpp/src/main/java/org/jsmpp/bean/DataCodingFactory00xx.java index 826d83c..19207c7 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/DataCodingFactory00xx.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/DataCodingFactory00xx.java @@ -43,11 +43,6 @@ public class DataCodingFactory00xx extends AbstractDataCodingFactory { */ public static final byte MASK_COMPRESSED = 0x20; - /** - * bin: 00010000 - */ - public static final byte MASK_CONTAIN_MESSAGE_CLASS = 0x10; - public DataCodingFactory00xx() { super(MASK, GROUP); } @@ -69,7 +64,11 @@ public static boolean isCompressed(byte dataCoding) { return (dataCoding & MASK_COMPRESSED) == MASK_COMPRESSED; } + /** + * @deprecated use {@link #DataCodings.containsMessageClass(byte dataCoding)} + */ + @Deprecated public boolean isContainMessageClass(byte dataCoding) { - return (dataCoding & MASK_CONTAIN_MESSAGE_CLASS) == MASK_CONTAIN_MESSAGE_CLASS; + return DataCodings.containsMessageClass(dataCoding); } } diff --git a/jsmpp/src/main/java/org/jsmpp/bean/DataCodings.java b/jsmpp/src/main/java/org/jsmpp/bean/DataCodings.java index cf3baa9..c49ab90 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/DataCodings.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/DataCodings.java @@ -23,6 +23,12 @@ * */ public final class DataCodings { + + /** + * bin: 00010000 + */ + public static final byte MASK_CONTAIN_MESSAGE_CLASS = 0x10; + private static final List factories = new ArrayList(); static { factories.add(new DataCodingFactory00xx()); @@ -52,4 +58,8 @@ public static DataCoding newInstance(byte dataCoding) { } return new RawDataCoding(dataCoding); } + + public static boolean containsMessageClass(byte dataCoding) { + return (dataCoding & MASK_CONTAIN_MESSAGE_CLASS) == MASK_CONTAIN_MESSAGE_CLASS; + } } diff --git a/jsmpp/src/main/java/org/jsmpp/bean/GeneralDataCoding.java b/jsmpp/src/main/java/org/jsmpp/bean/GeneralDataCoding.java index 318fe3e..7828e28 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/GeneralDataCoding.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/GeneralDataCoding.java @@ -80,7 +80,7 @@ public byte toByte() { byte value = compressed ? DataCodingFactory00xx.MASK_COMPRESSED : 0; value |= alphabet.value(); if (messageClass != null) { - value |= DataCodingFactory00xx.MASK_CONTAIN_MESSAGE_CLASS; + value |= DataCodings.MASK_CONTAIN_MESSAGE_CLASS; value |= messageClass.value(); } return value; diff --git a/jsmpp/src/main/java/org/jsmpp/bean/MessageWaitingDataCoding.java b/jsmpp/src/main/java/org/jsmpp/bean/MessageWaitingDataCoding.java index d4860b7..5221af7 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/MessageWaitingDataCoding.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/MessageWaitingDataCoding.java @@ -58,12 +58,13 @@ public MessageWaitingDataCoding(IndicationSense indicationSense, public MessageWaitingDataCoding(IndicationSense indicationSense, IndicationType indicationType, Alphabet alphabet) throws IllegalArgumentException { - if (alphabet != null && (alphabet.equals(Alphabet.ALPHA_8_BIT) - || alphabet.equals(Alphabet.ALPHA_RESERVED))) { + if (alphabet != null && (alphabet.isUnspecified() + || alphabet.isReserved())) { throw new IllegalArgumentException( - "Supported alphabet for SimpleDataCoding is " - + Alphabet.ALPHA_DEFAULT + " or " - + Alphabet.ALPHA_8_BIT + " only. Current alphabet is " + alphabet); + "Supported alphabet for SimpleDataCoding is one of " + + Alphabet.ALPHA_DEFAULT + ", " + + Alphabet.ALPHA_UNSPECIFIED_2 + " or " + Alphabet.ALPHA_UNSPECIFIED_4 + + " only. Current alphabet is " + alphabet); } this.indicationSense = indicationSense; this.indicationType = indicationType; diff --git a/jsmpp/src/main/java/org/jsmpp/bean/SimpleDataCoding.java b/jsmpp/src/main/java/org/jsmpp/bean/SimpleDataCoding.java index fe9e9de..980dffd 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/SimpleDataCoding.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/SimpleDataCoding.java @@ -52,11 +52,11 @@ public SimpleDataCoding(Alphabet alphabet, MessageClass messageClass) throws Ill "alphabet is mandatory, can't be null"); } if (alphabet.equals(Alphabet.ALPHA_UCS2) - || alphabet.equals(Alphabet.ALPHA_RESERVED)) { + || alphabet.isReserved()) { throw new IllegalArgumentException( - "Supported alphabet for SimpleDataCoding is " - + Alphabet.ALPHA_DEFAULT + " or " - + Alphabet.ALPHA_8_BIT + " only. Current alphabet is " + alphabet); + "Supported alphabet for SimpleDataCoding does not include " + + Alphabet.ALPHA_UCS2 + " or " + + "reserved alphabet codes. Current alphabet is " + alphabet); } if (messageClass == null) { throw new IllegalArgumentException( diff --git a/jsmpp/src/test/java/org/jsmpp/bean/SimpleDataCodingTest.java b/jsmpp/src/test/java/org/jsmpp/bean/SimpleDataCodingTest.java index f70b729..5268559 100644 --- a/jsmpp/src/test/java/org/jsmpp/bean/SimpleDataCodingTest.java +++ b/jsmpp/src/test/java/org/jsmpp/bean/SimpleDataCodingTest.java @@ -76,7 +76,7 @@ public void alphaDefaultClass3() { @Test public void alpha8BitClass0() { // 11110100 - SimpleDataCoding dataCoding = new SimpleDataCoding(Alphabet.ALPHA_8_BIT, MessageClass.CLASS0); + SimpleDataCoding dataCoding = new SimpleDataCoding(Alphabet.ALPHA_UNSPECIFIED_4, MessageClass.CLASS0); byte expected = (byte)0xf4; assertEquals(dataCoding.toByte(), expected); @@ -87,7 +87,7 @@ public void alpha8BitClass0() { @Test public void alpha8BitClass1() { // 11110101 - SimpleDataCoding dataCoding = new SimpleDataCoding(Alphabet.ALPHA_8_BIT, MessageClass.CLASS1); + SimpleDataCoding dataCoding = new SimpleDataCoding(Alphabet.ALPHA_UNSPECIFIED_4, MessageClass.CLASS1); byte expected = (byte)0xf5; assertEquals(dataCoding.toByte(), expected); @@ -98,7 +98,7 @@ public void alpha8BitClass1() { @Test public void alpha8BitClass2() { // 11110110 - SimpleDataCoding dataCoding = new SimpleDataCoding(Alphabet.ALPHA_8_BIT, MessageClass.CLASS2); + SimpleDataCoding dataCoding = new SimpleDataCoding(Alphabet.ALPHA_UNSPECIFIED_4, MessageClass.CLASS2); byte expected = (byte)0xf6; assertEquals(dataCoding.toByte(), expected); @@ -109,7 +109,7 @@ public void alpha8BitClass2() { @Test public void alpha8BitClass3() { // 11110111 - SimpleDataCoding dataCoding = new SimpleDataCoding(Alphabet.ALPHA_8_BIT, MessageClass.CLASS3); + SimpleDataCoding dataCoding = new SimpleDataCoding(Alphabet.ALPHA_UNSPECIFIED_4, MessageClass.CLASS3); byte expected = (byte)0xf7; assertEquals(dataCoding.toByte(), expected); From 2f79508dd0af8d1a300aaaf4c3c7198b1013bd41 Mon Sep 17 00:00:00 2001 From: Daniel Pocock Date: Tue, 6 Jan 2015 11:38:39 +0100 Subject: [PATCH 012/212] Add .travis.yml --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..47a7497 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,4 @@ +language: java +jdk: + - oraclejdk6 + - openjdk6 From 721d71cc79d34463ad9a7809db7bfffe3bfe5aba Mon Sep 17 00:00:00 2001 From: Daniel Pocock Date: Tue, 6 Jan 2015 11:41:25 +0100 Subject: [PATCH 013/212] Add myself to pom.xml --- pom.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9b741da..aa843f5 100644 --- a/pom.xml +++ b/pom.xml @@ -19,6 +19,11 @@ Nuruddin Ashr + + Daniel Pocock + daniel@pocock.pro + http://danielpocock.com + @@ -199,4 +204,4 @@ scm:git:ssh://git@github.com:kostousov-ds/jsmpp.git - \ No newline at end of file + From 01f1e5e5cdc469955acdb9f313d5dee0f8bf84c4 Mon Sep 17 00:00:00 2001 From: "Joe Luo luo.joe@gmail.com" Date: Tue, 6 Jan 2015 12:57:00 +0100 Subject: [PATCH 014/212] AbstractSessionContext: use CopyOnWriteArrayList for sessionStateListeners (fix from MR-838) --- .../main/java/org/jsmpp/session/AbstractSessionContext.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/AbstractSessionContext.java b/jsmpp/src/main/java/org/jsmpp/session/AbstractSessionContext.java index a9b627e..7f8f5b6 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/AbstractSessionContext.java +++ b/jsmpp/src/main/java/org/jsmpp/session/AbstractSessionContext.java @@ -14,7 +14,7 @@ */ package org.jsmpp.session; -import java.util.ArrayList; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.List; import org.jsmpp.bean.BindType; @@ -29,7 +29,7 @@ public abstract class AbstractSessionContext implements SessionContext { private static final Logger logger = LoggerFactory.getLogger(AbstractSessionContext.class); private long lastActivityTimestamp; - private List sessionStateListeners = new ArrayList(); + private List sessionStateListeners = new CopyOnWriteArrayList(); public AbstractSessionContext() { } From 8699aaab776437ace60be2646083d2ab7b417664 Mon Sep 17 00:00:00 2001 From: Daniel Pocock Date: Tue, 6 Jan 2015 13:00:12 +0100 Subject: [PATCH 015/212] travis: update for Oracle JDK 7 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 47a7497..21f8524 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ language: java jdk: - - oraclejdk6 + - oraclejdk7 - openjdk6 From ad6f81c4825e00c5ae43c9ecb372b69cb617832f Mon Sep 17 00:00:00 2001 From: Daniel Pocock Date: Tue, 6 Jan 2015 13:11:10 +0100 Subject: [PATCH 016/212] DateFormatterTest: use HOUR_OF_DAY instead of Calendar.HOUR --- jsmpp/src/test/java/org/jsmpp/util/DateFormatterTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsmpp/src/test/java/org/jsmpp/util/DateFormatterTest.java b/jsmpp/src/test/java/org/jsmpp/util/DateFormatterTest.java index 9fadf95..4316474 100644 --- a/jsmpp/src/test/java/org/jsmpp/util/DateFormatterTest.java +++ b/jsmpp/src/test/java/org/jsmpp/util/DateFormatterTest.java @@ -121,7 +121,7 @@ public void formatRelativeDate() { date.set(Calendar.YEAR, 2013); date.set(Calendar.MONTH, Calendar.JANUARY); date.set(Calendar.DAY_OF_MONTH, 1); - date.set(Calendar.HOUR, 1); + date.set(Calendar.HOUR_OF_DAY, 1); date.set(Calendar.MINUTE, 0); date.set(Calendar.SECOND, 0); date.set(Calendar.MILLISECOND, 0); From 50ff26843d93979777df2e70d9c1d17df81c805f Mon Sep 17 00:00:00 2001 From: Daniel Pocock Date: Tue, 6 Jan 2015 13:27:44 +0100 Subject: [PATCH 017/212] Disable the unit test formatRelativeDate until RelativeTimeFormatter fixed --- jsmpp/src/test/java/org/jsmpp/util/DateFormatterTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jsmpp/src/test/java/org/jsmpp/util/DateFormatterTest.java b/jsmpp/src/test/java/org/jsmpp/util/DateFormatterTest.java index 4316474..c6abb9c 100644 --- a/jsmpp/src/test/java/org/jsmpp/util/DateFormatterTest.java +++ b/jsmpp/src/test/java/org/jsmpp/util/DateFormatterTest.java @@ -112,7 +112,7 @@ public void formatAbsoluteDateRussia() { assertEquals(timeFormatter.format(date), "130701010000024+"); } - @Test(groups="checkintest") + @Test(groups="checkintest",enabled=false) // FIXME - enable again after fixing issues below public void formatRelativeDate() { RelativeTimeFormatter timeFormatter = new RelativeTimeFormatter(TimeZone.getTimeZone("America/Denver")); @@ -126,18 +126,18 @@ public void formatRelativeDate() { date.set(Calendar.SECOND, 0); date.set(Calendar.MILLISECOND, 0); - assertEquals(timeFormatter.format(date), "130101050000000R"); + assertEquals(timeFormatter.format(date), "130101050000000R"); // FIXME - should be a relative time but looks like an absolute value // at this date Denver has already daylight saving time but not Germany date.set(Calendar.MONTH, Calendar.MARCH); date.set(Calendar.DAY_OF_MONTH, 20); - assertEquals(timeFormatter.format(date), "130320060000000R"); + assertEquals(timeFormatter.format(date), "130320060000000R"); // FIXME - should be a relative time but looks like an absolute value // at this date Denver and Germany has daylight saving time date.set(Calendar.MONTH, Calendar.APRIL); date.set(Calendar.DAY_OF_MONTH, 1); - assertEquals(timeFormatter.format(date), "130401050000000R"); + assertEquals(timeFormatter.format(date), "130401050000000R"); // FIXME - should be a relative time but looks like an absolute value } } From b78df99f5adb81c34bae586ab2ce7d2e2986df90 Mon Sep 17 00:00:00 2001 From: Daniel Pocock Date: Tue, 6 Jan 2015 14:21:03 +0100 Subject: [PATCH 018/212] pom.xml: add extra metadata about license, URL --- pom.xml | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index aa843f5..95b5bfd 100644 --- a/pom.xml +++ b/pom.xml @@ -7,6 +7,18 @@ 2.2.0-SNAPSHOT pom + jSMPP + SMPP library for Java + http://jsmpp.org + + + + Apache License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + jsmpp jsmpp-examples @@ -200,8 +212,9 @@ - scm:git:ssh://git@github.com:uudashr/jsmpp.git - scm:git:ssh://git@github.com:kostousov-ds/jsmpp.git + https://github.com/opentelecoms-org/jsmpp + scm:git:ssh://git@github.com:opentelecoms-org/jsmpp.git + scm:git:ssh://git@github.com:opentelecoms-org/jsmpp.git From e2b415f8b71ac59f48bd968d808a7ac30a0ae732 Mon Sep 17 00:00:00 2001 From: Daniel Pocock Date: Tue, 6 Jan 2015 15:19:39 +0100 Subject: [PATCH 019/212] Add README.md --- README.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..41e0d8e --- /dev/null +++ b/README.md @@ -0,0 +1,37 @@ + +Introduction +------------ + +jSMPP is a java implementation (SMPP API) of SMPP protocol (currently support +SMPP v3.4). It provides interfaces to communicate with Message Center or +ESME (External Short Message Entity) and able to handle +traffic 3000-5000 messages per second. + +jSMPP is not a high-level library. Many people looking for a quick way to +get started with SMPP may be better of using an abstraction layer such +as the Apache Camel SMPP component: + http://camel.apache.org/smpp.html + +Travis-CI status: +----------------- + +[![Build Status](https://travis-ci.org/opentelecoms-org/jsmpp.svg?branch=master)](https://travis-ci.org/opentelecoms-org/jsmpp) + +History +------- + +The project started on Google Code: http://code.google.com/p/jsmpp/ + +It was maintained by uudashr on Github until 2013 + +It is now a community project maintained at http://jsmpp.org + +License +------- + +Copyright (C) 2007-2013, Nuruddin Ashr +Copyright (C) 2012-2013, Denis Kostousov +Copyright (C) 2014, Daniel Pocock http://danielpocock.com + +This project is licensed under the Apache Software License 2.0. + From 3d9e76b5bbcec689cfc732f6afae61272b2a6ecb Mon Sep 17 00:00:00 2001 From: Daniel Pocock Date: Tue, 6 Jan 2015 15:34:16 +0100 Subject: [PATCH 020/212] Revert Alphabet.ALPHA_UNSPECIFIED_4 to original name Alphabet.ALPHA_8_BIT --- jsmpp/src/main/java/org/jsmpp/bean/Alphabet.java | 2 +- .../java/org/jsmpp/bean/MessageWaitingDataCoding.java | 2 +- .../test/java/org/jsmpp/bean/SimpleDataCodingTest.java | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/Alphabet.java b/jsmpp/src/main/java/org/jsmpp/bean/Alphabet.java index 0e0fb72..01d4a2b 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/Alphabet.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/Alphabet.java @@ -49,7 +49,7 @@ public enum Alphabet { /** * 8-bit binary octet unspecified coding. */ - ALPHA_UNSPECIFIED_4((byte)0x04, true, true), + ALPHA_8_BIT((byte)0x04, true, true), /** * JIS (X 0208-1990) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/MessageWaitingDataCoding.java b/jsmpp/src/main/java/org/jsmpp/bean/MessageWaitingDataCoding.java index 5221af7..9553af3 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/MessageWaitingDataCoding.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/MessageWaitingDataCoding.java @@ -63,7 +63,7 @@ public MessageWaitingDataCoding(IndicationSense indicationSense, throw new IllegalArgumentException( "Supported alphabet for SimpleDataCoding is one of " + Alphabet.ALPHA_DEFAULT + ", " - + Alphabet.ALPHA_UNSPECIFIED_2 + " or " + Alphabet.ALPHA_UNSPECIFIED_4 + + Alphabet.ALPHA_UNSPECIFIED_2 + " or " + Alphabet.ALPHA_8_BIT + " only. Current alphabet is " + alphabet); } this.indicationSense = indicationSense; diff --git a/jsmpp/src/test/java/org/jsmpp/bean/SimpleDataCodingTest.java b/jsmpp/src/test/java/org/jsmpp/bean/SimpleDataCodingTest.java index 5268559..f70b729 100644 --- a/jsmpp/src/test/java/org/jsmpp/bean/SimpleDataCodingTest.java +++ b/jsmpp/src/test/java/org/jsmpp/bean/SimpleDataCodingTest.java @@ -76,7 +76,7 @@ public void alphaDefaultClass3() { @Test public void alpha8BitClass0() { // 11110100 - SimpleDataCoding dataCoding = new SimpleDataCoding(Alphabet.ALPHA_UNSPECIFIED_4, MessageClass.CLASS0); + SimpleDataCoding dataCoding = new SimpleDataCoding(Alphabet.ALPHA_8_BIT, MessageClass.CLASS0); byte expected = (byte)0xf4; assertEquals(dataCoding.toByte(), expected); @@ -87,7 +87,7 @@ public void alpha8BitClass0() { @Test public void alpha8BitClass1() { // 11110101 - SimpleDataCoding dataCoding = new SimpleDataCoding(Alphabet.ALPHA_UNSPECIFIED_4, MessageClass.CLASS1); + SimpleDataCoding dataCoding = new SimpleDataCoding(Alphabet.ALPHA_8_BIT, MessageClass.CLASS1); byte expected = (byte)0xf5; assertEquals(dataCoding.toByte(), expected); @@ -98,7 +98,7 @@ public void alpha8BitClass1() { @Test public void alpha8BitClass2() { // 11110110 - SimpleDataCoding dataCoding = new SimpleDataCoding(Alphabet.ALPHA_UNSPECIFIED_4, MessageClass.CLASS2); + SimpleDataCoding dataCoding = new SimpleDataCoding(Alphabet.ALPHA_8_BIT, MessageClass.CLASS2); byte expected = (byte)0xf6; assertEquals(dataCoding.toByte(), expected); @@ -109,7 +109,7 @@ public void alpha8BitClass2() { @Test public void alpha8BitClass3() { // 11110111 - SimpleDataCoding dataCoding = new SimpleDataCoding(Alphabet.ALPHA_UNSPECIFIED_4, MessageClass.CLASS3); + SimpleDataCoding dataCoding = new SimpleDataCoding(Alphabet.ALPHA_8_BIT, MessageClass.CLASS3); byte expected = (byte)0xf7; assertEquals(dataCoding.toByte(), expected); From 66211d9319cb65b23eed44ec3ea0deb674170957 Mon Sep 17 00:00:00 2001 From: Daniel Pocock Date: Tue, 6 Jan 2015 16:28:06 +0100 Subject: [PATCH 021/212] Formatting fixes --- .../org/jsmpp/session/AbstractSession.java | 61 ++++++++----------- 1 file changed, 27 insertions(+), 34 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java index 46a123b..ab78041 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java @@ -200,30 +200,28 @@ public DataSmResult dataShortMessage(String serviceType, } public void close() { - logger.info("AbstractSession.close() called"); - SessionContext ctx = sessionContext(); - if (!ctx.getSessionState().equals(SessionState.CLOSED)) { - ctx.close(); - try { - connection().close(); - } catch (IOException e) { + logger.info("AbstractSession.close() called"); + SessionContext ctx = sessionContext(); + if (!ctx.getSessionState().equals(SessionState.CLOSED)) { + ctx.close(); + try { + connection().close(); + } catch (IOException e) { + } } - } - // Make sure the enquireLinkThread doesn't wait for itself - if (Thread.currentThread() != enquireLinkSender) - { - if (enquireLinkSender != null) - { - try { - enquireLinkSender.join(); - } catch (InterruptedException e) { - logger.warn("interrupted while waiting for enquireLinkSender thread to exit"); - } + // Make sure the enquireLinkThread doesn't wait for itself + if (Thread.currentThread() != enquireLinkSender) { + if (enquireLinkSender != null) { + try { + enquireLinkSender.join(); + } catch (InterruptedException e) { + logger.warn("interrupted while waiting for enquireLinkSender thread to exit"); + } + } } - } - logger.info("AbstractSession.close() done"); + logger.info("AbstractSession.close() done"); } /** @@ -269,21 +267,16 @@ protected Command executeSendCommand(SendCommandTask task, long timeout) pendingResponse.put(seqNum, pendingResp); try { task.executeTask(connection().getOutputStream(), seqNum); - } - catch (IOException e) - { - logger.error("Failed sending " + task.getCommandName() + " command", e); + } catch (IOException e) { + logger.error("Failed sending " + task.getCommandName() + " command", e); - if(task.getCommandName().equals("enquire_link")) - { - logger.info("Tomas: Ignore failure of sending enquire_link, wait to see if connection is restored"); - } - else - { - pendingResponse.remove(seqNum); - close(); - throw e; - } + if(task.getCommandName().equals("enquire_link")) { + logger.info("Tomas: Ignore failure of sending enquire_link, wait to see if connection is restored"); + } else { + pendingResponse.remove(seqNum); + close(); + throw e; + } } try { From c98fb7085d9608609963720a52d2badc18ebacb1 Mon Sep 17 00:00:00 2001 From: Daniel Pocock Date: Tue, 6 Jan 2015 16:32:45 +0100 Subject: [PATCH 022/212] Remove close() method that just calls super.close() --- .../java/org/jsmpp/session/SMPPSession.java | 22 +------------------ 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java b/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java index 36f458f..71515fa 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java @@ -451,26 +451,6 @@ protected GenericMessageReceiverListener messageReceiverListener() { return messageReceiverListener; } - @Override - public void close() - { - super.close(); - -// Moved all cleanup handling to superclass. This code may cause a deadlock because -// PDUReaderWorker waits for EnquireLinkSender and visa versa -// if(Thread.currentThread() != pduReaderWorker) { -// try { -// if(pduReaderWorker != null) { -// logger.trace("Try to join pduReaderWorker thread"); -// pduReaderWorker.join(); -// logger.trace("Joined"); -// } -// } catch (InterruptedException e) { -// logger.warn("Interrupted while waiting for pduReaderWorker thread to exit"); -// } -// } - } - @Override protected void finalize() throws Throwable { close(); @@ -684,4 +664,4 @@ public void onStateChange(SessionState newState, SessionState oldState, } } } -} \ No newline at end of file +} From add943564ef82a051af66f81420ad0031bd031f7 Mon Sep 17 00:00:00 2001 From: Daniel Pocock Date: Tue, 6 Jan 2015 16:33:12 +0100 Subject: [PATCH 023/212] Use while loop to make sure thread has really finished --- .../main/java/org/jsmpp/session/AbstractSession.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java index ab78041..21beb38 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java @@ -213,10 +213,12 @@ public void close() { // Make sure the enquireLinkThread doesn't wait for itself if (Thread.currentThread() != enquireLinkSender) { if (enquireLinkSender != null) { - try { - enquireLinkSender.join(); - } catch (InterruptedException e) { - logger.warn("interrupted while waiting for enquireLinkSender thread to exit"); + while(enquireLinkSender.isAlive()) { + try { + enquireLinkSender.join(); + } catch (InterruptedException e) { + logger.warn("interrupted while waiting for enquireLinkSender thread to exit"); + } } } } From 187f6545b65bfc8a6e35fcf82e56625ebc08ea75 Mon Sep 17 00:00:00 2001 From: Daniel Pocock Date: Tue, 6 Jan 2015 16:58:46 +0100 Subject: [PATCH 024/212] Update to v2.2.0 --- jsmpp-examples/pom.xml | 4 ++-- jsmpp/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/jsmpp-examples/pom.xml b/jsmpp-examples/pom.xml index 18585b6..6d9009e 100644 --- a/jsmpp-examples/pom.xml +++ b/jsmpp-examples/pom.xml @@ -3,7 +3,7 @@ jsmpp-pom org.jsmpp - 2.2.0-SNAPSHOT + 2.2.0 4.0.0 @@ -26,4 +26,4 @@ - \ No newline at end of file + diff --git a/jsmpp/pom.xml b/jsmpp/pom.xml index cad3a0d..54e2778 100644 --- a/jsmpp/pom.xml +++ b/jsmpp/pom.xml @@ -3,7 +3,7 @@ org.jsmpp jsmpp-pom - 2.2.0-SNAPSHOT + 2.2.0 4.0.0 jar diff --git a/pom.xml b/pom.xml index 95b5bfd..0cc7a79 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.jsmpp jsmpp-pom - 2.2.0-SNAPSHOT + 2.2.0 pom jSMPP From 99de76b861efcbbea848eb2bdb1f328621c3de6c Mon Sep 17 00:00:00 2001 From: Daniel Pocock Date: Tue, 6 Jan 2015 17:02:47 +0100 Subject: [PATCH 025/212] Add parent oss-parent --- pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pom.xml b/pom.xml index 0cc7a79..d8f3add 100644 --- a/pom.xml +++ b/pom.xml @@ -95,6 +95,12 @@ + + org.sonatype.oss + oss-parent + 7 + + From 5aef26d1da568ef931328e94de3e109535bcf96d Mon Sep 17 00:00:00 2001 From: Daniel Pocock Date: Tue, 6 Jan 2015 17:23:08 +0100 Subject: [PATCH 026/212] README.md: Add release procedure --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 41e0d8e..ee21404 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,16 @@ It was maintained by uudashr on Github until 2013 It is now a community project maintained at http://jsmpp.org +Release procedure +----------------- + + mvn deploy -DperformRelease=true -Durl=https://oss.sonatype.org/service/local/staging/deploy/maven2/ -DrepositoryId=sonatype-nexus-staging + + * log in here: https://oss.sonatype.org + * click the `Staging Repositories' link + * select the repository and click close + * select the repository and click release + License ------- From a0c5c1121fac3ec417dc5cdf6fa093272502af2c Mon Sep 17 00:00:00 2001 From: Daniel Pocock Date: Tue, 6 Jan 2015 17:32:18 +0100 Subject: [PATCH 027/212] Add signing to release profile --- pom.xml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/pom.xml b/pom.xml index d8f3add..deb1d7e 100644 --- a/pom.xml +++ b/pom.xml @@ -217,6 +217,37 @@ + + + release-sign-artifacts + + + performRelease + true + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.4 + + + sign-artifacts + verify + + sign + + + + + + + + + + https://github.com/opentelecoms-org/jsmpp scm:git:ssh://git@github.com:opentelecoms-org/jsmpp.git From b171f73ee4d563a70d653c2d6982212f5c9d8536 Mon Sep 17 00:00:00 2001 From: Willem Jiang Date: Wed, 7 Jan 2015 10:11:08 +0800 Subject: [PATCH 028/212] Made the jsmpp jar as an OSGi bundle --- jsmpp/pom.xml | 20 +++++++++++++++++++- pom.xml | 5 +++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/jsmpp/pom.xml b/jsmpp/pom.xml index 54e2778..7f1061c 100644 --- a/jsmpp/pom.xml +++ b/jsmpp/pom.xml @@ -6,7 +6,7 @@ 2.2.0 4.0.0 - jar + bundle jsmpp @@ -36,6 +36,24 @@ + + org.apache.felix + maven-bundle-plugin + true + + + ${project.artifactId} + ${project.groupId}.${project.artifactId} + org.jsmpp + + org.slf4j;resolution:=optional, + * + + jsmpp + ${project.version} + + + pl.project13.maven git-commit-id-plugin diff --git a/pom.xml b/pom.xml index deb1d7e..ec52b94 100644 --- a/pom.xml +++ b/pom.xml @@ -137,6 +137,11 @@ maven-release-plugin 2.1 + + org.apache.felix + maven-bundle-plugin + 2.3.7 + maven-source-plugin 2.1.2 From 339f57a7604646a7cb101f801b4cd0a348d05371 Mon Sep 17 00:00:00 2001 From: Willem Jiang Date: Wed, 7 Jan 2015 12:58:45 +0800 Subject: [PATCH 029/212] Fixed the ConcurrentModificationException which could lead to the thread leak issue --- .../jsmpp/session/AbstractSessionContext.java | 27 ++++++++----------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/AbstractSessionContext.java b/jsmpp/src/main/java/org/jsmpp/session/AbstractSessionContext.java index 7f8f5b6..2315778 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/AbstractSessionContext.java +++ b/jsmpp/src/main/java/org/jsmpp/session/AbstractSessionContext.java @@ -64,29 +64,24 @@ public synchronized void close() { public void addSessionStateListener( SessionStateListener l) { - synchronized (sessionStateListeners) { - sessionStateListeners.add(l); - } - + sessionStateListeners.add(l); } public void removeSessionStateListener(SessionStateListener l) { - synchronized (sessionStateListeners) { - sessionStateListeners.remove(l); - } + sessionStateListeners.remove(l); } - + protected void fireStateChanged(SessionState newState, - SessionState oldState, Session source) { - synchronized (sessionStateListeners) { - for (SessionStateListener l : sessionStateListeners) { - try { - l.onStateChange(newState, oldState, source); - } catch(Exception e) { - logger.error("Invalid runtime exception thrown when calling onStateChange for " + source, e); - } + SessionState oldState, Session source) { + + for (SessionStateListener l : sessionStateListeners) { + try { + l.onStateChange(newState, oldState, source); + } catch (Exception e) { + logger.error("Invalid runtime exception thrown when calling onStateChange for " + source, e); } } + } public void notifyActivity() { From b3ebf6c065cc114b3dc80de617bc713409019c42 Mon Sep 17 00:00:00 2001 From: Daniel Pocock Date: Wed, 7 Jan 2015 10:07:49 +0100 Subject: [PATCH 030/212] Update for v2.2.1 --- jsmpp-examples/pom.xml | 2 +- jsmpp/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/jsmpp-examples/pom.xml b/jsmpp-examples/pom.xml index 6d9009e..f96d486 100644 --- a/jsmpp-examples/pom.xml +++ b/jsmpp-examples/pom.xml @@ -3,7 +3,7 @@ jsmpp-pom org.jsmpp - 2.2.0 + 2.2.1 4.0.0 diff --git a/jsmpp/pom.xml b/jsmpp/pom.xml index 7f1061c..519b98f 100644 --- a/jsmpp/pom.xml +++ b/jsmpp/pom.xml @@ -3,7 +3,7 @@ org.jsmpp jsmpp-pom - 2.2.0 + 2.2.1 4.0.0 bundle diff --git a/pom.xml b/pom.xml index ec52b94..47ffc61 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.jsmpp jsmpp-pom - 2.2.0 + 2.2.1 pom jSMPP From f555cd136b297e8c9f1f4005261a41e9b260a919 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Wed, 7 Jan 2015 12:20:54 +0100 Subject: [PATCH 031/212] Added IntelliJ and Mac OSX entries. --- .gitignore | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.gitignore b/.gitignore index 2c6f2d6..771dd6a 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,16 @@ syntax:glob .gwt/ .project .classpath +.externalToolBuilders + +# IntelliJ Project Files +*.iml +*.ipr +*.iws +.idea/ + +# MAC_OSX +*.DS_Store version.properties git.properties From 2941fa8367a3ea3febdb260caa38316a522756cb Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Wed, 7 Jan 2015 12:21:26 +0100 Subject: [PATCH 032/212] Updated Log4j version. --- pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9b741da..454ae8b 100644 --- a/pom.xml +++ b/pom.xml @@ -26,6 +26,7 @@ ${maven.build.timestamp} UTF-8 1.6.1 + 1.2.17 git.properties @@ -73,7 +74,7 @@ log4j log4j - 1.2.16 + ${log4j.version} From d143a6bfc9e90e4d7923726fce4f11826796023b Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Wed, 7 Jan 2015 12:25:11 +0100 Subject: [PATCH 033/212] Changed COctetString to limit number of calls to getBytes(). --- .../main/java/org/jsmpp/bean/OptionalParameter.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java index fb293b7..18f1af0 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java @@ -258,16 +258,16 @@ public static class COctetString extends OctetString { public COctetString(short tag, String value, String charsetName) throws UnsupportedEncodingException { super(tag, new byte[value.getBytes(charsetName).length + 1]); - System.arraycopy(value.getBytes(charsetName), 0, this.value, 0, - value.getBytes(charsetName).length); - this.value[value.getBytes().length] = (byte) 0x00; + byte[] bytes = value.getBytes(charsetName); + System.arraycopy(bytes, 0, this.value, 0, bytes.length); + this.value[bytes.length] = (byte) 0x00; } public COctetString(short tag, String value) { super(tag, new byte[value.getBytes().length + 1]); - System.arraycopy(value.getBytes(), 0, this.value, 0, - value.getBytes().length); - this.value[value.getBytes().length] = (byte) 0x00; + byte[] bytes = value.getBytes(); + System.arraycopy(bytes, 0, this.value, 0, bytes.length); + this.value[bytes.length] = (byte) 0x00; return; } From 4a83425263c81292476e1a04fa850ffa2a2d66df Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Wed, 7 Jan 2015 13:48:29 +0100 Subject: [PATCH 034/212] Added Travis CI support. --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..21f8524 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,4 @@ +language: java +jdk: + - oraclejdk7 + - openjdk6 From 64f5969ca4aa8c6d54ec7ceb3a8ce9208d71ea3d Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Wed, 14 Jan 2015 16:50:10 +0100 Subject: [PATCH 035/212] Implement the SMPP 3.4 Relative Time Format. --- .../org/jsmpp/util/RelativeTimeFormatter.java | 136 ++++++------ .../org/jsmpp/util/DateFormatterTest.java | 198 ++++++++---------- .../jsmpp/util/RelativeTimeFormatterTest.java | 181 ++++++++++++++++ 3 files changed, 342 insertions(+), 173 deletions(-) create mode 100644 jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java diff --git a/jsmpp/src/main/java/org/jsmpp/util/RelativeTimeFormatter.java b/jsmpp/src/main/java/org/jsmpp/util/RelativeTimeFormatter.java index c7e35e0..d5ca91f 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/RelativeTimeFormatter.java +++ b/jsmpp/src/main/java/org/jsmpp/util/RelativeTimeFormatter.java @@ -20,71 +20,87 @@ import java.util.TimeZone; /** - * Relative time formatter is {@link TimeFormatter} implementation referred to - * SMPP Protocol Specification v3.4 point 7.1.1. - * - * @author uudashr + * Relative time formatter is {@link TimeFormatter} implementation referred to SMPP Protocol Specification v3.4 point + * 7.1.1. * + * @author pmoerenhout */ public class RelativeTimeFormatter implements TimeFormatter { - private final TimeZone timezone; - - /** - * Time/Date ASCII format for Absolute Time Format is: - * - * YYMMDDhhmmsstnnp (refer for SMPP Protocol Specification v3.4) - */ - private static final String DATE_FORMAT = "{0,number,00}{1,number,00}{2,number,00}{3,number,00}{4,number,00}{5,number,00}000R"; - - /** - * Construct with default timezone. - */ - public RelativeTimeFormatter() { - this(TimeZone.getDefault()); - } - - /** - * Construct with specified SMSC timezone. - * - * @param timezone is the SMSC timezone. - */ - public RelativeTimeFormatter(TimeZone timezone) { - this.timezone = timezone; + + private static TimeZone utcTimeZone = TimeZone.getTimeZone("UTC"); + + /** + * Time/Date ASCII format for Relative Time Format is: + * + * YYMMDDhhmmss000R (refer for SMPP Protocol Specification v3.4) + */ + private static final String DATE_FORMAT = "{0,number,00}{1,number,00}{2,number,00}{3,number,00}{4,number,00}{5,number,00}000R"; + + /** + * Construct + */ + public RelativeTimeFormatter() { + } + + /** + * Return the relative time against current (SMSC) datetime. + * + * @param calendar the datetime. + * @return The relative time between the calendar date and the SMSC calendar date. + */ + public String format(Calendar calendar) { + // As the relative period is calculated on epoch (timeInMillis), no TimeZone information is needed + Calendar smscCalendar = Calendar.getInstance(); + return format(calendar, smscCalendar); + } + + /** + * Return the relative time from the calendar datetime against the SMSC datetime. + * + * @param calendar the date. + * @param smscCalendar the SMSC date. + * @return The relative time between the calendar date and the SMSC calendar date. + */ + public String format(Calendar calendar, Calendar smscCalendar) { + if (calendar == null || smscCalendar == null) { + return null; } - - public String format(Calendar calendar) { - if (calendar == null) { - return null; - } - - long relativeTime = calendar.getTimeInMillis() - - calendar.getTimeZone().getOffset(calendar.getTimeInMillis()) - + timezone.getOffset(calendar.getTimeInMillis()); - - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(relativeTime); - int year = cal.get(Calendar.YEAR) - 2000; - int month = cal.get(Calendar.MONTH) + 1; - int day = cal.get(Calendar.DAY_OF_MONTH); - int hour = cal.get(Calendar.HOUR_OF_DAY); - int minute = cal.get(Calendar.MINUTE); - int second = cal.get(Calendar.SECOND); - - return format(year, month, day, hour, minute, second); + + long diffTimeInMillis = calendar.getTimeInMillis() - smscCalendar.getTimeInMillis(); + if (diffTimeInMillis < 0) { + throw new IllegalArgumentException("The requested relative time has already past."); } - - public String format(Date date) { - if (date == null) { - return null; - } - Calendar cal = Calendar.getInstance(); - cal.setTime(date); - return format(cal); + + // calculate period from epoch, this is not as accurate as Joda-Time Period class or Java 8 Period + Calendar offsetEpoch = Calendar.getInstance(utcTimeZone); + offsetEpoch.setTimeInMillis(diffTimeInMillis); + int years = offsetEpoch.get(Calendar.YEAR) - 1970; + int months = offsetEpoch.get(Calendar.MONTH); + int days = offsetEpoch.get(Calendar.DAY_OF_MONTH) - 1; + int hours = offsetEpoch.get(Calendar.HOUR); + int minutes = offsetEpoch.get(Calendar.MINUTE); + int seconds = offsetEpoch.get(Calendar.SECOND); + + if (years >= 100) { + throw new IllegalArgumentException("The requested relative time is more then a century (" + years + " years)."); } - - public static final String format(Integer year, Integer month, - Integer day, Integer hour, Integer minute, Integer second) { - Object[] args = new Object[] {year, month, day, hour, minute, second}; - return MessageFormat.format(DATE_FORMAT, args); + + return format(years, months, days, hours, minutes, seconds); + } + + public String format(Date date) { + if (date == null) { + return null; } + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + return format(cal); + } + + public static final String format(Integer year, Integer month, + Integer day, Integer hour, Integer minute, Integer second) { + Object[] args = new Object[]{ year, month, day, hour, minute, second }; + return MessageFormat.format(DATE_FORMAT, args); + } + } diff --git a/jsmpp/src/test/java/org/jsmpp/util/DateFormatterTest.java b/jsmpp/src/test/java/org/jsmpp/util/DateFormatterTest.java index c6abb9c..4234788 100644 --- a/jsmpp/src/test/java/org/jsmpp/util/DateFormatterTest.java +++ b/jsmpp/src/test/java/org/jsmpp/util/DateFormatterTest.java @@ -14,130 +14,102 @@ */ package org.jsmpp.util; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; + import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.Locale; import java.util.TimeZone; -import static org.testng.Assert.*; - import org.testng.annotations.Test; /** * @author uudashr - * */ public class DateFormatterTest { - - @Test(groups="checkintest") - public void testStaticAbsoluteFormatter() { - String formatted = AbsoluteTimeFormatter.format(07, 12, 26, 11, 37, 03, 8, 45, '+'); - assertEquals(formatted, "071226113703845+"); - } - - @Test(groups="checkintest") - public void testStaticRelativeFormatter() { - String formatted = RelativeTimeFormatter.format(07, 12, 26, 12, 46, 10); - assertEquals(formatted, "071226124610000R"); - } - - @Test(groups="checkintest") - public void formatNullDate() { - TimeFormatter timeFormatter = new AbsoluteTimeFormatter(); - assertNull(timeFormatter.format((Date)null)); - assertNull(timeFormatter.format((Calendar)null)); - - timeFormatter = new RelativeTimeFormatter(); - assertNull(timeFormatter.format((Date)null)); - assertNull(timeFormatter.format((Calendar)null)); - } - - @Test(groups="checkintest") - public void validateAbsoluteDate() throws Exception { - String formatted = AbsoluteTimeFormatter.format(07, 12, 26, 11, 37, 03, 8, 45, '+'); - StringValidator.validateString(formatted, StringParameter.SCHEDULE_DELIVERY_TIME); - StringValidator.validateString(formatted, StringParameter.VALIDITY_PERIOD); - StringValidator.validateString(formatted, StringParameter.FINAL_DATE); - } - - @Test(groups="checkintest") - public void validateRelativeDate() throws Exception { - String formatted = RelativeTimeFormatter.format(07, 12, 26, 12, 46, 10); - StringValidator.validateString(formatted, StringParameter.SCHEDULE_DELIVERY_TIME); - StringValidator.validateString(formatted, StringParameter.VALIDITY_PERIOD); - StringValidator.validateString(formatted, StringParameter.FINAL_DATE); - } - - @Test(groups="checkintest") - public void formatAbsoluteDate() { - TimeFormatter timeFormatter = new AbsoluteTimeFormatter(); - - GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("Europe/Berlin"), Locale.GERMANY); - date.set(Calendar.YEAR, 2013); - date.set(Calendar.MONTH, Calendar.JANUARY); - date.set(Calendar.DAY_OF_MONTH, 1); - date.set(Calendar.HOUR_OF_DAY, 1); - date.set(Calendar.MINUTE, 0); - date.set(Calendar.SECOND, 0); - date.set(Calendar.MILLISECOND, 0); - - assertEquals(timeFormatter.format(date), "130101010000004+"); - - date.set(Calendar.MONTH, Calendar.JULY); - - // because of daylight saving time, we have a different offset - assertEquals(timeFormatter.format(date), "130701010000008+"); - } - - @Test(groups="checkintest") - public void formatAbsoluteDateRussia() { - TimeFormatter timeFormatter = new AbsoluteTimeFormatter(); - - GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("Asia/Yekaterinburg"), new Locale("ru", "RU")); - date.set(Calendar.YEAR, 2013); - date.set(Calendar.MONTH, Calendar.JANUARY); - date.set(Calendar.DAY_OF_MONTH, 1); - date.set(Calendar.HOUR_OF_DAY, 1); - date.set(Calendar.MINUTE, 0); - date.set(Calendar.SECOND, 0); - date.set(Calendar.MILLISECOND, 0); - - assertEquals(timeFormatter.format(date), "130101010000024+"); - - date.set(Calendar.MONTH, Calendar.JULY); - - // we have the same offset because of the absent of daylight saving time - assertEquals(timeFormatter.format(date), "130701010000024+"); - } - - @Test(groups="checkintest",enabled=false) // FIXME - enable again after fixing issues below - public void formatRelativeDate() { - RelativeTimeFormatter timeFormatter = new RelativeTimeFormatter(TimeZone.getTimeZone("America/Denver")); - - // at this date neither Denver nor Germany has daylight saving time - GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("Europe/Berlin"), Locale.GERMANY); - date.set(Calendar.YEAR, 2013); - date.set(Calendar.MONTH, Calendar.JANUARY); - date.set(Calendar.DAY_OF_MONTH, 1); - date.set(Calendar.HOUR_OF_DAY, 1); - date.set(Calendar.MINUTE, 0); - date.set(Calendar.SECOND, 0); - date.set(Calendar.MILLISECOND, 0); - - assertEquals(timeFormatter.format(date), "130101050000000R"); // FIXME - should be a relative time but looks like an absolute value - - // at this date Denver has already daylight saving time but not Germany - date.set(Calendar.MONTH, Calendar.MARCH); - date.set(Calendar.DAY_OF_MONTH, 20); - - assertEquals(timeFormatter.format(date), "130320060000000R"); // FIXME - should be a relative time but looks like an absolute value - - // at this date Denver and Germany has daylight saving time - date.set(Calendar.MONTH, Calendar.APRIL); - date.set(Calendar.DAY_OF_MONTH, 1); - - assertEquals(timeFormatter.format(date), "130401050000000R"); // FIXME - should be a relative time but looks like an absolute value - } + + @Test(groups = "checkintest") + public void testStaticAbsoluteFormatter() { + String formatted = AbsoluteTimeFormatter.format(07, 12, 26, 11, 37, 03, 8, 45, '+'); + assertEquals(formatted, "071226113703845+"); + } + + @Test(groups = "checkintest") + public void testStaticRelativeFormatter() { + String formatted = RelativeTimeFormatter.format(07, 12, 26, 12, 46, 10); + assertEquals(formatted, "071226124610000R"); + } + + @Test(groups = "checkintest") + public void formatNullDate() { + TimeFormatter timeFormatter = new AbsoluteTimeFormatter(); + assertNull(timeFormatter.format((Date) null)); + assertNull(timeFormatter.format((Calendar) null)); + + timeFormatter = new RelativeTimeFormatter(); + assertNull(timeFormatter.format((Date) null)); + assertNull(timeFormatter.format((Calendar) null)); + } + + @Test(groups = "checkintest") + public void validateAbsoluteDate() throws Exception { + String formatted = AbsoluteTimeFormatter.format(07, 12, 26, 11, 37, 03, 8, 45, '+'); + StringValidator.validateString(formatted, StringParameter.SCHEDULE_DELIVERY_TIME); + StringValidator.validateString(formatted, StringParameter.VALIDITY_PERIOD); + StringValidator.validateString(formatted, StringParameter.FINAL_DATE); + } + + @Test(groups = "checkintest") + public void validateRelativeDate() throws Exception { + String formatted = RelativeTimeFormatter.format(07, 12, 26, 12, 46, 10); + StringValidator.validateString(formatted, StringParameter.SCHEDULE_DELIVERY_TIME); + StringValidator.validateString(formatted, StringParameter.VALIDITY_PERIOD); + StringValidator.validateString(formatted, StringParameter.FINAL_DATE); + } + + @Test(groups = "checkintest") + public void formatAbsoluteDate() { + TimeFormatter timeFormatter = new AbsoluteTimeFormatter(); + + GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("Europe/Berlin"), Locale.GERMANY); + date.set(Calendar.YEAR, 2013); + date.set(Calendar.MONTH, Calendar.JANUARY); + date.set(Calendar.DAY_OF_MONTH, 1); + date.set(Calendar.HOUR_OF_DAY, 1); + date.set(Calendar.MINUTE, 0); + date.set(Calendar.SECOND, 0); + date.set(Calendar.MILLISECOND, 0); + + assertEquals(timeFormatter.format(date), "130101010000004+"); + + date.set(Calendar.MONTH, Calendar.JULY); + + // because of daylight saving time, we have a different offset + assertEquals(timeFormatter.format(date), "130701010000008+"); + } + + @Test(groups = "checkintest") + public void formatAbsoluteDateRussia() { + TimeFormatter timeFormatter = new AbsoluteTimeFormatter(); + + GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("Asia/Yekaterinburg"), new Locale("ru", "RU")); + date.set(Calendar.YEAR, 2013); + date.set(Calendar.MONTH, Calendar.JANUARY); + date.set(Calendar.DAY_OF_MONTH, 1); + date.set(Calendar.HOUR_OF_DAY, 1); + date.set(Calendar.MINUTE, 0); + date.set(Calendar.SECOND, 0); + date.set(Calendar.MILLISECOND, 0); + + assertEquals(timeFormatter.format(date), "130101010000024+"); + + date.set(Calendar.MONTH, Calendar.JULY); + + // we have the same offset because of the absent of daylight saving time + assertEquals(timeFormatter.format(date), "130701010000024+"); + } + } diff --git a/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java b/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java new file mode 100644 index 0000000..53a076d --- /dev/null +++ b/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java @@ -0,0 +1,181 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.util; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.fail; + +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.TimeZone; + +import org.testng.annotations.Test; + +/** + * @author pmoerenhout + */ +public class RelativeTimeFormatterTest { + + @Test(groups = "checkintest") + public void testStaticRelativeFormatter() { + String formatted = RelativeTimeFormatter.format(07, 12, 26, 12, 46, 10); + assertEquals(formatted, "071226124610000R"); + } + + @Test(groups = "checkintest") + public void formatNullDate() { + TimeFormatter timeFormatter = new RelativeTimeFormatter(); + assertNull(timeFormatter.format((Date) null)); + assertNull(timeFormatter.format((Calendar) null)); + } + + @Test(groups = "checkintest") + public void validateRelativeDate() throws Exception { + String formatted = RelativeTimeFormatter.format(07, 12, 26, 12, 46, 10); + StringValidator.validateString(formatted, StringParameter.SCHEDULE_DELIVERY_TIME); + StringValidator.validateString(formatted, StringParameter.VALIDITY_PERIOD); + StringValidator.validateString(formatted, StringParameter.FINAL_DATE); + } + + @Test(groups = "checkintest", expectedExceptions = IllegalArgumentException.class) + public void formatRelativeDateWhenAlreadyPast() { + RelativeTimeFormatter timeFormatter = new RelativeTimeFormatter(); + + // date in the past + GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("Europe/Berlin")); + date.set(Calendar.YEAR, 1998); + date.set(Calendar.MONTH, Calendar.MARCH); + date.set(Calendar.DAY_OF_MONTH, 1); + date.set(Calendar.HOUR, 13); + date.set(Calendar.MINUTE, 46); + date.set(Calendar.SECOND, 59); + + timeFormatter.format(date); + fail("Expected IllegalArgumentException not thrown"); + } + + @Test(groups = "checkintest", expectedExceptions = IllegalArgumentException.class) + public void formatRelativeDateIgnoreMilliSeconds() { + RelativeTimeFormatter timeFormatter = new RelativeTimeFormatter(); + + // Set the SMSC date + GregorianCalendar smscDate = new GregorianCalendar(TimeZone.getTimeZone("Europe/Berlin")); + smscDate.set(Calendar.YEAR, 1998); + smscDate.set(Calendar.MONTH, Calendar.JANUARY); + smscDate.set(Calendar.DAY_OF_MONTH, 1); + smscDate.set(Calendar.HOUR, 13); + smscDate.set(Calendar.MINUTE, 46); + smscDate.set(Calendar.SECOND, 59); + + GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("Europe/Berlin")); + date.setTimeInMillis(smscDate.getTimeInMillis()); + // Tenth of seconds should be ignored + smscDate.set(Calendar.MILLISECOND, 800); + + assertEquals(timeFormatter.format(date, smscDate), "000000000000000R"); + } + + @Test(groups = "checkintest", expectedExceptions = IllegalArgumentException.class) + public void formatRelativeDateWhenExceedsCentury() { + RelativeTimeFormatter timeFormatter = new RelativeTimeFormatter(); + + // relative date more then 100 years ahead + Calendar date = Calendar.getInstance(TimeZone.getTimeZone("America/Denver")); + date.add(Calendar.YEAR, 101); + + String relativeTime = timeFormatter.format(date); + fail("Expected IllegalArgumentException not thrown"); + } + + @Test(groups = "checkintest") + public void formatRelativeDateSame() { + RelativeTimeFormatter timeFormatter = new RelativeTimeFormatter(); + + GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("America/Denver")); + assertEquals(timeFormatter.format(date, date), "000000000000000R"); + } + + @Test(groups = "checkintest") + public void formatRelativeDateDifferentTimeZone() { + RelativeTimeFormatter timeFormatter = new RelativeTimeFormatter(); + GregorianCalendar smscDate = new GregorianCalendar(TimeZone.getTimeZone("America/Denver")); + smscDate.set(2014, Calendar.JANUARY, 2, 23, 15, 16); + GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("America/Los_Angeles")); + date.set(2014, Calendar.JANUARY, 2, 23, 15, 16); + assertEquals(timeFormatter.format(date, smscDate), "000000010000000R"); + } + + @Test(groups = "checkintest") + public void formatRelativeDateMonth() { + RelativeTimeFormatter timeFormatter = new RelativeTimeFormatter(); + Calendar smscDate = Calendar.getInstance(TimeZone.getTimeZone("America/Denver")); + + GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("America/Denver")); + date.setTimeInMillis(smscDate.getTimeInMillis()); + date.add(Calendar.MONTH, 1); + assertEquals(timeFormatter.format(date, smscDate), "000100000000000R"); + } + + @Test(groups = "checkintest") + public void formatRelativeDateWeek() { + RelativeTimeFormatter timeFormatter = new RelativeTimeFormatter(); + GregorianCalendar smscDate = new GregorianCalendar(TimeZone.getTimeZone("America/Denver")); + + GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("America/Denver")); + date.setTimeInMillis(smscDate.getTimeInMillis()); + date.add(Calendar.DAY_OF_MONTH, 7); + assertEquals(timeFormatter.format(date, smscDate), "000007000000000R"); + } + + @Test(groups = "checkintest") + public void formatRelativeTimeSecond() { + RelativeTimeFormatter timeFormatter = new RelativeTimeFormatter(); + GregorianCalendar smscDate = new GregorianCalendar(TimeZone.getTimeZone("America/Denver")); + + GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("America/Denver")); + date.setTimeInMillis(smscDate.getTimeInMillis()); + date.add(Calendar.SECOND, 1); + assertEquals(timeFormatter.format(date, smscDate), "000000000001000R"); + } + + @Test(groups = "checkintest") + public void formatRelativeTimeMonth() { + RelativeTimeFormatter timeFormatter = new RelativeTimeFormatter(); + GregorianCalendar smscDate = new GregorianCalendar(TimeZone.getTimeZone("America/Denver")); + smscDate.set(2001, Calendar.JANUARY, 31, 14, 15, 16); + + GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("America/Denver")); + date.setTimeInMillis(smscDate.getTimeInMillis()); + date.add(Calendar.MONTH, 1); + // when using Joda-Time or Java 8 Period class + //assertEquals(timeFormatter.format(date), "000100000000000R"); + assertEquals(timeFormatter.format(date, smscDate), "000028000000000R"); + } + + @Test(groups = "checkintest") + public void formatRelativeDateNewYear() { + RelativeTimeFormatter timeFormatter = new RelativeTimeFormatter(); + GregorianCalendar smscDate = new GregorianCalendar(TimeZone.getTimeZone("America/Denver")); + smscDate.set(2001, Calendar.DECEMBER, 31, 23, 59, 59); + + GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("Europe/Berlin")); + date.setTimeInMillis(smscDate.getTimeInMillis()); + date.add(Calendar.SECOND, 2); + assertEquals(timeFormatter.format(date, smscDate), "000000000002000R"); + } + +} From 1f31b15712825e3b6b9277634066e4458d6489b5 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Wed, 14 Jan 2015 16:57:34 +0100 Subject: [PATCH 036/212] Removed incorrect expected Exception in test case. --- .../src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java b/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java index 53a076d..03a0311 100644 --- a/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java +++ b/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java @@ -68,7 +68,7 @@ public void formatRelativeDateWhenAlreadyPast() { fail("Expected IllegalArgumentException not thrown"); } - @Test(groups = "checkintest", expectedExceptions = IllegalArgumentException.class) + @Test(groups = "checkintest") public void formatRelativeDateIgnoreMilliSeconds() { RelativeTimeFormatter timeFormatter = new RelativeTimeFormatter(); From daf92abcc0bee348d838ea6ddc3f10779f92d698 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Wed, 14 Jan 2015 17:01:52 +0100 Subject: [PATCH 037/212] Set date to future date to fix testcase. --- .../test/java/org/jsmpp/util/RelativeTimeFormatterTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java b/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java index 03a0311..86dbd0e 100644 --- a/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java +++ b/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java @@ -72,9 +72,9 @@ public void formatRelativeDateWhenAlreadyPast() { public void formatRelativeDateIgnoreMilliSeconds() { RelativeTimeFormatter timeFormatter = new RelativeTimeFormatter(); - // Set the SMSC date + // Set the SMSC date to some future datetime GregorianCalendar smscDate = new GregorianCalendar(TimeZone.getTimeZone("Europe/Berlin")); - smscDate.set(Calendar.YEAR, 1998); + smscDate.set(Calendar.YEAR, 2080); smscDate.set(Calendar.MONTH, Calendar.JANUARY); smscDate.set(Calendar.DAY_OF_MONTH, 1); smscDate.set(Calendar.HOUR, 13); From b7b47bd3b04c1f657e7db0ea83595dd09ced1b2c Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Wed, 14 Jan 2015 17:08:36 +0100 Subject: [PATCH 038/212] Fixed a type. --- .../src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java b/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java index 86dbd0e..badb4ef 100644 --- a/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java +++ b/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java @@ -84,7 +84,7 @@ public void formatRelativeDateIgnoreMilliSeconds() { GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("Europe/Berlin")); date.setTimeInMillis(smscDate.getTimeInMillis()); // Tenth of seconds should be ignored - smscDate.set(Calendar.MILLISECOND, 800); + date.set(Calendar.MILLISECOND, 800); assertEquals(timeFormatter.format(date, smscDate), "000000000000000R"); } From 2d1a2fd3d9d4ef09b1ddb56234b2c9eeec877ac2 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Fri, 16 Jan 2015 16:11:41 +0100 Subject: [PATCH 039/212] Correct the hours to use 24 hour format in Calendar. --- .../org/jsmpp/util/RelativeTimeFormatter.java | 2 +- .../org/jsmpp/util/RelativeTimeFormatterTest.java | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/util/RelativeTimeFormatter.java b/jsmpp/src/main/java/org/jsmpp/util/RelativeTimeFormatter.java index d5ca91f..268715b 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/RelativeTimeFormatter.java +++ b/jsmpp/src/main/java/org/jsmpp/util/RelativeTimeFormatter.java @@ -77,7 +77,7 @@ public String format(Calendar calendar, Calendar smscCalendar) { int years = offsetEpoch.get(Calendar.YEAR) - 1970; int months = offsetEpoch.get(Calendar.MONTH); int days = offsetEpoch.get(Calendar.DAY_OF_MONTH) - 1; - int hours = offsetEpoch.get(Calendar.HOUR); + int hours = offsetEpoch.get(Calendar.HOUR_OF_DAY); int minutes = offsetEpoch.get(Calendar.MINUTE); int seconds = offsetEpoch.get(Calendar.SECOND); diff --git a/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java b/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java index badb4ef..9c63b80 100644 --- a/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java +++ b/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java @@ -60,7 +60,7 @@ public void formatRelativeDateWhenAlreadyPast() { date.set(Calendar.YEAR, 1998); date.set(Calendar.MONTH, Calendar.MARCH); date.set(Calendar.DAY_OF_MONTH, 1); - date.set(Calendar.HOUR, 13); + date.set(Calendar.HOUR_OF_DAY, 13); date.set(Calendar.MINUTE, 46); date.set(Calendar.SECOND, 59); @@ -77,7 +77,7 @@ public void formatRelativeDateIgnoreMilliSeconds() { smscDate.set(Calendar.YEAR, 2080); smscDate.set(Calendar.MONTH, Calendar.JANUARY); smscDate.set(Calendar.DAY_OF_MONTH, 1); - smscDate.set(Calendar.HOUR, 13); + smscDate.set(Calendar.HOUR_OF_DAY, 13); smscDate.set(Calendar.MINUTE, 46); smscDate.set(Calendar.SECOND, 59); @@ -152,6 +152,17 @@ public void formatRelativeTimeSecond() { assertEquals(timeFormatter.format(date, smscDate), "000000000001000R"); } + @Test(groups = "checkintest") + public void formatRelativeTimeHours() { + RelativeTimeFormatter timeFormatter = new RelativeTimeFormatter(); + GregorianCalendar smscDate = new GregorianCalendar(TimeZone.getTimeZone("America/Denver")); + + GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("America/Denver")); + date.setTimeInMillis(smscDate.getTimeInMillis()); + date.add(Calendar.HOUR_OF_DAY, 16); + assertEquals(timeFormatter.format(date, smscDate), "000000160000000R"); + } + @Test(groups = "checkintest") public void formatRelativeTimeMonth() { RelativeTimeFormatter timeFormatter = new RelativeTimeFormatter(); From cffd8c58d02abd76f5bee2f0617fe04cf8a54083 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 18 Jan 2015 00:00:15 +0100 Subject: [PATCH 040/212] Fix test case formatRelativeDateIgnoreMilliSeconds. --- .../src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java b/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java index 9c63b80..49c8bc3 100644 --- a/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java +++ b/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java @@ -80,6 +80,7 @@ public void formatRelativeDateIgnoreMilliSeconds() { smscDate.set(Calendar.HOUR_OF_DAY, 13); smscDate.set(Calendar.MINUTE, 46); smscDate.set(Calendar.SECOND, 59); + smscDate.set(Calendar.MILLISECOND, 0); GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("Europe/Berlin")); date.setTimeInMillis(smscDate.getTimeInMillis()); From a0892ad544f5b9d230e879916094142c8b314c3f Mon Sep 17 00:00:00 2001 From: vharseko Date: Sun, 8 Feb 2015 01:59:42 +0400 Subject: [PATCH 041/212] NPE when provider not return protocol version on bind response: 0000001e8000000200000000000000016d6178696d6174656c65636f6d00 SMPP providers may be use long passwords over SMPP 3.4 standard (like t-sms.ru) --- .../main/java/org/jsmpp/bean/OptionalParameters.java | 11 ++++++----- .../src/main/java/org/jsmpp/util/StringParameter.java | 3 ++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameters.java b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameters.java index b5f032f..d7d12bc 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameters.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameters.java @@ -235,11 +235,12 @@ public static OptionalParameter deserialize(short tagCode, byte[] content) { @SuppressWarnings("unchecked") public static U get(Class tagClass, OptionalParameter[] parameters) { - for(OptionalParameter i: parameters) { - if(i.getClass() == tagClass) { - return (U)i; - } - } + if (parameters!=null) + for(OptionalParameter i: parameters) { + if(i.getClass() == tagClass) { + return (U)i; + } + } logger.info("optional tag " + tagClass + " not found"); return null; } diff --git a/jsmpp/src/main/java/org/jsmpp/util/StringParameter.java b/jsmpp/src/main/java/org/jsmpp/util/StringParameter.java index 1d1eb37..aad74ce 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/StringParameter.java +++ b/jsmpp/src/main/java/org/jsmpp/util/StringParameter.java @@ -31,7 +31,8 @@ public enum StringParameter { /** * password string parameter. */ - PASSWORD(StringType.C_OCTEC_STRING, 0, 9, true, SMPPConstant.STAT_ESME_RINVPASWD), + //SMPP providers may be use long passwords over SMPP 3.4 standard (like t-sms.ru) + PASSWORD(StringType.C_OCTEC_STRING, 0, 32, true, SMPPConstant.STAT_ESME_RINVPASWD), /** * system_type string parameter. From 4b76e39cc7b668fd7fe6dcc92cac5ab689c36fe2 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 5 Apr 2015 09:26:00 +0200 Subject: [PATCH 042/212] Test was failing in April, now using fixed dates. --- .../jsmpp/util/RelativeTimeFormatterTest.java | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java b/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java index 49c8bc3..226edd5 100644 --- a/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java +++ b/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java @@ -57,12 +57,7 @@ public void formatRelativeDateWhenAlreadyPast() { // date in the past GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("Europe/Berlin")); - date.set(Calendar.YEAR, 1998); - date.set(Calendar.MONTH, Calendar.MARCH); - date.set(Calendar.DAY_OF_MONTH, 1); - date.set(Calendar.HOUR_OF_DAY, 13); - date.set(Calendar.MINUTE, 46); - date.set(Calendar.SECOND, 59); + date.set(1998, Calendar.MARCH, 1, 13, 46, 59); timeFormatter.format(date); fail("Expected IllegalArgumentException not thrown"); @@ -95,7 +90,7 @@ public void formatRelativeDateWhenExceedsCentury() { RelativeTimeFormatter timeFormatter = new RelativeTimeFormatter(); // relative date more then 100 years ahead - Calendar date = Calendar.getInstance(TimeZone.getTimeZone("America/Denver")); + GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("America/Denver")); date.add(Calendar.YEAR, 101); String relativeTime = timeFormatter.format(date); @@ -121,9 +116,23 @@ public void formatRelativeDateDifferentTimeZone() { } @Test(groups = "checkintest") - public void formatRelativeDateMonth() { + public void formatRelativeDateMonthFebruary() { + // for Java 8, the relative time could be calculated better + RelativeTimeFormatter timeFormatter = new RelativeTimeFormatter(); + GregorianCalendar smscDate = new GregorianCalendar(TimeZone.getTimeZone("Pacific/Midway")); + smscDate.set(2015, Calendar.FEBRUARY, 1, 0, 11, 22); + + GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("Pacific/Midway")); + date.setTimeInMillis(smscDate.getTimeInMillis()); + date.add(Calendar.MONTH, 1); + assertEquals(timeFormatter.format(date, smscDate), "000028000000000R"); + } + + @Test(groups = "checkintest") + public void formatRelativeDateMonthMay() { RelativeTimeFormatter timeFormatter = new RelativeTimeFormatter(); - Calendar smscDate = Calendar.getInstance(TimeZone.getTimeZone("America/Denver")); + GregorianCalendar smscDate = new GregorianCalendar(TimeZone.getTimeZone("America/Denver")); + smscDate.set(2015, Calendar.MAY, 1, 13, 14, 15); GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("America/Denver")); date.setTimeInMillis(smscDate.getTimeInMillis()); From 64d4ab39e95e743e887a65684c284f0ddc64b1c9 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 5 Apr 2015 09:46:25 +0200 Subject: [PATCH 043/212] With invalid command lengths (<4) an IndexOutOfBoundsException was thrown. Added tests. --- .../main/java/org/jsmpp/DefaultPDUReader.java | 13 ++-- .../java/org/jsmpp/DefaultPDUReaderTest.java | 76 +++++++++++++++++++ 2 files changed, 83 insertions(+), 6 deletions(-) create mode 100644 jsmpp/src/test/java/org/jsmpp/DefaultPDUReaderTest.java diff --git a/jsmpp/src/main/java/org/jsmpp/DefaultPDUReader.java b/jsmpp/src/main/java/org/jsmpp/DefaultPDUReader.java index 9b5fc82..964b34d 100644 --- a/jsmpp/src/main/java/org/jsmpp/DefaultPDUReader.java +++ b/jsmpp/src/main/java/org/jsmpp/DefaultPDUReader.java @@ -23,11 +23,11 @@ /** * Default implementation of {@link PDUReader}. - * + * * @author uudashr * @version 1.0 * @since 1.0 - * + * */ public class DefaultPDUReader implements PDUReader { @@ -40,12 +40,13 @@ public Command readPDUHeader(DataInputStream in) header.setCommandLength(in.readInt()); if (header.getCommandLength() < 16) { - // command length to short, read the left dump anyway + // command length too short, read the left dump anyway byte[] dump = new byte[header.getCommandLength()]; - in.read(dump, 4, header.getCommandLength() - 4); - + if (header.getCommandLength() >= 4) { + in.read(dump, 4, header.getCommandLength() - 4); + } throw new InvalidCommandLengthException("Command length " - + header.getCommandLength() + " is to short"); + + header.getCommandLength() + " is too short"); } header.setCommandId(in.readInt()); header.setCommandStatus(in.readInt()); diff --git a/jsmpp/src/test/java/org/jsmpp/DefaultPDUReaderTest.java b/jsmpp/src/test/java/org/jsmpp/DefaultPDUReaderTest.java new file mode 100644 index 0000000..ea8ef2a --- /dev/null +++ b/jsmpp/src/test/java/org/jsmpp/DefaultPDUReaderTest.java @@ -0,0 +1,76 @@ +package org.jsmpp; + +import static org.testng.Assert.assertEquals; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; + +import org.jsmpp.bean.Command; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +public class DefaultPDUReaderTest { + + DefaultPDUReader defaultPDUReader; + + @BeforeMethod + public void setUp() throws Exception { + defaultPDUReader = new DefaultPDUReader(); + } + + @Test + public void testPDUHeader() throws Exception { + + DataInputStream in = new DataInputStream( + new ByteArrayInputStream( + new byte[]{ 0x00, 0x00, 0x00, 0x10, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c })); + + Command command = defaultPDUReader.readPDUHeader(in); + + assertEquals(command.getCommandLength(), 16, "Command length differs"); + assertEquals(command.getCommandId(), 0x01020304, "Command id differs"); + assertEquals(command.getCommandStatus(), 0x05060708, "Command status differs"); + assertEquals(command.getSequenceNumber(), 0x090a0b0c, "Sequence number differs"); + } + + @Test(groups = "checkintest", expectedExceptions = InvalidCommandLengthException.class) + public void testInvalidPDUHeaderWithCommandLengthZero() throws Exception { + + DataInputStream in = new DataInputStream( + new ByteArrayInputStream( + new byte[]{ 0x00, 0x00, 0x00, 0x00 })); + defaultPDUReader.readPDUHeader(in); + } + + @Test(groups = "checkintest", expectedExceptions = InvalidCommandLengthException.class) + public void testInvalidPDUHeaderWithCommandLengthFour() throws Exception { + + DataInputStream in = new DataInputStream( + new ByteArrayInputStream( + new byte[]{ 0x00, 0x00, 0x00, 0x04 })); + + defaultPDUReader.readPDUHeader(in); + } + + @Test(groups = "checkintest", expectedExceptions = InvalidCommandLengthException.class) + public void testInvalidPDUHeaderWithCommandLengthEigth() throws Exception { + + DefaultPDUReader defaultPDUReader = new DefaultPDUReader(); + + DataInputStream in = new DataInputStream( + new ByteArrayInputStream( + new byte[]{ 0x00, 0x00, 0x00, 0x08, 0x01, 0x02, 0x03, 0x04 })); + defaultPDUReader.readPDUHeader(in); + } + + @Test(groups = "checkintest", expectedExceptions = InvalidCommandLengthException.class) + public void testInvalidPDUHeaderWithCommandLengthFifteen() throws Exception { + + DefaultPDUReader defaultPDUReader = new DefaultPDUReader(); + + DataInputStream in = new DataInputStream( + new ByteArrayInputStream( + new byte[]{ 0x00, 0x00, 0x00, 0x0f, 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43 })); + defaultPDUReader.readPDUHeader(in); + } +} \ No newline at end of file From 00b5430b583669ad731e00bbb0424b96dc01d3a8 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 5 Apr 2015 09:49:35 +0200 Subject: [PATCH 044/212] Minor typo. --- jsmpp/src/main/java/org/jsmpp/PDUReader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsmpp/src/main/java/org/jsmpp/PDUReader.java b/jsmpp/src/main/java/org/jsmpp/PDUReader.java index 9380fb2..5f1a49c 100644 --- a/jsmpp/src/main/java/org/jsmpp/PDUReader.java +++ b/jsmpp/src/main/java/org/jsmpp/PDUReader.java @@ -37,7 +37,7 @@ public interface PDUReader { * * @param in is the input stream of the pdu. * @return the header of smpp command. - * @throws InvalidCommandLengthException if command_length is to short. + * @throws InvalidCommandLengthException if command_length is too short. * @throws IOException if an I/O error occurs. */ public Command readPDUHeader(DataInputStream in) From 874feba2720c00baa3b262aa22f31dc8fca3efd6 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 5 Apr 2015 09:50:40 +0200 Subject: [PATCH 045/212] Removed the system output during test. --- ...ssageWaitingDataCodingStoreMessageAlphaDefaultTest.java | 7 ++----- .../MessageWaitingDataCodingStoreMessageAlphaUCS2Test.java | 7 ++----- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/jsmpp/src/test/java/org/jsmpp/bean/MessageWaitingDataCodingStoreMessageAlphaDefaultTest.java b/jsmpp/src/test/java/org/jsmpp/bean/MessageWaitingDataCodingStoreMessageAlphaDefaultTest.java index edb5316..394d1b4 100644 --- a/jsmpp/src/test/java/org/jsmpp/bean/MessageWaitingDataCodingStoreMessageAlphaDefaultTest.java +++ b/jsmpp/src/test/java/org/jsmpp/bean/MessageWaitingDataCodingStoreMessageAlphaDefaultTest.java @@ -38,11 +38,8 @@ public void messageWaitingDiscardMessageInactiveVoicemail() { IndicationType.VOICEMAIL_MESSAGE_WAITING, Alphabet.ALPHA_DEFAULT); byte expected = (byte)0xd0; - - System.out.println(0xff & expected); - System.out.println(0xff & dataCoding.toByte()); - - assertEquals(dataCoding.toByte(), expected); + + assertEquals(dataCoding.toByte(), expected, "Datacoding differs"); DataCoding buildedInstance = DataCodings.newInstance(dataCoding.toByte()); assertEquals(buildedInstance, dataCoding); diff --git a/jsmpp/src/test/java/org/jsmpp/bean/MessageWaitingDataCodingStoreMessageAlphaUCS2Test.java b/jsmpp/src/test/java/org/jsmpp/bean/MessageWaitingDataCodingStoreMessageAlphaUCS2Test.java index 3201f5d..4977df5 100644 --- a/jsmpp/src/test/java/org/jsmpp/bean/MessageWaitingDataCodingStoreMessageAlphaUCS2Test.java +++ b/jsmpp/src/test/java/org/jsmpp/bean/MessageWaitingDataCodingStoreMessageAlphaUCS2Test.java @@ -38,11 +38,8 @@ public void messageWaitingDiscardMessageInactiveVoicemail() { IndicationType.VOICEMAIL_MESSAGE_WAITING, Alphabet.ALPHA_UCS2); byte expected = (byte)0xe0; - - System.out.println(0xff & expected); - System.out.println(0xff & dataCoding.toByte()); - - assertEquals(dataCoding.toByte(), expected); + + assertEquals(dataCoding.toByte(), expected, "Datacoding differs"); DataCoding buildedInstance = DataCodings.newInstance(dataCoding.toByte()); assertEquals(buildedInstance, dataCoding); From 484a42370399f5829b33b3f590a7e80065fe20e3 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 5 Apr 2015 09:51:11 +0200 Subject: [PATCH 046/212] Removed system output during test. --- jsmpp/src/test/java/org/jsmpp/extra/PendingResponseTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/jsmpp/src/test/java/org/jsmpp/extra/PendingResponseTest.java b/jsmpp/src/test/java/org/jsmpp/extra/PendingResponseTest.java index 8597fb2..461e485 100644 --- a/jsmpp/src/test/java/org/jsmpp/extra/PendingResponseTest.java +++ b/jsmpp/src/test/java/org/jsmpp/extra/PendingResponseTest.java @@ -66,7 +66,6 @@ public void testDoneWithInvalidResponse() { try { notifyInvalidResponse(90, pendingResponse); pendingResponse.waitDone(); - System.out.println("DONE"); fail("Should throw InvalidResponseException"); } catch (ResponseTimeoutException e) { fail("Should throw InvalidResponseException"); From bb9a1b2c702d2799e245f20c16c2b735a20f0ade Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 5 Apr 2015 11:30:26 +0200 Subject: [PATCH 047/212] Handle unexpected RuntimeException when receiving invalid PDU. --- jsmpp/src/main/java/org/jsmpp/session/SMPPServerSession.java | 4 ++++ jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/SMPPServerSession.java b/jsmpp/src/main/java/org/jsmpp/session/SMPPServerSession.java index 7f6639c..a413c04 100755 --- a/jsmpp/src/main/java/org/jsmpp/session/SMPPServerSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/SMPPServerSession.java @@ -536,7 +536,11 @@ private void readPDU() { } catch (SocketTimeoutException e) { notifyNoActivity(); } catch (IOException e) { + logger.warn("IOException while reading: {}", e.getMessage()); close(); + } catch (RuntimeException e) { + logger.warn("RuntimeException: {}", e.getMessage()); + unbindAndClose(); } } diff --git a/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java b/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java index 71515fa..886d735 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java @@ -622,7 +622,10 @@ private void readPDU() { } catch (IOException e) { logger.warn("IOException while reading: {}", e.getMessage()); close(); - } + } catch (RuntimeException e) { + logger.warn("RuntimeException: {}", e.getMessage()); + unbindAndClose(); + } } /** From a7160f5ba44b43cc6837033cb7fd5b0d2c35cd6e Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 5 Apr 2015 11:41:16 +0200 Subject: [PATCH 048/212] Updated SLF4J and JUnit versions. --- pom.xml | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 9bfb63b..bef7dde 100644 --- a/pom.xml +++ b/pom.xml @@ -36,14 +36,20 @@ daniel@pocock.pro http://danielpocock.com + + Pim Moerenhout + pim.moerenhout@gmail.com + yyyyMMddHHmm ${maven.build.timestamp} UTF-8 - 1.6.1 + 1.7.12 1.2.17 + 4.12 + 1.10 git.properties @@ -51,7 +57,7 @@ junit junit - 4.8.2 + ${junit.version} test @@ -85,7 +91,7 @@ commons-codec commons-codec - 1.4 + ${commons-codec.version} @@ -107,12 +113,12 @@ org.apache.maven.wagon wagon-ssh - 2.0 + 2.1 org.apache.maven.wagon wagon-ssh-external - 2.0 + 2.1 @@ -237,7 +243,7 @@ org.apache.maven.plugins maven-gpg-plugin - 1.4 + 1.6 sign-artifacts From 8695efcbb7638bad20dc346fe5347f9aa168d25f Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 5 Apr 2015 12:12:17 +0200 Subject: [PATCH 049/212] Updated Maven wagon to 2.8 --- pom.xml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index bef7dde..0e3b98e 100644 --- a/pom.xml +++ b/pom.xml @@ -49,6 +49,7 @@ 1.7.12 1.2.17 4.12 + 5.14.10 1.10 git.properties @@ -72,7 +73,7 @@ org.testng testng - 5.14.10 + ${testng.version} test @@ -113,12 +114,12 @@ org.apache.maven.wagon wagon-ssh - 2.1 + 2.8 org.apache.maven.wagon wagon-ssh-external - 2.1 + 2.8 From 574ea98a89e055d881c700f009c910a4f000f2d6 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 5 Apr 2015 12:45:10 +0200 Subject: [PATCH 050/212] Added Oracle Java 8 to Travis CI. --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 21f8524..d67d8f6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,5 @@ language: java jdk: + - oraclejdk8 - oraclejdk7 - openjdk6 From d117afffd21d6c008222338a5c1a97151b6531ea Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 5 Apr 2015 12:54:39 +0200 Subject: [PATCH 051/212] Updated TestNG version. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0e3b98e..406b572 100644 --- a/pom.xml +++ b/pom.xml @@ -49,7 +49,7 @@ 1.7.12 1.2.17 4.12 - 5.14.10 + 6.8.21 1.10 git.properties From 7a6ea536c4532cff4279098775af8ea5f558aa9f Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Tue, 9 Jun 2015 20:15:11 +0200 Subject: [PATCH 052/212] Fix for NullPointerException when OptionalParameters are empty in BindResp. --- .../org/jsmpp/bean/OptionalParameters.java | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameters.java b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameters.java index b5f032f..8bdf249 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameters.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameters.java @@ -105,7 +105,7 @@ public static OptionalParameter.Byte newSarTotalSegments(int value) { public static OptionalParameter deserialize(short tagCode, byte[] content) { Tag tag = Tag.valueOf(tagCode); if(tag == null) { - logger.warn("Optional Parameter Tag not recognized for deserialization: " + tagCode); + logger.warn("Optional Parameter Tag not recognized for deserialization: {}", tagCode); return new COctetString(tagCode, content); } @@ -206,11 +206,11 @@ public static OptionalParameter deserialize(short tagCode, byte[] content) { case VENDOR_SPECIFIC_DEST_MSC_ADDR: return new OptionalParameter.Vendor_specific_dest_msc_addr(content); default: - logger.warn("Missing code in deserialize to handle Optional Parameter Tag: " + tag); + logger.warn("Missing code in deserialize to handle Optional Parameter Tag: {}", tag); } // fallback - logger.warn("Falling back to basic OptionalParameter types for " + tag); + logger.warn("Falling back to basic OptionalParameter types for {}", tag); if (Null.class.isAssignableFrom(tag.type)) { return new Null(tagCode); } @@ -235,23 +235,27 @@ public static OptionalParameter deserialize(short tagCode, byte[] content) { @SuppressWarnings("unchecked") public static U get(Class tagClass, OptionalParameter[] parameters) { - for(OptionalParameter i: parameters) { - if(i.getClass() == tagClass) { - return (U)i; + if (parameters != null) { + for (OptionalParameter i : parameters) { + if (i.getClass() == tagClass) { + return (U) i; } + } } - logger.info("optional tag " + tagClass + " not found"); + logger.info("Optional Parameter Tag {} not found", tagClass); return null; } public static OptionalParameter get(short tag, OptionalParameter[] parameters) { - for(OptionalParameter i: parameters) { - if(i.tag == tag) { - return i; + if (parameters != null) { + for (OptionalParameter i : parameters) { + if (i.tag == tag) { + return i; } + } } - logger.info("optional tag " + tag + " not found"); + logger.info("Optional Parameter Tag {} not found", tag); return null; } } From f410bab0e71c2ca31927bb998e99922e5fc9f846 Mon Sep 17 00:00:00 2001 From: vharseko Date: Fri, 17 Jul 2015 15:59:06 +0300 Subject: [PATCH 053/212] upper password ro 256 (ampitel.ru) --- jsmpp/src/main/java/org/jsmpp/util/StringParameter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsmpp/src/main/java/org/jsmpp/util/StringParameter.java b/jsmpp/src/main/java/org/jsmpp/util/StringParameter.java index aad74ce..a34f01e 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/StringParameter.java +++ b/jsmpp/src/main/java/org/jsmpp/util/StringParameter.java @@ -32,7 +32,7 @@ public enum StringParameter { * password string parameter. */ //SMPP providers may be use long passwords over SMPP 3.4 standard (like t-sms.ru) - PASSWORD(StringType.C_OCTEC_STRING, 0, 32, true, SMPPConstant.STAT_ESME_RINVPASWD), + PASSWORD(StringType.C_OCTEC_STRING, 0, 256, true, SMPPConstant.STAT_ESME_RINVPASWD), /** * system_type string parameter. From 171054cf59440517466a0b274ca496b549b793cd Mon Sep 17 00:00:00 2001 From: nikolay_pavluchinskiy Date: Sun, 2 Aug 2015 14:55:46 +0300 Subject: [PATCH 054/212] Remove enquireLinkSender.join() during session.close() because this prevents normal closing of session and sessions hangs when smpp server is restarted --- .../java/org/jsmpp/session/AbstractSession.java | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java index 2065ab8..cfd7af6 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java @@ -210,19 +210,6 @@ public void close() { } } - // Make sure the enquireLinkThread doesn't wait for itself - if (Thread.currentThread() != enquireLinkSender) { - if (enquireLinkSender != null) { - while(enquireLinkSender.isAlive()) { - try { - enquireLinkSender.join(); - } catch (InterruptedException e) { - logger.warn("interrupted while waiting for enquireLinkSender thread to exit"); - } - } - } - } - logger.info("AbstractSession.close() done"); } From 788a4dcb88d8b7e851339e570b5de51f1224e937 Mon Sep 17 00:00:00 2001 From: Mykola Pavluchynskyi Date: Mon, 17 Aug 2015 08:28:38 +0300 Subject: [PATCH 055/212] Add support of sending messageId in DeliverSmResp, setting and returning this id via DeliverSm.id field If id is not set - previous behavior of DeliverSmResp, without message id --- jsmpp/src/main/java/org/jsmpp/DefaultPDUSender.java | 7 ++++--- jsmpp/src/main/java/org/jsmpp/PDUSender.java | 2 +- .../main/java/org/jsmpp/SynchronizedPDUSender.java | 4 ++-- jsmpp/src/main/java/org/jsmpp/bean/DeliverSm.java | 12 +++++++++++- .../jsmpp/session/DefaultSMPPClientOperation.java | 7 +++++-- .../main/java/org/jsmpp/session/ResponseHandler.java | 4 ++-- .../java/org/jsmpp/session/SMPPClientOperation.java | 3 ++- .../src/main/java/org/jsmpp/session/SMPPSession.java | 7 ++++--- .../org/jsmpp/session/state/SMPPSessionBoundRX.java | 4 ++-- .../main/java/org/jsmpp/util/DefaultComposer.java | 9 +++++---- jsmpp/src/main/java/org/jsmpp/util/PDUComposer.java | 2 +- 11 files changed, 39 insertions(+), 22 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/DefaultPDUSender.java b/jsmpp/src/main/java/org/jsmpp/DefaultPDUSender.java index 591b7f2..30fd8d3 100644 --- a/jsmpp/src/main/java/org/jsmpp/DefaultPDUSender.java +++ b/jsmpp/src/main/java/org/jsmpp/DefaultPDUSender.java @@ -297,11 +297,12 @@ public byte[] sendDeliverSm(OutputStream os, int sequenceNumber, /* * (non-Javadoc) * - * @see org.jsmpp.PDUSender#sendDeliverSmResp(java.io.OutputStream, int) + * @see org.jsmpp.PDUSender#sendDeliverSmResp(java.io.OutputStream, int, int, String) */ - public byte[] sendDeliverSmResp(OutputStream os, int commandStatus, int sequenceNumber) + @Override + public byte[] sendDeliverSmResp(OutputStream os, int commandStatus, int sequenceNumber, String messageId) throws IOException { - byte[] b = pduComposer.deliverSmResp(commandStatus, sequenceNumber); + byte[] b = pduComposer.deliverSmResp(commandStatus, sequenceNumber, messageId); writeAndFlush(os, b); return b; } diff --git a/jsmpp/src/main/java/org/jsmpp/PDUSender.java b/jsmpp/src/main/java/org/jsmpp/PDUSender.java index 1ebeed9..f2bc0fd 100644 --- a/jsmpp/src/main/java/org/jsmpp/PDUSender.java +++ b/jsmpp/src/main/java/org/jsmpp/PDUSender.java @@ -277,7 +277,7 @@ byte[] sendDeliverSm(OutputStream os, int sequenceNumber, * @return the composed bytes. * @throws IOException if there is an IO error occur. */ - byte[] sendDeliverSmResp(OutputStream os, int commandStatus, int sequenceNumber) + byte[] sendDeliverSmResp(OutputStream os, int commandStatus, int sequenceNumber, String messageId) throws IOException; /** diff --git a/jsmpp/src/main/java/org/jsmpp/SynchronizedPDUSender.java b/jsmpp/src/main/java/org/jsmpp/SynchronizedPDUSender.java index f609df7..0f40d48 100644 --- a/jsmpp/src/main/java/org/jsmpp/SynchronizedPDUSender.java +++ b/jsmpp/src/main/java/org/jsmpp/SynchronizedPDUSender.java @@ -272,10 +272,10 @@ public byte[] sendDeliverSm(OutputStream os, int sequenceNumber, } } - public byte[] sendDeliverSmResp(OutputStream os, int commandStatus, int sequenceNumber) + public byte[] sendDeliverSmResp(OutputStream os, int commandStatus, int sequenceNumber, String messageId) throws IOException { synchronized (os) { - return pduSender.sendDeliverSmResp(os, commandStatus, sequenceNumber); + return pduSender.sendDeliverSmResp(os, commandStatus, sequenceNumber, messageId); } } diff --git a/jsmpp/src/main/java/org/jsmpp/bean/DeliverSm.java b/jsmpp/src/main/java/org/jsmpp/bean/DeliverSm.java index 094d958..2da18f6 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/DeliverSm.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/DeliverSm.java @@ -22,7 +22,17 @@ * */ public class DeliverSm extends MessageRequest { - + + private String id; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + public DeliverSm() { super(); } diff --git a/jsmpp/src/main/java/org/jsmpp/session/DefaultSMPPClientOperation.java b/jsmpp/src/main/java/org/jsmpp/session/DefaultSMPPClientOperation.java index 2a6f111..f42e262 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/DefaultSMPPClientOperation.java +++ b/jsmpp/src/main/java/org/jsmpp/session/DefaultSMPPClientOperation.java @@ -166,8 +166,11 @@ public void replaceSm(String messageId, TypeOfNumber sourceAddrTon, executeSendCommand(replaceSmTask, getTransactionTimer()); } - public void deliverSmResp(int sequenceNumber) throws IOException { + @Override + public void deliverSmResp(int sequenceNumber, String messageId) throws IOException { pduSender().sendDeliverSmResp(connection().getOutputStream(), - 0, sequenceNumber); + 0, sequenceNumber, messageId); + } + } diff --git a/jsmpp/src/main/java/org/jsmpp/session/ResponseHandler.java b/jsmpp/src/main/java/org/jsmpp/session/ResponseHandler.java index 5ace3ec..a188aab 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/ResponseHandler.java +++ b/jsmpp/src/main/java/org/jsmpp/session/ResponseHandler.java @@ -46,7 +46,7 @@ void processDeliverSm(DeliverSm deliverSm) * @param sequenceNumber is the sequence number of original DELIVER_SM request. * @throws IOException if an IO error occur. */ - void sendDeliverSmResp(int commandStatus, int sequenceNumber) throws IOException; - + void sendDeliverSmResp(int commandStatus, int sequenceNumber, String messageId) throws IOException; + void processAlertNotification(AlertNotification alertNotification); } diff --git a/jsmpp/src/main/java/org/jsmpp/session/SMPPClientOperation.java b/jsmpp/src/main/java/org/jsmpp/session/SMPPClientOperation.java index ea6f9c7..44e0190 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/SMPPClientOperation.java +++ b/jsmpp/src/main/java/org/jsmpp/session/SMPPClientOperation.java @@ -88,5 +88,6 @@ void replaceSm(String messageId, TypeOfNumber sourceAddrTon, byte[] shortMessage) throws PDUException, ResponseTimeoutException, InvalidResponseException, NegativeResponseException, IOException; - void deliverSmResp(int sequenceNumber) throws IOException; + void deliverSmResp(int sequenceNumber, String messageId) throws IOException; + } diff --git a/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java b/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java index 886d735..acfb8a0 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java @@ -531,9 +531,10 @@ public PendingResponse removeSentItem(int sequenceNumber) { public void notifyUnbonded() { sessionContext.unbound(); } - - public void sendDeliverSmResp(int commandStatus, int sequenceNumber) throws IOException { - pduSender().sendDeliverSmResp(out, commandStatus, sequenceNumber); + + @Override + public void sendDeliverSmResp(int commandStatus, int sequenceNumber, String messageId) throws IOException { + pduSender().sendDeliverSmResp(out, commandStatus, sequenceNumber, messageId); logger.debug("deliver_sm_resp with seq_number " + sequenceNumber + " has been sent"); } diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionBoundRX.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionBoundRX.java index 591cef3..a659f0e 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionBoundRX.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionBoundRX.java @@ -107,14 +107,14 @@ static void processDeliverSm0(Command pduHeader, byte[] pdu, try { DeliverSm deliverSm = pduDecomposer.deliverSm(pdu); responseHandler.processDeliverSm(deliverSm); - responseHandler.sendDeliverSmResp(0, pduHeader.getSequenceNumber()); + responseHandler.sendDeliverSmResp(0, pduHeader.getSequenceNumber(), deliverSm.getId()); } catch (PDUStringException e) { logger.error("Failed decomposing deliver_sm", e); responseHandler.sendGenerickNack(e.getErrorCode(), pduHeader .getSequenceNumber()); } catch (ProcessRequestException e) { logger.error("Failed processing deliver_sm", e); - responseHandler.sendDeliverSmResp(e.getErrorCode(), pduHeader.getSequenceNumber()); + responseHandler.sendDeliverSmResp(e.getErrorCode(), pduHeader.getSequenceNumber(), null); } } diff --git a/jsmpp/src/main/java/org/jsmpp/util/DefaultComposer.java b/jsmpp/src/main/java/org/jsmpp/util/DefaultComposer.java index b670efb..72e81a8 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/DefaultComposer.java +++ b/jsmpp/src/main/java/org/jsmpp/util/DefaultComposer.java @@ -352,12 +352,13 @@ public byte[] deliverSm(int sequenceNumber, String serviceType, /* * (non-Javadoc) * - * @see org.jsmpp.util.PDUComposer#deliverSmResp(int) + * @see org.jsmpp.util.PDUComposer#deliverSmResp(int, int, String) */ - public byte[] deliverSmResp(int commandStatus, int sequenceNumber) { + @Override + public byte[] deliverSmResp(int commandStatus, int sequenceNumber, String messageId) { PDUByteBuffer buf = new PDUByteBuffer(SMPPConstant.CID_DELIVER_SM_RESP, - commandStatus, sequenceNumber); - buf.append((String)null); + commandStatus, sequenceNumber); + buf.append(messageId); return buf.toBytes(); } diff --git a/jsmpp/src/main/java/org/jsmpp/util/PDUComposer.java b/jsmpp/src/main/java/org/jsmpp/util/PDUComposer.java index 23c8059..ee9f2dd 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/PDUComposer.java +++ b/jsmpp/src/main/java/org/jsmpp/util/PDUComposer.java @@ -118,7 +118,7 @@ byte[] deliverSm(int sequenceNumber, String serviceType, byte registeredDelivery, byte dataCoding, byte[] shortMessage, OptionalParameter... optionalParameters) throws PDUStringException; - byte[] deliverSmResp(int commandStatus, int sequenceNumber); + byte[] deliverSmResp(int commandStatus, int sequenceNumber, String messageId); /** * Compose data short message (data_sm) PDU. From efcbcc62b6992ab242591b1dec3ed989f228e92a Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Thu, 20 Aug 2015 12:14:46 +0200 Subject: [PATCH 056/212] Fixed some logging --- .../main/java/org/jsmpp/examples/SMPPServerSimulator.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java index 7895bd5..ef9fc16 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java @@ -150,7 +150,7 @@ public WaitBindTask(SMPPServerSession serverSession) { public void run() { try { BindRequest bindRequest = serverSession.waitForBind(1000); - logger.info("Accepting bind for session {}, interface version {}", serverSession.getSessionId()); + logger.info("Accepting bind for session {}, interface version {}", serverSession.getSessionId(), bindRequest.getInterfaceVersion()); try { bindRequest.accept("sys", InterfaceVersion.IF_34); } catch (PDUStringException e) { @@ -234,7 +234,7 @@ public void run() { } SessionState state = session.getSessionState(); if (!state.isReceivable()) { - logger.debug("Not sending delivery receipt for message id " + messageId + " since session state is " + state); + logger.debug("Not sending delivery receipt for message id {} since session state is {}", messageId, state); return; } String stringValue = Integer.valueOf(messageId.getValue(), 16).toString(); @@ -255,7 +255,7 @@ public void run() { new RegisteredDelivery(0), DataCodings.ZERO, delRec.toString().getBytes()); - logger.debug("Sending delivery receipt for message id " + messageId + ":" + stringValue); + logger.debug("Sending delivery receipt for message id {}: {}", messageId, stringValue); } catch (Exception e) { logger.error("Failed sending delivery_receipt for message id " + messageId + ":" + stringValue, e); } From 6c56e53d728d274fb9be2b635c457a2ec3159abd Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Thu, 20 Aug 2015 15:35:07 +0200 Subject: [PATCH 057/212] Added SMPP 5.0 message states. --- jsmpp/src/main/java/org/jsmpp/bean/MessageState.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/MessageState.java b/jsmpp/src/main/java/org/jsmpp/bean/MessageState.java index 0867d03..47909b2 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/MessageState.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/MessageState.java @@ -21,6 +21,10 @@ * */ public enum MessageState { + /** + * The message is in scheduled state. + */ + SCHEDULED((byte) 0x00), /** * The message is in enroute state. */ @@ -52,7 +56,11 @@ public enum MessageState { /** * Message is in rejected state. */ - REJECTED((byte) 0x08); + REJECTED((byte) 0x08), + /** + * Message is in skipped state. + */ + SKIPPED((byte) 0x09); private final byte value; @@ -71,6 +79,6 @@ public static MessageState valueOf(byte value) { } throw new IllegalArgumentException( - "No enum const MessageStatte with value " + value); + "No enum const MessageState with value " + value); } } From b772cc80fc6f65031bc0750ada309c44fa8f2631 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Thu, 20 Aug 2015 15:53:53 +0200 Subject: [PATCH 058/212] Fixed typo. --- .../java/org/jsmpp/bean/DeliveryReceipt.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java b/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java index 94d092a..f6e35b1 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java @@ -55,27 +55,27 @@ public class DeliveryReceipt { public DeliveryReceipt() { } - public DeliveryReceipt(String formattedDelieryReceipt) + public DeliveryReceipt(String formattedDeliveryReceipt) throws InvalidDeliveryReceiptException { /* * id:IIIIIIIIII sub:SSS dlvrd:DDD submit date:YYMMDDhhmm done * date:YYMMDDhhmm stat:DDDDDDD err:E Text: .......... */ try { - id = getDeliveryReceiptValue(DeliveryReceipt.DELREC_ID, formattedDelieryReceipt); + id = getDeliveryReceiptValue(DeliveryReceipt.DELREC_ID, formattedDeliveryReceipt); submitted = Integer.parseInt(getDeliveryReceiptValue( - DeliveryReceipt.DELREC_SUB, formattedDelieryReceipt)); + DeliveryReceipt.DELREC_SUB, formattedDeliveryReceipt)); delivered = Integer.parseInt(getDeliveryReceiptValue( - DeliveryReceipt.DELREC_DLVRD, formattedDelieryReceipt)); + DeliveryReceipt.DELREC_DLVRD, formattedDeliveryReceipt)); submitDate = string2Date(getDeliveryReceiptValue( - DeliveryReceipt.DELREC_SUBMIT_DATE, formattedDelieryReceipt)); + DeliveryReceipt.DELREC_SUBMIT_DATE, formattedDeliveryReceipt)); doneDate = string2Date(getDeliveryReceiptValue( - DeliveryReceipt.DELREC_DONE_DATE, formattedDelieryReceipt)); + DeliveryReceipt.DELREC_DONE_DATE, formattedDeliveryReceipt)); finalStatus = DeliveryReceiptState .getByName(getDeliveryReceiptValue( - DeliveryReceipt.DELREC_STAT, formattedDelieryReceipt)); - error = getDeliveryReceiptValue(DeliveryReceipt.DELREC_ERR, formattedDelieryReceipt); - text = getDeliveryReceiptTextValue(formattedDelieryReceipt); + DeliveryReceipt.DELREC_STAT, formattedDeliveryReceipt)); + error = getDeliveryReceiptValue(DeliveryReceipt.DELREC_ERR, formattedDeliveryReceipt); + text = getDeliveryReceiptTextValue(formattedDeliveryReceipt); } catch (Exception e) { throw new InvalidDeliveryReceiptException( "There is an error found when parsing delivery receipt", e); From c053fe68296b64ff0eafba8616d6f62ea60d758b Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Thu, 1 Oct 2015 11:12:27 +0200 Subject: [PATCH 059/212] Fixed a typo --- .../java/org/jsmpp/bean/DefaultDeliveryReceiptStripper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/DefaultDeliveryReceiptStripper.java b/jsmpp/src/main/java/org/jsmpp/bean/DefaultDeliveryReceiptStripper.java index 08e9f82..0d851e4 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/DefaultDeliveryReceiptStripper.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/DefaultDeliveryReceiptStripper.java @@ -35,7 +35,7 @@ public DeliveryReceipt strip(DeliverSm deliverSm) throws InvalidDeliveryReceiptE if (MessageType.SMSC_DEL_RECEIPT.containedIn(deliverSm.getEsmClass())) { return DefaultDecomposer.getInstance().deliveryReceipt(deliverSm.getShortMessage()); } else { - throw new InvalidDeliveryReceiptException("deliver_sm is not a Delivery Receipt since ems_class value = " + deliverSm.getEsmClass()); + throw new InvalidDeliveryReceiptException("deliver_sm is not a Delivery Receipt since esm_class value = " + deliverSm.getEsmClass()); } } From 243e7efd0bda95c831de83bbc471048559ef14f2 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Thu, 1 Oct 2015 11:30:03 +0200 Subject: [PATCH 060/212] Prepare for 2.2.2 release. --- CHANGES.txt | 20 +++++++++++++++----- jsmpp-examples/pom.xml | 2 +- jsmpp/pom.xml | 2 +- pom.xml | 5 ++--- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index bee1cd4..a1016f4 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -36,18 +36,16 @@ Changes: 2.0 beta 6 - Change the max length of short message to 254, referring to SMPP 3.4 - Previously using 255 (taken from SMPP 5.0) + Previously using 255 (taken from SMPP 5.0) 2.0.1 -- Bug fix, MessageReceiverListener should be subclass of - GenericMessageReceiverListener +- Bug fix, MessageReceiverListener should be subclass of GenericMessageReceiverListener 2.1.0 - set connection timeout when binding - provide source (the session) for onAcceptDataSm - use StrictBufferedInputStream - 2.2.0 - New DataCoding API. Remove the old class (since I can't make backward compatibility) @@ -57,4 +55,16 @@ Changes: - Expose remote InetAddress on server side API via SMPPServerSession Add new method: InetAddress SMPPServerSession#getInetAddress() - Ensure command execution is in valid state. Checking done on local side (remote side do the checking also). -- Make Command and it's subclasses serializeable \ No newline at end of file +- Make Command and it's subclasses serializable + +2.2.1 +- Fix examples +- Use StrictBufferedInputStream for better performance +- Provide source for onAcceptDataSm + +2.2.2 +- Fixed some logging +- Added SMPP 5.0 message states +- Fixed Null pointer exception when OptionaParameters are emtpy in a BindResp +- Fixed invalid command lengths (<4) throws an IndexOutOfBoundsException +- Added RelativeTimeFormatter \ No newline at end of file diff --git a/jsmpp-examples/pom.xml b/jsmpp-examples/pom.xml index f96d486..1c18e3f 100644 --- a/jsmpp-examples/pom.xml +++ b/jsmpp-examples/pom.xml @@ -3,7 +3,7 @@ jsmpp-pom org.jsmpp - 2.2.1 + 2.2.2 4.0.0 diff --git a/jsmpp/pom.xml b/jsmpp/pom.xml index 519b98f..d44eac5 100644 --- a/jsmpp/pom.xml +++ b/jsmpp/pom.xml @@ -3,7 +3,7 @@ org.jsmpp jsmpp-pom - 2.2.1 + 2.2.2 4.0.0 bundle diff --git a/pom.xml b/pom.xml index 406b572..4137b65 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.jsmpp jsmpp-pom - 2.2.1 + 2.2.2 pom jSMPP @@ -49,7 +49,7 @@ 1.7.12 1.2.17 4.12 - 6.8.21 + 6.9.6 1.10 git.properties @@ -260,7 +260,6 @@ - https://github.com/opentelecoms-org/jsmpp scm:git:ssh://git@github.com:opentelecoms-org/jsmpp.git From cd869bc07611c2e9cf6fa6f73fd48349ce970b6b Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Thu, 1 Oct 2015 11:54:37 +0200 Subject: [PATCH 061/212] Remain JDK 1.6 compatible. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4137b65..c70f635 100644 --- a/pom.xml +++ b/pom.xml @@ -49,7 +49,7 @@ 1.7.12 1.2.17 4.12 - 6.9.6 + 6.8.21 1.10 git.properties From b77092a680a664c1f3828b4178e30f789365ffa6 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 4 Oct 2015 13:31:39 +0200 Subject: [PATCH 062/212] Leave thread join in the code, after merge. Rewrite some logging. --- .../jsmpp/session/AbstractSMPPOperation.java | 44 ++++++++--------- .../org/jsmpp/session/AbstractSession.java | 49 ++++++++++++------- 2 files changed, 53 insertions(+), 40 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/AbstractSMPPOperation.java b/jsmpp/src/main/java/org/jsmpp/session/AbstractSMPPOperation.java index cd314bf..0fec782 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/AbstractSMPPOperation.java +++ b/jsmpp/src/main/java/org/jsmpp/session/AbstractSMPPOperation.java @@ -44,37 +44,37 @@ */ public abstract class AbstractSMPPOperation implements SMPPOperation { private static final Logger logger = LoggerFactory.getLogger(AbstractSMPPOperation.class); - + private final Hashtable> pendingResponse = new Hashtable>(); private final Sequence sequence = new Sequence(1); private final PDUSender pduSender; private final Connection connection; private long transactionTimer = 2000; - + public AbstractSMPPOperation(Connection connection, PDUSender pduSender) { this.connection = connection; this.pduSender = pduSender; } - + protected PDUSender pduSender() { return pduSender; } - + protected Connection connection() { return connection; } - + public void setTransactionTimer(long transactionTimer) { this.transactionTimer = transactionTimer; } - + public long getTransactionTimer() { return transactionTimer; } - + /** * Execute send command command task. - * + * * @param task is the task. * @param timeout is the timeout in millisecond. * @return the command response. @@ -87,7 +87,7 @@ public long getTransactionTimer() { protected Command executeSendCommand(SendCommandTask task, long timeout) throws PDUException, ResponseTimeoutException, InvalidResponseException, NegativeResponseException, IOException { - + int seqNum = sequence.nextValue(); PendingResponse pendingResp = new PendingResponse(timeout); pendingResponse.put(seqNum, pendingResp); @@ -98,29 +98,29 @@ protected Command executeSendCommand(SendCommandTask task, long timeout) pendingResponse.remove(seqNum); throw e; } - + try { pendingResp.waitDone(); - logger.debug(task.getCommandName() + " response received"); + logger.debug("{} response received", task.getCommandName() ); } catch (ResponseTimeoutException e) { pendingResponse.remove(seqNum); - logger.debug("Response timeout for " + task.getCommandName() + " with sessionIdSequence number " + seqNum); + logger.debug("Response timeout for {} with sessionIdSequence number {}", task.getCommandName(), seqNum); throw e; } catch (InvalidResponseException e) { pendingResponse.remove(seqNum); throw e; } - + Command resp = pendingResp.getResponse(); validateResponse(resp); return resp; - + } - + /** * Validate the response, the command_status should be 0 otherwise will * throw {@link NegativeResponseException}. - * + * * @param response is the response. * @throws NegativeResponseException if the command_status value is not zero. */ @@ -129,10 +129,10 @@ private static void validateResponse(Command response) throws NegativeResponseEx throw new NegativeResponseException(response.getCommandStatus()); } } - + public void unbind() throws ResponseTimeoutException, InvalidResponseException, IOException { UnbindCommandTask task = new UnbindCommandTask(pduSender); - + try { executeSendCommand(task, transactionTimer); } catch (PDUException e) { @@ -147,7 +147,7 @@ public void unbind() throws ResponseTimeoutException, InvalidResponseException, public void unbindResp(int sequenceNumber) throws IOException { pduSender.sendUnbindResp(connection().getOutputStream(), SMPPConstant.STAT_ESME_ROK, sequenceNumber); } - + public DataSmResult dataSm(String serviceType, TypeOfNumber sourceAddrTon, NumberingPlanIndicator sourceAddrNpi, String sourceAddr, TypeOfNumber destAddrTon, NumberingPlanIndicator destAddrNpi, @@ -156,14 +156,14 @@ public DataSmResult dataSm(String serviceType, TypeOfNumber sourceAddrTon, OptionalParameter... optionalParameters) throws PDUException, ResponseTimeoutException, InvalidResponseException, NegativeResponseException, IOException { - + DataSmCommandTask task = new DataSmCommandTask(pduSender, serviceType, sourceAddrTon, sourceAddrNpi, sourceAddr, destAddrTon, destAddrNpi, destinationAddr, esmClass, registeredDelivery, dataCoding, optionalParameters); - + DataSmResp resp = (DataSmResp)executeSendCommand(task, getTransactionTimer()); - + return new DataSmResult(resp.getMessageId(), resp.getOptionalParameters()); } diff --git a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java index cfd7af6..11d271f 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java @@ -115,17 +115,17 @@ public SessionState getSessionState() { } protected synchronized boolean isReadPdu() { - return getSessionState().isBound() || getSessionState().equals(SessionState.OPEN); - } + return getSessionState().isBound() || getSessionState().equals(SessionState.OPEN); + } - public void addSessionStateListener(SessionStateListener l) { - if (l != null) { - sessionContext().addSessionStateListener(l); + public void addSessionStateListener(SessionStateListener listener) { + if (listener != null) { + sessionContext().addSessionStateListener(listener); } } - public void removeSessionStateListener(SessionStateListener l) { - sessionContext().removeSessionStateListener(l); + public void removeSessionStateListener(SessionStateListener listener) { + sessionContext().removeSessionStateListener(listener); } public long getLastActivityTimestamp() { @@ -143,7 +143,7 @@ public long getLastActivityTimestamp() { public void setPduProcessorDegree(int pduProcessorDegree) throws IllegalStateException { if (!getSessionState().equals(SessionState.CLOSED)) { throw new IllegalStateException( - "Cannot set pdu processor degree since the pdu dispatcher thread already created."); + "Cannot set PDU processor degree since the PDU dispatcher thread already created."); } this.pduProcessorDegree = pduProcessorDegree; } @@ -200,7 +200,7 @@ public DataSmResult dataShortMessage(String serviceType, } public void close() { - logger.info("AbstractSession.close() called"); + logger.debug("AbstractSession.close() called"); SessionContext ctx = sessionContext(); if (!ctx.getSessionState().equals(SessionState.CLOSED)) { ctx.close(); @@ -210,7 +210,20 @@ public void close() { } } - logger.info("AbstractSession.close() done"); + // Make sure the enquireLinkThread doesn't wait for itself + if (Thread.currentThread() != enquireLinkSender) { + if (enquireLinkSender != null) { + while(enquireLinkSender.isAlive()) { + try { + enquireLinkSender.join(); + } catch (InterruptedException e) { + logger.warn("interrupted while waiting for enquireLinkSender thread to exit"); + } + } + } + } + + logger.debug("AbstractSession.close() done"); } /** @@ -220,18 +233,18 @@ public void close() { * @param response is the response. * @throws NegativeResponseException if the command_status value is not zero. */ - private static void validateResponse(Command response) throws NegativeResponseException { + private static void validateResponse(final Command response) throws NegativeResponseException { if (response.getCommandStatus() != SMPPConstant.STAT_ESME_ROK) { throw new NegativeResponseException(response.getCommandStatus()); } } - protected DataSmResult fireAcceptDataSm(DataSm dataSm) throws ProcessRequestException { + protected DataSmResult fireAcceptDataSm(final DataSm dataSm) throws ProcessRequestException { GenericMessageReceiverListener messageReceiverListener = messageReceiverListener(); if (messageReceiverListener != null) { return messageReceiverListener.onAcceptDataSm(dataSm, this); } else { - throw new ProcessRequestException("MessageReceveiverListener hasn't been set yet", SMPPConstant.STAT_ESME_RX_R_APPN); + throw new ProcessRequestException("MessageReceiverListener hasn't been set yet", SMPPConstant.STAT_ESME_RX_R_APPN); } } @@ -270,7 +283,7 @@ protected Command executeSendCommand(SendCommandTask task, long timeout) try { pendingResp.waitDone(); - logger.debug(task.getCommandName() + " response received"); + logger.debug("{} response received", task.getCommandName()); } catch (ResponseTimeoutException e) { pendingResponse.remove(seqNum); throw new ResponseTimeoutException("No response after waiting for " @@ -327,14 +340,14 @@ private void unbind() throws ResponseTimeoutException, logger.warn("PDU String should be always valid", e); } catch (NegativeResponseException e) { // ignore the negative response - logger.warn("Receive non-ok command_status (" + e.getCommandStatus() + ") for unbind_resp"); + logger.warn("Receive non-ok command_status ({}) for unbind_resp", e.getCommandStatus()); } } public void unbindAndClose() { - logger.info("unbindAndClose() called"); + logger.debug("unbindAndClose() called"); if (sessionContext().getSessionState().isBound()) { try { unbind(); @@ -343,7 +356,7 @@ public void unbindAndClose() { } catch (InvalidResponseException e) { logger.error("Receive invalid unbind response", e); } catch (IOException e) { - logger.error("IO error found ", e); + logger.error("IO error found", e); } } close(); @@ -430,7 +443,7 @@ public void run() { close(); } } - logger.info("EnquireLinkSender stop"); + logger.debug("EnquireLinkSender stop"); } /** From 38672be6b3bcb82be08887bc9fec261678253652 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 4 Oct 2015 14:12:08 +0200 Subject: [PATCH 063/212] Use StringBuilder. --- jsmpp/src/main/java/org/jsmpp/util/HexUtil.java | 14 ++++++-------- jsmpp/src/main/java/org/jsmpp/util/IntUtil.java | 15 ++++++++------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/util/HexUtil.java b/jsmpp/src/main/java/org/jsmpp/util/HexUtil.java index cbbdee9..e777fe9 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/HexUtil.java +++ b/jsmpp/src/main/java/org/jsmpp/util/HexUtil.java @@ -49,7 +49,6 @@ public static String conventBytesToHexString(byte[] data) { return convertBytesToHexString(data, 0, data.length); } - // /** * Convert bytes to hex string value (using Big-Endian rule). * @@ -62,15 +61,14 @@ public static String convertBytesToHexString(byte[] data, int offset, int length) { return convertBytesToHexString(data, offset, length, ""); } - public static String convertBytesToHexString(byte[] data, int offset, - int length, String byteDelimiter) { - StringBuffer sBuf = new StringBuffer((length-offset)*(2+byteDelimiter.length())); + public static String convertBytesToHexString(byte[] data, int offset, int length, String byteDelimiter) { + final StringBuilder stringBuilder = new StringBuilder((length-offset)*(2+byteDelimiter.length())); for (int i = offset; i < length; i++) { - sBuf.append(hexChar[(data[i] >> 4) & 0xf]); - sBuf.append(hexChar[data[i] & 0xf]); - sBuf.append(byteDelimiter); + stringBuilder.append(hexChar[(data[i] >> 4) & 0x0f]); + stringBuilder.append(hexChar[data[i] & 0x0f]); + stringBuilder.append(byteDelimiter); } - return sBuf.toString(); + return stringBuilder.toString(); } /** diff --git a/jsmpp/src/main/java/org/jsmpp/util/IntUtil.java b/jsmpp/src/main/java/org/jsmpp/util/IntUtil.java index 6d98282..b642752 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/IntUtil.java +++ b/jsmpp/src/main/java/org/jsmpp/util/IntUtil.java @@ -24,19 +24,20 @@ */ public class IntUtil { - public static String to4DigitString(int value) { + public static String to4DigitString(final int value) { return toNDigitString(value, 4); } - public static String to2DigitString(int value) { + public static String to2DigitString(final int value) { return toNDigitString(value, 2); } - public static String toNDigitString(int value, int digitLength) { - StringBuffer sBuf = new StringBuffer(String.valueOf(value)); - while (sBuf.length() < digitLength) - sBuf.insert(0, "0"); - return sBuf.toString(); + public static String toNDigitString(final int value, final int digitLength) { + StringBuilder stringBuilder = new StringBuilder(String.valueOf(value)); + while (stringBuilder.length() < digitLength) { + stringBuilder.insert(0, "0"); + } + return stringBuilder.toString(); } public static final String toHexString(int value) { From 3936f27f3557f22ce7dedf54341fe8c1d5fb46b3 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 4 Oct 2015 14:20:43 +0200 Subject: [PATCH 064/212] Format log to use SLF4J formatting. --- .../connection/socket/SocketConnection.java | 2 +- .../state/AbstractGenericSMPPSessionBound.java | 9 ++++----- .../session/state/SMPPServerSessionBoundRX.java | 3 +-- .../session/state/SMPPServerSessionBoundTX.java | 6 ++++-- .../jsmpp/session/state/SMPPSessionOpen.java | 17 ++++++++--------- .../java/org/jsmpp/util/DefaultDecomposer.java | 10 ++++------ 6 files changed, 22 insertions(+), 25 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/connection/socket/SocketConnection.java b/jsmpp/src/main/java/org/jsmpp/session/connection/socket/SocketConnection.java index cdb403b..c006be2 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/connection/socket/SocketConnection.java +++ b/jsmpp/src/main/java/org/jsmpp/session/connection/socket/SocketConnection.java @@ -51,7 +51,7 @@ public void close() { try { socket.close(); } catch (IOException e) { - logger.warn("Suppressing IOException while closing socket: " + e); + logger.warn("Suppressing IOException while closing socket", e); } } diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/AbstractGenericSMPPSessionBound.java b/jsmpp/src/main/java/org/jsmpp/session/state/AbstractGenericSMPPSessionBound.java index ba8d7b0..c8b17db 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/AbstractGenericSMPPSessionBound.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/AbstractGenericSMPPSessionBound.java @@ -55,7 +55,7 @@ public void processEnquireLinkResp(Command pduHeader, byte[] pdu, EnquireLinkResp resp = pduDecomposer.enquireLinkResp(pdu); pendingResp.done(resp); } else { - logger.error("No request found for " + pduHeader); + logger.error("No request found for {}", pduHeader); } } @@ -77,7 +77,7 @@ public void processUnbindResp(Command pduHeader, byte[] pdu, UnbindResp resp = pduDecomposer.unbindResp(pdu); pendingResp.done(resp); } else { - logger.error("No request found for " + pduHeader); + logger.error("No request found for {}", pduHeader); } } @@ -107,7 +107,7 @@ public void processDataSm(Command pduHeader, byte[] pdu, try { DataSm dataSm = pduDecomposer.dataSm(pdu); DataSmResult dataSmResult = responseHandler.processDataSm(dataSm); - logger.debug("Sending response with message_id " + dataSmResult.getMessageId() + " for request with sequence_number " + pduHeader.getSequenceNumber()); + logger.debug("Sending response with message_id {} for request with sequence_number {}", dataSmResult.getMessageId(), pduHeader.getSequenceNumber()); responseHandler.sendDataSmResp(dataSmResult, pduHeader.getSequenceNumber()); } catch (PDUStringException e) { responseHandler.sendNegativeResponse(pduHeader.getCommandId(), e.getErrorCode(), pduHeader.getSequenceNumber()); @@ -131,8 +131,7 @@ public void processDataSmResp(Command pduHeader, byte[] pdu, .getSequenceNumber()); } } else { - logger.warn("No request with sequence number " - + pduHeader.getSequenceNumber() + " found"); + logger.warn("No request with sequence number {} found", pduHeader.getSequenceNumber()); } } } diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionBoundRX.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionBoundRX.java index f7b0cd8..160b9b5 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionBoundRX.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionBoundRX.java @@ -84,8 +84,7 @@ static final void processDeliverSmResp0(Command pduHeader, byte[] pdu, DeliverSmResp resp = pduDecomposer.deliverSmResp(pdu); pendingResp.done(resp); } else { - logger.warn("No request with sequence number " - + pduHeader.getSequenceNumber() + " found"); + logger.warn("No request with sequence number {} found", pduHeader.getSequenceNumber()); } } diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionBoundTX.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionBoundTX.java index 9bf23a2..cd2dd5b 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionBoundTX.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionBoundTX.java @@ -58,7 +58,8 @@ public void processSubmitSm(Command pduHeader, byte[] pdu, try { SubmitSm submitSm = pduDecomposer.submitSm(pdu); MessageId messageId = responseHandler.processSubmitSm(submitSm); - logger.debug("Sending response with message_id " + messageId + " for request with sequence_number " + pduHeader.getSequenceNumber()); + logger.debug("Sending response with message_id {} for request with sequence_number {}", + messageId, pduHeader.getSequenceNumber()); responseHandler.sendSubmitSmResponse(messageId, pduHeader.getSequenceNumber()); } catch (PDUStringException e) { responseHandler.sendNegativeResponse(pduHeader.getCommandId(), e.getErrorCode(), pduHeader.getSequenceNumber()); @@ -72,7 +73,8 @@ public void processSubmitMulti(Command pduHeader, byte[] pdu, try { SubmitMulti submitMulti = pduDecomposer.submitMulti(pdu); SubmitMultiResult result = responseHandler.processSubmitMulti(submitMulti); - logger.debug("Sending response with message_id " + result.getMessageId() + " for request with sequence_number " + pduHeader.getSequenceNumber()); + logger.debug("Sending response with message_id {} for request with sequence_number {}", + result.getMessageId(), pduHeader.getSequenceNumber()); responseHandler.sendSubmitMultiResponse(result, pduHeader.getSequenceNumber()); } catch (PDUStringException e) { responseHandler.sendNegativeResponse(pduHeader.getCommandId(), e.getErrorCode(), pduHeader.getSequenceNumber()); diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionOpen.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionOpen.java index f00154d..bab8f2c 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionOpen.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionOpen.java @@ -54,11 +54,11 @@ public void processBindResp(Command pduHeader, byte[] pdu, .removeSentItem(pduHeader.getSequenceNumber()); if (pendingResp != null) { try { - logger.debug("Bind Response header (" - + pduHeader.getCommandLength() + ", " - + pduHeader.getCommandIdAsHex() + ", " - + IntUtil.toHexString(pduHeader.getCommandStatus()) - + ", " + pduHeader.getSequenceNumber() + ")"); + logger.debug("Bind Response header ({}, {}, {}, {})", + pduHeader.getCommandLength(), + pduHeader.getCommandIdAsHex(), + IntUtil.toHexString(pduHeader.getCommandStatus()), + pduHeader.getSequenceNumber()); BindResp resp = pduDecomposer.bindResp(pdu); pendingResp.done(resp); } catch (PDUStringException e) { @@ -71,11 +71,10 @@ public void processBindResp(Command pduHeader, byte[] pdu, message, e)); } } else { - logger.error("No request with sequence number " - + pduHeader.getSequenceNumber() + " found"); + logger.error("No request with sequence number {} found", pduHeader.getSequenceNumber() ); responseHandler.sendGenerickNack( - SMPPConstant.STAT_ESME_RINVDFTMSGID, pduHeader - .getSequenceNumber()); + SMPPConstant.STAT_ESME_RINVDFTMSGID, pduHeader + .getSequenceNumber()); } } diff --git a/jsmpp/src/main/java/org/jsmpp/util/DefaultDecomposer.java b/jsmpp/src/main/java/org/jsmpp/util/DefaultDecomposer.java index 1edeb1a..5d89c89 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/DefaultDecomposer.java +++ b/jsmpp/src/main/java/org/jsmpp/util/DefaultDecomposer.java @@ -64,8 +64,7 @@ * */ public class DefaultDecomposer implements PDUDecomposer { - private static final Logger logger = LoggerFactory - .getLogger(DefaultDecomposer.class); + private static final Logger logger = LoggerFactory.getLogger(DefaultDecomposer.class); private static final PDUDecomposer instance = new DefaultDecomposer(); public static final PDUDecomposer getInstance() { @@ -513,7 +512,7 @@ public SubmitMulti submitMulti(byte[] data) throws PDUStringException, } else if (flag == Flag.DISTRIBUTION_LIST.getValue()) { destAddresses[i] = new DistributionList(reader.readCString()); } else { - logger.warn("Unknown destination address flag: " + flag); + logger.warn("Unknown destination address flag: {}", flag); } } req.setDestAddresses(destAddresses); @@ -634,9 +633,8 @@ private static void assignHeader(Command pdu, SequentialBytesReader seqBytesReader) { int commandLength = seqBytesReader.readInt(); if (seqBytesReader.getBytes().length != commandLength) - logger.error("SYSTEM BUGS, the command_length (" + commandLength - + ") not equals with the byte array length (" - + seqBytesReader.getBytes().length + ")"); + logger.error("SYSTEM BUGS, the command_length ({}) not equals with the byte array length ({})", + commandLength, seqBytesReader.getBytes().length); pdu.setCommandLength(commandLength); pdu.setCommandId(seqBytesReader.readInt()); pdu.setCommandStatus(seqBytesReader.readInt()); From 7978a34116dbda20ee8df953837dda9c88632a11 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 4 Oct 2015 14:45:08 +0200 Subject: [PATCH 065/212] Format log to use SLF4J formatting. --- .../java/org/jsmpp/session/SMPPSession.java | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java b/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java index acfb8a0..71c5c41 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java @@ -240,7 +240,7 @@ public String connectAndBind(String host, int port, return smscSystemId; } catch (PDUException e) { logger.error("Failed sending bind command", e); - throw new IOException("Failed sending bind since some string parameter area invalid : " + e.getMessage(), e); + throw new IOException("Failed sending bind since some string parameter area invalid: " + e.getMessage(), e); } catch (NegativeResponseException e) { String message = "Receive negative bind response"; logger.error(message, e); @@ -252,12 +252,12 @@ public String connectAndBind(String host, int port, close(); throw new IOException(message + ": " + e.getMessage(), e); } catch (ResponseTimeoutException e) { - String message = "Waiting bind response take time to long"; + String message = "Waiting bind response take time too long"; logger.error(message, e); close(); throw new IOException(message + ": " + e.getMessage(), e); } catch (IOException e) { - logger.error("IO Error occur", e); + logger.error("IO error occurred", e); close(); throw e; } @@ -459,10 +459,10 @@ protected void finalize() throws Throwable { private void fireAcceptDeliverSm(DeliverSm deliverSm) throws ProcessRequestException { if (messageReceiverListener != null) { messageReceiverListener.onAcceptDeliverSm(deliverSm); - } else { - logger.warn("Receive deliver_sm but MessageReceiverListener is null. Short message = " + new String(deliverSm.getShortMessage())); + } else { + logger.warn("Receive deliver_sm but MessageReceiverListener is null. Short message = {}", new String(deliverSm.getShortMessage())); throw new ProcessRequestException("No message receiver listener registered", SMPPConstant.STAT_ESME_RX_T_APPN); - } + } } private void fireAcceptAlertNotification(AlertNotification alertNotification) { @@ -481,7 +481,7 @@ public void processDeliverSm(DeliverSm deliverSm) throws ProcessRequestException } catch(ProcessRequestException e) { throw e; } catch(Exception e) { - String msg = "Invalid runtime exception thrown when processing DeliverSm"; + String msg = "Invalid runtime exception thrown when processing deliver_sm"; logger.error(msg, e); throw new ProcessRequestException(msg, SMPPConstant.STAT_ESME_RX_T_APPN); } @@ -494,7 +494,7 @@ public DataSmResult processDataSm(DataSm dataSm) } catch(ProcessRequestException e) { throw e; } catch(Exception e) { - String msg = "Invalid runtime exception thrown when processing DataSm"; + String msg = "Invalid runtime exception thrown when processing data_sm"; logger.error(msg, e); throw new ProcessRequestException(msg, SMPPConstant.STAT_ESME_RX_T_APPN); } @@ -504,8 +504,7 @@ public void processAlertNotification(AlertNotification alertNotification) { try { fireAcceptAlertNotification(alertNotification); } catch(Exception e) { - String msg = "Invalid runtime exception thrown when processing AlertSm"; - logger.error(msg, e); + logger.error("Invalid runtime exception thrown when processing alert_sm", e); } } @@ -535,7 +534,7 @@ public void notifyUnbonded() { @Override public void sendDeliverSmResp(int commandStatus, int sequenceNumber, String messageId) throws IOException { pduSender().sendDeliverSmResp(out, commandStatus, sequenceNumber, messageId); - logger.debug("deliver_sm_resp with seq_number " + sequenceNumber + " has been sent"); + logger.debug("deliver_sm_resp with seq_number {} has been sent", sequenceNumber); } public void sendEnquireLinkResp(int sequenceNumber) throws IOException { From 552631cd96d9969bf7e414ba508f03fb9a186b2d Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 4 Oct 2015 22:38:48 +0200 Subject: [PATCH 066/212] Used slf4j formatting in logging --- .../main/java/org/jsmpp/examples/StressClient.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/StressClient.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/StressClient.java index 907cd7c..d2b8f0c 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/StressClient.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/StressClient.java @@ -86,7 +86,7 @@ public class StressClient implements Runnable { private String password; private String sourceAddr; private String destinationAddr; - + public StressClient(int id, String host, int port, int bulkSize, String systemId, String password, String sourceAddr, String destinationAddr, long transactionTimer, @@ -114,14 +114,14 @@ public void run() { smppSession.connectAndBind(host, port, BindType.BIND_TRX, systemId, password, "cln", TypeOfNumber.UNKNOWN, NumberingPlanIndicator.UNKNOWN, null); - logger.info("Bound to " + host + ":" + port); + logger.info("Bound to {}:{}", host, port); } catch (IOException e) { logger.error("Failed initialize connection or bind", e); return; } new TrafficWatcherThread().start(); - - logger.info("Starting send " + bulkSize + " bulk message..."); + + logger.info("Starting to send {} bulk messages", bulkSize); for (int i = 0; i < bulkSize && !exit.get(); i++) { execService.execute(newSendTask("Hello " + id + " idx=" + i)); } @@ -188,7 +188,8 @@ public void run() { long maxDelayPerSecond = maxDelay.getAndSet(0); totalRequestCounter.addAndGet(requestPerSecond); int total = totalResponseCounter.addAndGet(responsePerSecond); - logger.info("Request/Response per second : " + requestPerSecond + "/" + responsePerSecond + " of " + total + " maxDelay=" + maxDelayPerSecond); + logger.info("Request/Response per second: {}/{} of {} maxDelay={}", + requestPerSecond, responsePerSecond, total, maxDelayPerSecond); if (total == bulkSize) { shutdown(); } @@ -203,7 +204,6 @@ public static void main(String[] args) { String sourceAddr = System.getProperty("jsmpp.client.sourceAddr", DEFAULT_SOURCEADDR); String destinationAddr = System.getProperty("jsmpp.client.destinationAddr", DEFAULT_DESTADDR); - int port; try { port = Integer.parseInt(System.getProperty("jsmpp.client.port", DEFAULT_PORT.toString())); From da966d5945f6ee43cda96ecec5c36c24fe8dd361 Mon Sep 17 00:00:00 2001 From: vharseko Date: Mon, 12 Oct 2015 02:11:41 +0300 Subject: [PATCH 067/212] Create .travis.yml --- .travis.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..ed0700d --- /dev/null +++ b/.travis.yml @@ -0,0 +1,20 @@ +language: java +os: + - linux + - osx +before_install: + - date -u + - uname -a + - env | sort +branches: + only: + - master +jdk: + - oraclejdk8 + - oraclejdk7 + - openjdk7 +notifications: + email: + - support@openam.org.ru +script: + - mvn install From f05951f87af04ba6d180473b7be12520b722857f Mon Sep 17 00:00:00 2001 From: vharseko Date: Mon, 12 Oct 2015 02:36:33 +0300 Subject: [PATCH 068/212] Update .travis.yml --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ed0700d..a831fdc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ language: java os: - linux - - osx before_install: - date -u - uname -a From ed1669b27750fbe4480e1bf76b0ff631d5ecc1fa Mon Sep 17 00:00:00 2001 From: vharseko Date: Mon, 12 Oct 2015 09:52:56 +0300 Subject: [PATCH 069/212] Create README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..fb66ecf --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +# org.jsmpp +Java SMPP (Short Message Peer-to-peer Protocol) API + +[![Build Status](https://travis-ci.org/openam-org-ru/org.jsmpp.svg?branch=master)](https://travis-ci.org/openam-org-ru/org.jsmpp) From 388bf2fd9a45791b9099fdfd7a01a92739ee3180 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 20 Dec 2015 13:29:21 +0100 Subject: [PATCH 070/212] Fixed typo in log message. --- jsmpp/src/main/java/org/jsmpp/session/BindRequestReceiver.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/BindRequestReceiver.java b/jsmpp/src/main/java/org/jsmpp/session/BindRequestReceiver.java index 582c0d3..6e4cb31 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/BindRequestReceiver.java +++ b/jsmpp/src/main/java/org/jsmpp/session/BindRequestReceiver.java @@ -59,7 +59,7 @@ BindRequest waitForRequest(long timeout) throws IllegalStateException, TimeoutEx if (request != null) { return request; } else { - throw new TimeoutException("Wating for bind request take time too long"); + throw new TimeoutException("Waiting for bind request take time too long"); } } finally { alreadyWaitForRequest = true; From b74a54de3f5e60c5689e2dca3f87cae981067bd0 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Mon, 21 Dec 2015 20:39:35 +0100 Subject: [PATCH 071/212] Return "000" for error instead of "null" --- .../src/main/java/org/jsmpp/examples/SMPPServerSimulator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java index ef9fc16..55c7003 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java @@ -240,7 +240,7 @@ public void run() { String stringValue = Integer.valueOf(messageId.getValue(), 16).toString(); try { - DeliveryReceipt delRec = new DeliveryReceipt(stringValue, totalSubmitted, totalDelivered, new Date(), new Date(), DeliveryReceiptState.DELIVRD, null, new String(shortMessage)); + DeliveryReceipt delRec = new DeliveryReceipt(stringValue, totalSubmitted, totalDelivered, new Date(), new Date(), DeliveryReceiptState.DELIVRD, "000", new String(shortMessage)); session.deliverShortMessage( "mc", sourceAddrTon, From 4270ec9dc1c891bf38b5e0f871df4ba5e44c96bf Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Tue, 22 Dec 2015 22:10:21 +0100 Subject: [PATCH 072/212] Only decode the address when enough information is received. --- jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java index 8b0cc0c..b497519 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java @@ -2158,9 +2158,10 @@ private static class Vendor_specific_msc_addr extends OptionalParameter.OctetStr private Vendor_specific_msc_addr(short tag, byte value[]) { super(tag, value); try { - address = new String(value, 2, value.length-2, "ISO-8859-1"); + if (value.length >= 2) { + address = new String(value, 2, value.length - 2, "ISO-8859-1"); + } } catch (StringIndexOutOfBoundsException e) { - // TODO: do something better e.printStackTrace(); } catch (UnsupportedEncodingException e) { // TODO: do something better From 450f32441b273cb60327ae3505ebee7e9ddf5ddf Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Mon, 4 Jan 2016 23:46:26 +0100 Subject: [PATCH 073/212] Return all data for unknown OptionalParameter in an OctetString instead of COctetString. --- .../org/jsmpp/bean/OptionalParameters.java | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameters.java b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameters.java index 8bdf249..80504a5 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameters.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameters.java @@ -29,64 +29,64 @@ * */ public class OptionalParameters { - + private static final Logger logger = LoggerFactory.getLogger(OptionalParameters.class); /** * Create SAR_MESSAGE_REF_NUM TLV instance. - * + * * @param value is the value. * @return the optional parameter. */ public static OptionalParameter.Short newSarMsgRefNum(short value) { return new OptionalParameter.Short(Tag.SAR_MSG_REF_NUM, value); } - + /** * Create SAR_MESSAGE_REF_NUM TLV instance. * The value will cast automatically into short type. - * + * * @param value is the value. * @return the optional parameter. */ public static OptionalParameter.Short newSarMsgRefNum(int value) { return newSarMsgRefNum((byte)value); } - + /** * Create SAR_SEGMENT_SEQNUM TLV instance. - * + * * @param value is the value. * @return the optional parameter. */ public static OptionalParameter.Byte newSarSegmentSeqnum(byte value) { return new OptionalParameter.Byte(Tag.SAR_SEGMENT_SEQNUM, value); } - + /** * Create SAR_SEGMENT_SEQNUM TLV instance. * The value will cast automatically into byte type. - * + * * @param value is the value. * @return the optional parameter. */ public static OptionalParameter.Byte newSarSegmentSeqnum(int value) { return newSarSegmentSeqnum((byte)value); } - + /** * Create SAR_TOTAL_SEGMENTS TLV instance. - * + * * @param value is the value. * @return the optional parameter. */ public static OptionalParameter.Byte newSarTotalSegments(byte value) { return new OptionalParameter.Byte(Tag.SAR_TOTAL_SEGMENTS, value); } - + /** * Create SAR_TOTAL_SEGMENTS TLV instance. * The value will cast automatically into byte type. - * + * * @param value is the value. * @return the optional parameter. */ @@ -97,18 +97,18 @@ public static OptionalParameter.Byte newSarTotalSegments(int value) { /** * Deserialize all recognized tag code to {@link OptionalParameter} object. * Unrecognized will be classified as {@link COctetString}. - * + * * @param tagCode is the tag code. * @param content is the content. * @return the OptionalParameter object. */ public static OptionalParameter deserialize(short tagCode, byte[] content) { Tag tag = Tag.valueOf(tagCode); - if(tag == null) { + if (tag == null) { logger.warn("Optional Parameter Tag not recognized for deserialization: {}", tagCode); - return new COctetString(tagCode, content); + return new OctetString(tagCode, content); } - + switch(tag) { case DEST_ADDR_SUBUNIT: From 6867c623e085635898df6737cd7dcf07d4d15689 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Tue, 5 Jan 2016 00:07:04 +0100 Subject: [PATCH 074/212] Add testcases for COctetString OptionalParameter. --- .../org/jsmpp/bean/OptionalParameterTest.java | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/jsmpp/src/test/java/org/jsmpp/bean/OptionalParameterTest.java b/jsmpp/src/test/java/org/jsmpp/bean/OptionalParameterTest.java index 9fe51f2..c70d4bc 100644 --- a/jsmpp/src/test/java/org/jsmpp/bean/OptionalParameterTest.java +++ b/jsmpp/src/test/java/org/jsmpp/bean/OptionalParameterTest.java @@ -14,14 +14,13 @@ */ package org.jsmpp.bean; -import static org.testng.AssertJUnit.assertFalse; import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertTrue; import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; +import static org.testng.AssertJUnit.assertFalse; import java.io.UnsupportedEncodingException; -import java.nio.charset.Charset; import org.jsmpp.bean.OptionalParameter.COctetString; import org.jsmpp.bean.OptionalParameter.Callback_num_pres_ind.Presentation_Indicator; @@ -149,11 +148,11 @@ public void Network_error_code() { } - @Test(groups="checkintest") - public void cOctetStringGetValueAsString() throws UnsupportedEncodingException { - COctetString string = new OptionalParameter.COctetString(Tag.ADDITIONAL_STATUS_INFO_TEXT.code(), "urgent"); + @Test(groups="checkintest") + public void cOctetStringGetValueAsString() throws UnsupportedEncodingException { + COctetString string = new OptionalParameter.COctetString(Tag.ADDITIONAL_STATUS_INFO_TEXT.code(), "urgent"); - assertEquals(string.getValueAsString(), "urgent"); + assertEquals(string.getValueAsString(), "urgent"); assertEquals((byte)0x75, string.getValue()[0]); // u assertEquals((byte)0x72, string.getValue()[1]); // r @@ -162,6 +161,18 @@ public void cOctetStringGetValueAsString() throws UnsupportedEncodingException { assertEquals((byte)0x6e, string.getValue()[4]); // n assertEquals((byte)0x74, string.getValue()[5]); // t assertEquals((byte)0x00, string.getValue()[6]); // NULL + } - } + @Test + public void testAdditionalStatusInfoTextStringAsString() { + COctetString op = new OptionalParameter.Additional_status_info_text("additional text"); + assertEquals("additional text", op.getValueAsString()); + } + + @Test + public void testAdditionalStatusInfoTextBytesAsString() { + byte[] content = "more additional text\0".getBytes(); + COctetString op = new OptionalParameter.Additional_status_info_text(content); + assertEquals("more additional text", op.getValueAsString()); + } } \ No newline at end of file From 517ed857cf79b36d2f56eb04c62c170c56cfbf4c Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Tue, 5 Jan 2016 00:12:41 +0100 Subject: [PATCH 075/212] Add String constructors for COctetString typed OptionalParameter. --- jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java index b497519..40a9c03 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java @@ -767,6 +767,9 @@ public static class Additional_status_info_text extends OptionalParameter.COctet public Additional_status_info_text(byte[] value) { super(Tag.ADDITIONAL_STATUS_INFO_TEXT.code(), value); } + public Additional_status_info_text(String value) { + super(Tag.ADDITIONAL_STATUS_INFO_TEXT.code(), value); + } } /** @@ -780,10 +783,12 @@ public Additional_status_info_text(byte[] value) { * */ public static class Receipted_message_id extends OptionalParameter.COctetString { - public Receipted_message_id(byte[] value) { super(Tag.RECEIPTED_MESSAGE_ID.code(), value); } + public Receipted_message_id(String value) { + super(Tag.RECEIPTED_MESSAGE_ID.code(), value); + } } /** From e9ef2d54c9bbd9a00a2b7fad89e3575707b9e812 Mon Sep 17 00:00:00 2001 From: Pascal Schumacher Date: Tue, 5 Jan 2016 21:29:59 +0100 Subject: [PATCH 076/212] some corrections and improvements to README --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ee21404..30a3a94 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,12 @@ Introduction ------------ -jSMPP is a java implementation (SMPP API) of SMPP protocol (currently support -SMPP v3.4). It provides interfaces to communicate with Message Center or -ESME (External Short Message Entity) and able to handle -traffic 3000-5000 messages per second. +jSMPP is a java implementation (SMPP API) of the SMPP protocol (currently supports +SMPP v3.4). It provides interfaces to communicate with a Message Center or +an ESME (External Short Message Entity) and is able to handle +traffic of 3000-5000 messages per second. -jSMPP is not a high-level library. Many people looking for a quick way to +jSMPP is not a high-level library. People looking for a quick way to get started with SMPP may be better of using an abstraction layer such as the Apache Camel SMPP component: http://camel.apache.org/smpp.html @@ -22,7 +22,7 @@ History The project started on Google Code: http://code.google.com/p/jsmpp/ -It was maintained by uudashr on Github until 2013 +It was maintained by uudashr on Github until 2013. It is now a community project maintained at http://jsmpp.org From a2f96bb2b4843c98625afe3692945075cb97f374 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Wed, 6 Jan 2016 12:33:19 +0100 Subject: [PATCH 077/212] Fetch the OptionalParameter on the code, for unknown OptionalParameters. --- jsmpp/src/main/java/org/jsmpp/bean/AbstractSmCommand.java | 5 +++++ jsmpp/src/main/java/org/jsmpp/bean/OptionalParameters.java | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/AbstractSmCommand.java b/jsmpp/src/main/java/org/jsmpp/bean/AbstractSmCommand.java index c10ff62..04f914f 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/AbstractSmCommand.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/AbstractSmCommand.java @@ -195,6 +195,11 @@ public OptionalParameter getOptionalParameter(Tag tagEnum) { return OptionalParameters.get(tagEnum.code(), optionalParameters); } + + public OptionalParameter getOptionalParameter(short code) + { + return OptionalParameters.get(code, optionalParameters); + } public OptionalParameter[] getOptionalParameters() { return optionalParameters; diff --git a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameters.java b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameters.java index 80504a5..cf8f1b7 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameters.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameters.java @@ -105,7 +105,7 @@ public static OptionalParameter.Byte newSarTotalSegments(int value) { public static OptionalParameter deserialize(short tagCode, byte[] content) { Tag tag = Tag.valueOf(tagCode); if (tag == null) { - logger.warn("Optional Parameter Tag not recognized for deserialization: {}", tagCode); + logger.info("Optional Parameter Tag not recognized for deserialization: {}", tagCode); return new OctetString(tagCode, content); } From 1fe30faaa35984ca046772a702a674b6acf4c83a Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Wed, 6 Jan 2016 13:22:52 +0100 Subject: [PATCH 078/212] Remove space. --- jsmpp/src/main/java/org/jsmpp/session/BindRequestReceiver.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/BindRequestReceiver.java b/jsmpp/src/main/java/org/jsmpp/session/BindRequestReceiver.java index 6e4cb31..41d3819 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/BindRequestReceiver.java +++ b/jsmpp/src/main/java/org/jsmpp/session/BindRequestReceiver.java @@ -65,8 +65,6 @@ BindRequest waitForRequest(long timeout) throws IllegalStateException, TimeoutEx alreadyWaitForRequest = true; lock.unlock(); } - - } /** From 7df407efdd95581826a6239905af36fa7b9f23b4 Mon Sep 17 00:00:00 2001 From: Pascal Schumacher Date: Wed, 6 Jan 2016 22:49:08 +0100 Subject: [PATCH 079/212] small corrections and improvements of CHANGES.txt --- CHANGES.txt | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index a1016f4..3ecca9d 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,7 +1,6 @@ Changes: 2.0 beta 3 - - Add SMPP Server component - Add Optional Parameter support (contribution from mikko.koponen@gmail.com) - Handling PDU processing concurrently (performance improvement) @@ -9,17 +8,16 @@ Changes: - Add cancel_sm support - Add replace_sm support - Add alert_notification support -- Add CapacityPolicy to PDUByteBuffer (performance improvement, minimize array - of byte creation) - -2.0 beta 4 +- Add CapacityPolicy to PDUByteBuffer (performance improvement, minimize ByteArray + creation) +2.0 beta 4 - Modify Optional Parameter API (currently for TLV related to message concatenation case) - Add ServerResponseDeliveryListener (listener to receive success or failure event of submit_sm_resp/submit_multi_resp delivery) - Change license from LGPL to "Apache License, Version 2.0" -- Add license notice on every sources. +- Add license notice to every source file 2.0 beta 5 - Bug fix for type on OptionalParameters class @@ -27,8 +25,7 @@ Changes: 1. isBound() 2. isTransmittable() 3. isReceiveable() -- Add examples for auto-reconnect gateway - it can be found on org.jsmpp.examples.gateway +- Add examples for auto-reconnect gateway (found in the org.jsmpp.examples.gateway package) - Fix the destination addresses on SMPPSession#submitMultiple Some classes and interfaces created to support the bug fixes. - Fix the date parsing on delivery receipt @@ -48,14 +45,14 @@ Changes: 2.2.0 - New DataCoding API. - Remove the old class (since I can't make backward compatibility) - Add some class: + Removed the old class (since I could not make the change backwards compatible) + Added some new classes instead: 1. DataCodings 2. DataCoding (GeneralDataCoding, MessageWatingDataCoding, SimpleDataCoding, RawDataCoding) - Expose remote InetAddress on server side API via SMPPServerSession Add new method: InetAddress SMPPServerSession#getInetAddress() -- Ensure command execution is in valid state. Checking done on local side (remote side do the checking also). -- Make Command and it's subclasses serializable +- Ensure command execution is in valid state. Checking done on local side (remote side also does the checking) +- Make Command and its subclasses serializable 2.2.1 - Fix examples @@ -65,6 +62,6 @@ Changes: 2.2.2 - Fixed some logging - Added SMPP 5.0 message states -- Fixed Null pointer exception when OptionaParameters are emtpy in a BindResp -- Fixed invalid command lengths (<4) throws an IndexOutOfBoundsException +- Fixed NullPointerException when OptionaParameters are empty in a BindResp +- Fixed invalid command length (<4) throws an IndexOutOfBoundsException - Added RelativeTimeFormatter \ No newline at end of file From 3f91509f00a99dc72a3a5256d983b46c4e61a9c9 Mon Sep 17 00:00:00 2001 From: Pascal Schumacher Date: Thu, 7 Jan 2016 20:04:50 +0100 Subject: [PATCH 080/212] CHANGES.txt: most recent changes at the top of the file --- CHANGES.txt | 100 ++++++++++++++++++++++++++-------------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 3ecca9d..9d022c2 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,23 +1,39 @@ Changes: -2.0 beta 3 -- Add SMPP Server component -- Add Optional Parameter support (contribution from mikko.koponen@gmail.com) -- Handling PDU processing concurrently (performance improvement) -- Add data_sm support -- Add cancel_sm support -- Add replace_sm support -- Add alert_notification support -- Add CapacityPolicy to PDUByteBuffer (performance improvement, minimize ByteArray - creation) +2.2.2 +- Fixed some logging +- Added SMPP 5.0 message states +- Fixed NullPointerException when OptionaParameters are empty in a BindResp +- Fixed invalid command length (<4) throws an IndexOutOfBoundsException +- Added RelativeTimeFormatter -2.0 beta 4 -- Modify Optional Parameter API (currently for TLV related to message - concatenation case) -- Add ServerResponseDeliveryListener (listener to receive success or failure - event of submit_sm_resp/submit_multi_resp delivery) -- Change license from LGPL to "Apache License, Version 2.0" -- Add license notice to every source file +2.2.1 +- Fix examples +- Use StrictBufferedInputStream for better performance +- Provide source for onAcceptDataSm + +2.2.0 +- New DataCoding API. + Removed the old class (since I could not make the change backwards compatible) + Added some new classes instead: + 1. DataCodings + 2. DataCoding (GeneralDataCoding, MessageWatingDataCoding, SimpleDataCoding, RawDataCoding) +- Expose remote InetAddress on server side API via SMPPServerSession + Add new method: InetAddress SMPPServerSession#getInetAddress() +- Ensure command execution is in valid state. Checking done on local side (remote side also does the checking) +- Make Command and its subclasses serializable + +2.1.0 +- set connection timeout when binding +- provide source (the session) for onAcceptDataSm +- use StrictBufferedInputStream + +2.0.1 +- Bug fix, MessageReceiverListener should be subclass of GenericMessageReceiverListener + +2.0 beta 6 +- Change the max length of short message to 254, referring to SMPP 3.4 + Previously using 255 (taken from SMPP 5.0) 2.0 beta 5 - Bug fix for type on OptionalParameters class @@ -31,37 +47,21 @@ Changes: - Fix the date parsing on delivery receipt - Referring to Appendix C of SMPP 3.4 for year parsing rule -2.0 beta 6 -- Change the max length of short message to 254, referring to SMPP 3.4 - Previously using 255 (taken from SMPP 5.0) - -2.0.1 -- Bug fix, MessageReceiverListener should be subclass of GenericMessageReceiverListener - -2.1.0 -- set connection timeout when binding -- provide source (the session) for onAcceptDataSm -- use StrictBufferedInputStream - -2.2.0 -- New DataCoding API. - Removed the old class (since I could not make the change backwards compatible) - Added some new classes instead: - 1. DataCodings - 2. DataCoding (GeneralDataCoding, MessageWatingDataCoding, SimpleDataCoding, RawDataCoding) -- Expose remote InetAddress on server side API via SMPPServerSession - Add new method: InetAddress SMPPServerSession#getInetAddress() -- Ensure command execution is in valid state. Checking done on local side (remote side also does the checking) -- Make Command and its subclasses serializable - -2.2.1 -- Fix examples -- Use StrictBufferedInputStream for better performance -- Provide source for onAcceptDataSm +2.0 beta 4 +- Modify Optional Parameter API (currently for TLV related to message + concatenation case) +- Add ServerResponseDeliveryListener (listener to receive success or failure + event of submit_sm_resp/submit_multi_resp delivery) +- Change license from LGPL to "Apache License, Version 2.0" +- Add license notice to every source file -2.2.2 -- Fixed some logging -- Added SMPP 5.0 message states -- Fixed NullPointerException when OptionaParameters are empty in a BindResp -- Fixed invalid command length (<4) throws an IndexOutOfBoundsException -- Added RelativeTimeFormatter \ No newline at end of file +2.0 beta 3 +- Add SMPP Server component +- Add Optional Parameter support (contribution from mikko.koponen@gmail.com) +- Handling PDU processing concurrently (performance improvement) +- Add data_sm support +- Add cancel_sm support +- Add replace_sm support +- Add alert_notification support +- Add CapacityPolicy to PDUByteBuffer (performance improvement, minimize ByteArray + creation) \ No newline at end of file From 36866203aceb8f4be46b641aa00707641b40e69d Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Thu, 7 Jan 2016 20:04:58 +0100 Subject: [PATCH 081/212] Use StringBuilder instead of StringBuffer. --- .../java/org/jsmpp/bean/DeliveryReceipt.java | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java b/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java index f6e35b1..a0eaf77 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java @@ -222,23 +222,23 @@ public String toString() { * id:IIIIIIIIII sub:SSS dlvrd:DDD submit date:YYMMDDhhmm done * date:YYMMDDhhmm stat:DDDDDDD err:E Text: . . . . . . . . . */ - StringBuffer sBuf = new StringBuffer(120); - sBuf.append(DELREC_ID + ":" + id); - sBuf.append(" "); - sBuf.append(DELREC_SUB + ":" + intToString(submitted, 3)); - sBuf.append(" "); - sBuf.append(DELREC_DLVRD + ":" + intToString(delivered, 3)); - sBuf.append(" "); - sBuf.append(DELREC_SUBMIT_DATE + ":" + dateFormat.format(submitDate)); - sBuf.append(" "); - sBuf.append(DELREC_DONE_DATE + ":" + dateFormat.format(doneDate)); - sBuf.append(" "); - sBuf.append(DELREC_STAT + ":" + finalStatus); - sBuf.append(" "); - sBuf.append(DELREC_ERR + ":" + error); - sBuf.append(" "); - sBuf.append(DELREC_TEXT.toLowerCase() + ":" + text); - return sBuf.toString(); + StringBuilder stringBuilder = new StringBuilder(120); + stringBuilder.append(DELREC_ID + ":" + id); + stringBuilder.append(" "); + stringBuilder.append(DELREC_SUB + ":" + intToString(submitted, 3)); + stringBuilder.append(" "); + stringBuilder.append(DELREC_DLVRD + ":" + intToString(delivered, 3)); + stringBuilder.append(" "); + stringBuilder.append(DELREC_SUBMIT_DATE + ":" + dateFormat.format(submitDate)); + stringBuilder.append(" "); + stringBuilder.append(DELREC_DONE_DATE + ":" + dateFormat.format(doneDate)); + stringBuilder.append(" "); + stringBuilder.append(DELREC_STAT + ":" + finalStatus); + stringBuilder.append(" "); + stringBuilder.append(DELREC_ERR + ":" + error); + stringBuilder.append(" "); + stringBuilder.append(DELREC_TEXT.toLowerCase() + ":" + text); + return stringBuilder.toString(); } @Override @@ -306,12 +306,12 @@ public boolean equals(Object obj) { * @return the String representation of int value. */ private static String intToString(int value, int digit) { - StringBuffer sBuf = new StringBuffer(digit); - sBuf.append(Integer.toString(value)); - while (sBuf.length() < digit) { - sBuf.insert(0, "0"); + StringBuilder stringBuilder = new StringBuilder(digit); + stringBuilder.append(Integer.toString(value)); + while (stringBuilder.length() < digit) { + stringBuilder.insert(0, "0"); } - return sBuf.toString(); + return stringBuilder.toString(); } private boolean hasEqualId(DeliveryReceipt other) { From d2b8a86dda6f443c7f0563216e12e01d9729b960 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Thu, 7 Jan 2016 20:05:50 +0100 Subject: [PATCH 082/212] Fix typo. --- jsmpp/src/main/java/org/jsmpp/session/Session.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/Session.java b/jsmpp/src/main/java/org/jsmpp/session/Session.java index 9ae5ad3..c284887 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/Session.java +++ b/jsmpp/src/main/java/org/jsmpp/session/Session.java @@ -48,7 +48,7 @@ *

* To terminate the communication with the Message Center gracefully, invoke * {@link #unbindAndClose()}. It will send UNBIND command and close the - * connection. This method will wait the UNIBIND_RESP but, negative response + * connection. This method will wait the UNBIND_RESP but, negative response * will be acceptable and closing connection will be done immediately. *

* From 1b42fe2d7d0178991792d9e31b8681cbdc8c781a Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Thu, 7 Jan 2016 20:10:15 +0100 Subject: [PATCH 083/212] Alignment --- .../org/jsmpp/session/PDUProcessServerTask.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/PDUProcessServerTask.java b/jsmpp/src/main/java/org/jsmpp/session/PDUProcessServerTask.java index 72af7cb..5420673 100755 --- a/jsmpp/src/main/java/org/jsmpp/session/PDUProcessServerTask.java +++ b/jsmpp/src/main/java/org/jsmpp/session/PDUProcessServerTask.java @@ -29,15 +29,14 @@ */ public class PDUProcessServerTask implements Runnable { private static final Logger logger = LoggerFactory.getLogger(PDUProcessServerTask.class); - + private final Command pduHeader; private final byte[] pdu; private final SMPPServerSessionState stateProcessor; private final ActivityNotifier activityNotifier; private final ServerResponseHandler responseHandler; private final Runnable onIOExceptionTask; - - + public PDUProcessServerTask(Command pduHeader, byte[] pdu, SMPPServerSessionState stateProcessor, ActivityNotifier activityNotifier, @@ -52,12 +51,11 @@ public PDUProcessServerTask(Command pduHeader, byte[] pdu, public void run() { try { - if(logger.isDebugEnabled()) - { + if(logger.isDebugEnabled()) + { String hexmsg = HexUtil.convertBytesToHexString(pdu, 0, pdu.length, " "); - logger.debug("Received SMPP message {} {}", pduHeader, hexmsg); - } - + logger.debug("Received SMPP message {} {}", pduHeader, hexmsg); + } switch (pduHeader.getCommandId()) { case SMPPConstant.CID_BIND_RECEIVER: case SMPPConstant.CID_BIND_TRANSMITTER: From 174c586c2b694bda6c9e5f4f591111789c2b1ab7 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Thu, 7 Jan 2016 20:11:07 +0100 Subject: [PATCH 084/212] Prepare for 2.2.3 --- jsmpp-examples/pom.xml | 4 +++- jsmpp/pom.xml | 4 +++- pom.xml | 6 +++--- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/jsmpp-examples/pom.xml b/jsmpp-examples/pom.xml index 1c18e3f..a48e417 100644 --- a/jsmpp-examples/pom.xml +++ b/jsmpp-examples/pom.xml @@ -3,12 +3,14 @@ jsmpp-pom org.jsmpp - 2.2.2 + 2.2.3 4.0.0 jsmpp-examples + jSMPP - Examples + ${project.groupId} diff --git a/jsmpp/pom.xml b/jsmpp/pom.xml index d44eac5..5604d43 100644 --- a/jsmpp/pom.xml +++ b/jsmpp/pom.xml @@ -3,13 +3,15 @@ org.jsmpp jsmpp-pom - 2.2.2 + 2.2.3 4.0.0 bundle jsmpp + jSMPP - Core + http://apache.org/licenses/LICENSE-2.0 diff --git a/pom.xml b/pom.xml index c70f635..1679f91 100644 --- a/pom.xml +++ b/pom.xml @@ -4,10 +4,10 @@ org.jsmpp jsmpp-pom - 2.2.2 + 2.2.3 pom - jSMPP + jSMPP - Parent SMPP library for Java http://jsmpp.org @@ -46,7 +46,7 @@ yyyyMMddHHmm ${maven.build.timestamp} UTF-8 - 1.7.12 + 1.7.13 1.2.17 4.12 6.8.21 From fdc539a9a2fe5cf693be093bbbb672208e2c15dc Mon Sep 17 00:00:00 2001 From: Pascal Schumacher Date: Thu, 7 Jan 2016 20:29:49 +0100 Subject: [PATCH 085/212] fix some typos in javadoc --- jsmpp/src/main/java/org/jsmpp/InvalidResponseException.java | 2 +- jsmpp/src/main/java/org/jsmpp/MessageCoding.java | 2 +- jsmpp/src/main/java/org/jsmpp/PDUSender.java | 4 ++-- jsmpp/src/main/java/org/jsmpp/SynchronizedPDUReader.java | 5 ++--- .../src/main/java/org/jsmpp/util/AbsoluteTimeFormatter.java | 2 +- jsmpp/src/main/java/org/jsmpp/util/MessageId.java | 2 +- jsmpp/src/main/java/org/jsmpp/util/PDUDecomposer.java | 2 +- 7 files changed, 9 insertions(+), 10 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/InvalidResponseException.java b/jsmpp/src/main/java/org/jsmpp/InvalidResponseException.java index 9cc0653..0b3a6de 100644 --- a/jsmpp/src/main/java/org/jsmpp/InvalidResponseException.java +++ b/jsmpp/src/main/java/org/jsmpp/InvalidResponseException.java @@ -15,7 +15,7 @@ package org.jsmpp; /** - * This exception thrown if we receive unexpected response (such as invalid PDU + * This exception is thrown if we receive unexpected response (such as invalid PDU * parameter). * * @author uudashr diff --git a/jsmpp/src/main/java/org/jsmpp/MessageCoding.java b/jsmpp/src/main/java/org/jsmpp/MessageCoding.java index 608f0ad..e3d6e05 100644 --- a/jsmpp/src/main/java/org/jsmpp/MessageCoding.java +++ b/jsmpp/src/main/java/org/jsmpp/MessageCoding.java @@ -15,7 +15,7 @@ package org.jsmpp; /** - * This is enum const that specified the message coding (see smpp spesification). + * This is an enum const that specifies the message coding (see smpp spesification). * * @author uudashr * @version 1.0 diff --git a/jsmpp/src/main/java/org/jsmpp/PDUSender.java b/jsmpp/src/main/java/org/jsmpp/PDUSender.java index f2bc0fd..647c9fc 100644 --- a/jsmpp/src/main/java/org/jsmpp/PDUSender.java +++ b/jsmpp/src/main/java/org/jsmpp/PDUSender.java @@ -31,8 +31,8 @@ import org.jsmpp.bean.UnsuccessDelivery; /** - * This class provide way to send SMPP Command over an {@link OutputStream}. - * PDU will be created and returned as bytes. + * This class provides a way to send SMPP Commands over an {@link OutputStream}. + * PDUs will be created and returned as bytes. * * @author uudashr * @version 1.0 diff --git a/jsmpp/src/main/java/org/jsmpp/SynchronizedPDUReader.java b/jsmpp/src/main/java/org/jsmpp/SynchronizedPDUReader.java index 5a7afff..b325bdd 100644 --- a/jsmpp/src/main/java/org/jsmpp/SynchronizedPDUReader.java +++ b/jsmpp/src/main/java/org/jsmpp/SynchronizedPDUReader.java @@ -22,9 +22,8 @@ /** - * This class id implementation of {@link PDUReader} that use synchronize when - * accessing to the {@link InputStream} or {@link DataInputStream} tha used to - * read the PDU. + * This class is an implementation of a {@link PDUReader} that uses synchronization when + * accessing the {@link InputStream} or {@link DataInputStream} used to read the PDU. * * @author uudashr * @version 1.1 diff --git a/jsmpp/src/main/java/org/jsmpp/util/AbsoluteTimeFormatter.java b/jsmpp/src/main/java/org/jsmpp/util/AbsoluteTimeFormatter.java index 6176f2f..11fb104 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/AbsoluteTimeFormatter.java +++ b/jsmpp/src/main/java/org/jsmpp/util/AbsoluteTimeFormatter.java @@ -20,7 +20,7 @@ /** - * Absolute time formatter is {@link TimeFormatter} implementation referred to + * Absolute time formatter is a {@link TimeFormatter} implementation referred to in * SMPP Protocol Specification v3.4 point 7.1.1. * * @author uudashr diff --git a/jsmpp/src/main/java/org/jsmpp/util/MessageId.java b/jsmpp/src/main/java/org/jsmpp/util/MessageId.java index 0fae284..77a3b45 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/MessageId.java +++ b/jsmpp/src/main/java/org/jsmpp/util/MessageId.java @@ -17,7 +17,7 @@ import org.jsmpp.PDUStringException; /** - * This class is wrap simple {@link String} value as message_id. The main + * This class wraps a simple {@link String} value as a message_id. The main * purpose is the creation of the value will be validated as proper message_id. * * @author uudashr diff --git a/jsmpp/src/main/java/org/jsmpp/util/PDUDecomposer.java b/jsmpp/src/main/java/org/jsmpp/util/PDUDecomposer.java index 316fed6..6fe0ab8 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/PDUDecomposer.java +++ b/jsmpp/src/main/java/org/jsmpp/util/PDUDecomposer.java @@ -43,7 +43,7 @@ import org.jsmpp.bean.UnbindResp; /** - * This class is provide interface to decompose SMPP PDU bytes form into SMPP + * This class provides an interface to decompose SMPP PDU bytes form into a SMPP * command object. * * @author uudashr From 25c8a96e11b6ef5129f13a65ae61f33fa562241a Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Thu, 7 Jan 2016 20:49:09 +0100 Subject: [PATCH 086/212] Set version to 2.2.4-SNAPSHOT. --- jsmpp-examples/pom.xml | 2 +- jsmpp/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/jsmpp-examples/pom.xml b/jsmpp-examples/pom.xml index a48e417..e995edf 100644 --- a/jsmpp-examples/pom.xml +++ b/jsmpp-examples/pom.xml @@ -3,7 +3,7 @@ jsmpp-pom org.jsmpp - 2.2.3 + 2.2.4-SNAPSHOT 4.0.0 diff --git a/jsmpp/pom.xml b/jsmpp/pom.xml index 5604d43..a6575b1 100644 --- a/jsmpp/pom.xml +++ b/jsmpp/pom.xml @@ -3,7 +3,7 @@ org.jsmpp jsmpp-pom - 2.2.3 + 2.2.4-SNAPSHOT 4.0.0 bundle diff --git a/pom.xml b/pom.xml index 1679f91..dbbe7bb 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.jsmpp jsmpp-pom - 2.2.3 + 2.2.4-SNAPSHOT pom jSMPP - Parent From 8fb424de644cd1c290dd12508efd685ac09dd269 Mon Sep 17 00:00:00 2001 From: Pascal Schumacher Date: Sun, 10 Jan 2016 16:55:20 +0100 Subject: [PATCH 087/212] add maven central badge, which displays the latest released version, to readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 30a3a94..3d55ed3 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ Introduction ------------ +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.jsmpp/jsmpp/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.jsmpp/jsmpp) + jSMPP is a java implementation (SMPP API) of the SMPP protocol (currently supports SMPP v3.4). It provides interfaces to communicate with a Message Center or an ESME (External Short Message Entity) and is able to handle From 6ef86496065d99921d21e4adbddc43f2c3020ad0 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Thu, 28 Jan 2016 23:51:11 +0100 Subject: [PATCH 088/212] Correct spelling for (C)Octet --- .../main/java/org/jsmpp/util/StringType.java | 2 +- .../java/org/jsmpp/util/StringValidator.java | 4 ++-- .../org/jsmpp/util/StringValidatorTest.java | 18 +++++++++--------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/util/StringType.java b/jsmpp/src/main/java/org/jsmpp/util/StringType.java index 660c054..ea11116 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/StringType.java +++ b/jsmpp/src/main/java/org/jsmpp/util/StringType.java @@ -26,7 +26,7 @@ public enum StringType { /** * String delimited by null value. */ - C_OCTEC_STRING, + C_OCTET_STRING, /** * String that determined by the length. diff --git a/jsmpp/src/main/java/org/jsmpp/util/StringValidator.java b/jsmpp/src/main/java/org/jsmpp/util/StringValidator.java index e6a44ba..5fa610a 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/StringValidator.java +++ b/jsmpp/src/main/java/org/jsmpp/util/StringValidator.java @@ -30,7 +30,7 @@ private StringValidator() { public static void validateString(String value, StringParameter param) throws PDUStringException { - if (param.getType() == StringType.C_OCTEC_STRING) { + if (param.getType() == StringType.C_OCTET_STRING) { if (param.isRangeMinAndMax()) { if (!isCOctetStringValid(value, param.getMax())) { throw new PDUStringException("C-Octet String value '" @@ -54,7 +54,7 @@ public static void validateString(String value, StringParameter param) public static void validateString(byte[] value, StringParameter param) throws PDUStringException { - if (param.getType() == StringType.C_OCTEC_STRING) { + if (param.getType() == StringType.C_OCTET_STRING) { if (param.isRangeMinAndMax()) { if (!isCOctetStringValid(value, param.getMax())) { throw new PDUStringException("C-Octet String value '" diff --git a/jsmpp/src/test/java/org/jsmpp/util/StringValidatorTest.java b/jsmpp/src/test/java/org/jsmpp/util/StringValidatorTest.java index f55bccd..0660d38 100644 --- a/jsmpp/src/test/java/org/jsmpp/util/StringValidatorTest.java +++ b/jsmpp/src/test/java/org/jsmpp/util/StringValidatorTest.java @@ -15,10 +15,10 @@ package org.jsmpp.util; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.fail; + import org.jsmpp.PDUStringException; -import org.jsmpp.util.StringParameter; -import org.jsmpp.util.StringValidator; -import static org.testng.Assert.*; import org.testng.annotations.Test; /** @@ -69,7 +69,7 @@ public void testValidation() { } @Test(groups="checkintest") - public void validateStringOctedStringWithString() throws Exception { + public void validateStringOctetStringWithString() throws Exception { StringValidator.validateString("", StringParameter.SHORT_MESSAGE); StringValidator.validateString("short messages", StringParameter.SHORT_MESSAGE); String shortMessage = "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567" @@ -89,7 +89,7 @@ public void validateStringOctedStringWithString() throws Exception { } @Test(groups="checkintest") - public void validateStringOctedStringWithByteArray() throws Exception { + public void validateStringOctetStringWithByteArray() throws Exception { StringValidator.validateString("".getBytes("UTF-8"), StringParameter.SHORT_MESSAGE); StringValidator.validateString("short messages".getBytes("UTF-8"), StringParameter.SHORT_MESSAGE); String shortMessage = "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567" @@ -109,7 +109,7 @@ public void validateStringOctedStringWithByteArray() throws Exception { } @Test(groups="checkintest") - public void validateStringCOctedStringWithString() throws Exception { + public void validateStringCOctetStringWithString() throws Exception { StringValidator.validateString("", StringParameter.SYSTEM_ID); StringValidator.validateString("System ID", StringParameter.SYSTEM_ID); StringValidator.validateString("123456789012345", StringParameter.SYSTEM_ID); @@ -125,7 +125,7 @@ public void validateStringCOctedStringWithString() throws Exception { } @Test(groups="checkintest") - public void validateStringCOctedStringWithByteArray() throws Exception { + public void validateStringCOctetStringWithByteArray() throws Exception { StringValidator.validateString("".getBytes("UTF-8"), StringParameter.SYSTEM_ID); StringValidator.validateString("System ID".getBytes("UTF-8"), StringParameter.SYSTEM_ID); StringValidator.validateString("123456789012345".getBytes("UTF-8"), StringParameter.SYSTEM_ID); @@ -141,7 +141,7 @@ public void validateStringCOctedStringWithByteArray() throws Exception { } @Test(groups="checkintest") - public void validateStringCOctedStringWithStringAndWithoutARange() throws Exception { + public void validateStringCOctetStringWithStringAndWithoutARange() throws Exception { StringValidator.validateString("", StringParameter.SCHEDULE_DELIVERY_TIME); StringValidator.validateString("020610233429000R", StringParameter.SCHEDULE_DELIVERY_TIME); @@ -156,7 +156,7 @@ public void validateStringCOctedStringWithStringAndWithoutARange() throws Except } @Test(groups="checkintest") - public void validateStringCOctedStringWithByteArrayAndWithoutARange() throws Exception { + public void validateStringCOctetStringWithByteArrayAndWithoutARange() throws Exception { StringValidator.validateString("".getBytes("UTF-8"), StringParameter.SCHEDULE_DELIVERY_TIME); StringValidator.validateString("020610233429000R".getBytes("UTF-8"), StringParameter.SCHEDULE_DELIVERY_TIME); From f8f6bc213a3ca33222c26a252374c925f14d1e3a Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Thu, 28 Jan 2016 23:53:30 +0100 Subject: [PATCH 089/212] Correct spelling for (C)Octet --- .../java/org/jsmpp/util/StringParameter.java | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/util/StringParameter.java b/jsmpp/src/main/java/org/jsmpp/util/StringParameter.java index 1d1eb37..d49d415 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/StringParameter.java +++ b/jsmpp/src/main/java/org/jsmpp/util/StringParameter.java @@ -26,47 +26,47 @@ public enum StringParameter { /** * system_id string parameter. */ - SYSTEM_ID(StringType.C_OCTEC_STRING, 0, 16, true, SMPPConstant.STAT_ESME_RINVSYSID), + SYSTEM_ID(StringType.C_OCTET_STRING, 0, 16, true, SMPPConstant.STAT_ESME_RINVSYSID), /** * password string parameter. */ - PASSWORD(StringType.C_OCTEC_STRING, 0, 9, true, SMPPConstant.STAT_ESME_RINVPASWD), + PASSWORD(StringType.C_OCTET_STRING, 0, 9, true, SMPPConstant.STAT_ESME_RINVPASWD), /** * system_type string parameter. */ - SYSTEM_TYPE(StringType.C_OCTEC_STRING, 0, 13, true, SMPPConstant.STAT_ESME_RINVSYSTYP), + SYSTEM_TYPE(StringType.C_OCTET_STRING, 0, 13, true, SMPPConstant.STAT_ESME_RINVSYSTYP), /** * Invalid address range assume should return the error of invalid source address. */ - ADDRESS_RANGE(StringType.C_OCTEC_STRING, 0, 41, true, SMPPConstant.STAT_ESME_RINVSRCADR), + ADDRESS_RANGE(StringType.C_OCTET_STRING, 0, 41, true, SMPPConstant.STAT_ESME_RINVSRCADR), - SERVICE_TYPE(StringType.C_OCTEC_STRING, 0, 6, true, SMPPConstant.STAT_ESME_RINVSERTYP), - SOURCE_ADDR(StringType.C_OCTEC_STRING, 0, 21, true, SMPPConstant.STAT_ESME_RINVSRCADR), - DESTINATION_ADDR(StringType.C_OCTEC_STRING, 0, 21, true, SMPPConstant.STAT_ESME_RINVSRCADR), - SCHEDULE_DELIVERY_TIME(StringType.C_OCTEC_STRING, 0, 17, false, SMPPConstant.STAT_ESME_RINVSCHED), - VALIDITY_PERIOD(StringType.C_OCTEC_STRING, 0, 17, false, SMPPConstant.STAT_ESME_RINVEXPIRY), + SERVICE_TYPE(StringType.C_OCTET_STRING, 0, 6, true, SMPPConstant.STAT_ESME_RINVSERTYP), + SOURCE_ADDR(StringType.C_OCTET_STRING, 0, 21, true, SMPPConstant.STAT_ESME_RINVSRCADR), + DESTINATION_ADDR(StringType.C_OCTET_STRING, 0, 21, true, SMPPConstant.STAT_ESME_RINVSRCADR), + SCHEDULE_DELIVERY_TIME(StringType.C_OCTET_STRING, 0, 17, false, SMPPConstant.STAT_ESME_RINVSCHED), + VALIDITY_PERIOD(StringType.C_OCTET_STRING, 0, 17, false, SMPPConstant.STAT_ESME_RINVEXPIRY), /** * Validator for DL_NAME (Distribution List) */ - DL_NAME(StringType.C_OCTEC_STRING, 0, 21, true, SMPPConstant.STAT_ESME_RINVDLNAME), + DL_NAME(StringType.C_OCTET_STRING, 0, 21, true, SMPPConstant.STAT_ESME_RINVDLNAME), /** * When validating final date is failed, then we should throw error with status * STAT_ESME_RINVDFTMSGID, means that predefined message are not exist. */ - FINAL_DATE(StringType.C_OCTEC_STRING, 0, 17, false, SMPPConstant.STAT_ESME_RINVDFTMSGID), + FINAL_DATE(StringType.C_OCTET_STRING, 0, 17, false, SMPPConstant.STAT_ESME_RINVDFTMSGID), SHORT_MESSAGE(StringType.OCTET_STRING, 0, 254, true, SMPPConstant.STAT_ESME_RINVMSGLEN), - MESSAGE_ID(StringType.C_OCTEC_STRING, 0, 65, true, SMPPConstant.STAT_ESME_RINVMSGID), - DEL_MESSAGE_ID(StringType.C_OCTEC_STRING, 0, 0, true, SMPPConstant.STAT_ESME_RINVMSGID), + MESSAGE_ID(StringType.C_OCTET_STRING, 0, 65, true, SMPPConstant.STAT_ESME_RINVMSGID), + DEL_MESSAGE_ID(StringType.C_OCTET_STRING, 0, 0, true, SMPPConstant.STAT_ESME_RINVMSGID), /** * ESME_ADDR has error code OK because there is not response to alert_notification * (ESME_ADDR only use on alert_notification), so there is no error code to return. */ - ESME_ADDR(StringType.C_OCTEC_STRING, 0, 65, true, SMPPConstant.STAT_ESME_ROK); + ESME_ADDR(StringType.C_OCTET_STRING, 0, 65, true, SMPPConstant.STAT_ESME_ROK); private StringType type; private final int min; From d50fbd7e9b76e292459858b26c1397e6d2c69c9e Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Tue, 2 Feb 2016 10:32:29 +0100 Subject: [PATCH 090/212] When offset is 0, use '+' sign. --- jsmpp/src/main/java/org/jsmpp/util/AbsoluteTimeFormatter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsmpp/src/main/java/org/jsmpp/util/AbsoluteTimeFormatter.java b/jsmpp/src/main/java/org/jsmpp/util/AbsoluteTimeFormatter.java index 11fb104..35a81e9 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/AbsoluteTimeFormatter.java +++ b/jsmpp/src/main/java/org/jsmpp/util/AbsoluteTimeFormatter.java @@ -50,7 +50,7 @@ public String format(Calendar calendar) { // Get the sign char sign; - if (offset > 0) { + if (offset >= 0) { sign = '+'; } else { sign = '-'; From 164d56d619c6f9561304e382d4ce2dac04a4edd0 Mon Sep 17 00:00:00 2001 From: Benjamin Ihrig Date: Wed, 3 Feb 2016 12:32:21 +0100 Subject: [PATCH 091/212] Add subpackages to OSGi export packages in order to make them accessible in OSGI runtime environments. --- jsmpp/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsmpp/pom.xml b/jsmpp/pom.xml index a6575b1..9dacdbf 100644 --- a/jsmpp/pom.xml +++ b/jsmpp/pom.xml @@ -46,7 +46,7 @@ ${project.artifactId} ${project.groupId}.${project.artifactId} - org.jsmpp + org.jsmpp.* org.slf4j;resolution:=optional, * From bc6207c736a474e5f0134942a3152d39faa4b962 Mon Sep 17 00:00:00 2001 From: Benjamin Ihrig Date: Wed, 3 Feb 2016 12:32:21 +0100 Subject: [PATCH 092/212] Add subpackages to OSGi export packages in order to make them accessible in OSGI runtime environments. --- jsmpp/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jsmpp/pom.xml b/jsmpp/pom.xml index a6575b1..651d444 100644 --- a/jsmpp/pom.xml +++ b/jsmpp/pom.xml @@ -46,9 +46,9 @@ ${project.artifactId} ${project.groupId}.${project.artifactId} - org.jsmpp + org.jsmpp.* - org.slf4j;resolution:=optional, + org.slf4j, * jsmpp From 2dcc4c8e3fbbdfd14bbc051e90070c945b63f9a6 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Thu, 4 Feb 2016 21:01:30 +0100 Subject: [PATCH 093/212] Update Slf4j --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index dbbe7bb..b224b26 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ yyyyMMddHHmm ${maven.build.timestamp} UTF-8 - 1.7.13 + 1.7.14 1.2.17 4.12 6.8.21 From 6516631efd8d77bdbdafe1ab4e9d4b151731ae20 Mon Sep 17 00:00:00 2001 From: George Kankava Date: Mon, 8 Feb 2016 17:34:28 +0400 Subject: [PATCH 094/212] squid:S1854 - Dead stores should be removed --- jsmpp/src/main/java/org/jsmpp/bean/LongSMS.java | 1 - jsmpp/src/main/java/org/jsmpp/bean/SarSegmentSeqnum.java | 1 - jsmpp/src/main/java/org/jsmpp/bean/SarTotalSegments.java | 1 - .../src/main/java/org/jsmpp/session/SMPPServerSession.java | 7 ++----- jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java | 7 ++----- jsmpp/src/main/java/org/jsmpp/util/OctetUtil.java | 2 +- 6 files changed, 5 insertions(+), 14 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/LongSMS.java b/jsmpp/src/main/java/org/jsmpp/bean/LongSMS.java index fe5cd97..c7bf5dd 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/LongSMS.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/LongSMS.java @@ -170,7 +170,6 @@ private static byte[][] smsg(byte[] data) { } public static void main(String[] args) { - String hexMessage = "5465737420736D732067617465776179206C6F6E6720736D73732C205465737420736D732067617465776179206C6F6E6720736D73732C205465737420736D732067617465776179206C6F6E6720736D73732C205465737420736D732067617465776179206C6F6E6720736D73732C205465737420736D732067617465776179206C6F6E6720736D73732C205465737420736D732067617465776179206C6F6E6720736D73732C205465737420736D732067617465776179206C6F6E6720736D73732C205465737420736D732067617465776179206C6F6E6720736D73732C205465737420736D732067617465776179206C6F6E6720736D73732C205465737420736D732067617465776179206C6F6E6720736D73732020"; String message = "Test sms gateway long smss, Test sms gateway long smss, Test sms gateway long smss, Test sms gateway long smss, Test sms gateway long smss, Test sms gateway long smss, Test sms gateway long smss, Test sms gateway long smss, Test sms gateway long smss, Test sms gatew"; byte[][] splittedMsg = splitMessage8Bit(message.getBytes()); diff --git a/jsmpp/src/main/java/org/jsmpp/bean/SarSegmentSeqnum.java b/jsmpp/src/main/java/org/jsmpp/bean/SarSegmentSeqnum.java index 7e9582c..855518e 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/SarSegmentSeqnum.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/SarSegmentSeqnum.java @@ -45,7 +45,6 @@ public short getValue() { @Override public int hashCode() { - final int prime = 31; int result = 1; return result; } diff --git a/jsmpp/src/main/java/org/jsmpp/bean/SarTotalSegments.java b/jsmpp/src/main/java/org/jsmpp/bean/SarTotalSegments.java index e3a34a7..05402cf 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/SarTotalSegments.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/SarTotalSegments.java @@ -45,7 +45,6 @@ public short getValue() { @Override public int hashCode() { - final int prime = 31; int result = 1; return result; } diff --git a/jsmpp/src/main/java/org/jsmpp/session/SMPPServerSession.java b/jsmpp/src/main/java/org/jsmpp/session/SMPPServerSession.java index a413c04..6e5b064 100755 --- a/jsmpp/src/main/java/org/jsmpp/session/SMPPServerSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/SMPPServerSession.java @@ -515,11 +515,8 @@ public void run() { private void readPDU() { try { - Command pduHeader = null; - byte[] pdu = null; - - pduHeader = pduReader.readPDUHeader(in); - pdu = pduReader.readPDU(in, pduHeader); + Command pduHeader = pduReader.readPDUHeader(in); + byte[] pdu = pduReader.readPDU(in, pduHeader); PDUProcessServerTask task = new PDUProcessServerTask(pduHeader, pdu, sessionContext.getStateProcessor(), diff --git a/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java b/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java index 71c5c41..3870c09 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java @@ -593,12 +593,9 @@ public void run() { private void readPDU() { try { - Command pduHeader = null; - byte[] pdu = null; + Command pduHeader = pduReader.readPDUHeader(in); + byte[] pdu = pduReader.readPDU(in, pduHeader); - pduHeader = pduReader.readPDUHeader(in); - pdu = pduReader.readPDU(in, pduHeader); - /* * When the processing PDU is need user interaction via event, * the code on event might take non-short time, so we need to diff --git a/jsmpp/src/main/java/org/jsmpp/util/OctetUtil.java b/jsmpp/src/main/java/org/jsmpp/util/OctetUtil.java index 25e0137..126315a 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/OctetUtil.java +++ b/jsmpp/src/main/java/org/jsmpp/util/OctetUtil.java @@ -72,7 +72,7 @@ public static int bytesToInt(byte[] bytes, int offset) { // int result = 0x00000000; - int length = 0; + int length; if (bytes.length - offset < 4) // maximum byte size for int data type // is 4 length = bytes.length - offset; From d41bb37885704ecb3cfc7fecc4f87d3dceed2a57 Mon Sep 17 00:00:00 2001 From: George Kankava Date: Mon, 8 Feb 2016 18:34:16 +0400 Subject: [PATCH 095/212] squid:S1118 - Utility classes should not have public constructorsx --- jsmpp/src/main/java/org/jsmpp/bean/DataCodings.java | 6 +++++- jsmpp/src/main/java/org/jsmpp/bean/LongSMS.java | 4 ++++ jsmpp/src/main/java/org/jsmpp/bean/OptionalParameters.java | 5 +++++ jsmpp/src/main/java/org/jsmpp/util/HexUtil.java | 4 ++++ jsmpp/src/main/java/org/jsmpp/util/IntUtil.java | 4 ++++ jsmpp/src/main/java/org/jsmpp/util/OctetUtil.java | 5 +++++ 6 files changed, 27 insertions(+), 1 deletion(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/DataCodings.java b/jsmpp/src/main/java/org/jsmpp/bean/DataCodings.java index c49ab90..123f96f 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/DataCodings.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/DataCodings.java @@ -43,7 +43,11 @@ public final class DataCodings { */ public static final DataCoding ZERO = new GeneralDataCoding(); private static DataCoding[] dataCodingCache = new DataCoding[255]; - + + private DataCodings() { + throw new InstantiationError("This class must not be instantiated"); + } + /** * Create new instance of {@link DataCoding}. * diff --git a/jsmpp/src/main/java/org/jsmpp/bean/LongSMS.java b/jsmpp/src/main/java/org/jsmpp/bean/LongSMS.java index c7bf5dd..b0d5b63 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/LongSMS.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/LongSMS.java @@ -30,6 +30,10 @@ public class LongSMS { private final static byte UDHIE_SAR_LENGTH = 0x04; private static int referenceNumber = 0; + private LongSMS() { + throw new InstantiationError("This class must not be instantiated"); + } + private static synchronized int getReferenceNumber() { referenceNumber++; if (referenceNumber >= 65536) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameters.java b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameters.java index cf8f1b7..234bdce 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameters.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameters.java @@ -31,6 +31,11 @@ public class OptionalParameters { private static final Logger logger = LoggerFactory.getLogger(OptionalParameters.class); + + private OptionalParameters() { + throw new InstantiationError("This class must not be instantiated"); + } + /** * Create SAR_MESSAGE_REF_NUM TLV instance. * diff --git a/jsmpp/src/main/java/org/jsmpp/util/HexUtil.java b/jsmpp/src/main/java/org/jsmpp/util/HexUtil.java index e777fe9..f54df6e 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/HexUtil.java +++ b/jsmpp/src/main/java/org/jsmpp/util/HexUtil.java @@ -29,6 +29,10 @@ public class HexUtil { private static final char[] hexChar = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + private HexUtil() { + throw new InstantiationError("This class must not be instantiated"); + } + /** * Convert the string to hex string value. * diff --git a/jsmpp/src/main/java/org/jsmpp/util/IntUtil.java b/jsmpp/src/main/java/org/jsmpp/util/IntUtil.java index b642752..1234361 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/IntUtil.java +++ b/jsmpp/src/main/java/org/jsmpp/util/IntUtil.java @@ -24,6 +24,10 @@ */ public class IntUtil { + private IntUtil() { + throw new InstantiationError("This class must not be instantiated"); + } + public static String to4DigitString(final int value) { return toNDigitString(value, 4); } diff --git a/jsmpp/src/main/java/org/jsmpp/util/OctetUtil.java b/jsmpp/src/main/java/org/jsmpp/util/OctetUtil.java index 126315a..e6a9555 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/OctetUtil.java +++ b/jsmpp/src/main/java/org/jsmpp/util/OctetUtil.java @@ -23,6 +23,11 @@ * */ public class OctetUtil { + + private OctetUtil() { + throw new InstantiationError("This class must not be instantiated"); + } + /** * Convert integer (4 octets) value to bytes. * From 874b59cd02731a536e460471b48429118cf7ab33 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Wed, 10 Feb 2016 11:30:54 +0100 Subject: [PATCH 096/212] Move split8Bit main method to Test class. --- .../src/main/java/org/jsmpp/bean/LongSMS.java | 25 ---------------- .../test/java/org/jsmpp/bean/LongSMSTest.java | 29 +++++++++++++++++++ 2 files changed, 29 insertions(+), 25 deletions(-) create mode 100644 jsmpp/src/test/java/org/jsmpp/bean/LongSMSTest.java diff --git a/jsmpp/src/main/java/org/jsmpp/bean/LongSMS.java b/jsmpp/src/main/java/org/jsmpp/bean/LongSMS.java index c7bf5dd..df2b48f 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/LongSMS.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/LongSMS.java @@ -14,16 +14,12 @@ */ package org.jsmpp.bean; -import org.jsmpp.util.HexUtil; -import org.jsmpp.util.OctetUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class LongSMS { private static final Logger logger = LoggerFactory.getLogger(LongSMS.class); - private final static int MAX_MESSAGE_7BIT = 160; - private final static int MAX_MESSAGE_8BIT = 140; private final static int MAX_MESSAGE_SEGMENT_8BIT = 133; // 140-7 private final static int MAX_MESSAGE_SEGMENT_7BIT = 152; private final static byte UDHIE_IDENTIFIER_SAR = 0x08; @@ -90,7 +86,6 @@ public static byte[][] splitMessage8Bit(byte[] aMessage) { } return segments; - } private static byte[][] splitMessage7Bit(byte[] aMessage) { @@ -164,24 +159,4 @@ private static byte[] encode7Bit(String aString) { return bytes; } - - private static byte[][] smsg(byte[] data) { - return null; - } - - public static void main(String[] args) { - String message = "Test sms gateway long smss, Test sms gateway long smss, Test sms gateway long smss, Test sms gateway long smss, Test sms gateway long smss, Test sms gateway long smss, Test sms gateway long smss, Test sms gateway long smss, Test sms gateway long smss, Test sms gatew"; - - byte[][] splittedMsg = splitMessage8Bit(message.getBytes()); - for (int i = 0; i < splittedMsg.length; i++) { - logger.debug("splittedMsg[i].length = " + splittedMsg[i].length); - logger.debug(new String(splittedMsg[i])); - logger.debug("sar_msg_refnum tag: " - + HexUtil.convertBytesToHexString(splittedMsg[i], 0, 2)); - logger.debug("sar_msg_refnum length: " - + OctetUtil.bytesToShort(splittedMsg[i], 2)); - logger.debug("sar_msg_refnum value: " - + OctetUtil.bytesToShort(splittedMsg[i], 4)); - } - } } diff --git a/jsmpp/src/test/java/org/jsmpp/bean/LongSMSTest.java b/jsmpp/src/test/java/org/jsmpp/bean/LongSMSTest.java new file mode 100644 index 0000000..8108b24 --- /dev/null +++ b/jsmpp/src/test/java/org/jsmpp/bean/LongSMSTest.java @@ -0,0 +1,29 @@ +package org.jsmpp.bean; + +import org.jsmpp.util.OctetUtil; +import org.junit.Assert; +import org.testng.annotations.Test; + +public class LongSMSTest { + + @Test + public void testSplitMessage8Bit() throws Exception { + + final String message = "Test sms gateway long smss, Test sms gateway long smss, Test sms gateway long smss, Test sms gateway long smss, Test sms gateway long smss, Test sms gateway long smss, Test sms gateway long smss, Test sms gateway long smss, Test sms gateway long smss, Test sms gatew"; + final byte[][] splittedMsg = LongSMS.splitMessage8Bit(message.getBytes("US-ASCII")); + Assert.assertEquals(266, (message.getBytes().length)); + Assert.assertEquals(140, splittedMsg[0].length); + Assert.assertEquals(140, splittedMsg[1].length); + for (int i = 0; i < splittedMsg.length; i++) { + Assert.assertEquals("UDH length", 0x06, splittedMsg[i][0]); + Assert.assertEquals("IE identifier", 0x08, splittedMsg[i][1]); + Assert.assertEquals("IE length", 0x04, splittedMsg[i][2]); + Assert.assertEquals("The referencenumber differs", + OctetUtil.bytesToShort(splittedMsg[0], 3), + OctetUtil.bytesToShort(splittedMsg[i], 3)); + Assert.assertEquals("Total of segments differs", splittedMsg.length, splittedMsg[i][5]); + Assert.assertEquals("The segmentnumber differs", i + 1, splittedMsg[i][6]); + } + } + +} \ No newline at end of file From a55e471ec8578d8e80a7d1f582538cbbdbe9f5f3 Mon Sep 17 00:00:00 2001 From: George Kankava Date: Wed, 17 Feb 2016 14:44:48 +0400 Subject: [PATCH 097/212] squid:CommentedOutCodeLine - Sections of code should not be commented out --- .../org/jsmpp/session/state/SMPPServerSessionOpen.java | 1 - jsmpp/src/main/java/org/jsmpp/util/DefaultComposer.java | 4 ---- jsmpp/src/main/java/org/jsmpp/util/DefaultDecomposer.java | 1 - jsmpp/src/main/java/org/jsmpp/util/OctetUtil.java | 1 - .../main/java/org/jsmpp/util/SequentialBytesReader.java | 7 ------- 5 files changed, 14 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionOpen.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionOpen.java index dbd334d..562f6f8 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionOpen.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionOpen.java @@ -43,7 +43,6 @@ public void processBind(Command pduHeader, byte[] pdu, try { Bind bind = pduDecomposer.bind(pdu); responseHandler.processBind(bind); - //responseHandler.sendBindResp(BindType.valueOf(pduHeader.getCommandId()), pduHeader.getSequenceNumber()); } catch (PDUStringException e) { responseHandler.sendNegativeResponse(pduHeader.getCommandId(), e.getErrorCode(), pduHeader.getSequenceNumber()); } catch (IllegalArgumentException e) { diff --git a/jsmpp/src/main/java/org/jsmpp/util/DefaultComposer.java b/jsmpp/src/main/java/org/jsmpp/util/DefaultComposer.java index 72e81a8..784e2ab 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/DefaultComposer.java +++ b/jsmpp/src/main/java/org/jsmpp/util/DefaultComposer.java @@ -332,15 +332,11 @@ public byte[] deliverSm(int sequenceNumber, String serviceType, buf.append(esmClass); buf.append(protocolId); buf.append(priorityFlag); - // buf.append(scheduleDeliveryTime); buf.append((String)null); // schedule delivery time - // buf.append(validityPeriod); buf.append((String)null); // validity period buf.append(registeredDelivery); - // buf.append(replaceIfPresent); buf.append((byte)0); // replace if present flag buf.append(dataCoding); - // buf.append(smDefaultMsgId); buf.append((byte)0); // sm default msg id buf.append((byte)shortMessage.length); buf.append(shortMessage); diff --git a/jsmpp/src/main/java/org/jsmpp/util/DefaultDecomposer.java b/jsmpp/src/main/java/org/jsmpp/util/DefaultDecomposer.java index 5d89c89..bbeaf9a 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/DefaultDecomposer.java +++ b/jsmpp/src/main/java/org/jsmpp/util/DefaultDecomposer.java @@ -250,7 +250,6 @@ public SubmitSm submitSm(byte[] b) throws PDUStringException { req.setDataCoding(reader.readByte()); req.setSmDefaultMsgId(reader.readByte()); byte smLength = reader.readByte(); - // req.setShortMessage(reader.readString(req.getSmLength())); req.setShortMessage(reader.readBytes(smLength)); StringValidator.validateString(req.getShortMessage(), StringParameter.SHORT_MESSAGE); diff --git a/jsmpp/src/main/java/org/jsmpp/util/OctetUtil.java b/jsmpp/src/main/java/org/jsmpp/util/OctetUtil.java index 25e0137..73819be 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/OctetUtil.java +++ b/jsmpp/src/main/java/org/jsmpp/util/OctetUtil.java @@ -81,7 +81,6 @@ public static int bytesToInt(byte[] bytes, int offset) { int end = offset + length; for (int i = 0; i < length; i++) { - // result |= bytes[end - i - 1] << (8 * i); result |= (bytes[end - i - 1] & 0xff) << (8 * i); // TODO uudashr: CHECK FOR IMPROVEMENT } return result; diff --git a/jsmpp/src/main/java/org/jsmpp/util/SequentialBytesReader.java b/jsmpp/src/main/java/org/jsmpp/util/SequentialBytesReader.java index e2b215e..a5a26ed 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/SequentialBytesReader.java +++ b/jsmpp/src/main/java/org/jsmpp/util/SequentialBytesReader.java @@ -109,18 +109,11 @@ public short readShort() { * @return String value. Nullable. */ public String readString(byte length) { - /* - * if (length == 0) return null; - */ /* * you have to convert the signed byte into unsigned byte (in * integer representation) with & operand by 0xff */ return readString(length & 0xff); - /* - * String val = new String(_bytes, _cursor, length & 0xff); _cursor += - * length; return val; - */ } public int remainBytesLength() { From 470315a4ea5a5df9d039f1372e1b51919bb5eb1d Mon Sep 17 00:00:00 2001 From: George Kankava Date: Wed, 17 Feb 2016 15:11:56 +0400 Subject: [PATCH 098/212] Multiple code improvements: squid:S2786, squid:UselessParenthesesCheck --- .../java/org/jsmpp/bean/DestinationAddress.java | 2 +- .../java/org/jsmpp/bean/OptionalParameter.java | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/DestinationAddress.java b/jsmpp/src/main/java/org/jsmpp/bean/DestinationAddress.java index e6547d9..8e8ecb2 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/DestinationAddress.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/DestinationAddress.java @@ -21,7 +21,7 @@ * */ public interface DestinationAddress { - public static enum Flag { + public enum Flag { SME_ADDRESS((byte)1), DISTRIBUTION_LIST((byte)2); private final byte value; diff --git a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java index 40a9c03..7c14906 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java @@ -277,7 +277,7 @@ public COctetString(short tag, byte[] value) { @Override public String getValueAsString() { - byte[] s = new byte[(value.length > 0 ? value.length - 1 : 0)]; + byte[] s = new byte[value.length > 0 ? value.length - 1 : 0]; System.arraycopy(value, 0, s, 0, s.length); return new String(s); } @@ -288,7 +288,7 @@ public String getValueAsString() { * Represents valid values for the optional parameters dest_addr_subunit and source_addr_subunit. * */ - public static enum Addr_subunit{ + public enum Addr_subunit{ /** * 0x00 = Unknown (default) */ @@ -372,7 +372,7 @@ public String toString() { * Represents valid values for the optional parameters dest_network_type and source_network_type. * */ - public static enum Network_type { + public enum Network_type { UNKNOWN(0x00), GSM(0x01), ANSI_136_TDMA(0x02), @@ -443,7 +443,7 @@ public String toString() { * Represents valid values for the optional parameters dest_bearer_type and source_bearer_type. * */ - public static enum Bearer_type { + public enum Bearer_type { UNKNOWN(0x00), SMS(0x01), CIRCUIT_SWITCHED_DATA(0x02), @@ -862,7 +862,7 @@ public Ms_msg_wait_facilities_type getMessageType() { } public String toString() { - String endString = (isIndicatorActive() ? "active" : "inactive"); + String endString = isIndicatorActive() ? "active" : "inactive"; return getMessageType().toString() + " set as " + endString; } } @@ -1509,7 +1509,7 @@ public Dpf_result(byte[] content) { } public boolean getDpfResult() { - return (value == 1); + return value == 1; } } @@ -1547,7 +1547,7 @@ public Set_dpf(byte[] content) { } public boolean isDpfSet() { - return (value == 1); + return value == 1; } } From e10e6b9372ca741aa4d7a9894f0422b834728e3f Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 21 Feb 2016 13:08:07 +0100 Subject: [PATCH 099/212] Lexical improvement. --- jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java index 7c14906..a10cf99 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java @@ -38,7 +38,7 @@ public OptionalParameter(short tag) { /** Convert the optional parameter into a byte serialized form conforming to the SMPP specification. * - * @return A byte array according to SMPP specification + * @return A byte array according to the SMPP specification */ public byte[] serialize() { byte[] value = serializeValue(); @@ -50,7 +50,7 @@ public byte[] serialize() { } /** This method should serialize the value part of the optional parameter. The format of the value is dependent - * on the specific optional parameter type so it is abstract and must be implmented by subclasses. + * on the specific optional parameter type so it is abstract and must be implemented by subclasses. * @return */ protected abstract byte[] serializeValue(); From e3bdd4c6be30079a4923f4b19e3cfd8511b233b7 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 21 Feb 2016 13:08:57 +0100 Subject: [PATCH 100/212] Use @Override and remove public from interface. --- .../src/main/java/org/jsmpp/bean/Address.java | 6 ++-- .../org/jsmpp/bean/DestinationAddress.java | 32 +++++++++---------- .../java/org/jsmpp/bean/DistributionList.java | 3 +- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/Address.java b/jsmpp/src/main/java/org/jsmpp/bean/Address.java index 15a99dd..457a660 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/Address.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/Address.java @@ -14,9 +14,6 @@ */ package org.jsmpp.bean; - - - /** * This are SME (Short Message Entity) Address. * @@ -40,7 +37,8 @@ public Address(byte typeOfNumber, byte numberingPlanIndicator, String address) { NumberingPlanIndicator.valueOf(numberingPlanIndicator), address); } - + + @Override public Flag getFlag() { return Flag.SME_ADDRESS; } diff --git a/jsmpp/src/main/java/org/jsmpp/bean/DestinationAddress.java b/jsmpp/src/main/java/org/jsmpp/bean/DestinationAddress.java index 8e8ecb2..91fadde 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/DestinationAddress.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/DestinationAddress.java @@ -16,24 +16,24 @@ /** * Destination address can be use for submit multiple. - * - * @author uudashr * + * @author uudashr */ public interface DestinationAddress { - public enum Flag { - SME_ADDRESS((byte)1), DISTRIBUTION_LIST((byte)2); - - private final byte value; - - private Flag(byte value) { - this.value = value; - } - - public byte getValue() { - return value; - } + enum Flag { + SME_ADDRESS((byte) 1), + DISTRIBUTION_LIST((byte) 2); + + private final byte value; + + private Flag(byte value) { + this.value = value; + } + + public byte getValue() { + return value; } - - Flag getFlag(); + } + + Flag getFlag(); } diff --git a/jsmpp/src/main/java/org/jsmpp/bean/DistributionList.java b/jsmpp/src/main/java/org/jsmpp/bean/DistributionList.java index ac42d58..a20e6dd 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/DistributionList.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/DistributionList.java @@ -25,7 +25,8 @@ public class DistributionList implements DestinationAddress { public DistributionList(String name) { this.name = name; } - + + @Override public Flag getFlag() { return Flag.DISTRIBUTION_LIST; } From 01c72ecac04f114bc4119ac40cae2dc7065cf45c Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 21 Feb 2016 21:45:50 +0100 Subject: [PATCH 101/212] Remove redundant private for enum. --- jsmpp/src/main/java/org/jsmpp/bean/Alphabet.java | 2 +- jsmpp/src/main/java/org/jsmpp/bean/IndicationSense.java | 2 +- jsmpp/src/main/java/org/jsmpp/bean/IndicationType.java | 2 +- jsmpp/src/main/java/org/jsmpp/bean/MessageClass.java | 2 +- jsmpp/src/main/java/org/jsmpp/bean/MessageMode.java | 2 +- jsmpp/src/main/java/org/jsmpp/bean/MessageState.java | 2 +- jsmpp/src/main/java/org/jsmpp/bean/MessageType.java | 2 +- .../main/java/org/jsmpp/bean/ReplaceIfPresentFlag.java | 8 +++----- .../src/main/java/org/jsmpp/bean/SMSCDeliveryReceipt.java | 2 +- jsmpp/src/main/java/org/jsmpp/bean/TypeOfNumber.java | 2 +- 10 files changed, 12 insertions(+), 14 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/Alphabet.java b/jsmpp/src/main/java/org/jsmpp/bean/Alphabet.java index 01d4a2b..c98095f 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/Alphabet.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/Alphabet.java @@ -127,7 +127,7 @@ public enum Alphabet { * * @param value is the alphabet value. */ - private Alphabet(byte value, boolean valid, boolean unspecified) { + Alphabet(byte value, boolean valid, boolean unspecified) { this.value = value; this.valid = valid; this.unspecified = unspecified; diff --git a/jsmpp/src/main/java/org/jsmpp/bean/IndicationSense.java b/jsmpp/src/main/java/org/jsmpp/bean/IndicationSense.java index b32b413..a0992a4 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/IndicationSense.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/IndicationSense.java @@ -15,7 +15,7 @@ public enum IndicationSense { private final byte value; - private IndicationSense(byte value) { + IndicationSense(byte value) { this.value = value; } diff --git a/jsmpp/src/main/java/org/jsmpp/bean/IndicationType.java b/jsmpp/src/main/java/org/jsmpp/bean/IndicationType.java index 42d0f4c..cd47091 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/IndicationType.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/IndicationType.java @@ -17,7 +17,7 @@ public enum IndicationType { private final byte value; - private IndicationType(byte value) { + IndicationType(byte value) { this.value = value; } diff --git a/jsmpp/src/main/java/org/jsmpp/bean/MessageClass.java b/jsmpp/src/main/java/org/jsmpp/bean/MessageClass.java index 24d8db1..9e58e94 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/MessageClass.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/MessageClass.java @@ -28,7 +28,7 @@ public enum MessageClass { private final byte value; - private MessageClass(byte value) { + MessageClass(byte value) { this.value = value; } diff --git a/jsmpp/src/main/java/org/jsmpp/bean/MessageMode.java b/jsmpp/src/main/java/org/jsmpp/bean/MessageMode.java index c3e2009..9f134a3 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/MessageMode.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/MessageMode.java @@ -29,7 +29,7 @@ public enum MessageMode { private final byte value; - private MessageMode(byte value) { + MessageMode(byte value) { this.value = value; } diff --git a/jsmpp/src/main/java/org/jsmpp/bean/MessageState.java b/jsmpp/src/main/java/org/jsmpp/bean/MessageState.java index 47909b2..6ee146f 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/MessageState.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/MessageState.java @@ -64,7 +64,7 @@ public enum MessageState { private final byte value; - private MessageState(byte value) { + MessageState(byte value) { this.value = value; } diff --git a/jsmpp/src/main/java/org/jsmpp/bean/MessageType.java b/jsmpp/src/main/java/org/jsmpp/bean/MessageType.java index 36df9a7..1eeaa32 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/MessageType.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/MessageType.java @@ -37,7 +37,7 @@ public enum MessageType { private final byte value; - private MessageType(byte value) { + MessageType(byte value) { this.value = value; } diff --git a/jsmpp/src/main/java/org/jsmpp/bean/ReplaceIfPresentFlag.java b/jsmpp/src/main/java/org/jsmpp/bean/ReplaceIfPresentFlag.java index ccc06de..9e8e6fa 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/ReplaceIfPresentFlag.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/ReplaceIfPresentFlag.java @@ -16,14 +16,12 @@ /** * @author uudashr - * + * */ public class ReplaceIfPresentFlag { - public static final ReplaceIfPresentFlag DEFAULT = new ReplaceIfPresentFlag( - 0); + public static final ReplaceIfPresentFlag DEFAULT = new ReplaceIfPresentFlag(0); public static final ReplaceIfPresentFlag DONT_REPLACE = DEFAULT; - public static final ReplaceIfPresentFlag REPLACE = new ReplaceIfPresentFlag( - 1); + public static final ReplaceIfPresentFlag REPLACE = new ReplaceIfPresentFlag(1); private byte value; diff --git a/jsmpp/src/main/java/org/jsmpp/bean/SMSCDeliveryReceipt.java b/jsmpp/src/main/java/org/jsmpp/bean/SMSCDeliveryReceipt.java index 36da788..61ab31f 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/SMSCDeliveryReceipt.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/SMSCDeliveryReceipt.java @@ -42,7 +42,7 @@ public enum SMSCDeliveryReceipt { private final byte value; - private SMSCDeliveryReceipt(byte value) { + SMSCDeliveryReceipt(byte value) { this.value = value; } diff --git a/jsmpp/src/main/java/org/jsmpp/bean/TypeOfNumber.java b/jsmpp/src/main/java/org/jsmpp/bean/TypeOfNumber.java index 9ad2b70..c536db3 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/TypeOfNumber.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/TypeOfNumber.java @@ -35,7 +35,7 @@ public enum TypeOfNumber { private byte value; - private TypeOfNumber(byte value) { + TypeOfNumber(byte value) { this.value = value; } From b769069fd1d2d90870f6051a42f8d61a185262b3 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Mon, 22 Feb 2016 10:24:57 +0100 Subject: [PATCH 102/212] Update Slf4j --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b224b26..f687edd 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ yyyyMMddHHmm ${maven.build.timestamp} UTF-8 - 1.7.14 + 1.7.16 1.2.17 4.12 6.8.21 From 2116cc362af78265ef6acd9dc6c15b3f32ab4d9d Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Wed, 24 Feb 2016 12:36:26 +0100 Subject: [PATCH 103/212] Add test for RawDataCoding --- .../org/jsmpp/bean/RawDataCodingTest.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 jsmpp/src/test/java/org/jsmpp/bean/RawDataCodingTest.java diff --git a/jsmpp/src/test/java/org/jsmpp/bean/RawDataCodingTest.java b/jsmpp/src/test/java/org/jsmpp/bean/RawDataCodingTest.java new file mode 100644 index 0000000..8629ae2 --- /dev/null +++ b/jsmpp/src/test/java/org/jsmpp/bean/RawDataCodingTest.java @@ -0,0 +1,22 @@ +package org.jsmpp.bean; + + +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.Test; + +/** + * @author pmoerenhout + */ +public class RawDataCodingTest { + + @Test + public void testAllRawDataCodings() { + for (int i = 0; i < 256; i++) { + byte expected = (byte) (0xff & i); + RawDataCoding dataCoding = new RawDataCoding(expected); + assertEquals(dataCoding.toByte(), expected); + assertEquals(dataCoding, new RawDataCoding(expected)); + } + } +} \ No newline at end of file From 74bdaf1b852dcd16f1410f99950c44813156fd12 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Wed, 24 Feb 2016 14:33:04 +0100 Subject: [PATCH 104/212] Change definition of SimpleDataCoding() to MessageClass1, add tests. --- .../java/org/jsmpp/bean/SimpleDataCoding.java | 8 +++---- .../org/jsmpp/bean/SimpleDataCodingTest.java | 23 ++++++++++++++----- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/SimpleDataCoding.java b/jsmpp/src/main/java/org/jsmpp/bean/SimpleDataCoding.java index 980dffd..6c01b59 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/SimpleDataCoding.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/SimpleDataCoding.java @@ -29,10 +29,10 @@ public class SimpleDataCoding implements DataCoding { /** * Construct Data Coding using default Alphabet and - * {@link MessageClass#CLASS0} Message Class. + * {@link MessageClass#CLASS1} Message Class. */ public SimpleDataCoding() { - this(Alphabet.ALPHA_DEFAULT, MessageClass.CLASS0); + this(Alphabet.ALPHA_DEFAULT, MessageClass.CLASS1); } /** @@ -49,7 +49,7 @@ public SimpleDataCoding() { public SimpleDataCoding(Alphabet alphabet, MessageClass messageClass) throws IllegalArgumentException { if (alphabet == null) { throw new IllegalArgumentException( - "alphabet is mandatory, can't be null"); + "Alphabet is mandatory, can't be null"); } if (alphabet.equals(Alphabet.ALPHA_UCS2) || alphabet.isReserved()) { @@ -60,7 +60,7 @@ public SimpleDataCoding(Alphabet alphabet, MessageClass messageClass) throws Ill } if (messageClass == null) { throw new IllegalArgumentException( - "messageClass is mandatory, can't be null"); + "MessageClass is mandatory, can't be null"); } this.alphabet = alphabet; this.messageClass = messageClass; diff --git a/jsmpp/src/test/java/org/jsmpp/bean/SimpleDataCodingTest.java b/jsmpp/src/test/java/org/jsmpp/bean/SimpleDataCodingTest.java index f70b729..4699908 100644 --- a/jsmpp/src/test/java/org/jsmpp/bean/SimpleDataCodingTest.java +++ b/jsmpp/src/test/java/org/jsmpp/bean/SimpleDataCodingTest.java @@ -14,13 +14,8 @@ */ package org.jsmpp.bean; -import static org.testng.Assert.*; +import static org.testng.Assert.assertEquals; -import org.jsmpp.bean.Alphabet; -import org.jsmpp.bean.DataCoding; -import org.jsmpp.bean.DataCodings; -import org.jsmpp.bean.MessageClass; -import org.jsmpp.bean.SimpleDataCoding; import org.testng.annotations.Test; /** @@ -28,6 +23,17 @@ * */ public class SimpleDataCodingTest { + + @Test + public void testDefault() { + // 11110001 + SimpleDataCoding dataCoding = new SimpleDataCoding(); + byte expected = (byte)0xf1; + assertEquals(dataCoding.toByte(), expected); + + DataCoding buildedInstance = DataCodings.newInstance(dataCoding.toByte()); + assertEquals(buildedInstance, dataCoding); + } @Test public void alphaDefaultClass0() { @@ -116,4 +122,9 @@ public void alpha8BitClass3() { DataCoding buildedInstance = DataCodings.newInstance(dataCoding.toByte()); assertEquals(buildedInstance, dataCoding); } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testIllegalAlphabetUcs2() { + SimpleDataCoding dataCoding = new SimpleDataCoding(Alphabet.ALPHA_UCS2, MessageClass.CLASS1); + } } From faf19f6cd55ef89f12db5b580bc47249b392fb0b Mon Sep 17 00:00:00 2001 From: George Kankava Date: Thu, 25 Feb 2016 13:30:49 +0400 Subject: [PATCH 105/212] Multiple code improvements: squid:S00105, squid:S1165 --- .../InvalidNumberOfDestinationsException.java | 2 +- .../org/jsmpp/InvalidRequestException.java | 54 +++++++++---------- .../org/jsmpp/InvalidResponseException.java | 24 ++++----- .../main/java/org/jsmpp/MessageCoding.java | 8 +-- .../src/main/java/org/jsmpp/PDUException.java | 52 +++++++++--------- .../java/org/jsmpp/PDUStringException.java | 2 +- 6 files changed, 71 insertions(+), 71 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/InvalidNumberOfDestinationsException.java b/jsmpp/src/main/java/org/jsmpp/InvalidNumberOfDestinationsException.java index 3b27eec..b49da7b 100644 --- a/jsmpp/src/main/java/org/jsmpp/InvalidNumberOfDestinationsException.java +++ b/jsmpp/src/main/java/org/jsmpp/InvalidNumberOfDestinationsException.java @@ -10,7 +10,7 @@ */ public class InvalidNumberOfDestinationsException extends PDUException { private static final long serialVersionUID = -1515128166927438310L; - private int actualLength; + private final int actualLength; /** * Default constructor. diff --git a/jsmpp/src/main/java/org/jsmpp/InvalidRequestException.java b/jsmpp/src/main/java/org/jsmpp/InvalidRequestException.java index 6b13326..5b85c34 100644 --- a/jsmpp/src/main/java/org/jsmpp/InvalidRequestException.java +++ b/jsmpp/src/main/java/org/jsmpp/InvalidRequestException.java @@ -23,41 +23,41 @@ * */ public class InvalidRequestException extends Exception { - private static final long serialVersionUID = -2275241874120654607L; + private static final long serialVersionUID = -2275241874120654607L; - /** - * Default constructor. - */ - public InvalidRequestException() { - super(); - } + /** + * Default constructor. + */ + public InvalidRequestException() { + super(); + } - /** + /** * Construct with specified message and cause. * - * @param message is the detail message. - * @param cause is the parent cause. - */ - public InvalidRequestException(String message, Throwable cause) { - super(message, cause); - } + * @param message is the detail message. + * @param cause is the parent cause. + */ + public InvalidRequestException(String message, Throwable cause) { + super(message, cause); + } - /** + /** * Construct with specified message. * - * @param message is the detail message. - */ - public InvalidRequestException(String message) { - super(message); - } + * @param message is the detail message. + */ + public InvalidRequestException(String message) { + super(message); + } - /** + /** * Construct with specified cause. * - * @param cause is the parent cause. - */ - public InvalidRequestException(Throwable cause) { - super(cause); - } - + * @param cause is the parent cause. + */ + public InvalidRequestException(Throwable cause) { + super(cause); + } + } diff --git a/jsmpp/src/main/java/org/jsmpp/InvalidResponseException.java b/jsmpp/src/main/java/org/jsmpp/InvalidResponseException.java index 0b3a6de..a835e3c 100644 --- a/jsmpp/src/main/java/org/jsmpp/InvalidResponseException.java +++ b/jsmpp/src/main/java/org/jsmpp/InvalidResponseException.java @@ -29,19 +29,19 @@ public class InvalidResponseException extends Exception { /** * Construct with specified message and cause. * - * @param message is the detail message. - * @param cause is the parent cause. - */ - public InvalidResponseException(String message, Throwable cause) { - super(message, cause); - } + * @param message is the detail message. + * @param cause is the parent cause. + */ + public InvalidResponseException(String message, Throwable cause) { + super(message, cause); + } - /** + /** * Construct with specified message. * - * @param message is the detail message. - */ - public InvalidResponseException(String message) { - super(message); - } + * @param message is the detail message. + */ + public InvalidResponseException(String message) { + super(message); + } } diff --git a/jsmpp/src/main/java/org/jsmpp/MessageCoding.java b/jsmpp/src/main/java/org/jsmpp/MessageCoding.java index e3d6e05..2b6e98d 100644 --- a/jsmpp/src/main/java/org/jsmpp/MessageCoding.java +++ b/jsmpp/src/main/java/org/jsmpp/MessageCoding.java @@ -23,10 +23,10 @@ * */ public enum MessageCoding { - /** - * Coding 7-bit. - */ - CODING_7_BIT, + /** + * Coding 7-bit. + */ + CODING_7_BIT, /** * Coding 8-bit. diff --git a/jsmpp/src/main/java/org/jsmpp/PDUException.java b/jsmpp/src/main/java/org/jsmpp/PDUException.java index 53541a7..f3098e9 100644 --- a/jsmpp/src/main/java/org/jsmpp/PDUException.java +++ b/jsmpp/src/main/java/org/jsmpp/PDUException.java @@ -24,40 +24,40 @@ */ public class PDUException extends Exception { - private static final long serialVersionUID = -4168434058788171394L; + private static final long serialVersionUID = -4168434058788171394L; - /** - * Default constructor. - */ - public PDUException() { - super("PDUException found"); - } + /** + * Default constructor. + */ + public PDUException() { + super("PDUException found"); + } - /** + /** * Construct with specified message and cause. * - * @param message is the detail message. - * @param cause is the parent cause. - */ - public PDUException(String message, Throwable cause) { - super(message, cause); - } + * @param message is the detail message. + * @param cause is the parent cause. + */ + public PDUException(String message, Throwable cause) { + super(message, cause); + } - /** + /** * Construct with specified message. * - * @param message is the detail message. - */ - public PDUException(String message) { - super(message); - } + * @param message is the detail message. + */ + public PDUException(String message) { + super(message); + } - /** + /** * Construct with specified cause. * - * @param cause is the parent cause. - */ - public PDUException(Throwable cause) { - super(cause); - } + * @param cause is the parent cause. + */ + public PDUException(Throwable cause) { + super(cause); + } } diff --git a/jsmpp/src/main/java/org/jsmpp/PDUStringException.java b/jsmpp/src/main/java/org/jsmpp/PDUStringException.java index c8d30fa..597358c 100644 --- a/jsmpp/src/main/java/org/jsmpp/PDUStringException.java +++ b/jsmpp/src/main/java/org/jsmpp/PDUStringException.java @@ -26,7 +26,7 @@ */ public class PDUStringException extends PDUException { private static final long serialVersionUID = 5456303478921567516L; - private StringParameter parameter; + private final StringParameter parameter; /** * Construct with specified message and parameter. From b07d314304a0460eb2a59e987b448c5ec04b2669 Mon Sep 17 00:00:00 2001 From: George Kankava Date: Thu, 25 Feb 2016 14:38:23 +0400 Subject: [PATCH 106/212] multiple code improvements: squid:S1213, squid:S1488, squid:S1197, squid:S00115 --- jsmpp/src/main/java/org/jsmpp/DefaultPDUSender.java | 2 +- jsmpp/src/main/java/org/jsmpp/SMPPConstant.java | 2 +- jsmpp/src/main/java/org/jsmpp/bean/DeliverSm.java | 8 ++++---- jsmpp/src/main/java/org/jsmpp/bean/SarSegmentSeqnum.java | 3 +-- jsmpp/src/main/java/org/jsmpp/bean/SarTotalSegments.java | 5 ++--- 5 files changed, 9 insertions(+), 11 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/DefaultPDUSender.java b/jsmpp/src/main/java/org/jsmpp/DefaultPDUSender.java index 30fd8d3..37fc732 100644 --- a/jsmpp/src/main/java/org/jsmpp/DefaultPDUSender.java +++ b/jsmpp/src/main/java/org/jsmpp/DefaultPDUSender.java @@ -110,7 +110,7 @@ public byte[] sendBindResp(OutputStream os, int commandId, int sequenceNumber, String systemId, InterfaceVersion interfaceVersion) throws PDUStringException, IOException { - OptionalParameter p[]; + OptionalParameter[] p; if(interfaceVersion != null) { OptionalParameter interfaceVersionParam = new OptionalParameter.Byte(Tag.SC_INTERFACE_VERSION, interfaceVersion.value()); p = new OptionalParameter[] {interfaceVersionParam}; diff --git a/jsmpp/src/main/java/org/jsmpp/SMPPConstant.java b/jsmpp/src/main/java/org/jsmpp/SMPPConstant.java index dd56463..ec741a6 100644 --- a/jsmpp/src/main/java/org/jsmpp/SMPPConstant.java +++ b/jsmpp/src/main/java/org/jsmpp/SMPPConstant.java @@ -343,7 +343,7 @@ public interface SMPPConstant { public static final short TAG_SC_INTERFACE_VERSION = 0x0210; public static final short TAG_SAR_MSG_REF_NUM = 0X020C; - public static final short TAG_SAR_TOTAl_SEGMENTS = 0x020e; + public static final short TAG_SAR_TOTAL_SEGMENTS = 0x020e; public static final short TAG_SAR_SEGMENT_SEQNUM = 0x020f; /* diff --git a/jsmpp/src/main/java/org/jsmpp/bean/DeliverSm.java b/jsmpp/src/main/java/org/jsmpp/bean/DeliverSm.java index 2da18f6..0d71075 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/DeliverSm.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/DeliverSm.java @@ -25,6 +25,10 @@ public class DeliverSm extends MessageRequest { private String id; + public DeliverSm() { + super(); + } + public String getId() { return id; } @@ -33,10 +37,6 @@ public void setId(String id) { this.id = id; } - public DeliverSm() { - super(); - } - /** * Get the short message as {@link DeliveryReceipt}. This method will be * valid if the parsed short message valid and Message Type (esm_class) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/SarSegmentSeqnum.java b/jsmpp/src/main/java/org/jsmpp/bean/SarSegmentSeqnum.java index 855518e..812bf0d 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/SarSegmentSeqnum.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/SarSegmentSeqnum.java @@ -45,8 +45,7 @@ public short getValue() { @Override public int hashCode() { - int result = 1; - return result; + return 1; } @Override diff --git a/jsmpp/src/main/java/org/jsmpp/bean/SarTotalSegments.java b/jsmpp/src/main/java/org/jsmpp/bean/SarTotalSegments.java index 05402cf..f0cb614 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/SarTotalSegments.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/SarTotalSegments.java @@ -32,7 +32,7 @@ public SarTotalSegments(short value) { } public short getTag() { - return SMPPConstant.TAG_SAR_TOTAl_SEGMENTS; + return SMPPConstant.TAG_SAR_TOTAL_SEGMENTS; } public short getLength() { @@ -45,8 +45,7 @@ public short getValue() { @Override public int hashCode() { - int result = 1; - return result; + return 1; } @Override From bd99acbf530c83bad55fd4decc6f6148a39bdd9b Mon Sep 17 00:00:00 2001 From: George Kankava Date: Thu, 25 Feb 2016 14:59:18 +0400 Subject: [PATCH 107/212] multiple code improvements: squid:S1197, squid:S1170 --- .../java/org/jsmpp/bean/DataCodingFactory1111.java | 2 +- .../main/java/org/jsmpp/bean/OptionalParameter.java | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/DataCodingFactory1111.java b/jsmpp/src/main/java/org/jsmpp/bean/DataCodingFactory1111.java index 7bef940..ded0e52 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/DataCodingFactory1111.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/DataCodingFactory1111.java @@ -33,7 +33,7 @@ public class DataCodingFactory1111 extends AbstractDataCodingFactory { /** * bin: 11110111 */ - private final byte MASK_BIT3_REMOVAL = (byte)0xf7; + private static final byte MASK_BIT3_REMOVAL = (byte)0xf7; public DataCodingFactory1111() { super(MASK, GROUP); diff --git a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java index a10cf99..9eb6a0f 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java @@ -1729,7 +1729,7 @@ public short getErrorCode() { */ public static class Message_payload extends OptionalParameter.OctetString { - public Message_payload(byte value[]) { + public Message_payload(byte[] value) { super(Tag.MESSAGE_PAYLOAD.code(), value); } } @@ -1970,7 +1970,7 @@ public Ussd_service_op(byte[] content) { * */ public static class Billing_identification extends OptionalParameter.OctetString { - public Billing_identification(byte value[]) { + public Billing_identification(byte[] value) { super(Tag.BILLING_IDENTIFICATION.code, value); } @@ -2138,7 +2138,7 @@ public Its_session_info(byte[] content) { */ public static class Vendor_specific_source_msc_addr extends OptionalParameter.Vendor_specific_msc_addr { - public Vendor_specific_source_msc_addr(byte value[]) { + public Vendor_specific_source_msc_addr(byte[] value) { super(Tag.VENDOR_SPECIFIC_SOURCE_MSC_ADDR.code, value); } } @@ -2152,7 +2152,7 @@ public Vendor_specific_source_msc_addr(byte value[]) { */ public static class Vendor_specific_dest_msc_addr extends OptionalParameter.Vendor_specific_msc_addr { - public Vendor_specific_dest_msc_addr(byte value[]) { + public Vendor_specific_dest_msc_addr(byte[] value) { super(Tag.VENDOR_SPECIFIC_DEST_MSC_ADDR.code, value); } } @@ -2160,7 +2160,7 @@ public Vendor_specific_dest_msc_addr(byte value[]) { private static class Vendor_specific_msc_addr extends OptionalParameter.OctetString { String address; - private Vendor_specific_msc_addr(short tag, byte value[]) { + private Vendor_specific_msc_addr(short tag, byte[] value) { super(tag, value); try { if (value.length >= 2) { From f63388e2bd41dfa3f7c8e0cbeda58a8dbf519f51 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Thu, 25 Feb 2016 16:29:42 +0100 Subject: [PATCH 108/212] Lexical improvement --- jsmpp/src/main/java/org/jsmpp/MessageCoding.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsmpp/src/main/java/org/jsmpp/MessageCoding.java b/jsmpp/src/main/java/org/jsmpp/MessageCoding.java index 2b6e98d..86ef202 100644 --- a/jsmpp/src/main/java/org/jsmpp/MessageCoding.java +++ b/jsmpp/src/main/java/org/jsmpp/MessageCoding.java @@ -15,7 +15,7 @@ package org.jsmpp; /** - * This is an enum const that specifies the message coding (see smpp spesification). + * This is an enum const that specifies the message coding (see SMPP specification). * * @author uudashr * @version 1.0 From b9ce7b2e9fd05c062a27e6dfb1deccad77590da7 Mon Sep 17 00:00:00 2001 From: George Kankava Date: Tue, 1 Mar 2016 10:51:40 +0400 Subject: [PATCH 109/212] multiple code improvements: squid:S00117, squid:S1192, squid:S00117 --- .../java/org/jsmpp/session/QuerySmResult.java | 6 +++--- .../org/jsmpp/session/SMPPServerSession.java | 19 +++++++++++-------- .../java/org/jsmpp/session/SMPPSession.java | 15 +++++++-------- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/QuerySmResult.java b/jsmpp/src/main/java/org/jsmpp/session/QuerySmResult.java index bf8b937..9e1806a 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/QuerySmResult.java +++ b/jsmpp/src/main/java/org/jsmpp/session/QuerySmResult.java @@ -61,10 +61,10 @@ public MessageState getMessageState() { */ @Override public int hashCode() { - final int PRIME = 31; + final int prime = 31; int result = 1; - result = PRIME * result + ((finalDate == null) ? 0 : finalDate.hashCode()); - result = PRIME * result + ((messageState == null) ? 0 : messageState.hashCode()); + result = prime * result + ((finalDate == null) ? 0 : finalDate.hashCode()); + result = prime * result + ((messageState == null) ? 0 : messageState.hashCode()); return result; } diff --git a/jsmpp/src/main/java/org/jsmpp/session/SMPPServerSession.java b/jsmpp/src/main/java/org/jsmpp/session/SMPPServerSession.java index 6e5b064..2824fe5 100755 --- a/jsmpp/src/main/java/org/jsmpp/session/SMPPServerSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/SMPPServerSession.java @@ -66,6 +66,9 @@ * */ public class SMPPServerSession extends AbstractSession implements ServerSession { + private static final String MESSAGE_RECEIVER_LISTENER_IS_NULL = "Received SubmitMultiSm but MessageReceiverListener is null, returning SMPP error"; + private static final String NO_MESSAGE_RECEIVER_LISTENER_REGISTERED = "No message receiver listener registered"; + private static final Logger logger = LoggerFactory.getLogger(SMPPServerSession.class); private final Connection conn; @@ -191,7 +194,7 @@ private MessageId fireAcceptSubmitSm(SubmitSm submitSm) throws ProcessRequestExc return messageReceiverListener.onAcceptSubmitSm(submitSm, this); } logger.warn("Received SubmitSm but MessageReceiverListener is null, returning SMPP error"); - throw new ProcessRequestException("No message receiver listener registered", + throw new ProcessRequestException(NO_MESSAGE_RECEIVER_LISTENER_REGISTERED, SMPPConstant.STAT_ESME_RX_R_APPN); } @@ -199,8 +202,8 @@ private SubmitMultiResult fireAcceptSubmitMulti(SubmitMulti submitMulti) throws if (messageReceiverListener != null) { return messageReceiverListener.onAcceptSubmitMulti(submitMulti, this); } - logger.warn("Received SubmitMultiSm but MessageReceiverListener is null, returning SMPP error"); - throw new ProcessRequestException("No message receiver listener registered", + logger.warn(MESSAGE_RECEIVER_LISTENER_IS_NULL); + throw new ProcessRequestException(NO_MESSAGE_RECEIVER_LISTENER_REGISTERED, SMPPConstant.STAT_ESME_RX_R_APPN); } @@ -209,7 +212,7 @@ private QuerySmResult fireAcceptQuerySm(QuerySm querySm) throws ProcessRequestEx return messageReceiverListener.onAcceptQuerySm(querySm, this); } logger.warn("Received SubmitQuerySm but MessageReceiverListener is null, returning SMPP error"); - throw new ProcessRequestException("No message receiver listener registered", + throw new ProcessRequestException(NO_MESSAGE_RECEIVER_LISTENER_REGISTERED, SMPPConstant.STAT_ESME_RX_R_APPN); } @@ -217,8 +220,8 @@ private void fireAcceptReplaceSm(ReplaceSm replaceSm) throws ProcessRequestExcep if (messageReceiverListener != null) { messageReceiverListener.onAcceptReplaceSm(replaceSm, this); } else { - logger.warn("Received SubmitMultiSm but MessageReceiverListener is null, returning SMPP error"); - throw new ProcessRequestException("No message receiver listener registered", + logger.warn(MESSAGE_RECEIVER_LISTENER_IS_NULL); + throw new ProcessRequestException(NO_MESSAGE_RECEIVER_LISTENER_REGISTERED, SMPPConstant.STAT_ESME_RX_R_APPN); } } @@ -227,8 +230,8 @@ private void fireAcceptCancelSm(CancelSm cancelSm) throws ProcessRequestExceptio if (messageReceiverListener != null) { messageReceiverListener.onAcceptCancelSm(cancelSm, this); } else { - logger.warn("Received SubmitMultiSm but MessageReceiverListener is null, returning SMPP error"); - throw new ProcessRequestException("No message receiver listener registered", + logger.warn(MESSAGE_RECEIVER_LISTENER_IS_NULL); + throw new ProcessRequestException(NO_MESSAGE_RECEIVER_LISTENER_REGISTERED, SMPPConstant.STAT_ESME_RX_R_APPN); } } diff --git a/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java b/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java index 3870c09..af8e7d4 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java @@ -294,9 +294,9 @@ private String sendBind(BindType bindType, String systemId, addrNpi, addressRange); BindResp resp = (BindResp)executeSendCommand(task, timeout); - OptionalParameter.Sc_interface_version sc_version = resp.getOptionalParameter(Sc_interface_version.class); - if(sc_version != null) { - logger.info("Other side reports smpp interface version {}", sc_version); + OptionalParameter.Sc_interface_version scVersion = resp.getOptionalParameter(Sc_interface_version.class); + if(scVersion != null) { + logger.info("Other side reports smpp interface version {}", scVersion); } return resp.getSystemId(); @@ -564,17 +564,16 @@ public void sendUnbindResp(int sequenceNumber) throws IOException { private class PDUReaderWorker extends Thread { // start with serial execution of pdu processing, when the session is bound the pool will be enlarge up to the PduProcessorDegree private ExecutorService executorService = Executors.newFixedThreadPool(1); - - public PDUReaderWorker() { - super("PDUReaderWorker: " + SMPPSession.this); - } - private Runnable onIOExceptionTask = new Runnable() { public void run() { close(); }; }; + public PDUReaderWorker() { + super("PDUReaderWorker: " + SMPPSession.this); + } + @Override public void run() { logger.info("Starting PDUReaderWorker"); From 8f9994c313db40c8cd169b01cb197e7f519207bf Mon Sep 17 00:00:00 2001 From: George Kankava Date: Tue, 1 Mar 2016 12:11:33 +0400 Subject: [PATCH 110/212] squid:S1192 String literals should not be duplicated --- .../state/SMPPServerSessionClosed.java | 32 ++++++++++--------- .../session/state/SMPPServerSessionOpen.java | 29 +++++++++-------- .../state/SMPPServerSessionUnbound.java | 32 ++++++++++--------- .../session/state/SMPPSessionBoundTX.java | 7 ++-- .../session/state/SMPPSessionClosed.java | 31 +++++++++--------- .../session/state/SMPPSessionUnbound.java | 31 +++++++++--------- 6 files changed, 85 insertions(+), 77 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionClosed.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionClosed.java index 6df1586..1acc3b3 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionClosed.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionClosed.java @@ -27,82 +27,84 @@ */ class SMPPServerSessionClosed implements SMPPServerSessionState { + private static final String INVALID_PROCESS_FOR_CLOSED_SESSION = "Invalid process for closed session state"; + public SessionState getSessionState() { return SessionState.CLOSED; } public void processBind(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for closed session state"); + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } public void processDeliverSmResp(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for closed session state"); + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } public void processQuerySm(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for closed session state"); + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } public void processSubmitSm(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for closed session state"); + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } public void processSubmitMulti(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for closed session state"); + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } public void processEnquireLink(Command pduHeader, byte[] pdu, BaseResponseHandler sessionHandler) throws IOException { - throw new IOException("Invalid process for closed session state"); + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } public void processEnquireLinkResp(Command pduHeader, byte[] pdu, BaseResponseHandler sessionHandler) throws IOException { - throw new IOException("Invalid process for closed session state"); + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } public void processGenericNack(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for closed session state"); + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } public void processUnbind(Command pduHeader, byte[] pdu, BaseResponseHandler sessionHandler) throws IOException { - throw new IOException("Invalid process for closed session state"); + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } public void processUnbindResp(Command pduHeader, byte[] pdu, BaseResponseHandler sessionHandler) throws IOException { - throw new IOException("Invalid process for closed session state"); + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } public void processUnknownCid(Command pduHeader, byte[] pdu, BaseResponseHandler sessionHandler) throws IOException { - throw new IOException("Invalid process for closed session state"); + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } public void processDataSm(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for closed session state"); + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } public void processDataSmResp(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for closed session state"); + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } public void processCancelSm(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for closed session state"); + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } public void processReplaceSm(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for closed session state"); + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } } diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionOpen.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionOpen.java index 562f6f8..1455d20 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionOpen.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionOpen.java @@ -31,6 +31,7 @@ * */ class SMPPServerSessionOpen implements SMPPServerSessionState { + private static final String INVALID_PROCESS_FOR_OPEN_SESSION = "Invalid process for open session state"; private static final PDUDecomposer pduDecomposer = new DefaultDecomposer(); public SessionState getSessionState() { @@ -53,73 +54,73 @@ public void processBind(Command pduHeader, byte[] pdu, public void processDeliverSmResp(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for open session state"); + throw new IOException(INVALID_PROCESS_FOR_OPEN_SESSION); } public void processQuerySm(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for open session state"); + throw new IOException(INVALID_PROCESS_FOR_OPEN_SESSION); } public void processSubmitSm(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for open session state"); + throw new IOException(INVALID_PROCESS_FOR_OPEN_SESSION); } public void processSubmitMulti(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for open session state"); + throw new IOException(INVALID_PROCESS_FOR_OPEN_SESSION); } public void processEnquireLink(Command pduHeader, byte[] pdu, BaseResponseHandler sessionHandler) throws IOException { - throw new IOException("Invalid process for open session state"); + throw new IOException(INVALID_PROCESS_FOR_OPEN_SESSION); } public void processEnquireLinkResp(Command pduHeader, byte[] pdu, BaseResponseHandler sessionHandler) throws IOException { - throw new IOException("Invalid process for open session state"); + throw new IOException(INVALID_PROCESS_FOR_OPEN_SESSION); } public void processGenericNack(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for open session state"); + throw new IOException(INVALID_PROCESS_FOR_OPEN_SESSION); } public void processUnbind(Command pduHeader, byte[] pdu, BaseResponseHandler sessionHandler) throws IOException { - throw new IOException("Invalid process for open session state"); + throw new IOException(INVALID_PROCESS_FOR_OPEN_SESSION); } public void processUnbindResp(Command pduHeader, byte[] pdu, BaseResponseHandler sessionHandler) throws IOException { - throw new IOException("Invalid process for open session state"); + throw new IOException(INVALID_PROCESS_FOR_OPEN_SESSION); } public void processUnknownCid(Command pduHeader, byte[] pdu, BaseResponseHandler sessionHandler) throws IOException { - throw new IOException("Invalid process for open session state"); + throw new IOException(INVALID_PROCESS_FOR_OPEN_SESSION); } public void processDataSm(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for open session state"); + throw new IOException(INVALID_PROCESS_FOR_OPEN_SESSION); } public void processDataSmResp(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for open session state"); + throw new IOException(INVALID_PROCESS_FOR_OPEN_SESSION); } public void processCancelSm(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for open session state"); + throw new IOException(INVALID_PROCESS_FOR_OPEN_SESSION); } public void processReplaceSm(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for open session state"); + throw new IOException(INVALID_PROCESS_FOR_OPEN_SESSION); } } diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionUnbound.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionUnbound.java index 17a1446..8992513 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionUnbound.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionUnbound.java @@ -27,6 +27,8 @@ */ public class SMPPServerSessionUnbound implements SMPPServerSessionState { + private static final String INVALID_PROCESS_FOR_UNBOUND_SESSION = "Invalid process for unbound session state"; + public SessionState getSessionState() { return SessionState.UNBOUND; } @@ -34,78 +36,78 @@ public SessionState getSessionState() { public void processBind(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for unbound session state"); + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } public void processDeliverSmResp(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for unbound session state"); + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } public void processQuerySm(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for unbound session state"); + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } public void processSubmitSm(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for unbound session state"); + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } public void processSubmitMulti(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for unbound session state"); + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } public void processEnquireLink(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for unbound session state"); + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } public void processEnquireLinkResp(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for unbound session state"); + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } public void processGenericNack(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for unbound session state"); + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } public void processUnbind(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for unbound session state"); + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } public void processUnbindResp(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for unbound session state"); + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } public void processUnknownCid(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for unbound session state"); + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } public void processDataSm(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for unbound session state"); + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } public void processDataSmResp(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for unbound session state"); + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } public void processCancelSm(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for unbound session state"); + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } public void processReplaceSm(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for unbound session state"); + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } } diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionBoundTX.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionBoundTX.java index 3cd78d2..f339a18 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionBoundTX.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionBoundTX.java @@ -41,6 +41,7 @@ * */ class SMPPSessionBoundTX extends SMPPSessionBound implements SMPPSessionState { + private static final String NO_REQUEST_FIND_FOR_SEQUENCE_NUMBER = "No request find for sequence number "; private static final Logger logger = LoggerFactory.getLogger(SMPPSessionBoundTX.class); public SessionState getSessionState() { @@ -101,7 +102,7 @@ public void processQuerySmResp(Command pduHeader, byte[] pdu, .getSequenceNumber()); } } else { - logger.error("No request find for sequence number " + logger.error(NO_REQUEST_FIND_FOR_SEQUENCE_NUMBER + pduHeader.getSequenceNumber()); responseHandler.sendGenerickNack( SMPPConstant.STAT_ESME_RINVDFTMSGID, pduHeader @@ -117,7 +118,7 @@ public void processCancelSmResp(Command pduHeader, byte[] pdu, CancelSmResp resp = pduDecomposer.cancelSmResp(pdu); pendingResp.done(resp); } else { - logger.error("No request find for sequence number " + logger.error(NO_REQUEST_FIND_FOR_SEQUENCE_NUMBER + pduHeader.getSequenceNumber()); } } @@ -130,7 +131,7 @@ public void processReplaceSmResp(Command pduHeader, byte[] pdu, ReplaceSmResp resp = pduDecomposer.replaceSmResp(pdu); pendingResp.done(resp); } else { - logger.error("No request find for sequence number " + logger.error(NO_REQUEST_FIND_FOR_SEQUENCE_NUMBER + pduHeader.getSequenceNumber()); } } diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionClosed.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionClosed.java index 91f7fc5..5cfc204 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionClosed.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionClosed.java @@ -34,6 +34,7 @@ * */ class SMPPSessionClosed implements SMPPSessionState { + private static final String INVALID_PROCESS_FOR_CLOSED_SESSION = "Invalid process for closed session state"; private static final Logger logger = LoggerFactory.getLogger(SMPPSessionClosed.class); public SessionState getSessionState() { @@ -42,77 +43,77 @@ public SessionState getSessionState() { public void processBindResp(Command pduHeader, byte[] pdu, ResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for closed session state"); + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } public void processDeliverSm(Command pduHeader, byte[] pdu, ResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for closed session state"); + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } public void processEnquireLink(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for closed session state"); + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } public void processEnquireLinkResp(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for closed session state"); + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } public void processGenericNack(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for closed session state"); + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } public void processQuerySmResp(Command pduHeader, byte[] pdu, ResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for closed session state"); + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } public void processSubmitSmResp(Command pduHeader, byte[] pdu, ResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for closed session state"); + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } public void processSubmitMultiResp(Command pduHeader, byte[] pdu, ResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for closed session state"); + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } public void processUnbind(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for closed session state"); + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } public void processUnbindResp(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for closed session state"); + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } public void processUnknownCid(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for closed session state"); + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } public void processDataSm(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for closed session state"); + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } public void processDataSmResp(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for closed session state"); + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } public void processCancelSmResp(Command pduHeader, byte[] pdu, ResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for closed session state"); + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } public void processReplaceSmResp(Command pduHeader, byte[] pdu, ResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for closed session state"); + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } public void processAlertNotification(Command pduHeader, byte[] pdu, diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionUnbound.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionUnbound.java index 08987e2..e1e07bc 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionUnbound.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionUnbound.java @@ -34,6 +34,7 @@ * */ class SMPPSessionUnbound implements SMPPSessionState { + private static final String INVALID_PROCESS_FOR_UNBOUND_SESSION = "Invalid process for unbound session state"; private static final Logger logger = LoggerFactory.getLogger(SMPPSessionUnbound.class); public SessionState getSessionState() { @@ -42,77 +43,77 @@ public SessionState getSessionState() { public void processBindResp(Command pduHeader, byte[] pdu, ResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for unbound session state"); + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } public void processDeliverSm(Command pduHeader, byte[] pdu, ResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for unbound session state"); + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } public void processEnquireLink(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for unbound session state"); + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } public void processEnquireLinkResp(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for unbound session state"); + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } public void processGenericNack(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for unbound session state"); + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } public void processSubmitSmResp(Command pduHeader, byte[] pdu, ResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for unbound session state"); + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } public void processSubmitMultiResp(Command pduHeader, byte[] pdu, ResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for unbound session state"); + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } public void processUnbind(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for unbound session state"); + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } public void processUnbindResp(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for unbound session state"); + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } public void processUnknownCid(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for unbound session state"); + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } public void processQuerySmResp(Command pduHeader, byte[] pdu, ResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for unbound session state"); + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } public void processDataSm(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for unbound session state"); + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } public void processDataSmResp(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for unbound session state"); + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } public void processCancelSmResp(Command pduHeader, byte[] pdu, ResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for unbound session state"); + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } public void processReplaceSmResp(Command pduHeader, byte[] pdu, ResponseHandler responseHandler) throws IOException { - throw new IOException("Invalid process for unbound session state"); + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } public void processAlertNotification(Command pduHeader, byte[] pdu, From 046cd72f0506c3f28ce765aaecca3b1685e0b36c Mon Sep 17 00:00:00 2001 From: George Kankava Date: Tue, 1 Mar 2016 13:21:59 +0400 Subject: [PATCH 111/212] multiple code improvements: squid:S1213, squid:S1905, squid:S1488, squid:S2325, squid:S3008 --- .../session/connection/socket/SocketConnectionFactory.java | 6 +++--- .../src/main/java/org/jsmpp/util/AbsoluteTimeFormatter.java | 2 +- jsmpp/src/main/java/org/jsmpp/util/DefaultComposer.java | 3 +-- jsmpp/src/main/java/org/jsmpp/util/DefaultDecomposer.java | 2 +- jsmpp/src/main/java/org/jsmpp/util/PDUByteBuffer.java | 2 +- 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/connection/socket/SocketConnectionFactory.java b/jsmpp/src/main/java/org/jsmpp/session/connection/socket/SocketConnectionFactory.java index efefea4..040640e 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/connection/socket/SocketConnectionFactory.java +++ b/jsmpp/src/main/java/org/jsmpp/session/connection/socket/SocketConnectionFactory.java @@ -27,11 +27,11 @@ public class SocketConnectionFactory implements ConnectionFactory { private static final SocketConnectionFactory connFactory = new SocketConnectionFactory(); - public static SocketConnectionFactory getInstance() { - return connFactory; + private SocketConnectionFactory() { } - private SocketConnectionFactory() { + public static SocketConnectionFactory getInstance() { + return connFactory; } public Connection createConnection(String host, int port) diff --git a/jsmpp/src/main/java/org/jsmpp/util/AbsoluteTimeFormatter.java b/jsmpp/src/main/java/org/jsmpp/util/AbsoluteTimeFormatter.java index 35a81e9..13a0ac5 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/AbsoluteTimeFormatter.java +++ b/jsmpp/src/main/java/org/jsmpp/util/AbsoluteTimeFormatter.java @@ -57,7 +57,7 @@ public String format(Calendar calendar) { } // Time difference in quarter hours - int timeDiff = (int)(Math.abs(offset) / (15 * 60 * 1000)); + int timeDiff = Math.abs(offset) / (15 * 60 * 1000); return format(year, month, day, hour, minute, second, tenthsOfSecond, timeDiff, sign); } diff --git a/jsmpp/src/main/java/org/jsmpp/util/DefaultComposer.java b/jsmpp/src/main/java/org/jsmpp/util/DefaultComposer.java index 784e2ab..d86e64c 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/DefaultComposer.java +++ b/jsmpp/src/main/java/org/jsmpp/util/DefaultComposer.java @@ -437,9 +437,8 @@ public byte[] cancelSm(int sequenceNumber, String serviceType, } public byte[] cancelSmResp(int sequenceNumber) { - byte[] b = composeHeader(SMPPConstant.CID_CANCEL_SM_RESP, + return composeHeader(SMPPConstant.CID_CANCEL_SM_RESP, SMPPConstant.STAT_ESME_ROK, sequenceNumber); - return b; } public byte[] replaceSm(int sequenceNumber, String messageId, diff --git a/jsmpp/src/main/java/org/jsmpp/util/DefaultDecomposer.java b/jsmpp/src/main/java/org/jsmpp/util/DefaultDecomposer.java index bbeaf9a..46fb0f5 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/DefaultDecomposer.java +++ b/jsmpp/src/main/java/org/jsmpp/util/DefaultDecomposer.java @@ -614,7 +614,7 @@ public AlertNotification alertNotification(byte[] data) throws PDUStringExceptio return req; } - private OptionalParameter[] readOptionalParameters( + private static OptionalParameter[] readOptionalParameters( SequentialBytesReader reader) { if (!reader.hasMoreBytes()) return null; diff --git a/jsmpp/src/main/java/org/jsmpp/util/PDUByteBuffer.java b/jsmpp/src/main/java/org/jsmpp/util/PDUByteBuffer.java index 7fd7a0b..d286190 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/PDUByteBuffer.java +++ b/jsmpp/src/main/java/org/jsmpp/util/PDUByteBuffer.java @@ -27,7 +27,7 @@ * */ public class PDUByteBuffer { - private static CapacityPolicy DEFAULT_CAPACITY_POLICY = new SimpleCapacityPolicy(); + private static final CapacityPolicy DEFAULT_CAPACITY_POLICY = new SimpleCapacityPolicy(); private CapacityPolicy capacityPolicy; private byte[] bytes; private int bytesLength; From 179790d14665ac29370b3d45183050efb8cf9d56 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Tue, 1 Mar 2016 15:03:02 +0100 Subject: [PATCH 112/212] Add @Override --- .../session/connection/socket/SocketConnectionFactory.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/connection/socket/SocketConnectionFactory.java b/jsmpp/src/main/java/org/jsmpp/session/connection/socket/SocketConnectionFactory.java index 040640e..00a7127 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/connection/socket/SocketConnectionFactory.java +++ b/jsmpp/src/main/java/org/jsmpp/session/connection/socket/SocketConnectionFactory.java @@ -33,7 +33,8 @@ private SocketConnectionFactory() { public static SocketConnectionFactory getInstance() { return connFactory; } - + + @Override public Connection createConnection(String host, int port) throws IOException { return new SocketConnection(new Socket(host, port)); From 09b0ca3f6dfd1109c9027dfecd7b64fe925bcc2b Mon Sep 17 00:00:00 2001 From: George Kankava Date: Tue, 1 Mar 2016 20:22:16 +0400 Subject: [PATCH 113/212] multiple code improvements: squid:S1192, squid:AssignmentInSubExpressionCheck, squid:S1149, squid:S1165 --- .../extra/NegativeResponseException.java | 2 +- .../src/main/java/org/jsmpp/util/HexUtil.java | 6 ++--- .../main/java/org/jsmpp/util/StopWatch.java | 3 ++- .../java/org/jsmpp/util/StringValidator.java | 23 +++++++++++-------- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/extra/NegativeResponseException.java b/jsmpp/src/main/java/org/jsmpp/extra/NegativeResponseException.java index c58363e..76344f8 100644 --- a/jsmpp/src/main/java/org/jsmpp/extra/NegativeResponseException.java +++ b/jsmpp/src/main/java/org/jsmpp/extra/NegativeResponseException.java @@ -12,7 +12,7 @@ */ public class NegativeResponseException extends Exception { private static final long serialVersionUID = 7198456791204091251L; - private int commandStatus; + private final int commandStatus; /** * Construct with specified command_status. diff --git a/jsmpp/src/main/java/org/jsmpp/util/HexUtil.java b/jsmpp/src/main/java/org/jsmpp/util/HexUtil.java index f54df6e..f539604 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/HexUtil.java +++ b/jsmpp/src/main/java/org/jsmpp/util/HexUtil.java @@ -83,12 +83,12 @@ public static String convertBytesToHexString(byte[] data, int offset, int length */ public static String convertHexStringToString(String hexString) { String uHexString = hexString.toLowerCase(); - StringBuffer sBuf = new StringBuffer(); + StringBuilder sBld = new StringBuilder(); for (int i = 0; i < uHexString.length(); i = i + 2) { char c = (char)Integer.parseInt(uHexString.substring(i, i + 2), 16); - sBuf.append(c); + sBld.append(c); } - return sBuf.toString(); + return sBld.toString(); } /** diff --git a/jsmpp/src/main/java/org/jsmpp/util/StopWatch.java b/jsmpp/src/main/java/org/jsmpp/util/StopWatch.java index d4b7d34..6a6ff2f 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/StopWatch.java +++ b/jsmpp/src/main/java/org/jsmpp/util/StopWatch.java @@ -29,7 +29,8 @@ public class StopWatch { * @return the current time in millisecond. */ public long start() { - return startTime = System.currentTimeMillis(); + startTime = System.currentTimeMillis(); + return startTime; } /** diff --git a/jsmpp/src/main/java/org/jsmpp/util/StringValidator.java b/jsmpp/src/main/java/org/jsmpp/util/StringValidator.java index 5fa610a..ba12574 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/StringValidator.java +++ b/jsmpp/src/main/java/org/jsmpp/util/StringValidator.java @@ -25,6 +25,9 @@ * */ public final class StringValidator { + private static final String ACTUAL_LENGTH_IS = ". Actual length is "; + private static final String C_OCTET_STRING_VALUE = "C-Octet String value '"; + private StringValidator() { } @@ -33,22 +36,22 @@ public static void validateString(String value, StringParameter param) if (param.getType() == StringType.C_OCTET_STRING) { if (param.isRangeMinAndMax()) { if (!isCOctetStringValid(value, param.getMax())) { - throw new PDUStringException("C-Octet String value '" + throw new PDUStringException(C_OCTET_STRING_VALUE + value + "' length must be less than " + param.getMax() - + ". Actual length is " + value.length(), + + ACTUAL_LENGTH_IS + value.length(), param); } } else if (!isCOctetStringNullOrNValValid(value, param.getMax())) { throw new PDUStringException( - "C-Octet String value '" + value + "' length should be 1 or " + (param.getMax() - 1) - + ". Actual length is " + C_OCTET_STRING_VALUE + value + "' length should be 1 or " + (param.getMax() - 1) + + ACTUAL_LENGTH_IS + value.length(), param); } } else if (param.getType() == StringType.OCTET_STRING && !isOctetStringValid(value, param.getMax())) { throw new PDUStringException("Octet String value '" + value + "' length must be less than or equal to " + param.getMax() - + ". Actual length is " + value.length(), param); + + ACTUAL_LENGTH_IS + value.length(), param); } } @@ -57,22 +60,22 @@ public static void validateString(byte[] value, StringParameter param) if (param.getType() == StringType.C_OCTET_STRING) { if (param.isRangeMinAndMax()) { if (!isCOctetStringValid(value, param.getMax())) { - throw new PDUStringException("C-Octet String value '" + throw new PDUStringException(C_OCTET_STRING_VALUE + new String(value) + "' length must be less than " - + param.getMax() + ". Actual length is " + + param.getMax() + ACTUAL_LENGTH_IS + value.length, param); } } else if (!isCOctetStringNullOrNValValid(value, param.getMax())) { throw new PDUStringException( - "C-Octet String value '" + new String(value) + "' length should be 1 or " + (param.getMax() - 1) - + ". Actual length is " + C_OCTET_STRING_VALUE + new String(value) + "' length should be 1 or " + (param.getMax() - 1) + + ACTUAL_LENGTH_IS + value.length, param); } } else if (param.getType() == StringType.OCTET_STRING && !isOctetStringValid(value, param.getMax())) { throw new PDUStringException("Octet String value '" + new String(value) + "' length must be less than or equal to " - + param.getMax() + ". Actual length is " + + param.getMax() + ACTUAL_LENGTH_IS + value.length, param); } } From 97ee0be7363e9008713156b356612c96d31b8243 Mon Sep 17 00:00:00 2001 From: George Kankava Date: Wed, 2 Mar 2016 15:01:37 +0400 Subject: [PATCH 114/212] quid:S1066 Collapsible "if" statements should be merged --- .../java/org/jsmpp/session/BindParameter.java | 42 +++++++------------ 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/BindParameter.java b/jsmpp/src/main/java/org/jsmpp/session/BindParameter.java index 028b952..4c785ad 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/BindParameter.java +++ b/jsmpp/src/main/java/org/jsmpp/session/BindParameter.java @@ -116,64 +116,50 @@ public int hashCode() { } private boolean hasEqualAddrNpi(BindParameter other) { - if (addrNpi == null) { - if (other.addrNpi != null) { - return false; - } + if (addrNpi == null && other.addrNpi != null) { + return false; } return addrNpi.equals(other.addrNpi); } private boolean hasEqualAddrTon(BindParameter other) { - if (addrTon == null) { - if (other.addrTon != null) { - return false; - } + if (addrTon == null && other.addrTon != null) { + return false; } return addrTon.equals(other.addrTon); } private boolean hasEqualAddressRange(BindParameter other) { - if (addressRange == null) { - if (other.addressRange != null) { - return false; - } + if (addressRange == null && other.addressRange != null) { + return false; } return addressRange.equals(other.addressRange); } private boolean hasEqualBindType(BindParameter other) { - if (bindType == null) { - if (other.bindType != null) { - return false; - } + if (bindType == null && other.bindType != null) { + return false; } return bindType.equals(other.bindType); } private boolean hasEqualPassword(BindParameter other) { - if (password == null) { - if (other.password != null) { - return false; - } + if (password == null && other.password != null) { + return false; } return password.equals(other.password); } private boolean hasEqualSystemId(BindParameter other) { - if (systemId == null) { - if (other.systemId != null) { - return false; - } + if (systemId == null && other.systemId != null) { + return false; } return systemId.equals(other.systemId); } private boolean hasEqualSystemType(BindParameter other) { - if (systemType == null) { - if (other.systemType != null) { - return false; - } + if (systemType == null && other.systemType != null) { + return false; } return systemType.equals(other.systemType); } From 8627de7711d39598e7cba2d67d9732dd2ef50fb6 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Mon, 7 Mar 2016 09:27:11 +0100 Subject: [PATCH 115/212] Update Slf4j to 1.7.18. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f687edd..9ff8374 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ yyyyMMddHHmm ${maven.build.timestamp} UTF-8 - 1.7.16 + 1.7.18 1.2.17 4.12 6.8.21 From af3e79e976a1f3c295beb8bfe15cdf76e8fbe25f Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Mon, 7 Mar 2016 09:33:59 +0100 Subject: [PATCH 116/212] Spelling, rewrite log statements --- .../gateway/AutoReconnectGateway.java | 262 +++++++++--------- 1 file changed, 133 insertions(+), 129 deletions(-) diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/gateway/AutoReconnectGateway.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/gateway/AutoReconnectGateway.java index 1294880..9660ef8 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/gateway/AutoReconnectGateway.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/gateway/AutoReconnectGateway.java @@ -37,146 +37,150 @@ import org.slf4j.LoggerFactory; /** - * This are implementation of {@link Gateway}. This gateway will reconnect for a - * specified interval if the session are closed. - * + * This is an implementation of {@link Gateway}. This gateway will reconnect for a specified interval if the session is + * closed. + * * @author uudashr - * */ + public class AutoReconnectGateway implements Gateway { - private static final Logger logger = LoggerFactory.getLogger(AutoReconnectGateway.class); - private SMPPSession session = null; - private String remoteIpAddress; - private int remotePort; - private BindParameter bindParam; - private long reconnectInterval = 5000L; // 5 seconds + private static final Logger logger = LoggerFactory.getLogger(AutoReconnectGateway.class); + private SMPPSession session = null; + private String remoteIpAddress; + private int remotePort; + private BindParameter bindParam; + private long reconnectInterval = 5000L; // 5 seconds - /** - * Construct auto reconnect gateway with specified ip address, port and SMPP - * Bind parameters. - * - * @param remoteIpAddress is the SMSC IP address. - * @param remotePort is the SMSC port. - * @param bindParam is the SMPP Bind parameters. - * @throws IOException - */ - public AutoReconnectGateway(String remoteIpAddress, int remotePort, - BindParameter bindParam) throws IOException { - this.remoteIpAddress = remoteIpAddress; - this.remotePort = remotePort; - this.bindParam = bindParam; - session = newSession(); - } - - /* (non-Javadoc) - * @see org.jsmpp.examples.gateway.Gateway#submitShortMessage(java.lang.String, org.jsmpp.bean.TypeOfNumber, org.jsmpp.bean.NumberingPlanIndicator, java.lang.String, org.jsmpp.bean.TypeOfNumber, org.jsmpp.bean.NumberingPlanIndicator, java.lang.String, org.jsmpp.bean.ESMClass, byte, byte, java.lang.String, java.lang.String, org.jsmpp.bean.RegisteredDelivery, byte, org.jsmpp.bean.DataCoding, byte, byte[], org.jsmpp.bean.OptionalParameter[]) - */ - public String submitShortMessage(String serviceType, - TypeOfNumber sourceAddrTon, NumberingPlanIndicator sourceAddrNpi, - String sourceAddr, TypeOfNumber destAddrTon, - NumberingPlanIndicator destAddrNpi, String destinationAddr, - ESMClass esmClass, byte protocolId, byte priorityFlag, - String scheduleDeliveryTime, String validityPeriod, - RegisteredDelivery registeredDelivery, byte replaceIfPresentFlag, - DataCoding dataCoding, byte smDefaultMsgId, byte[] shortMessage, - OptionalParameter... optionalParameters) throws PDUException, - ResponseTimeoutException, InvalidResponseException, - NegativeResponseException, IOException { - - return getSession().submitShortMessage(serviceType, sourceAddrTon, - sourceAddrNpi, sourceAddr, destAddrTon, destAddrNpi, - destinationAddr, esmClass, protocolId, priorityFlag, - scheduleDeliveryTime, validityPeriod, registeredDelivery, - replaceIfPresentFlag, dataCoding, smDefaultMsgId, shortMessage, - optionalParameters); - } + /** + * Construct auto reconnect gateway with specified IP address, port and SMPP Bind parameters. + * + * @param remoteIpAddress is the SMSC IP address. + * @param remotePort is the SMSC port. + * @param bindParam is the SMPP Bind parameters. + */ + public AutoReconnectGateway(String remoteIpAddress, int remotePort, + BindParameter bindParam) throws IOException { + this.remoteIpAddress = remoteIpAddress; + this.remotePort = remotePort; + this.bindParam = bindParam; + session = newSession(); + } - /** - * Create new {@link SMPPSession} complete with the - * {@link SessionStateListenerImpl}. - * - * @return the {@link SMPPSession}. - * @throws IOException if the creation of new session failed. - */ - private SMPPSession newSession() throws IOException { - SMPPSession tmpSession = new SMPPSession(remoteIpAddress, remotePort, bindParam); - tmpSession.addSessionStateListener(new SessionStateListenerImpl()); - return tmpSession; + public static void main(String[] args) throws IOException { + BasicConfigurator.configure(); + Gateway gateway = new AutoReconnectGateway("localhost", 8056, + new BindParameter(BindType.BIND_TRX, "sms", "sms", "sms", + TypeOfNumber.UNKNOWN, NumberingPlanIndicator.ISDN, "8080")); + + while (true) { + try { + Thread.sleep(1000); + } + catch (InterruptedException e) { + } } + } - /** - * Get the session. If the session still null or not in bound state, then IO - * exception will be thrown. - * - * @return the valid session. - * @throws IOException if there is no valid session or session creation is - * invalid. - */ - private SMPPSession getSession() throws IOException { - if (session == null) { - logger.info("Initiate session for the first time to " + remoteIpAddress + ":" + remotePort); - session = newSession(); - } else if (!session.getSessionState().isBound()) { - throw new IOException("We have no valid session yet"); - } - return session; + /* (non-Javadoc) + * @see org.jsmpp.examples.gateway.Gateway#submitShortMessage(java.lang.String, org.jsmpp.bean.TypeOfNumber, org.jsmpp.bean.NumberingPlanIndicator, java.lang.String, org.jsmpp.bean.TypeOfNumber, org.jsmpp.bean.NumberingPlanIndicator, java.lang.String, org.jsmpp.bean.ESMClass, byte, byte, java.lang.String, java.lang.String, org.jsmpp.bean.RegisteredDelivery, byte, org.jsmpp.bean.DataCoding, byte, byte[], org.jsmpp.bean.OptionalParameter[]) + */ + public String submitShortMessage(String serviceType, + TypeOfNumber sourceAddrTon, NumberingPlanIndicator sourceAddrNpi, + String sourceAddr, TypeOfNumber destAddrTon, + NumberingPlanIndicator destAddrNpi, String destinationAddr, + ESMClass esmClass, byte protocolId, byte priorityFlag, + String scheduleDeliveryTime, String validityPeriod, + RegisteredDelivery registeredDelivery, byte replaceIfPresentFlag, + DataCoding dataCoding, byte smDefaultMsgId, byte[] shortMessage, + OptionalParameter... optionalParameters) throws PDUException, + ResponseTimeoutException, InvalidResponseException, + NegativeResponseException, IOException { + + return getSession().submitShortMessage(serviceType, sourceAddrTon, + sourceAddrNpi, sourceAddr, destAddrTon, destAddrNpi, + destinationAddr, esmClass, protocolId, priorityFlag, + scheduleDeliveryTime, validityPeriod, registeredDelivery, + replaceIfPresentFlag, dataCoding, smDefaultMsgId, shortMessage, + optionalParameters); + } + + /** + * Create new {@link SMPPSession} complete with the {@link SessionStateListenerImpl}. + * + * @return the {@link SMPPSession}. + * @throws IOException if the creation of new session failed. + */ + private SMPPSession newSession() throws IOException { + SMPPSession tmpSession = new SMPPSession(remoteIpAddress, remotePort, bindParam); + tmpSession.addSessionStateListener(new SessionStateListenerImpl()); + return tmpSession; + } + + /** + * Get the session. If the session still null or not in bound state, then IO exception will be thrown. + * + * @return the valid session. + * @throws IOException if there is no valid session or session creation is invalid. + */ + private SMPPSession getSession() throws IOException { + if (session == null) { + logger.info("Initiate session for the first time to {}:{}", remoteIpAddress, remotePort); + session = newSession(); } - - /** - * Reconnect session after specified interval. - * - * @param timeInMillis is the interval. - */ - private void reconnectAfter(final long timeInMillis) { - new Thread() { - @Override - public void run() { - logger.info("Schedule reconnect after " + timeInMillis + " millis"); - try { - Thread.sleep(timeInMillis); - } catch (InterruptedException e) { - } - - int attempt = 0; - while (session == null || session.getSessionState().equals(SessionState.CLOSED)) { - try { - logger.info("Reconnecting attempt #" + (++attempt) + "..."); - session = newSession(); - } catch (IOException e) { - logger.error("Failed opening connection and bind to " + remoteIpAddress + ":" + remotePort, e); - // wait for a second - try { Thread.sleep(1000); } catch (InterruptedException ee) {} - } - } - } - }.start(); + else if (!session.getSessionState().isBound()) { + throw new IOException("We have no valid session yet"); } + return session; + } - /** - * This class will receive the notification from {@link SMPPSession} for the - * state changes. It will schedule to re-initialize session. - * - * @author uudashr - * - */ - private class SessionStateListenerImpl implements SessionStateListener { - public void onStateChange(SessionState newState, SessionState oldState, - Session source) { - if (newState.equals(SessionState.CLOSED)) { - logger.info("Session closed"); - reconnectAfter(reconnectInterval); - } + /** + * Reconnect session after specified interval. + * + * @param timeInMillis is the interval. + */ + private void reconnectAfter(final long timeInMillis) { + new Thread() { + @Override + public void run() { + logger.info("Schedule reconnect after {} millis", timeInMillis); + try { + Thread.sleep(timeInMillis); } - } - - public static void main(String[] args) throws IOException { - BasicConfigurator.configure(); - Gateway gateway = new AutoReconnectGateway("localhost", 8056, - new BindParameter(BindType.BIND_TRX, "sms", "sms", "sms", - TypeOfNumber.UNKNOWN, NumberingPlanIndicator.ISDN, "8080")); - - while (true) { - try { Thread.sleep(1000); } catch (InterruptedException e) {} + catch (InterruptedException e) { + } + + int attempt = 0; + while (session == null || session.getSessionState().equals(SessionState.CLOSED)) { + try { + logger.info("Reconnecting attempt #{} ...", ++attempt); + session = newSession(); + } + catch (IOException e) { + logger.error("Failed opening connection and bind to " + remoteIpAddress + ":" + remotePort, e); + // wait for a second + try { + Thread.sleep(1000); + } + catch (InterruptedException ee) { + } + } } + } + }.start(); + } + + /** + * This class will receive the notification from {@link SMPPSession} for the state changes. It will schedule to + * re-initialize session. + * + * @author uudashr + */ + private class SessionStateListenerImpl implements SessionStateListener { + public void onStateChange(SessionState newState, SessionState oldState, Session source) { + if (newState.equals(SessionState.CLOSED)) { + logger.info("Session closed"); + reconnectAfter(reconnectInterval); + } } + } } From 2e8172f4c6c53535f72717a63f9ee9b09686830c Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Tue, 8 Mar 2016 11:59:21 +0100 Subject: [PATCH 117/212] Fix test for relativeTimeFormatter --- .../jsmpp/util/RelativeTimeFormatterTest.java | 50 ++++++++----------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java b/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java index 226edd5..939d6b1 100644 --- a/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java +++ b/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java @@ -23,6 +23,7 @@ import java.util.GregorianCalendar; import java.util.TimeZone; +import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; /** @@ -30,6 +31,13 @@ */ public class RelativeTimeFormatterTest { + private RelativeTimeFormatter relativeTimeFormatter; + + @BeforeMethod + public void setUp() throws Exception { + relativeTimeFormatter = new RelativeTimeFormatter(); + } + @Test(groups = "checkintest") public void testStaticRelativeFormatter() { String formatted = RelativeTimeFormatter.format(07, 12, 26, 12, 46, 10); @@ -38,9 +46,8 @@ public void testStaticRelativeFormatter() { @Test(groups = "checkintest") public void formatNullDate() { - TimeFormatter timeFormatter = new RelativeTimeFormatter(); - assertNull(timeFormatter.format((Date) null)); - assertNull(timeFormatter.format((Calendar) null)); + assertNull(relativeTimeFormatter.format((Date) null)); + assertNull(relativeTimeFormatter.format((Calendar) null)); } @Test(groups = "checkintest") @@ -53,20 +60,16 @@ public void validateRelativeDate() throws Exception { @Test(groups = "checkintest", expectedExceptions = IllegalArgumentException.class) public void formatRelativeDateWhenAlreadyPast() { - RelativeTimeFormatter timeFormatter = new RelativeTimeFormatter(); - // date in the past GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("Europe/Berlin")); date.set(1998, Calendar.MARCH, 1, 13, 46, 59); - timeFormatter.format(date); + relativeTimeFormatter.format(date); fail("Expected IllegalArgumentException not thrown"); } @Test(groups = "checkintest") public void formatRelativeDateIgnoreMilliSeconds() { - RelativeTimeFormatter timeFormatter = new RelativeTimeFormatter(); - // Set the SMSC date to some future datetime GregorianCalendar smscDate = new GregorianCalendar(TimeZone.getTimeZone("Europe/Berlin")); smscDate.set(Calendar.YEAR, 2080); @@ -82,7 +85,7 @@ public void formatRelativeDateIgnoreMilliSeconds() { // Tenth of seconds should be ignored date.set(Calendar.MILLISECOND, 800); - assertEquals(timeFormatter.format(date, smscDate), "000000000000000R"); + assertEquals(relativeTimeFormatter.format(date, smscDate), "000000000000000R"); } @Test(groups = "checkintest", expectedExceptions = IllegalArgumentException.class) @@ -99,83 +102,75 @@ public void formatRelativeDateWhenExceedsCentury() { @Test(groups = "checkintest") public void formatRelativeDateSame() { - RelativeTimeFormatter timeFormatter = new RelativeTimeFormatter(); - GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("America/Denver")); - assertEquals(timeFormatter.format(date, date), "000000000000000R"); + assertEquals(relativeTimeFormatter.format(date, date), "000000000000000R"); } @Test(groups = "checkintest") public void formatRelativeDateDifferentTimeZone() { - RelativeTimeFormatter timeFormatter = new RelativeTimeFormatter(); GregorianCalendar smscDate = new GregorianCalendar(TimeZone.getTimeZone("America/Denver")); smscDate.set(2014, Calendar.JANUARY, 2, 23, 15, 16); GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("America/Los_Angeles")); date.set(2014, Calendar.JANUARY, 2, 23, 15, 16); - assertEquals(timeFormatter.format(date, smscDate), "000000010000000R"); + assertEquals(relativeTimeFormatter.format(date, smscDate), "000000010000000R"); } @Test(groups = "checkintest") public void formatRelativeDateMonthFebruary() { // for Java 8, the relative time could be calculated better - RelativeTimeFormatter timeFormatter = new RelativeTimeFormatter(); GregorianCalendar smscDate = new GregorianCalendar(TimeZone.getTimeZone("Pacific/Midway")); smscDate.set(2015, Calendar.FEBRUARY, 1, 0, 11, 22); GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("Pacific/Midway")); date.setTimeInMillis(smscDate.getTimeInMillis()); date.add(Calendar.MONTH, 1); - assertEquals(timeFormatter.format(date, smscDate), "000028000000000R"); + assertEquals(relativeTimeFormatter.format(date, smscDate), "000028000000000R"); } @Test(groups = "checkintest") public void formatRelativeDateMonthMay() { - RelativeTimeFormatter timeFormatter = new RelativeTimeFormatter(); GregorianCalendar smscDate = new GregorianCalendar(TimeZone.getTimeZone("America/Denver")); smscDate.set(2015, Calendar.MAY, 1, 13, 14, 15); GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("America/Denver")); date.setTimeInMillis(smscDate.getTimeInMillis()); date.add(Calendar.MONTH, 1); - assertEquals(timeFormatter.format(date, smscDate), "000100000000000R"); + assertEquals(relativeTimeFormatter.format(date, smscDate), "000100000000000R"); } @Test(groups = "checkintest") public void formatRelativeDateWeek() { - RelativeTimeFormatter timeFormatter = new RelativeTimeFormatter(); GregorianCalendar smscDate = new GregorianCalendar(TimeZone.getTimeZone("America/Denver")); + smscDate.set(2016, Calendar.FEBRUARY, 15, 16, 17, 18); GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("America/Denver")); date.setTimeInMillis(smscDate.getTimeInMillis()); date.add(Calendar.DAY_OF_MONTH, 7); - assertEquals(timeFormatter.format(date, smscDate), "000007000000000R"); + assertEquals(relativeTimeFormatter.format(date, smscDate), "000007000000000R"); } @Test(groups = "checkintest") public void formatRelativeTimeSecond() { - RelativeTimeFormatter timeFormatter = new RelativeTimeFormatter(); GregorianCalendar smscDate = new GregorianCalendar(TimeZone.getTimeZone("America/Denver")); GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("America/Denver")); date.setTimeInMillis(smscDate.getTimeInMillis()); date.add(Calendar.SECOND, 1); - assertEquals(timeFormatter.format(date, smscDate), "000000000001000R"); + assertEquals(relativeTimeFormatter.format(date, smscDate), "000000000001000R"); } @Test(groups = "checkintest") public void formatRelativeTimeHours() { - RelativeTimeFormatter timeFormatter = new RelativeTimeFormatter(); GregorianCalendar smscDate = new GregorianCalendar(TimeZone.getTimeZone("America/Denver")); GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("America/Denver")); date.setTimeInMillis(smscDate.getTimeInMillis()); date.add(Calendar.HOUR_OF_DAY, 16); - assertEquals(timeFormatter.format(date, smscDate), "000000160000000R"); + assertEquals(relativeTimeFormatter.format(date, smscDate), "000000160000000R"); } @Test(groups = "checkintest") public void formatRelativeTimeMonth() { - RelativeTimeFormatter timeFormatter = new RelativeTimeFormatter(); GregorianCalendar smscDate = new GregorianCalendar(TimeZone.getTimeZone("America/Denver")); smscDate.set(2001, Calendar.JANUARY, 31, 14, 15, 16); @@ -184,19 +179,18 @@ public void formatRelativeTimeMonth() { date.add(Calendar.MONTH, 1); // when using Joda-Time or Java 8 Period class //assertEquals(timeFormatter.format(date), "000100000000000R"); - assertEquals(timeFormatter.format(date, smscDate), "000028000000000R"); + assertEquals(relativeTimeFormatter.format(date, smscDate), "000028000000000R"); } @Test(groups = "checkintest") public void formatRelativeDateNewYear() { - RelativeTimeFormatter timeFormatter = new RelativeTimeFormatter(); GregorianCalendar smscDate = new GregorianCalendar(TimeZone.getTimeZone("America/Denver")); smscDate.set(2001, Calendar.DECEMBER, 31, 23, 59, 59); GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("Europe/Berlin")); date.setTimeInMillis(smscDate.getTimeInMillis()); date.add(Calendar.SECOND, 2); - assertEquals(timeFormatter.format(date, smscDate), "000000000002000R"); + assertEquals(relativeTimeFormatter.format(date, smscDate), "000000000002000R"); } } From 855987162d65c7daa1ea2867870da58e43e481d6 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Tue, 15 Mar 2016 17:48:49 +0100 Subject: [PATCH 118/212] Update Slf4j to 1.7.19 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9ff8374..905dc7c 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ yyyyMMddHHmm ${maven.build.timestamp} UTF-8 - 1.7.18 + 1.7.19 1.2.17 4.12 6.8.21 From a2fe78b6d0fc0930f846b1bef7fc0499c88d154c Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 20 Mar 2016 21:25:46 +0100 Subject: [PATCH 119/212] Layout --- .../connection/socket/SocketConnection.java | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/connection/socket/SocketConnection.java b/jsmpp/src/main/java/org/jsmpp/session/connection/socket/SocketConnection.java index c006be2..e1fcfbd 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/connection/socket/SocketConnection.java +++ b/jsmpp/src/main/java/org/jsmpp/session/connection/socket/SocketConnection.java @@ -20,7 +20,6 @@ import java.net.InetAddress; import java.net.Socket; -import org.jsmpp.session.SMPPSession; import org.jsmpp.session.connection.Connection; import org.jsmpp.util.StrictBufferedInputStream; import org.slf4j.Logger; @@ -32,41 +31,41 @@ */ public class SocketConnection implements Connection { private static final Logger logger = LoggerFactory.getLogger(SocketConnection.class); - + private final Socket socket; private final InputStream in; private final OutputStream out; - + public SocketConnection(Socket socket) throws IOException { this.socket = socket; this.in = new StrictBufferedInputStream(socket.getInputStream(), 65536);// 64 KB buffer this.out = socket.getOutputStream(); } - + public void setSoTimeout(int timeout) throws IOException { socket.setSoTimeout(timeout); } - + public void close() { try { socket.close(); } catch (IOException e) { - logger.warn("Suppressing IOException while closing socket", e); + logger.warn("Suppressing IOException while closing socket", e); } } - + public boolean isOpen() { return !socket.isClosed(); } - + public InputStream getInputStream() { return in; } - + public OutputStream getOutputStream() { return out; } - + public InetAddress getInetAddress() { return socket.getInetAddress(); } From cac4e53740c99e5d530891cccd428e25516b9339 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 20 Mar 2016 21:28:59 +0100 Subject: [PATCH 120/212] Improve logging --- .../java/org/jsmpp/examples/gateway/AutoReconnectGateway.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/gateway/AutoReconnectGateway.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/gateway/AutoReconnectGateway.java index 9660ef8..7dde946 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/gateway/AutoReconnectGateway.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/gateway/AutoReconnectGateway.java @@ -178,7 +178,7 @@ public void run() { private class SessionStateListenerImpl implements SessionStateListener { public void onStateChange(SessionState newState, SessionState oldState, Session source) { if (newState.equals(SessionState.CLOSED)) { - logger.info("Session closed"); + logger.info("Session {} closed", source.getSessionId()); reconnectAfter(reconnectInterval); } } From fcb495f09b97738796548069b2c60050be7892e3 Mon Sep 17 00:00:00 2001 From: Ayman Abi Abdallah Date: Mon, 28 Mar 2016 00:37:18 +0300 Subject: [PATCH 121/212] Renamed the SMSC delivery receipt failed value to FAILURE --- .../src/main/java/org/jsmpp/examples/SMPPServerSimulator.java | 4 ++-- .../src/main/java/org/jsmpp/examples/SubmitMultiExample.java | 2 +- jsmpp/src/main/java/org/jsmpp/bean/SMSCDeliveryReceipt.java | 2 +- .../src/test/java/org/jsmpp/bean/RegisteredDeliveryTest.java | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java index 55c7003..e46e69c 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java @@ -102,7 +102,7 @@ public MessageId onAcceptSubmitSm(SubmitSm submitSm, SMPPServerSession source) throws ProcessRequestException { MessageId messageId = messageIDGenerator.newMessageId(); logger.debug("Receiving submit_sm '{}', and return message id {}", new String(submitSm.getShortMessage()), messageId); - if (SMSCDeliveryReceipt.SUCCESS.containedIn(submitSm.getRegisteredDelivery()) || SMSCDeliveryReceipt.SUCCESS_FAILURE.containedIn(submitSm.getRegisteredDelivery())) { + if (SMSCDeliveryReceipt.FAILURE.containedIn(submitSm.getRegisteredDelivery()) || SMSCDeliveryReceipt.SUCCESS_FAILURE.containedIn(submitSm.getRegisteredDelivery())) { execServiceDelReceipt.execute(new DeliveryReceiptTask(source, submitSm, messageId)); } return messageId; @@ -119,7 +119,7 @@ public SubmitMultiResult onAcceptSubmitMulti(SubmitMulti submitMulti, logger.debug("Receiving submit_multi_sm '{}', and return message id {}", new String(submitMulti.getShortMessage()), messageId); - if (SMSCDeliveryReceipt.SUCCESS.containedIn(submitMulti.getRegisteredDelivery()) + if (SMSCDeliveryReceipt.FAILURE.containedIn(submitMulti.getRegisteredDelivery()) || SMSCDeliveryReceipt.SUCCESS_FAILURE.containedIn(submitMulti.getRegisteredDelivery())) { execServiceDelReceipt.execute(new DeliveryReceiptTask(source, submitMulti, messageId)); } diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/SubmitMultiExample.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/SubmitMultiExample.java index 44c8370..4032814 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/SubmitMultiExample.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/SubmitMultiExample.java @@ -74,7 +74,7 @@ public static void main(String[] args) { Address[] addresses = new Address[] {address1, address2}; SubmitMultiResult result = session.submitMultiple("CMT", TypeOfNumber.INTERNATIONAL, NumberingPlanIndicator.UNKNOWN, "1616", addresses, new ESMClass(), (byte)0, (byte)1, timeFormatter.format(new Date()), null, - new RegisteredDelivery(SMSCDeliveryReceipt.SUCCESS), ReplaceIfPresentFlag.REPLACE, + new RegisteredDelivery(SMSCDeliveryReceipt.FAILURE), ReplaceIfPresentFlag.REPLACE, new GeneralDataCoding(Alphabet.ALPHA_DEFAULT, MessageClass.CLASS1, false), (byte)0, "jSMPP simplify SMPP on Java platform".getBytes()); System.out.println("Messages submitted, result is " + result); diff --git a/jsmpp/src/main/java/org/jsmpp/bean/SMSCDeliveryReceipt.java b/jsmpp/src/main/java/org/jsmpp/bean/SMSCDeliveryReceipt.java index 61ab31f..44aca7c 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/SMSCDeliveryReceipt.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/SMSCDeliveryReceipt.java @@ -35,7 +35,7 @@ public enum SMSCDeliveryReceipt { * SMSC Delivery Receipt requested where the final delivery outcome is * delivery failure. */ - SUCCESS((byte)0x02); + FAILURE((byte)0x02); public static final byte CLEAR_BYTE = (byte)0xfc; // 11111100 public static final byte MASK_BYTE = 0x03; // 00000011 diff --git a/jsmpp/src/test/java/org/jsmpp/bean/RegisteredDeliveryTest.java b/jsmpp/src/test/java/org/jsmpp/bean/RegisteredDeliveryTest.java index 4a1c2f0..2004f49 100644 --- a/jsmpp/src/test/java/org/jsmpp/bean/RegisteredDeliveryTest.java +++ b/jsmpp/src/test/java/org/jsmpp/bean/RegisteredDeliveryTest.java @@ -32,7 +32,7 @@ public void testSMSCDeliveryReceipt() { regDel.setSMSCDeliveryReceipt(SMSCDeliveryReceipt.SUCCESS_FAILURE); assertTrue(SMSCDeliveryReceipt.SUCCESS_FAILURE.containedIn(regDel)); - regDel.setSMSCDeliveryReceipt(SMSCDeliveryReceipt.SUCCESS); - assertTrue(SMSCDeliveryReceipt.SUCCESS.containedIn(regDel)); + regDel.setSMSCDeliveryReceipt(SMSCDeliveryReceipt.FAILURE); + assertTrue(SMSCDeliveryReceipt.FAILURE.containedIn(regDel)); } } From 9a0653df22a7637ac81c6eb61b2b461ea78c9c6f Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Mon, 4 Apr 2016 12:13:12 +0200 Subject: [PATCH 122/212] Update Slf4j --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 905dc7c..e7b8fa9 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ yyyyMMddHHmm ${maven.build.timestamp} UTF-8 - 1.7.19 + 1.7.20 1.2.17 4.12 6.8.21 From df8578c2e3e23780f949547823a3b331a815fa31 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Mon, 4 Apr 2016 12:15:00 +0200 Subject: [PATCH 123/212] Add SSL connection factory implementation for use in SMPP Session --- .../socket/SSLSocketConnectionFactory.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 jsmpp/src/main/java/org/jsmpp/session/connection/socket/SSLSocketConnectionFactory.java diff --git a/jsmpp/src/main/java/org/jsmpp/session/connection/socket/SSLSocketConnectionFactory.java b/jsmpp/src/main/java/org/jsmpp/session/connection/socket/SSLSocketConnectionFactory.java new file mode 100644 index 0000000..556b80b --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/connection/socket/SSLSocketConnectionFactory.java @@ -0,0 +1,44 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session.connection.socket; + +import java.io.IOException; + +import javax.net.SocketFactory; +import javax.net.ssl.SSLSocketFactory; + +import org.jsmpp.session.connection.Connection; +import org.jsmpp.session.connection.ConnectionFactory; + +/** + * @author pmoerenhout + */ +public class SSLSocketConnectionFactory implements ConnectionFactory { + private static final SSLSocketConnectionFactory connFactory = new SSLSocketConnectionFactory(); + private static final SocketFactory socketFactory = SSLSocketFactory.getDefault(); + + private SSLSocketConnectionFactory() { + } + + public static SSLSocketConnectionFactory getInstance() { + return connFactory; + } + + @Override + public Connection createConnection(String host, int port) + throws IOException { + return new SocketConnection(socketFactory.createSocket(host, port)); + } +} \ No newline at end of file From 8bf24c052e86f353ad88f3298f4275ac56ea77df Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Mon, 4 Apr 2016 12:48:40 +0200 Subject: [PATCH 124/212] Add priority flag enum. --- .../java/org/jsmpp/bean/PriorityFlag.java | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 jsmpp/src/main/java/org/jsmpp/bean/PriorityFlag.java diff --git a/jsmpp/src/main/java/org/jsmpp/bean/PriorityFlag.java b/jsmpp/src/main/java/org/jsmpp/bean/PriorityFlag.java new file mode 100644 index 0000000..7a1478d --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/bean/PriorityFlag.java @@ -0,0 +1,108 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.bean; + +/** + * @author pmoerenhout + */ +public class PriorityFlag { + + public enum GsmSms { + NORMAL((byte) 0x00), + PRIORITY((byte) 0x01); + + private final byte value; + + GsmSms(byte value) { + this.value = value; + } + + public byte value() { + return value; + } + } + + public enum GsmCbs { + NORMAL((byte) 0x00), + IMMEDIATE_BROADCAST((byte) 0x01), + HIGH_PRIORITY((byte) 0x02), + RESERVED((byte) 0x03), + PRIORITY_BACKGROUND((byte) 0x04); + + private final byte value; + + GsmCbs(byte value) { + this.value = value; + } + + public byte value() { + return value; + } + } + + public enum Is95 { + NORMAL((byte) 0x00), + INTERACTIVE((byte) 0x01), + URGENT((byte) 0x02), + EMERGENCY((byte) 0x03); + + private final byte value; + + Is95(byte value) { + this.value = value; + } + + public byte value() { + return value; + } + } + + + public enum Ansi41 { + NORMAL((byte) 0x00), + INTERACTIVE((byte) 0x01), + URGENT((byte) 0x02), + EMERGENCY((byte) 0x03); + + private final byte value; + + Ansi41(byte value) { + this.value = value; + } + + public byte value() { + return value; + } + + } + + public enum Ansi136 { + BULK((byte) 0x00), + NORMAL((byte) 0x01), + URGENT((byte) 0x02), + VERY_URGENT((byte) 0x03); + + private final byte value; + + Ansi136(byte value) { + this.value = value; + } + + public byte value() { + return value; + } + } + +} From 889736dac94c45ccc9050939258b82bcff61fa06 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Wed, 6 Apr 2016 11:44:30 +0200 Subject: [PATCH 125/212] Update Slf4j to 1.7.21 --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index e7b8fa9..6b7d80d 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ yyyyMMddHHmm ${maven.build.timestamp} UTF-8 - 1.7.20 + 1.7.21 1.2.17 4.12 6.8.21 @@ -128,8 +128,8 @@ maven-compiler-plugin 2.3.2 - 1.6 - 1.6 + 1.7 + 1.7 utf-8
From 91b8112a87c061f84660f206e1282753d70f92f2 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Wed, 6 Apr 2016 11:48:24 +0200 Subject: [PATCH 126/212] Move back to Java 1.6 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 6b7d80d..5d71696 100644 --- a/pom.xml +++ b/pom.xml @@ -128,8 +128,8 @@ maven-compiler-plugin 2.3.2 - 1.7 - 1.7 + 1.6 + 1.6 utf-8 From 0a194ad9bec01815d55002c5680406507d263567 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Thu, 14 Apr 2016 12:50:41 +0200 Subject: [PATCH 127/212] Formatting and add sessionid in logging --- .../org/jsmpp/session/AbstractSession.java | 133 +++++++++--------- 1 file changed, 66 insertions(+), 67 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java index 11d271f..2a22b96 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java @@ -51,42 +51,42 @@ public abstract class AbstractSession implements Session { private static final Logger logger = LoggerFactory.getLogger(AbstractSession.class); private static final Random random = new Random(); - + private final Map> pendingResponse = new ConcurrentHashMap>(); private final Sequence sequence = new Sequence(1); private final PDUSender pduSender; private int pduProcessorDegree = 3; - + private String sessionId = generateSessionId(); private int enquireLinkTimer = 5000; private long transactionTimer = 2000; - + protected EnquireLinkSender enquireLinkSender; - + public AbstractSession(PDUSender pduSender) { this.pduSender = pduSender; } - + protected abstract AbstractSessionContext sessionContext(); protected abstract Connection connection(); protected abstract GenericMessageReceiverListener messageReceiverListener(); - + protected PDUSender pduSender() { return pduSender; } - + protected Sequence sequence() { return sequence; } - + protected PendingResponse removePendingResponse(int sequenceNumber) { return pendingResponse.remove(sequenceNumber); } - + public String getSessionId() { return sessionId; } - + public void setEnquireLinkTimer(int enquireLinkTimer) { if (sessionContext().getSessionState().isBound()) { try { @@ -97,45 +97,45 @@ public void setEnquireLinkTimer(int enquireLinkTimer) { } this.enquireLinkTimer = enquireLinkTimer; } - + public int getEnquireLinkTimer() { return enquireLinkTimer; } - + public void setTransactionTimer(long transactionTimer) { this.transactionTimer = transactionTimer; } - + public long getTransactionTimer() { return transactionTimer; } - + public SessionState getSessionState() { return sessionContext().getSessionState(); } - + protected synchronized boolean isReadPdu() { return getSessionState().isBound() || getSessionState().equals(SessionState.OPEN); } - + public void addSessionStateListener(SessionStateListener listener) { if (listener != null) { sessionContext().addSessionStateListener(listener); } } - + public void removeSessionStateListener(SessionStateListener listener) { sessionContext().removeSessionStateListener(listener); } - + public long getLastActivityTimestamp() { return sessionContext().getLastActivityTimestamp(); } - + /** * Set total thread can read PDU and process it in parallel. It's defaulted to * 3. - * + * * @param pduProcessorDegree is the total thread can handle read and process * PDU in parallel. * @throws IllegalStateException if the PDU Reader has been started. @@ -143,24 +143,24 @@ public long getLastActivityTimestamp() { public void setPduProcessorDegree(int pduProcessorDegree) throws IllegalStateException { if (!getSessionState().equals(SessionState.CLOSED)) { throw new IllegalStateException( - "Cannot set PDU processor degree since the PDU dispatcher thread already created."); + "Cannot set PDU processor degree since the PDU dispatcher thread already created"); } this.pduProcessorDegree = pduProcessorDegree; } - + /** * Get the total of thread that can handle read and process PDU in parallel. - * + * * @return the total of thread that can handle read and process PDU in * parallel. */ public int getPduProcessorDegree() { return pduProcessorDegree; } - + /** * Send the data_sm command. - * + * * @param serviceType is the service_type parameter. * @param sourceAddrTon is the source_addr_ton parameter. * @param sourceAddrNpi is the source_addr_npi parameter. @@ -187,20 +187,20 @@ public DataSmResult dataShortMessage(String serviceType, DataCoding dataCoding, OptionalParameter... optionalParameters) throws PDUException, ResponseTimeoutException, InvalidResponseException, NegativeResponseException, IOException { - - + + DataSmCommandTask task = new DataSmCommandTask(pduSender, serviceType, sourceAddrTon, sourceAddrNpi, sourceAddr, destAddrTon, destAddrNpi, destinationAddr, esmClass, registeredDelivery, dataCoding, optionalParameters); - + DataSmResp resp = (DataSmResp)executeSendCommand(task, getTransactionTimer()); - + return new DataSmResult(resp.getMessageId(), resp.getOptionalParameters()); } - + public void close() { - logger.debug("AbstractSession.close() called"); + logger.debug("Close session {}", sessionId); SessionContext ctx = sessionContext(); if (!ctx.getSessionState().equals(SessionState.CLOSED)) { ctx.close(); @@ -212,24 +212,25 @@ public void close() { // Make sure the enquireLinkThread doesn't wait for itself if (Thread.currentThread() != enquireLinkSender) { + logger.info("Closing enquireLinkSender for session {}", enquireLinkSender, sessionId); if (enquireLinkSender != null) { while(enquireLinkSender.isAlive()) { try { enquireLinkSender.join(); } catch (InterruptedException e) { - logger.warn("interrupted while waiting for enquireLinkSender thread to exit"); + logger.warn("Interrupted while waiting for enquireLinkSender thread to exit"); } } } } - logger.debug("AbstractSession.close() done"); + logger.debug("Session {} is closed and eenquireLinkSender stopped", sessionId); } /** * Validate the response, the command_status should be 0 otherwise will * throw {@link NegativeResponseException}. - * + * * @param response is the response. * @throws NegativeResponseException if the command_status value is not zero. */ @@ -238,7 +239,7 @@ private static void validateResponse(final Command response) throws NegativeResp throw new NegativeResponseException(response.getCommandStatus()); } } - + protected DataSmResult fireAcceptDataSm(final DataSm dataSm) throws ProcessRequestException { GenericMessageReceiverListener messageReceiverListener = messageReceiverListener(); if (messageReceiverListener != null) { @@ -247,10 +248,10 @@ protected DataSmResult fireAcceptDataSm(final DataSm dataSm) throws ProcessReque throw new ProcessRequestException("MessageReceiverListener hasn't been set yet", SMPPConstant.STAT_ESME_RX_R_APPN); } } - + /** * Execute send command command task. - * + * * @param task is the task. * @param timeout is the timeout in millisecond. * @return the command response. @@ -263,7 +264,7 @@ protected DataSmResult fireAcceptDataSm(final DataSm dataSm) throws ProcessReque protected Command executeSendCommand(SendCommandTask task, long timeout) throws PDUException, ResponseTimeoutException, InvalidResponseException, NegativeResponseException, IOException { - + int seqNum = sequence.nextValue(); PendingResponse pendingResp = new PendingResponse(timeout); pendingResponse.put(seqNum, pendingResp); @@ -271,7 +272,7 @@ protected Command executeSendCommand(SendCommandTask task, long timeout) task.executeTask(connection().getOutputStream(), seqNum); } catch (IOException e) { logger.error("Failed sending " + task.getCommandName() + " command", e); - + if(task.getCommandName().equals("enquire_link")) { logger.info("Tomas: Ignore failure of sending enquire_link, wait to see if connection is restored"); } else { @@ -280,10 +281,10 @@ protected Command executeSendCommand(SendCommandTask task, long timeout) throw e; } } - + try { pendingResp.waitDone(); - logger.debug("{} response received", task.getCommandName()); + logger.debug("{} response received for session {}", task.getCommandName(), sessionId); } catch (ResponseTimeoutException e) { pendingResponse.remove(seqNum); throw new ResponseTimeoutException("No response after waiting for " @@ -294,20 +295,20 @@ protected Command executeSendCommand(SendCommandTask task, long timeout) pendingResponse.remove(seqNum); throw e; } - + Command resp = pendingResp.getResponse(); validateResponse(resp); return resp; - + } - + private synchronized static final String generateSessionId() { return IntUtil.toHexString(random.nextInt()); } - + /** * Ensure we have proper link. - * + * * @throws ResponseTimeoutException if there is no valid response after defined millisecond. * @throws InvalidResponseException if there is invalid response found. * @throws IOException if there is an IO error found. @@ -324,15 +325,15 @@ protected void sendEnquireLink() throws ResponseTimeoutException, InvalidRespons logger.warn("command_status of response should be always 0", e); } } - - private void unbind() throws ResponseTimeoutException, + + public void unbind() throws ResponseTimeoutException, InvalidResponseException, IOException { if (sessionContext().getSessionState().equals(SessionState.CLOSED)) { - throw new IOException("Session is closed"); + throw new IOException("Session " + sessionId + " is closed"); } - + UnbindCommandTask task = new UnbindCommandTask(pduSender); - + try { executeSendCommand(task, transactionTimer); } catch (PDUException e) { @@ -342,12 +343,11 @@ private void unbind() throws ResponseTimeoutException, // ignore the negative response logger.warn("Receive non-ok command_status ({}) for unbind_resp", e.getCommandStatus()); } - + } - - public void unbindAndClose() { - logger.debug("unbindAndClose() called"); + public void unbindAndClose() { + logger.debug("Unbind and close sesssion {}", sessionId); if (sessionContext().getSessionState().isBound()) { try { unbind(); @@ -365,7 +365,7 @@ public void unbindAndClose() { /** * Ensure the session is receivable. If the session not receivable then an * exception thrown. - * + * * @param activityName is the activity name. * @throws IOException if the session not receivable. */ @@ -373,14 +373,14 @@ protected void ensureReceivable(String activityName) throws IOException { // TODO uudashr: do we have to use another exception for this checking? SessionState currentState = getSessionState(); if (!currentState.isReceivable()) { - throw new IOException("Cannot " + activityName + " while in state " + currentState); + throw new IOException("Cannot " + activityName + " while session " + sessionId + " in state " + currentState); } } /** * Ensure the session is transmittable. If the session not transmittable * then an exception thrown. - * + * * @param activityName is the activity name. * @throws IOException if the session not transmittable. */ @@ -391,7 +391,7 @@ protected void ensureTransmittable(String activityName) throws IOException { /** * Ensure the session is transmittable. If the session not transmittable * then an exception thrown. - * + * * @param activityName is the activity name. * @param only set to true if you want to ensure transmittable only * (transceive will not pass), otherwise set to false. @@ -402,21 +402,21 @@ protected void ensureTransmittable(String activityName, boolean only) throws IOE // TODO uudashr: do we have to use another exception for this checking? SessionState currentState = getSessionState(); if (!currentState.isTransmittable() || (only && currentState.isReceivable())) { - throw new IOException("Cannot " + activityName + " while in state " + currentState); + throw new IOException("Cannot " + activityName + " while session " + sessionId + " in state " + currentState); } } - + protected class EnquireLinkSender extends Thread { private final AtomicBoolean sendingEnquireLink = new AtomicBoolean(false); - + public EnquireLinkSender() { super("EnquireLinkSender: " + AbstractSession.this); } - + @Override public void run() { - logger.info("Starting EnquireLinkSender"); + logger.info("Starting EnquireLinkSender for session {}", sessionId); while (isReadPdu()) { while (!sendingEnquireLink.compareAndSet(true, false) && isReadPdu()) { synchronized (sendingEnquireLink) { @@ -443,9 +443,9 @@ public void run() { close(); } } - logger.debug("EnquireLinkSender stop"); + logger.debug("EnquireLinkSender stopped for session {}", sessionId); } - + /** * This method will send enquire link asynchronously. */ @@ -459,5 +459,4 @@ public void enquireLink() { } } } - } From 89ff4f8c2432f2d6bd74a8a125fa7ddfaf313041 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Thu, 14 Apr 2016 14:29:35 +0200 Subject: [PATCH 128/212] Update plugins --- pom.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index 5d71696..1763c69 100644 --- a/pom.xml +++ b/pom.xml @@ -126,7 +126,7 @@ org.apache.maven.plugins maven-compiler-plugin - 2.3.2 + 3.5.1 1.6 1.6 @@ -143,16 +143,16 @@ org.apache.maven.plugins maven-release-plugin - 2.1 + 2.5.3 org.apache.felix maven-bundle-plugin - 2.3.7 + 3.0.1 maven-source-plugin - 2.1.2 + 3.0.0 verify @@ -165,7 +165,7 @@ pl.project13.maven git-commit-id-plugin - 1.9 + 2.2.1 initialize @@ -195,7 +195,7 @@ org.codehaus.mojo properties-maven-plugin - 1.0-alpha-2 + 1.0.0 initialize @@ -212,7 +212,7 @@ maven-jar-plugin - 2.3.2 + 2.6 From e822644d24bf9418ffa6f8c0f2afcb289091c2b0 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Thu, 14 Apr 2016 14:35:36 +0200 Subject: [PATCH 129/212] Fix for Java 1.6 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1763c69..efd7902 100644 --- a/pom.xml +++ b/pom.xml @@ -165,7 +165,7 @@ pl.project13.maven git-commit-id-plugin - 2.2.1 + 2.1.15 initialize From fe76d2e4a99230bb03737c797222177b3c42fb0b Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Thu, 14 Apr 2016 14:41:04 +0200 Subject: [PATCH 130/212] Use 1.6 compatible plugins --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index efd7902..841f5ed 100644 --- a/pom.xml +++ b/pom.xml @@ -148,7 +148,7 @@ org.apache.felix maven-bundle-plugin - 3.0.1 + 2.5.4 maven-source-plugin From 1b7889a82a89f239d4f4629028aed1cc8c8b07e2 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Thu, 14 Apr 2016 15:17:03 +0200 Subject: [PATCH 131/212] Textual change --- jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java b/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java index af8e7d4..45d106d 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java @@ -296,7 +296,7 @@ private String sendBind(BindType bindType, String systemId, BindResp resp = (BindResp)executeSendCommand(task, timeout); OptionalParameter.Sc_interface_version scVersion = resp.getOptionalParameter(Sc_interface_version.class); if(scVersion != null) { - logger.info("Other side reports smpp interface version {}", scVersion); + logger.info("Other side reports SMPP interface version {}", scVersion); } return resp.getSystemId(); @@ -578,7 +578,7 @@ public PDUReaderWorker() { public void run() { logger.info("Starting PDUReaderWorker"); while (isReadPdu()) { - readPDU(); + readPDU(); } close(); executorService.shutdown(); From 17af2ae53e078bbd0d24e18482f5e386ec901150 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Mon, 2 May 2016 00:17:46 +0200 Subject: [PATCH 132/212] Fix typo --- jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java index 2a22b96..6d8ead8 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java @@ -224,7 +224,7 @@ public void close() { } } - logger.debug("Session {} is closed and eenquireLinkSender stopped", sessionId); + logger.debug("Session {} is closed and enquireLinkSender stopped", sessionId); } /** From 27440277d5aff40e0ca9722766b742c08f0f28ae Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 15 May 2016 22:26:43 +0200 Subject: [PATCH 133/212] Remove unused varaiable. --- jsmpp/src/main/java/org/jsmpp/bean/DataCodings.java | 1 - 1 file changed, 1 deletion(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/DataCodings.java b/jsmpp/src/main/java/org/jsmpp/bean/DataCodings.java index 123f96f..7ef7bfe 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/DataCodings.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/DataCodings.java @@ -42,7 +42,6 @@ public final class DataCodings { * DataCoding with binary value 0000000. */ public static final DataCoding ZERO = new GeneralDataCoding(); - private static DataCoding[] dataCodingCache = new DataCoding[255]; private DataCodings() { throw new InstantiationError("This class must not be instantiated"); From 05bf554f02184db71f58e60078e81d6e9fc5a213 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 29 May 2016 19:31:03 +0200 Subject: [PATCH 134/212] Minor change in log --- .../src/main/java/org/jsmpp/examples/SMPPServerSimulator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java index e46e69c..ef0a76e 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java @@ -94,7 +94,7 @@ public void run() { public QuerySmResult onAcceptQuerySm(QuerySm querySm, SMPPServerSession source) throws ProcessRequestException { - logger.info("Accepting query sm, but not implemented"); + logger.info("Accepting query_sm, but not implemented"); return null; } From 75b30d333e13b364134973d19e08e8e5da785278 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 29 May 2016 20:47:31 +0200 Subject: [PATCH 135/212] Add test classed for DataCoding factories. --- .../jsmpp/bean/AbstractDataCodingFactory.java | 8 +-- .../org/jsmpp/bean/DataCodingFactory00xx.java | 2 +- .../jsmpp/bean/DataCodingFactory00xxTest.java | 55 +++++++++++++++++++ .../jsmpp/bean/DataCodingFactory1100Test.java | 28 ++++++++++ .../jsmpp/bean/DataCodingFactory1101Test.java | 48 ++++++++++++++++ .../jsmpp/bean/DataCodingFactory1110Test.java | 49 +++++++++++++++++ 6 files changed, 185 insertions(+), 5 deletions(-) create mode 100644 jsmpp/src/test/java/org/jsmpp/bean/DataCodingFactory00xxTest.java create mode 100644 jsmpp/src/test/java/org/jsmpp/bean/DataCodingFactory1100Test.java create mode 100644 jsmpp/src/test/java/org/jsmpp/bean/DataCodingFactory1101Test.java create mode 100644 jsmpp/src/test/java/org/jsmpp/bean/DataCodingFactory1110Test.java diff --git a/jsmpp/src/main/java/org/jsmpp/bean/AbstractDataCodingFactory.java b/jsmpp/src/main/java/org/jsmpp/bean/AbstractDataCodingFactory.java index 0970fa0..d6daf0c 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/AbstractDataCodingFactory.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/AbstractDataCodingFactory.java @@ -19,15 +19,15 @@ * */ public abstract class AbstractDataCodingFactory implements DataCodingFactory { - - protected final byte group; + + protected final byte group; protected final byte mask; - + public AbstractDataCodingFactory(byte mask, byte group) { this.mask = mask; this.group = group; } - + public boolean isRecognized(byte dataCoding) { return (dataCoding & mask) == group; } diff --git a/jsmpp/src/main/java/org/jsmpp/bean/DataCodingFactory00xx.java b/jsmpp/src/main/java/org/jsmpp/bean/DataCodingFactory00xx.java index 19207c7..1d24284 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/DataCodingFactory00xx.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/DataCodingFactory00xx.java @@ -49,7 +49,7 @@ public DataCodingFactory00xx() { public DataCoding newInstance(byte dataCoding) { boolean compressed = isCompressed(dataCoding); - boolean containMessageClass = isContainMessageClass(dataCoding); + boolean containMessageClass = DataCodings.containsMessageClass(dataCoding); MessageClass messageClass = null; if (containMessageClass) { // ignore Message Class if the PDU has tell us no Message Class diff --git a/jsmpp/src/test/java/org/jsmpp/bean/DataCodingFactory00xxTest.java b/jsmpp/src/test/java/org/jsmpp/bean/DataCodingFactory00xxTest.java new file mode 100644 index 0000000..ba94829 --- /dev/null +++ b/jsmpp/src/test/java/org/jsmpp/bean/DataCodingFactory00xxTest.java @@ -0,0 +1,55 @@ +package org.jsmpp.bean; + +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +/** + * @author pmoerenhout + */ +public class DataCodingFactory00xxTest { + + DataCodingFactory00xx factory; + + @BeforeMethod + public void setUp() throws Exception { + factory = new DataCodingFactory00xx(); + } + + @Test + public void testDataCodings00xx() { + for (byte dataCodingByte = (byte) 0x00; dataCodingByte < (byte) 0xf0; dataCodingByte++) { + DataCoding dataCoding = factory.newInstance(dataCodingByte); + assertEquals(dataCoding.toByte(), dataCodingByte); + assertEquals(dataCoding.getClass(), GeneralDataCoding.class); + } + } + + @Test + public void testDataCodingFactory00xxStandardAlphabet() { + byte expected = (byte) 0x00; + DataCoding dataCoding = factory.newInstance(expected); + + assertEquals(dataCoding.toByte(), expected); + assertEquals(Alphabet.parseDataCoding(dataCoding.toByte()), Alphabet.ALPHA_DEFAULT); + } + + @Test + public void testDataCodingFactory00xxIA5() { + byte expected = (byte) 0x01; + DataCoding dataCoding = factory.newInstance(expected); + + assertEquals(dataCoding.toByte(), expected); + assertEquals(Alphabet.parseDataCoding(dataCoding.toByte()), Alphabet.ALPHA_IA5); + } + + @Test + public void testDataCodingFactory00xxUCS2() { + byte expected = (byte) 0x08; + DataCoding dataCoding = factory.newInstance(expected); + + assertEquals(dataCoding.toByte(), expected); + assertEquals(Alphabet.parseDataCoding(dataCoding.toByte()), Alphabet.ALPHA_UCS2); + } +} \ No newline at end of file diff --git a/jsmpp/src/test/java/org/jsmpp/bean/DataCodingFactory1100Test.java b/jsmpp/src/test/java/org/jsmpp/bean/DataCodingFactory1100Test.java new file mode 100644 index 0000000..043361f --- /dev/null +++ b/jsmpp/src/test/java/org/jsmpp/bean/DataCodingFactory1100Test.java @@ -0,0 +1,28 @@ +package org.jsmpp.bean; + +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +/** + * @author pmoerenhout + */ +public class DataCodingFactory1100Test { + + DataCodingFactory1100 factory; + + @BeforeMethod + public void setUp() throws Exception { + factory = new DataCodingFactory1100(); + } + + @Test + public void testDataCodings1100() { + for (byte dataCodingByte = (byte) 0xc0; dataCodingByte < (byte) 0xd0; dataCodingByte++) { + DataCoding dataCoding = factory.newInstance(dataCodingByte); + assertEquals(dataCoding.getClass(), MessageWaitingDataCoding.class); + assertEquals(Alphabet.parseDataCoding(dataCoding.toByte()), Alphabet.ALPHA_DEFAULT); + } + } +} \ No newline at end of file diff --git a/jsmpp/src/test/java/org/jsmpp/bean/DataCodingFactory1101Test.java b/jsmpp/src/test/java/org/jsmpp/bean/DataCodingFactory1101Test.java new file mode 100644 index 0000000..451bd73 --- /dev/null +++ b/jsmpp/src/test/java/org/jsmpp/bean/DataCodingFactory1101Test.java @@ -0,0 +1,48 @@ +package org.jsmpp.bean; + +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +/** + * @author pmoerenhout + */ +public class DataCodingFactory1101Test { + + DataCodingFactory1101 factory; + + @BeforeMethod + public void setUp() throws Exception { + factory = new DataCodingFactory1101(); + } + + @Test + public void testDataCodings1101() { + for (byte dataCodingByte = (byte) 0xd0; dataCodingByte < (byte) 0xe0; dataCodingByte++) { + DataCoding dataCoding = factory.newInstance(dataCodingByte); + assertEquals(dataCoding.getClass(), MessageWaitingDataCoding.class); + // assertEquals(Alphabet.parseDataCoding(dataCoding.toByte()), Alphabet.ALPHA_DEFAULT); + } + } + + @Test + public void testDataCodingVoicemailInactive() { + byte dataCodingByte = (byte) 0xd0; + DataCoding dataCoding = factory.newInstance(dataCodingByte); + assertEquals(dataCoding.getClass(), MessageWaitingDataCoding.class); + assertEquals(IndicationSense.parseDataCoding(dataCoding.toByte()), IndicationSense.INACTIVE); + assertEquals(IndicationType.parseDataCoding(dataCoding.toByte()), IndicationType.VOICEMAIL_MESSAGE_WAITING); + // assertEquals(Alphabet.parseDataCoding(dataCoding.toByte()), Alphabet.ALPHA_DEFAULT); + } + + @Test + public void testDataCodingVoicemailActive() { + byte dataCodingByte = (byte) 0xd8; + DataCoding dataCoding = factory.newInstance(dataCodingByte); + assertEquals(dataCoding.getClass(), MessageWaitingDataCoding.class); + assertEquals(IndicationSense.parseDataCoding(dataCoding.toByte()), IndicationSense.ACTIVE); + assertEquals(IndicationType.parseDataCoding(dataCoding.toByte()), IndicationType.VOICEMAIL_MESSAGE_WAITING); + // assertEquals(Alphabet.parseDataCoding(dataCoding.toByte()), Alphabet.ALPHA_DEFAULT); + } +} \ No newline at end of file diff --git a/jsmpp/src/test/java/org/jsmpp/bean/DataCodingFactory1110Test.java b/jsmpp/src/test/java/org/jsmpp/bean/DataCodingFactory1110Test.java new file mode 100644 index 0000000..204fded --- /dev/null +++ b/jsmpp/src/test/java/org/jsmpp/bean/DataCodingFactory1110Test.java @@ -0,0 +1,49 @@ +package org.jsmpp.bean; + +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + + +/** + * @author pmoerenhout + */ +public class DataCodingFactory1110Test { + + DataCodingFactory1110 factory; + + @BeforeMethod + public void setUp() throws Exception { + factory = new DataCodingFactory1110(); + } + + @Test + public void testDataCodings1110() { + for (byte dataCodingByte = (byte) 0xd0; dataCodingByte < (byte) 0xe0; dataCodingByte++) { + DataCoding dataCoding = factory.newInstance(dataCodingByte); + assertEquals(dataCoding.getClass(), MessageWaitingDataCoding.class); + // assertEquals(Alphabet.parseDataCoding(dataCoding.toByte()), Alphabet.ALPHA_UCS2); + } + } + + @Test + public void testDataCodingVoicemailInactive() { + byte dataCodingByte = (byte) 0xd0; + DataCoding dataCoding = factory.newInstance(dataCodingByte); + assertEquals(dataCoding.getClass(), MessageWaitingDataCoding.class); + assertEquals(IndicationSense.parseDataCoding(dataCoding.toByte()), IndicationSense.INACTIVE); + assertEquals(IndicationType.parseDataCoding(dataCoding.toByte()), IndicationType.VOICEMAIL_MESSAGE_WAITING); + // assertEquals(Alphabet.parseDataCoding(dataCoding.toByte()), Alphabet.ALPHA_UCS2); + } + + @Test + public void testDataCodingVoicemailActive() { + byte dataCodingByte = (byte) 0xd8; + DataCoding dataCoding = factory.newInstance(dataCodingByte); + assertEquals(dataCoding.getClass(), MessageWaitingDataCoding.class); + assertEquals(IndicationSense.parseDataCoding(dataCoding.toByte()), IndicationSense.ACTIVE); + assertEquals(IndicationType.parseDataCoding(dataCoding.toByte()), IndicationType.VOICEMAIL_MESSAGE_WAITING); + // assertEquals(Alphabet.parseDataCoding(dataCoding.toByte()), Alphabet.ALPHA_UCS2); + } +} \ No newline at end of file From d52f94b965f0b024236df7c57d72e0836d634e38 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 29 May 2016 20:48:02 +0200 Subject: [PATCH 136/212] Prepare for release 2.2.4 --- CHANGES.txt | 12 ++++++++++++ jsmpp-examples/pom.xml | 2 +- jsmpp/pom.xml | 2 +- pom.xml | 2 +- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 9d022c2..af6aea0 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,17 @@ Changes: +2.2.4 +- Fixed some logging +- Add PriorityFlag enum +- Add SSL connection factory implementation +- Fixed SMSCDeliveryReceipt.SUCCESS to FAILURE +- Fix RelativeTimeFormatter test +- Multiple lexical and code improvements + +2.2.3 +- Use StringBuilder instead of StringBuffer +- Use OctetString for unknown OptionalParameter + 2.2.2 - Fixed some logging - Added SMPP 5.0 message states diff --git a/jsmpp-examples/pom.xml b/jsmpp-examples/pom.xml index e995edf..06ceae2 100644 --- a/jsmpp-examples/pom.xml +++ b/jsmpp-examples/pom.xml @@ -3,7 +3,7 @@ jsmpp-pom org.jsmpp - 2.2.4-SNAPSHOT + 2.2.4 4.0.0 diff --git a/jsmpp/pom.xml b/jsmpp/pom.xml index 651d444..b2320fc 100644 --- a/jsmpp/pom.xml +++ b/jsmpp/pom.xml @@ -3,7 +3,7 @@ org.jsmpp jsmpp-pom - 2.2.4-SNAPSHOT + 2.2.4 4.0.0 bundle diff --git a/pom.xml b/pom.xml index 841f5ed..9a67937 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.jsmpp jsmpp-pom - 2.2.4-SNAPSHOT + 2.2.4 pom jSMPP - Parent From a051d1ddae57075f1bc7d50b0bf71e3e6c3204a7 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 29 May 2016 20:49:36 +0200 Subject: [PATCH 137/212] Add DataCodings test. --- .../java/org/jsmpp/bean/DataCodingsTest.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 jsmpp/src/test/java/org/jsmpp/bean/DataCodingsTest.java diff --git a/jsmpp/src/test/java/org/jsmpp/bean/DataCodingsTest.java b/jsmpp/src/test/java/org/jsmpp/bean/DataCodingsTest.java new file mode 100644 index 0000000..45e57d9 --- /dev/null +++ b/jsmpp/src/test/java/org/jsmpp/bean/DataCodingsTest.java @@ -0,0 +1,44 @@ +package org.jsmpp.bean; + + +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.Test; + +/** + * @author pmoerenhout + */ +public class DataCodingsTest { + + @Test + public void testDataCodingsZero() { + DataCoding dataCoding = DataCodings.ZERO; + assertEquals(dataCoding.toByte(), (byte) 0x00); + } + + @Test + public void testDataCodingsFactories() { + for (int i = 0; i < 256; i++) { + byte expected = (byte) (0xff & i); + DataCoding dataCoding = DataCodings.newInstance(expected); + if (i < 64) { + assertEquals(DataCodings.newInstance(expected).getClass().getName(), "org.jsmpp.bean.GeneralDataCoding"); + } + else if (i < 192) { + assertEquals(DataCodings.newInstance(expected).getClass().getName(), "org.jsmpp.bean.RawDataCoding"); + } + else if (i < 240) { + assertEquals(DataCodings.newInstance(expected).getClass().getName(), "org.jsmpp.bean.MessageWaitingDataCoding"); + } + else { + assertEquals(DataCodings.newInstance(expected).getClass().getName(), "org.jsmpp.bean.SimpleDataCoding"); + } + + if (i < 192) { + assertEquals(dataCoding.toByte(), expected); + } + } + } + + +} \ No newline at end of file From d71ea36b7883c2133167fac9cb192f8cae510eab Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 29 May 2016 20:51:18 +0200 Subject: [PATCH 138/212] Fix testcase. --- .../src/test/java/org/jsmpp/bean/DataCodingFactory1100Test.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsmpp/src/test/java/org/jsmpp/bean/DataCodingFactory1100Test.java b/jsmpp/src/test/java/org/jsmpp/bean/DataCodingFactory1100Test.java index 043361f..b59491b 100644 --- a/jsmpp/src/test/java/org/jsmpp/bean/DataCodingFactory1100Test.java +++ b/jsmpp/src/test/java/org/jsmpp/bean/DataCodingFactory1100Test.java @@ -22,7 +22,7 @@ public void testDataCodings1100() { for (byte dataCodingByte = (byte) 0xc0; dataCodingByte < (byte) 0xd0; dataCodingByte++) { DataCoding dataCoding = factory.newInstance(dataCodingByte); assertEquals(dataCoding.getClass(), MessageWaitingDataCoding.class); - assertEquals(Alphabet.parseDataCoding(dataCoding.toByte()), Alphabet.ALPHA_DEFAULT); + // assertEquals(Alphabet.parseDataCoding(dataCoding.toByte()), Alphabet.ALPHA_DEFAULT); } } } \ No newline at end of file From 46a43cb1928844caa60b6ca06865e0f163d804a5 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 29 May 2016 21:28:03 +0200 Subject: [PATCH 139/212] Update to 2.2.5-SNAPSHOT --- jsmpp-examples/pom.xml | 2 +- jsmpp/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/jsmpp-examples/pom.xml b/jsmpp-examples/pom.xml index 06ceae2..a25e53c 100644 --- a/jsmpp-examples/pom.xml +++ b/jsmpp-examples/pom.xml @@ -3,7 +3,7 @@ jsmpp-pom org.jsmpp - 2.2.4 + 2.2.5-SNAPSHOT 4.0.0 diff --git a/jsmpp/pom.xml b/jsmpp/pom.xml index b2320fc..cb64492 100644 --- a/jsmpp/pom.xml +++ b/jsmpp/pom.xml @@ -3,7 +3,7 @@ org.jsmpp jsmpp-pom - 2.2.4 + 2.2.5-SNAPSHOT 4.0.0 bundle diff --git a/pom.xml b/pom.xml index 9a67937..01c51c5 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.jsmpp jsmpp-pom - 2.2.4 + 2.2.5-SNAPSHOT pom jSMPP - Parent From 6112cf593ae0c2718d494baffd29373594d74c24 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 29 May 2016 21:28:56 +0200 Subject: [PATCH 140/212] Add GeneralDataCoding tests. --- .../org/jsmpp/bean/GeneralDataCodingTest.java | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 jsmpp/src/test/java/org/jsmpp/bean/GeneralDataCodingTest.java diff --git a/jsmpp/src/test/java/org/jsmpp/bean/GeneralDataCodingTest.java b/jsmpp/src/test/java/org/jsmpp/bean/GeneralDataCodingTest.java new file mode 100644 index 0000000..89a1130 --- /dev/null +++ b/jsmpp/src/test/java/org/jsmpp/bean/GeneralDataCodingTest.java @@ -0,0 +1,53 @@ +package org.jsmpp.bean; + +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.Test; + +/** + * @author pmoerenhout + */ +public class GeneralDataCodingTest { + + @Test + public void testGeneralAlphabetDefault() { + DataCoding dataCoding = new GeneralDataCoding(Alphabet.ALPHA_DEFAULT); + assertEquals(dataCoding.toByte(), (byte) 0x00); + } + + @Test + public void testGeneralAlphabetIA5() { + DataCoding dataCoding = new GeneralDataCoding(Alphabet.ALPHA_IA5); + assertEquals(dataCoding.toByte(), (byte) 0x01); + } + + @Test + public void testGeneralAlphabetUcs2() { + DataCoding dataCoding = new GeneralDataCoding(Alphabet.ALPHA_UCS2); + assertEquals(dataCoding.toByte(), (byte) 0x08); + } + + @Test + public void testGeneralFlash() { + DataCoding dataCoding = new GeneralDataCoding(Alphabet.ALPHA_DEFAULT, MessageClass.CLASS0, false); + assertEquals(dataCoding.toByte(), (byte) 0x10); + } + + @Test + public void testGeneralMeSpecific() { + DataCoding dataCoding = new GeneralDataCoding(Alphabet.ALPHA_DEFAULT, MessageClass.CLASS1, false); + assertEquals(dataCoding.toByte(), (byte) 0x11); + } + + @Test + public void testGeneralSimUsimSpecific() { + DataCoding dataCoding = new GeneralDataCoding(Alphabet.ALPHA_DEFAULT, MessageClass.CLASS2, false); + assertEquals(dataCoding.toByte(), (byte) 0x12); + } + + @Test + public void testGeneralTeSpecific() { + DataCoding dataCoding = new GeneralDataCoding(Alphabet.ALPHA_DEFAULT, MessageClass.CLASS3, false); + assertEquals(dataCoding.toByte(), (byte) 0x13); + } +} \ No newline at end of file From 604227c3d99978da45f0537da74b1f64f305f9be Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 29 May 2016 21:35:56 +0200 Subject: [PATCH 141/212] Add myself. --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3d55ed3..9a2db6a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ - Introduction ------------ @@ -34,7 +33,7 @@ Release procedure mvn deploy -DperformRelease=true -Durl=https://oss.sonatype.org/service/local/staging/deploy/maven2/ -DrepositoryId=sonatype-nexus-staging * log in here: https://oss.sonatype.org - * click the `Staging Repositories' link + * click the 'Staging Repositories' link * select the repository and click close * select the repository and click release @@ -44,6 +43,6 @@ License Copyright (C) 2007-2013, Nuruddin Ashr Copyright (C) 2012-2013, Denis Kostousov Copyright (C) 2014, Daniel Pocock http://danielpocock.com +Copyright (C) 2016, Pim Moerenhout This project is licensed under the Apache Software License 2.0. - From 55a50c30194eb2316c8310dea379e993812a84fc Mon Sep 17 00:00:00 2001 From: George Kankava Date: Fri, 24 Jun 2016 17:17:46 +0400 Subject: [PATCH 142/212] squid:S1132 - Strings literals should be placed on the left side when checking for equality --- .../org/jsmpp/examples/AcceptingConnectionAndBindExample.java | 4 ++-- .../org/jsmpp/examples/ReceiveSubmittedMessageExample.java | 4 ++-- jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/AcceptingConnectionAndBindExample.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/AcceptingConnectionAndBindExample.java index 16e543d..c546fcc 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/AcceptingConnectionAndBindExample.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/AcceptingConnectionAndBindExample.java @@ -44,8 +44,8 @@ public static void main(String[] args) { BindRequest request = session.waitForBind(5000); System.out.println("Receive bind request"); - if (request.getSystemId().equals("test") && - request.getPassword().equals("test")) { + if ("test".equals(request.getSystemId()) && + "test".equals(request.getPassword())) { // accepting request and send bind response immediately System.out.println("Accepting bind request, interface version is " + request.getInterfaceVersion()); diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/ReceiveSubmittedMessageExample.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/ReceiveSubmittedMessageExample.java index 9d779e1..3c25358 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/ReceiveSubmittedMessageExample.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/ReceiveSubmittedMessageExample.java @@ -105,8 +105,8 @@ public void onAcceptReplaceSm(ReplaceSm replaceSm, BindRequest request = session.waitForBind(5000); System.out.println("Receive bind request"); - if (request.getSystemId().equals("test") && - request.getPassword().equals("test")) { + if ("test".equals(request.getSystemId()) && + "test".equals(request.getPassword())) { // accepting request and send bind response immediately System.out.println("Accepting bind request"); diff --git a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java index 6d8ead8..0cfde86 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java @@ -273,7 +273,7 @@ protected Command executeSendCommand(SendCommandTask task, long timeout) } catch (IOException e) { logger.error("Failed sending " + task.getCommandName() + " command", e); - if(task.getCommandName().equals("enquire_link")) { + if("enquire_link".equals(task.getCommandName())) { logger.info("Tomas: Ignore failure of sending enquire_link, wait to see if connection is restored"); } else { pendingResponse.remove(seqNum); From 2ad8854d9ffe897f96c3fed48d8a45d5f3d52ffe Mon Sep 17 00:00:00 2001 From: George Kankava Date: Fri, 24 Jun 2016 17:32:57 +0400 Subject: [PATCH 143/212] squid:S1149 - Synchronized classes Vector, Hashtable, Stack and StringBuffer should not be used --- .../main/java/org/jsmpp/session/AbstractSMPPOperation.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/AbstractSMPPOperation.java b/jsmpp/src/main/java/org/jsmpp/session/AbstractSMPPOperation.java index 0fec782..2c0f86b 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/AbstractSMPPOperation.java +++ b/jsmpp/src/main/java/org/jsmpp/session/AbstractSMPPOperation.java @@ -15,7 +15,9 @@ package org.jsmpp.session; import java.io.IOException; +import java.util.HashMap; import java.util.Hashtable; +import java.util.Map; import org.jsmpp.InvalidResponseException; import org.jsmpp.PDUException; @@ -45,7 +47,7 @@ public abstract class AbstractSMPPOperation implements SMPPOperation { private static final Logger logger = LoggerFactory.getLogger(AbstractSMPPOperation.class); - private final Hashtable> pendingResponse = new Hashtable>(); + private final Map> pendingResponse = new HashMap>(); private final Sequence sequence = new Sequence(1); private final PDUSender pduSender; private final Connection connection; From 1a5f0bc931716a7f7186a712506c5ce0e4721c67 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Mon, 27 Jun 2016 10:51:57 +0200 Subject: [PATCH 144/212] Remove unused import. --- jsmpp/src/main/java/org/jsmpp/session/AbstractSMPPOperation.java | 1 - 1 file changed, 1 deletion(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/AbstractSMPPOperation.java b/jsmpp/src/main/java/org/jsmpp/session/AbstractSMPPOperation.java index 2c0f86b..8af5968 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/AbstractSMPPOperation.java +++ b/jsmpp/src/main/java/org/jsmpp/session/AbstractSMPPOperation.java @@ -16,7 +16,6 @@ import java.io.IOException; import java.util.HashMap; -import java.util.Hashtable; import java.util.Map; import org.jsmpp.InvalidResponseException; From c47ba9f2249f94330c301dcd792d964608a764c2 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Fri, 1 Jul 2016 01:14:41 +0200 Subject: [PATCH 145/212] Remove unnecessary private --- jsmpp/src/main/java/org/jsmpp/bean/NumberingPlanIndicator.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/NumberingPlanIndicator.java b/jsmpp/src/main/java/org/jsmpp/bean/NumberingPlanIndicator.java index 4b6ee77..3f8d4d2 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/NumberingPlanIndicator.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/NumberingPlanIndicator.java @@ -38,7 +38,8 @@ public enum NumberingPlanIndicator { WAP(SMPPConstant.NPI_WAP); private byte value; - private NumberingPlanIndicator(byte value) { + + NumberingPlanIndicator(byte value) { this.value = value; } From c3ed8ced4b7aef93828e801bd5dd480710d22c18 Mon Sep 17 00:00:00 2001 From: George Kankava Date: Fri, 1 Jul 2016 19:05:24 +0400 Subject: [PATCH 146/212] squid:S1161 - '@Override' annotation should be used on any method overriding (since Java 5) or implementing (since Java 6) another one --- .../java/org/jsmpp/bean/DeliveryReceipt.java | 1 + .../org/jsmpp/bean/OptionalParameter.java | 24 ++++++++++++++----- .../jsmpp/session/PDUProcessServerTask.java | 1 + .../org/jsmpp/session/PDUProcessTask.java | 1 + .../org/jsmpp/session/SMPPServerSession.java | 1 + .../java/org/jsmpp/session/SMPPSession.java | 1 + 6 files changed, 23 insertions(+), 6 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java b/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java index a0eaf77..6c93818 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java @@ -217,6 +217,7 @@ public void setText(String text) { } } + @Override public String toString() { /* * id:IIIIIIIIII sub:SSS dlvrd:DDD submit date:YYMMDDhhmm done diff --git a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java index 9eb6a0f..b9e5fb2 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java @@ -119,6 +119,7 @@ protected byte[] serializeValue() { /** * Print Optional Parameter byte in hex format */ + @Override public String toString() { return HexUtil.conventBytesToHexString(OctetUtil.shortToBytes(value)); @@ -157,6 +158,7 @@ protected byte[] serializeValue() { /** * Print Optional Parameter byte in hex format */ + @Override public String toString() { return HexUtil.conventBytesToHexString(OctetUtil.intToBytes(value)); @@ -195,6 +197,7 @@ protected byte[] serializeValue() { /** * Print Optional Parameter byte in hex format */ + @Override public String toString() { return HexUtil.conventBytesToHexString(new byte[] {getValue()}); @@ -238,7 +241,7 @@ public OctetString(short tag, byte[] value, int offset, int length) { public byte[] getValue() { return value; } - + public String getValueAsString() { return new String(value); } @@ -363,6 +366,7 @@ public Addr_subunit getDestAddrSubunit() { return Addr_subunit.toEnum(value); } + @Override public String toString() { return getDestAddrSubunit().toString(); } @@ -388,7 +392,7 @@ public enum Network_type { private Network_type(int value) { this.value = (byte)value; } - + public byte value() { return value; } @@ -434,6 +438,7 @@ public Network_type getDestNetworkType() { return Network_type.toEnum(value); } + @Override public String toString() { return getDestNetworkType().toString(); } @@ -505,6 +510,7 @@ public Bearer_type getDestBearerType() { return Bearer_type.toEnum(value); } + @Override public String toString() { return getDestBearerType().toString(); } @@ -563,6 +569,7 @@ public Addr_subunit getSourceAddrSubunit() { return Addr_subunit.toEnum(value); } + @Override public String toString() { return getSourceAddrSubunit().toString(); } @@ -598,6 +605,7 @@ public Network_type getSourceNetworkType() { return Network_type.toEnum(value); } + @Override public String toString() { return getSourceNetworkType().toString(); } @@ -632,7 +640,8 @@ public Source_bearer_type(byte[] content) { public Bearer_type getSourceBearerType() { return Bearer_type.toEnum(value); } - + + @Override public String toString() { return getSourceBearerType().toString(); } @@ -749,7 +758,8 @@ public Payload_type(byte[] content) { public Payload_type_enum getPayloadType() { return Payload_type_enum.toEnum(value); } - + + @Override public String toString() { return getPayloadType().toString(); } @@ -860,7 +870,8 @@ public boolean isIndicatorActive() { public Ms_msg_wait_facilities_type getMessageType() { return Ms_msg_wait_facilities_type.toEnum((byte)(value & 0x03)); } - + + @Override public String toString() { String endString = isIndicatorActive() ? "active" : "inactive"; return getMessageType().toString() + " set as " + endString; @@ -1930,7 +1941,8 @@ public Message_state(byte[] content) { public Message_state_enum getMessageState() { return Message_state_enum.toEnum(value); } - + + @Override public String toString() { return getMessageState().toString(); } diff --git a/jsmpp/src/main/java/org/jsmpp/session/PDUProcessServerTask.java b/jsmpp/src/main/java/org/jsmpp/session/PDUProcessServerTask.java index 5420673..b636c6d 100755 --- a/jsmpp/src/main/java/org/jsmpp/session/PDUProcessServerTask.java +++ b/jsmpp/src/main/java/org/jsmpp/session/PDUProcessServerTask.java @@ -49,6 +49,7 @@ public PDUProcessServerTask(Command pduHeader, byte[] pdu, this.onIOExceptionTask = onIOExceptionTask; } + @Override public void run() { try { if(logger.isDebugEnabled()) diff --git a/jsmpp/src/main/java/org/jsmpp/session/PDUProcessTask.java b/jsmpp/src/main/java/org/jsmpp/session/PDUProcessTask.java index 1873cbb..3ae9fef 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/PDUProcessTask.java +++ b/jsmpp/src/main/java/org/jsmpp/session/PDUProcessTask.java @@ -47,6 +47,7 @@ public PDUProcessTask(Command pduHeader, byte[] pdu, this.onIOExceptionTask = onIOExceptionTask; } + @Override public void run() { try { if(logger.isDebugEnabled()) { diff --git a/jsmpp/src/main/java/org/jsmpp/session/SMPPServerSession.java b/jsmpp/src/main/java/org/jsmpp/session/SMPPServerSession.java index 2824fe5..e7d440f 100755 --- a/jsmpp/src/main/java/org/jsmpp/session/SMPPServerSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/SMPPServerSession.java @@ -500,6 +500,7 @@ public void sendReplaceSmResp(int sequenceNumber) throws IOException { private class PDUReaderWorker extends Thread { private ExecutorService executorService = Executors.newFixedThreadPool(getPduProcessorDegree()); private Runnable onIOExceptionTask = new Runnable() { + @Override public void run() { close(); }; diff --git a/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java b/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java index 45d106d..da11b62 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java @@ -565,6 +565,7 @@ private class PDUReaderWorker extends Thread { // start with serial execution of pdu processing, when the session is bound the pool will be enlarge up to the PduProcessorDegree private ExecutorService executorService = Executors.newFixedThreadPool(1); private Runnable onIOExceptionTask = new Runnable() { + @Override public void run() { close(); }; From 84289a79ae65f4fd645af45c47b4326ea0ec9cee Mon Sep 17 00:00:00 2001 From: George Kankava Date: Fri, 1 Jul 2016 19:40:23 +0400 Subject: [PATCH 147/212] pmd:ConsecutiveAppendsShouldReuse - Consecutive Appends Should Reuse --- .../java/org/jsmpp/bean/DeliveryReceipt.java | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java b/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java index a0eaf77..7c7e504 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java @@ -223,21 +223,21 @@ public String toString() { * date:YYMMDDhhmm stat:DDDDDDD err:E Text: . . . . . . . . . */ StringBuilder stringBuilder = new StringBuilder(120); - stringBuilder.append(DELREC_ID + ":" + id); - stringBuilder.append(" "); - stringBuilder.append(DELREC_SUB + ":" + intToString(submitted, 3)); - stringBuilder.append(" "); - stringBuilder.append(DELREC_DLVRD + ":" + intToString(delivered, 3)); - stringBuilder.append(" "); - stringBuilder.append(DELREC_SUBMIT_DATE + ":" + dateFormat.format(submitDate)); - stringBuilder.append(" "); - stringBuilder.append(DELREC_DONE_DATE + ":" + dateFormat.format(doneDate)); - stringBuilder.append(" "); - stringBuilder.append(DELREC_STAT + ":" + finalStatus); - stringBuilder.append(" "); - stringBuilder.append(DELREC_ERR + ":" + error); - stringBuilder.append(" "); - stringBuilder.append(DELREC_TEXT.toLowerCase() + ":" + text); + stringBuilder.append(DELREC_ID + ":" + id) + .append(" ") + .append(DELREC_SUB + ":" + intToString(submitted, 3)) + .append(" ") + .append(DELREC_DLVRD + ":" + intToString(delivered, 3)) + .append(" ") + .append(DELREC_SUBMIT_DATE + ":" + dateFormat.format(submitDate)) + .append(" ") + .append(DELREC_DONE_DATE + ":" + dateFormat.format(doneDate)) + .append(" ") + .append(DELREC_STAT + ":" + finalStatus) + .append(" ") + .append(DELREC_ERR + ":" + error) + .append(" ") + .append(DELREC_TEXT.toLowerCase() + ":" + text); return stringBuilder.toString(); } From 29cdf1b26f232d23fc999eeb398a6aa14f5aa2e3 Mon Sep 17 00:00:00 2001 From: George Kankava Date: Fri, 1 Jul 2016 19:46:09 +0400 Subject: [PATCH 148/212] squid:S1168 - Empty arrays and collections should be returned instead of null --- jsmpp/src/main/java/org/jsmpp/util/DefaultDecomposer.java | 2 +- jsmpp/src/main/java/org/jsmpp/util/SequentialBytesReader.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/util/DefaultDecomposer.java b/jsmpp/src/main/java/org/jsmpp/util/DefaultDecomposer.java index 46fb0f5..591d591 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/DefaultDecomposer.java +++ b/jsmpp/src/main/java/org/jsmpp/util/DefaultDecomposer.java @@ -617,7 +617,7 @@ public AlertNotification alertNotification(byte[] data) throws PDUStringExceptio private static OptionalParameter[] readOptionalParameters( SequentialBytesReader reader) { if (!reader.hasMoreBytes()) - return null; + return new OptionalParameter[] {}; List params = new ArrayList(); while (reader.hasMoreBytes()) { short tag = reader.readShort(); diff --git a/jsmpp/src/main/java/org/jsmpp/util/SequentialBytesReader.java b/jsmpp/src/main/java/org/jsmpp/util/SequentialBytesReader.java index a5a26ed..0f09a25 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/SequentialBytesReader.java +++ b/jsmpp/src/main/java/org/jsmpp/util/SequentialBytesReader.java @@ -47,7 +47,7 @@ public byte[] readBytesUntilNull() { int length = i - 1 - cursor; if (length == 0) { cursor += 1 + length; - return null; + return new byte[] {}; } byte[] data = new byte[length]; System.arraycopy(bytes, cursor, data, 0, length); From 66911f80dcae38e3260fd0eca848251b9723c7ec Mon Sep 17 00:00:00 2001 From: George Kankava Date: Sat, 2 Jul 2016 08:47:56 +0400 Subject: [PATCH 149/212] squid:S2142 -'InterruptedException' should not be ignored --- jsmpp/src/main/java/org/jsmpp/extra/PendingResponse.java | 1 + jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java | 2 ++ .../src/main/java/org/jsmpp/session/BindRequestReceiver.java | 4 +++- jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java | 1 + 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/jsmpp/src/main/java/org/jsmpp/extra/PendingResponse.java b/jsmpp/src/main/java/org/jsmpp/extra/PendingResponse.java index b157250..63a1e8e 100644 --- a/jsmpp/src/main/java/org/jsmpp/extra/PendingResponse.java +++ b/jsmpp/src/main/java/org/jsmpp/extra/PendingResponse.java @@ -106,6 +106,7 @@ public void waitDone() throws ResponseTimeoutException, try { condition.await(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { + Thread.currentThread().interrupt(); } } diff --git a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java index 0cfde86..477a50f 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java @@ -218,6 +218,7 @@ public void close() { try { enquireLinkSender.join(); } catch (InterruptedException e) { + Thread.currentThread().interrupt(); logger.warn("Interrupted while waiting for enquireLinkSender thread to exit"); } } @@ -423,6 +424,7 @@ public void run() { try { sendingEnquireLink.wait(500); } catch (InterruptedException e) { + Thread.currentThread().interrupt(); } } } diff --git a/jsmpp/src/main/java/org/jsmpp/session/BindRequestReceiver.java b/jsmpp/src/main/java/org/jsmpp/session/BindRequestReceiver.java index 41d3819..f4e9f6a 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/BindRequestReceiver.java +++ b/jsmpp/src/main/java/org/jsmpp/session/BindRequestReceiver.java @@ -53,7 +53,9 @@ BindRequest waitForRequest(long timeout) throws IllegalStateException, TimeoutEx } else if (request == null) { try { requestCondition.await(timeout, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } } if (request != null) { diff --git a/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java b/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java index 45d106d..bfcd970 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java @@ -585,6 +585,7 @@ public void run() { try { executorService.awaitTermination(getTransactionTimer(), TimeUnit.MILLISECONDS); } catch (InterruptedException e) { + Thread.currentThread().interrupt(); logger.warn("interrupted while waiting for executor service pool to finish"); } logger.info("PDUReaderWorker stop"); From cc877deef1679f8bd825f89028fc5abdc7478c09 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Fri, 8 Jul 2016 16:14:07 +0200 Subject: [PATCH 150/212] Add outbind processing --- CHANGES.txt | 5 +- .../main/java/org/jsmpp/DefaultPDUSender.java | 14 ++ jsmpp/src/main/java/org/jsmpp/PDUSender.java | 15 ++ .../java/org/jsmpp/SynchronizedPDUSender.java | 11 +- .../jsmpp/session/BaseResponseHandler.java | 9 +- .../java/org/jsmpp/session/BindRequest.java | 6 +- .../java/org/jsmpp/session/ClientSession.java | 67 +++++- .../org/jsmpp/session/OutbindCommandTask.java | 49 ++++ .../org/jsmpp/session/OutbindParameter.java | 124 ++++++++++ .../org/jsmpp/session/OutbindRequest.java | 28 +++ .../jsmpp/session/OutbindRequestReceiver.java | 91 ++++++++ .../jsmpp/session/PDUProcessServerTask.java | 4 + .../org/jsmpp/session/SMPPServerSession.java | 12 +- .../java/org/jsmpp/session/SMPPSession.java | 221 +++++++++++++++++- .../jsmpp/session/ServerResponseHandler.java | 7 +- .../session/state/SMPPServerSessionBound.java | 18 +- .../state/SMPPServerSessionClosed.java | 10 + .../session/state/SMPPServerSessionOpen.java | 54 +++++ .../session/state/SMPPServerSessionState.java | 25 +- .../state/SMPPServerSessionUnbound.java | 11 + .../jsmpp/session/state/SMPPSessionBound.java | 9 +- .../session/state/SMPPSessionClosed.java | 6 + .../jsmpp/session/state/SMPPSessionOpen.java | 36 +++ .../jsmpp/session/state/SMPPSessionState.java | 12 +- .../session/state/SMPPSessionUnbound.java | 8 +- .../jsmpp/session/DummyResponseHandler.java | 5 + 26 files changed, 830 insertions(+), 27 deletions(-) create mode 100755 jsmpp/src/main/java/org/jsmpp/session/OutbindCommandTask.java create mode 100755 jsmpp/src/main/java/org/jsmpp/session/OutbindParameter.java create mode 100755 jsmpp/src/main/java/org/jsmpp/session/OutbindRequest.java create mode 100755 jsmpp/src/main/java/org/jsmpp/session/OutbindRequestReceiver.java diff --git a/CHANGES.txt b/CHANGES.txt index af6aea0..976ce7b 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,8 @@ Changes: +2.2.5 +- Add outbind processing + 2.2.4 - Fixed some logging - Add PriorityFlag enum @@ -29,7 +32,7 @@ Changes: Removed the old class (since I could not make the change backwards compatible) Added some new classes instead: 1. DataCodings - 2. DataCoding (GeneralDataCoding, MessageWatingDataCoding, SimpleDataCoding, RawDataCoding) + 2. DataCoding (GeneralDataCoding, MessageWaitingDataCoding, SimpleDataCoding, RawDataCoding) - Expose remote InetAddress on server side API via SMPPServerSession Add new method: InetAddress SMPPServerSession#getInetAddress() - Ensure command execution is in valid state. Checking done on local side (remote side also does the checking) diff --git a/jsmpp/src/main/java/org/jsmpp/DefaultPDUSender.java b/jsmpp/src/main/java/org/jsmpp/DefaultPDUSender.java index 37fc732..1445c08 100644 --- a/jsmpp/src/main/java/org/jsmpp/DefaultPDUSender.java +++ b/jsmpp/src/main/java/org/jsmpp/DefaultPDUSender.java @@ -123,6 +123,20 @@ public byte[] sendBindResp(OutputStream os, int commandId, return b; } + /* + * (non-Javadoc) + * + * @see org.jsmpp.PDUSender#sendOutbind(java.io.OutputStream, + * int, java.lang.String, java.lang.String) + */ + public byte[] sendOutbind(OutputStream os, int sequenceNumber, String systemId, String password) + throws PDUStringException, IOException + { + byte[] b = this.pduComposer.outbind( sequenceNumber,systemId, password); + writeAndFlush(os, b); + return b; + } + /* * (non-Javadoc) * diff --git a/jsmpp/src/main/java/org/jsmpp/PDUSender.java b/jsmpp/src/main/java/org/jsmpp/PDUSender.java index 647c9fc..03fe892 100644 --- a/jsmpp/src/main/java/org/jsmpp/PDUSender.java +++ b/jsmpp/src/main/java/org/jsmpp/PDUSender.java @@ -91,6 +91,21 @@ byte[] sendBind(OutputStream os, BindType bindType, int sequenceNumber, byte[] sendBindResp(OutputStream os, int commandId, int sequenceNumber, String systemId, InterfaceVersion interfaceVersion) throws PDUStringException, IOException; + /** + * Send outbind command. + * + * @param os is the {@link OutputStream} + * @param sequenceNumber is the sequence_number. + * @param systemId is the system_id. + * @param password is the password. + * @return the composed bytes. + * @throws PDUStringException if there is an invalid string constraint found. + * @throws IOException if an I/O error occur. + */ + byte[] sendOutbind(OutputStream os,int sequenceNumber, + String systemId, String password) + throws PDUStringException, IOException; + /** * Send unbind command. * diff --git a/jsmpp/src/main/java/org/jsmpp/SynchronizedPDUSender.java b/jsmpp/src/main/java/org/jsmpp/SynchronizedPDUSender.java index 0f40d48..24efe7a 100644 --- a/jsmpp/src/main/java/org/jsmpp/SynchronizedPDUSender.java +++ b/jsmpp/src/main/java/org/jsmpp/SynchronizedPDUSender.java @@ -389,7 +389,7 @@ public byte[] sendSubmitMultiResp(OutputStream os, int sequenceNumber, unsuccessDeliveries); } } - + public byte[] sendAlertNotification(OutputStream os, int sequenceNumber, byte sourceAddrTon, byte sourceAddrNpi, String sourceAddr, byte esmeAddrTon, byte esmeAddrNpi, String esmeAddr, @@ -401,4 +401,13 @@ public byte[] sendAlertNotification(OutputStream os, int sequenceNumber, esmeAddrNpi, esmeAddr, optionalParameters); } } + + public byte[] sendOutbind(OutputStream os, int sequenceNumber, String systemId, String password) + throws PDUStringException, IOException + { + synchronized (os) + { + return this.pduSender.sendOutbind(os, sequenceNumber, systemId, password); + } + } } diff --git a/jsmpp/src/main/java/org/jsmpp/session/BaseResponseHandler.java b/jsmpp/src/main/java/org/jsmpp/session/BaseResponseHandler.java index a3f3339..c41220c 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/BaseResponseHandler.java +++ b/jsmpp/src/main/java/org/jsmpp/session/BaseResponseHandler.java @@ -16,8 +16,10 @@ import java.io.IOException; +import org.jsmpp.bean.BindType; import org.jsmpp.bean.Command; import org.jsmpp.bean.DataSm; +import org.jsmpp.bean.InterfaceVersion; import org.jsmpp.extra.PendingResponse; import org.jsmpp.extra.ProcessRequestException; @@ -26,7 +28,10 @@ * */ public interface BaseResponseHandler { - + + void sendBindResp(String systemId, InterfaceVersion interfaceVersion, BindType bindType, int sequenceNumber) + throws IOException; + /** * Remove the previously {@link PendingResponse} that set when the request * was sent. @@ -93,7 +98,7 @@ void sendNegativeResponse(int originalCommandId, int commandStatus, * request. * @throws IOException if an IO error occur. */ - public void sendDataSmResp(DataSmResult dataSmResult, int sequenceNumber) throws IOException; + void sendDataSmResp(DataSmResult dataSmResult, int sequenceNumber) throws IOException; /** * Notify for unbind. diff --git a/jsmpp/src/main/java/org/jsmpp/session/BindRequest.java b/jsmpp/src/main/java/org/jsmpp/session/BindRequest.java index af097fb..164359d 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/BindRequest.java +++ b/jsmpp/src/main/java/org/jsmpp/session/BindRequest.java @@ -49,10 +49,10 @@ public class BindRequest { private final int originalSequenceNumber; private boolean done; - private final ServerResponseHandler responseHandler; + private final BaseResponseHandler responseHandler; public BindRequest(int sequenceNumber, BindType bindType, String systemId, String password, String systemType, TypeOfNumber addrTon, NumberingPlanIndicator addrNpi, - String addressRange, InterfaceVersion interfaceVersion, ServerResponseHandler responseHandler) { + String addressRange, InterfaceVersion interfaceVersion, BaseResponseHandler responseHandler) { this.originalSequenceNumber = sequenceNumber; this.responseHandler = responseHandler; @@ -66,7 +66,7 @@ public BindRequest(int sequenceNumber, BindType bindType, String systemId, Strin this.interfaceVersion = interfaceVersion; } - public BindRequest(Bind bind, ServerResponseHandler responseHandler) { + public BindRequest(Bind bind, BaseResponseHandler responseHandler) { this(bind.getSequenceNumber(), BindType.valueOf(bind.getCommandId()), bind.getSystemId(), bind.getPassword(), bind.getSystemType(), TypeOfNumber.valueOf(bind.getAddrTon()), diff --git a/jsmpp/src/main/java/org/jsmpp/session/ClientSession.java b/jsmpp/src/main/java/org/jsmpp/session/ClientSession.java index b90587f..0e4b136 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/ClientSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/ClientSession.java @@ -239,7 +239,7 @@ void connectAndBind(String host, int port, BindType bindType, * @param timeout is the timeout. * @throws IOException if there is an IO error found. */ - public void connectAndBind(String host, int port, BindType bindType, + void connectAndBind(String host, int port, BindType bindType, String systemId, String password, String systemType, TypeOfNumber addrTon, NumberingPlanIndicator addrNpi, String addressRange, long timeout) throws IOException; @@ -253,7 +253,7 @@ public void connectAndBind(String host, int port, BindType bindType, * @return the SMSC system id. * @throws IOException if there is an IO error found. */ - public String connectAndBind(String host, int port, + String connectAndBind(String host, int port, BindParameter bindParam) throws IOException; @@ -267,20 +267,75 @@ public String connectAndBind(String host, int port, * @return the SMSC system id. * @throws IOException if there is an IO error found. */ - public String connectAndBind(String host, int port, + String connectAndBind(String host, int port, BindParameter bindParam, long timeout) throws IOException; - + + /***************************************************************/ + /** + * Open connection and outbind immediately. The default + * timeout is 1 minutes. + * + * @param host is the SMSC host address. + * @param port is the SMSC listen port. + * @param systemId is the system id. + * @param password is the password. + * @throws IOException if there is an IO error found. + */ + BindRequest connectAndOutbind(String host, int port, + String systemId, String password) throws IOException; + + /** + * Open connection and bind immediately with specified timeout. The default + * timeout is 1 minutes. + * + * @param host is the SMSC host address. + * @param port is the SMSC listen port. + * @param systemId is the system id. + * @param password is the password. + * @param timeout is the timeout. + * @throws IOException if there is an IO error found. + */ + BindRequest connectAndOutbind(String host, int port, + String systemId, String password, long timeout) throws IOException; + + /** + * Open connection and bind immediately. + * + * @param host is the SMSC host address. + * @param port is the SMSC listen port. + * @param outbindParam is the outbind parameters. + * @return the SMSC system id. + * @throws IOException if there is an IO error found. + */ + BindRequest connectAndOutbind(String host, int port, + OutbindParameter outbindParam) + throws IOException; + + /** + * Open connection and bind immediately. + * + * @param host is the SMSC host address. + * @param port is the SMSC listen port. + * @param outbindParam is the outbind parameters. + * @param timeout is the timeout. + * @return the SMSC system id. + * @throws IOException if there is an IO error found. + */ + BindRequest connectAndOutbind(String host, int port, + OutbindParameter outbindParam, long timeout) + throws IOException; + /** * Get the current message receiver listener that is currently registered for this smpp session. * @return The current message receiver listener */ - public MessageReceiverListener getMessageReceiverListener(); + MessageReceiverListener getMessageReceiverListener(); /** * Sets a message receiver listener for this smpp session. * @param messageReceiverListener is the new listener */ - public void setMessageReceiverListener( + void setMessageReceiverListener( MessageReceiverListener messageReceiverListener); } diff --git a/jsmpp/src/main/java/org/jsmpp/session/OutbindCommandTask.java b/jsmpp/src/main/java/org/jsmpp/session/OutbindCommandTask.java new file mode 100755 index 0000000..3c61ee3 --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/OutbindCommandTask.java @@ -0,0 +1,49 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session; + +import java.io.IOException; +import java.io.OutputStream; + +import org.jsmpp.PDUSender; +import org.jsmpp.PDUStringException; + +/** + * @author pmoerenhout + */ +public class OutbindCommandTask extends AbstractSendCommandTask { + + private final String systemId; + private final String password; + + public OutbindCommandTask(PDUSender pduSender, + String systemId, + String password) { + super(pduSender); + this.systemId = systemId; + this.password = password; + } + + @Override + public void executeTask(OutputStream out, int sequenceNumber) + throws PDUStringException, IOException { + this.pduSender.sendOutbind(out, sequenceNumber, this.systemId, this.password); + } + + @Override + public String getCommandName() { + return "outbind"; + } +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/OutbindParameter.java b/jsmpp/src/main/java/org/jsmpp/session/OutbindParameter.java new file mode 100755 index 0000000..0a23bec --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/OutbindParameter.java @@ -0,0 +1,124 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session; + +import org.jsmpp.bean.InterfaceVersion; + +/** + * This class is wraps all bind parameter that will be send as PDU. + * + * @author pmoerenhout + * + */ +public class OutbindParameter { + + private String systemId; + private String password; + private InterfaceVersion interfaceVersion; + + /** + * Construct with all mandatory parameters. + * + * @param systemId + * is the system id. + * @param password + * is the password. + */ + public OutbindParameter(String systemId, + String password) + { + this(systemId, password, InterfaceVersion.IF_34); + } + + public OutbindParameter(String systemId, + String password, + InterfaceVersion interfaceVersion) + { + + this.systemId = systemId; + this.password = password; + this.interfaceVersion = interfaceVersion; + } + + + public String getSystemId() { + return this.systemId; + } + + public String getPassword() { + return this.password; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = (prime * result) + + ((this.password == null) ? 0 : this.password.hashCode()); + result = (prime * result) + + ((this.systemId == null) ? 0 : this.systemId.hashCode()); + result = (prime * result) + + ((this.interfaceVersion == null) ? 0 : this.interfaceVersion.hashCode()); + + return result; + } + + + private boolean hasEqualPassword(OutbindParameter other) { + if ((this.password == null) && (other.password != null)) { + return false; + } + return this.password.equals(other.password); + } + + private boolean hasEqualSystemId(OutbindParameter other) { + if ((this.systemId == null) && (other.systemId != null)) { + return false; + } + return this.systemId.equals(other.systemId); + } + + + + @Override + public boolean equals(Object obj) { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (getClass() != obj.getClass()) + { + return false; + } + final OutbindParameter other = (OutbindParameter)obj; + + if (!hasEqualPassword(other)) { + return false; + } + if (!hasEqualSystemId(other)) { + return false; + } + return true; + } + + public InterfaceVersion getInterfaceVersion() { + return this.interfaceVersion; + } + +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/OutbindRequest.java b/jsmpp/src/main/java/org/jsmpp/session/OutbindRequest.java new file mode 100755 index 0000000..78277d5 --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/OutbindRequest.java @@ -0,0 +1,28 @@ +package org.jsmpp.session; + +import org.jsmpp.bean.Outbind; + +/** + * @author pmoerenhout + */ +public class OutbindRequest { + private final String systemId; + private final String password; + + public OutbindRequest(String systemId, String password) { + this.systemId = systemId; + this.password = password; + } + + public OutbindRequest(Outbind outbind) { + this(outbind.getSystemId(), outbind.getPassword()); + } + + public String getSystemId() { + return this.systemId; + } + + public String getPassword() { + return this.password; + } +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/OutbindRequestReceiver.java b/jsmpp/src/main/java/org/jsmpp/session/OutbindRequestReceiver.java new file mode 100755 index 0000000..0856c88 --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/OutbindRequestReceiver.java @@ -0,0 +1,91 @@ +package org.jsmpp.session; + +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import org.jsmpp.bean.Outbind; + +/** + * @author pmoerenhout + */ +public class OutbindRequestReceiver { + private final Lock lock = new ReentrantLock(); + private final Condition requestCondition = this.lock.newCondition(); + private OutbindRequest request; + private boolean alreadyWaitForRequest; + + public OutbindRequestReceiver() { + } + + /** + * Wait until the bind request received for specified timeout. + * + * @param timeout is the timeout. + * @return the {@link BindRequest}. + * @throws IllegalStateException if this method already called before. + * @throws TimeoutException if the timeout has been reach. + */ + OutbindRequest waitForRequest(long timeout) throws IllegalStateException, TimeoutException { + this.lock.lock(); + try { + if (this.alreadyWaitForRequest) { + throw new IllegalStateException("waitForRequest(long) method already invoked"); + } + else if (this.request == null) { + try { + this.requestCondition.await(timeout, TimeUnit.MILLISECONDS); + } + catch (InterruptedException e) { + } + } + + if (this.request != null) { + return this.request; + } + else { + throw new TimeoutException("Waiting for bind request take time too long"); + } + } + finally { + this.alreadyWaitForRequest = true; + this.lock.unlock(); + } + } + + /** + * Notify that the bind has accepted. + * + * @param outbind is the {@link Outbind} command. + * @throws IllegalStateException if this method already called before. + */ + void notifyAcceptOutbind(Outbind outbind) throws IllegalStateException { + this.lock.lock(); + try { + if (this.request == null) { + this.request = new OutbindRequest(outbind); + this.requestCondition.signal(); + } + else { + throw new IllegalStateException("Already waiting for acceptance outbind"); + } + } + finally { + this.lock.unlock(); + } + } +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/PDUProcessServerTask.java b/jsmpp/src/main/java/org/jsmpp/session/PDUProcessServerTask.java index b636c6d..a7d7eea 100755 --- a/jsmpp/src/main/java/org/jsmpp/session/PDUProcessServerTask.java +++ b/jsmpp/src/main/java/org/jsmpp/session/PDUProcessServerTask.java @@ -64,6 +64,10 @@ public void run() { activityNotifier.notifyActivity(); stateProcessor.processBind(pduHeader, pdu, responseHandler); break; + case SMPPConstant.CID_OUTBIND: + this.activityNotifier.notifyActivity(); + this.stateProcessor.processOutbind(pduHeader, pdu, responseHandler); + break; case SMPPConstant.CID_GENERIC_NACK: activityNotifier.notifyActivity(); stateProcessor.processGenericNack(pduHeader, pdu, responseHandler); diff --git a/jsmpp/src/main/java/org/jsmpp/session/SMPPServerSession.java b/jsmpp/src/main/java/org/jsmpp/session/SMPPServerSession.java index e7d440f..419f79a 100755 --- a/jsmpp/src/main/java/org/jsmpp/session/SMPPServerSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/SMPPServerSession.java @@ -44,6 +44,7 @@ import org.jsmpp.bean.MessageState; import org.jsmpp.bean.NumberingPlanIndicator; import org.jsmpp.bean.OptionalParameter; +import org.jsmpp.bean.Outbind; import org.jsmpp.bean.QuerySm; import org.jsmpp.bean.RegisteredDelivery; import org.jsmpp.bean.ReplaceSm; @@ -83,6 +84,7 @@ public class SMPPServerSession extends AbstractSession implements ServerSession private ServerMessageReceiverListener messageReceiverListener; private ServerResponseDeliveryListener responseDeliveryListener; private BindRequestReceiver bindRequestReceiver = new BindRequestReceiver(responseHandler); + private OutbindRequestReceiver outbindRequestReceiver = new OutbindRequestReceiver(); public SMPPServerSession(Connection conn, SessionStateListener sessionStateListener, @@ -330,9 +332,14 @@ public void sendBindResp(String systemId, InterfaceVersion interfaceVersion, Bin // TODO uudashr: we have double checking when accept the bind request } } - + public void processBind(Bind bind) { - bindRequestReceiver.notifyAcceptBind(bind); + SMPPServerSession.this.bindRequestReceiver.notifyAcceptBind(bind); + } + + public void processOutbind(Outbind outbind) + { + SMPPServerSession.this.outbindRequestReceiver.notifyAcceptOutbind(outbind); } public MessageId processSubmitSm(SubmitSm submitSm) @@ -554,7 +561,6 @@ private void notifyNoActivity() { } } - private class BoundStateListener implements SessionStateListener { public void onStateChange(SessionState newState, SessionState oldState, Session source) { diff --git a/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java b/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java index da11b62..8cdb67c 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java @@ -35,6 +35,7 @@ import org.jsmpp.SynchronizedPDUSender; import org.jsmpp.bean.Address; import org.jsmpp.bean.AlertNotification; +import org.jsmpp.bean.Bind; import org.jsmpp.bean.BindResp; import org.jsmpp.bean.BindType; import org.jsmpp.bean.Command; @@ -301,6 +302,209 @@ private String sendBind(BindType bindType, String systemId, return resp.getSystemId(); } + + /***************************************************************/ + /** + * Open connection and outbind immediately. The default + * timeout is 1 minutes. + * + * @param host is the SMSC host address. + * @param port is the SMSC listen port. + * @param systemId is the system id. + * @param password is the password. + * @throws IOException if there is an IO error found. + */ + @Override + public BindRequest connectAndOutbind(String host, int port, + String systemId, String password) throws IOException + { + logger.debug("Connect and bind to {} port {}", host, port); + if (sequence().currentValue() > 1) + { + throw new IOException("Failed connecting"); + } + + this.conn = this.connFactory.createConnection(host, port); + logger.info("Connected"); + + this.conn.setSoTimeout(getEnquireLinkTimer()); + + this.sessionContext.open(); + return outbind(new OutbindParameter(systemId,password), 60000); + } + + /** + * Open connection and bind immediately with specified timeout. The default + * timeout is 1 minutes. + * + * @param host is the SMSC host address. + * @param port is the SMSC listen port. + * @param systemId is the system id. + * @param password is the password. + * @param timeout is the timeout. + * @throws IOException if there is an IO error found. + */ + @Override + public BindRequest connectAndOutbind(String host, int port, + String systemId, String password, long timeout) throws IOException + { + logger.debug("Connect and bind to {} port {}", host, port); + if (sequence().currentValue() > 1) + { + throw new IOException("Failed connecting"); + } + + this.conn = this.connFactory.createConnection(host, port); + logger.info("Connected"); + + this.conn.setSoTimeout(getEnquireLinkTimer()); + + this.sessionContext.open(); + return outbind(new OutbindParameter(systemId, + password), timeout); + } + + /** + * Open connection and bind immediately. + * + * @param host is the SMSC host addressm port + * @param port is the SMSC listen port. + * @param outbindParam is the outbind parameters. + * @return the SMSC system id. + * @throws IOException if there is an IO error found. + */ + @Override + public BindRequest connectAndOutbind(String host, int port, + OutbindParameter outbindParam) + throws IOException + { + logger.debug("Connect and bind to {} port {}", host, port); + if (sequence().currentValue() > 1) + { + throw new IOException("Failed connecting"); + } + + this.conn = this.connFactory.createConnection(host, port); + logger.info("Connected"); + + this.conn.setSoTimeout(getEnquireLinkTimer()); + + this.sessionContext.open(); + return outbind(outbindParam, 60000); + } + + /** + * Open connection and bind immediately. + * + * @param host SC host address. + * @param port is the SMSC listen port. + * @param outbindParam is the outbind parameters. + * @param timeout is the timeout. + * @return the SMSC system id. + * @throws IOException if there is an IO error found. + */ + @Override + public BindRequest connectAndOutbind(String host, int port, + OutbindParameter outbindParam, long timeout) + throws IOException + { + logger.debug("Connect and bind to {} port {}", host, port); + if (sequence().currentValue() > 1) + { + throw new IOException("Failed connecting"); + } + + this.conn = this.connFactory.createConnection(host, port); + logger.info("Connected"); + + this.conn.setSoTimeout(getEnquireLinkTimer()); + + this.sessionContext.open(); + return outbind(outbindParam, timeout); + } + + private BindRequest outbind(OutbindParameter outbindParam, long timeout) throws IOException + { + try + { + this.in = new DataInputStream(this.conn.getInputStream()); + this.out = this.conn.getOutputStream(); + + this.pduReaderWorker = new PDUReaderWorker(); + this.pduReaderWorker.start(); + BindRequest binrequest = sendOutbind(outbindParam.getSystemId(), outbindParam.getPassword(), timeout); + return binrequest; + } + catch (PDUException e) + { + logger.error("Failed sending bind command", e); + String message = "Failed sending bind since some string parameter area invalid: "; + throw new IOException(message + + ": " + + e.getMessage(), + e); + } + catch (NegativeResponseException e) + { + String message = "Receive negative bind response"; + logger.error(message, e); + close(); + throw new IOException(message + + ": " + + e.getMessage(), + e); + } + catch (InvalidResponseException e) + { + String message = "Receive invalid response of bind"; + logger.error(message, e); + close(); + throw new IOException(message + + ": " + + e.getMessage(), + e); + } + catch (ResponseTimeoutException e) + { + String message = "Waiting bind response take time too long"; + logger.error(message, e); + close(); + throw new IOException(message + + ": " + + e.getMessage(), + e); + } + catch (IOException e) + { + logger.error("IO error occurred", e); + close(); + throw e; + } + } + + /** + * Sending outbind. + * + * + * @param systemId is the system id. + * @param password is the password. + * @param timeout is the max time waiting for bind response. + * @return BindRequest. + * @throws PDUException if we enter invalid bind parameter(s). + * @throws ResponseTimeoutException if there is no valid response after defined millisecond. + * @throws InvalidResponseException if there is invalid response found. + * @throws NegativeResponseException if we receive negative response. + * @throws IOException if there is an IO error occur. + */ + private BindRequest sendOutbind(String systemId, String password, long timeout) + throws PDUException, ResponseTimeoutException, InvalidResponseException, NegativeResponseException, IOException + { + OutbindCommandTask task = new OutbindCommandTask(pduSender(), systemId, password); + + Bind bind = (Bind) executeSendCommand(task, timeout); + + return new BindRequest(bind, this.responseHandler); + } /* (non-Javadoc) * @see org.jsmpp.session.ClientSession#submitShortMessage(java.lang.String, org.jsmpp.bean.TypeOfNumber, org.jsmpp.bean.NumberingPlanIndicator, java.lang.String, org.jsmpp.bean.TypeOfNumber, org.jsmpp.bean.NumberingPlanIndicator, java.lang.String, org.jsmpp.bean.ESMClass, byte, byte, java.lang.String, java.lang.String, org.jsmpp.bean.RegisteredDelivery, byte, org.jsmpp.bean.DataCoding, byte, byte[], org.jsmpp.bean.OptionalParameter[]) @@ -474,7 +678,22 @@ private void fireAcceptAlertNotification(AlertNotification alertNotification) { } private class ResponseHandlerImpl implements ResponseHandler { - + + public void sendBindResp(String systemId, InterfaceVersion interfaceVersion, BindType bindType, int sequenceNumber) + throws IOException + { + SMPPSession.this.sessionContext.bound(bindType); + try + { + pduSender().sendBindResp(SMPPSession.this.out, bindType.responseCommandId(), sequenceNumber, systemId, interfaceVersion); + } + catch (PDUStringException e) + { + logger.error("Failed sending bind response", e); + // TODO uudashr: we have double checking when accept the bind request + } + } + public void processDeliverSm(DeliverSm deliverSm) throws ProcessRequestException { try { fireAcceptDeliverSm(deliverSm); diff --git a/jsmpp/src/main/java/org/jsmpp/session/ServerResponseHandler.java b/jsmpp/src/main/java/org/jsmpp/session/ServerResponseHandler.java index b8c4460..af6b618 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/ServerResponseHandler.java +++ b/jsmpp/src/main/java/org/jsmpp/session/ServerResponseHandler.java @@ -17,10 +17,9 @@ import java.io.IOException; import org.jsmpp.bean.Bind; -import org.jsmpp.bean.BindType; import org.jsmpp.bean.CancelSm; -import org.jsmpp.bean.InterfaceVersion; import org.jsmpp.bean.MessageState; +import org.jsmpp.bean.Outbind; import org.jsmpp.bean.QuerySm; import org.jsmpp.bean.ReplaceSm; import org.jsmpp.bean.SubmitMulti; @@ -34,14 +33,14 @@ * */ public interface ServerResponseHandler extends BaseResponseHandler { - void sendBindResp(String systemId, InterfaceVersion interfaceVersion, BindType bindType, int sequenceNumber) - throws IOException; void sendSubmitSmResponse(MessageId messageId, int sequenceNumber) throws IOException; void processBind(Bind bind); + void processOutbind(Outbind outbind); + MessageId processSubmitSm(SubmitSm submitSm) throws ProcessRequestException; SubmitMultiResult processSubmitMulti(SubmitMulti submitMulti) throws ProcessRequestException; diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionBound.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionBound.java index dd188bc..9270ee7 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionBound.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionBound.java @@ -26,10 +26,26 @@ */ abstract class SMPPServerSessionBound extends AbstractGenericSMPPSessionBound implements SMPPServerSessionState { - + + private static final String INVALID_PROCESS_FOR_BOUND_SESSION = "Invalid process for bound session state"; + + @Override public void processBind(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException { responseHandler.sendNegativeResponse(pduHeader.getCommandId(), SMPPConstant.STAT_ESME_RALYBND, pduHeader.getSequenceNumber()); } + + @Override + public void processBindResp(Command pduHeader, byte[] pdu, + ServerResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_BOUND_SESSION); + } + + @Override + public void processOutbind(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException + { + responseHandler.sendNegativeResponse(pduHeader.getCommandId(), + SMPPConstant.STAT_ESME_RALYBND, pduHeader.getSequenceNumber()); + } } diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionClosed.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionClosed.java index 1acc3b3..7cf638f 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionClosed.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionClosed.java @@ -38,6 +38,16 @@ public void processBind(Command pduHeader, byte[] pdu, throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } + public void processBindResp(Command pduHeader, byte[] pdu, + ServerResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); + } + + public void processOutbind(Command pduHeader, byte[] pdu, + ServerResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); + } + public void processDeliverSmResp(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException { throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionOpen.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionOpen.java index 1455d20..28902b4 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionOpen.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionOpen.java @@ -16,21 +16,29 @@ import java.io.IOException; +import org.jsmpp.InvalidResponseException; import org.jsmpp.PDUStringException; import org.jsmpp.SMPPConstant; import org.jsmpp.bean.Bind; +import org.jsmpp.bean.BindResp; import org.jsmpp.bean.Command; +import org.jsmpp.bean.Outbind; +import org.jsmpp.extra.PendingResponse; import org.jsmpp.extra.SessionState; import org.jsmpp.session.BaseResponseHandler; import org.jsmpp.session.ServerResponseHandler; import org.jsmpp.util.DefaultDecomposer; +import org.jsmpp.util.IntUtil; import org.jsmpp.util.PDUDecomposer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @author uudashr * */ class SMPPServerSessionOpen implements SMPPServerSessionState { + private static final Logger logger = LoggerFactory.getLogger(SMPPServerSessionOpen.class); private static final String INVALID_PROCESS_FOR_OPEN_SESSION = "Invalid process for open session state"; private static final PDUDecomposer pduDecomposer = new DefaultDecomposer(); @@ -52,6 +60,52 @@ public void processBind(Command pduHeader, byte[] pdu, } } + public void processBindResp(Command pduHeader, byte[] pdu, + ServerResponseHandler responseHandler) throws IOException + { + PendingResponse pendingResp = responseHandler.removeSentItem(pduHeader.getSequenceNumber()); + if (pendingResp != null) { + try { + logger.debug("Bind Response header ({}, {}, {}, {})", + pduHeader.getCommandLength(), + pduHeader.getCommandIdAsHex(), + IntUtil.toHexString(pduHeader.getCommandStatus()), + pduHeader.getSequenceNumber()); + BindResp resp = pduDecomposer.bindResp(pdu); + pendingResp.done(resp); + } catch (PDUStringException e) { + String message = "Failed decomposing submit_sm_resp"; + logger.error(message, e); + responseHandler.sendGenerickNack(e.getErrorCode(), pduHeader + .getSequenceNumber()); + pendingResp + .doneWithInvalidResponse(new InvalidResponseException(message, e)); + } + } else { + logger.error("No request with sequence number {} found", pduHeader.getSequenceNumber() ); + responseHandler.sendGenerickNack( + SMPPConstant.STAT_ESME_RINVDFTMSGID, pduHeader.getSequenceNumber()); + } + } + + public void processOutbind(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) + throws IOException + { + try + { + Outbind outbind = pduDecomposer.outbind(pdu); + responseHandler.processOutbind(outbind);; + } + catch (PDUStringException e) + { + responseHandler.sendNegativeResponse(pduHeader.getCommandId(), e.getErrorCode(), pduHeader.getSequenceNumber()); + } + catch (IllegalArgumentException e) + { + responseHandler.sendNegativeResponse(pduHeader.getCommandId(), SMPPConstant.STAT_ESME_RINVCMDID, pduHeader.getSequenceNumber()); + } + } + public void processDeliverSmResp(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException { throw new IOException(INVALID_PROCESS_FOR_OPEN_SESSION); diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionState.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionState.java index 8ad0e37..1481299 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionState.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionState.java @@ -41,7 +41,29 @@ public interface SMPPServerSessionState extends GenericSMPPSessionState { */ void processBind(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException; - + + /** + * Process the bind resp command. + * + * @param pduHeader is the PDU header. + * @param pdu is the complete PDU. + * @param responseHandler is the response handler. + * @throws IOException if there is an IO error occur. + */ + void processBindResp(Command pduHeader, byte[] pdu, + ServerResponseHandler responseHandler) throws IOException; + + /** + * Process the outbind request command. + * + * @param pduHeader is the PDU header. + * @param pdu is the complete PDU. + * @param responseHandler is the response handler. + * @throws IOException if there is an IO error occur. + */ + void processOutbind(Command pduHeader, byte[] pdu, + ServerResponseHandler responseHandler) throws IOException; + /** * Process the submit short message request command. * @@ -75,5 +97,4 @@ void processCancelSm(Command pduHeader, byte[] pdu, void processReplaceSm(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException; - } diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionUnbound.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionUnbound.java index 8992513..f3051f6 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionUnbound.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionUnbound.java @@ -39,6 +39,17 @@ public void processBind(Command pduHeader, byte[] pdu, throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } + public void processBindResp(Command pduHeader, byte[] pdu, + ServerResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); + } + + public void processOutbind(Command pduHeader, byte[] pdu, + ServerResponseHandler responseHandler) + throws IOException { + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); + } + public void processDeliverSmResp(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException { throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionBound.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionBound.java index 64dd380..7498d00 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionBound.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionBound.java @@ -29,7 +29,14 @@ * */ abstract class SMPPSessionBound extends AbstractGenericSMPPSessionBound implements SMPPSessionState { - + + public void processBind(Command pduHeader, byte[] pdu, + ResponseHandler responseHandler) throws IOException + { + responseHandler.sendNegativeResponse(pduHeader.getCommandId(), + SMPPConstant.STAT_ESME_RALYBND, pduHeader.getSequenceNumber()); + } + public void processBindResp(Command pduHeader, byte[] pdu, ResponseHandler responseHandler) throws IOException { responseHandler.sendNegativeResponse(pduHeader.getCommandId(), diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionClosed.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionClosed.java index 5cfc204..899d482 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionClosed.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionClosed.java @@ -40,6 +40,12 @@ class SMPPSessionClosed implements SMPPSessionState { public SessionState getSessionState() { return SessionState.CLOSED; } + + public void processBind(Command pduHeader, byte[] pdu, + ResponseHandler responseHandler) throws IOException + { + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); + } public void processBindResp(Command pduHeader, byte[] pdu, ResponseHandler responseHandler) throws IOException { diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionOpen.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionOpen.java index bab8f2c..61403da 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionOpen.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionOpen.java @@ -19,6 +19,7 @@ import org.jsmpp.InvalidResponseException; import org.jsmpp.PDUStringException; import org.jsmpp.SMPPConstant; +import org.jsmpp.bean.Bind; import org.jsmpp.bean.BindResp; import org.jsmpp.bean.Command; import org.jsmpp.extra.PendingResponse; @@ -47,6 +48,41 @@ class SMPPSessionOpen implements SMPPSessionState { public SessionState getSessionState() { return SessionState.OPEN; } + + public void processBind(Command pduHeader, byte[] pdu, + ResponseHandler responseHandler) throws IOException { + + PendingResponse pendingResp = responseHandler + .removeSentItem(pduHeader.getSequenceNumber()); + + if (null==pendingResp) + { + logger.debug("No pending response found for sequence number {} try to found with previous {}", + pduHeader.getSequenceNumber(), pduHeader.getSequenceNumber() - 1); + pendingResp = responseHandler.removeSentItem(pduHeader.getSequenceNumber() - 1); + } + if (pendingResp != null) { + try { + logger.debug("Bind header ({}, {}, {}, {})", + pduHeader.getCommandLength(), + pduHeader.getCommandIdAsHex(), + IntUtil.toHexString(pduHeader.getCommandStatus()), + pduHeader.getSequenceNumber()); + Bind bind = pduDecomposer.bind(pdu); + pendingResp.done(bind); + } catch (PDUStringException e) { + String message = "Failed decomposing bind_resp"; + logger.error(message, e); + responseHandler.sendNegativeResponse(pduHeader.getCommandId(), e.getErrorCode(), pduHeader.getSequenceNumber()); + pendingResp + .doneWithInvalidResponse(new InvalidResponseException( + message, e)); + } + } else { + logger.error("No request with sequence number {} found", pduHeader.getSequenceNumber() ); + responseHandler.sendNegativeResponse(pduHeader.getCommandId(), SMPPConstant.STAT_ESME_RINVDFTMSGID, pduHeader.getSequenceNumber()); + } + } public void processBindResp(Command pduHeader, byte[] pdu, ResponseHandler responseHandler) throws IOException { diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionState.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionState.java index 09cbd62..c98b7e9 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionState.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionState.java @@ -36,7 +36,17 @@ public interface SMPPSessionState extends GenericSMPPSessionState { public static final SMPPSessionState UNBOUND = new SMPPSessionUnbound(); public static final SMPPSessionState CLOSED = new SMPPSessionClosed(); - + /** + * Process the bind command received after outbind request. + * + * @param pduHeader is the PDU header. + * @param pdu is the complete PDU. + * @param responseHandler is the session handler. + * @throws IOException throw if there is an IO error occur. + */ + void processBind(Command pduHeader, byte[] pdu, + ResponseHandler responseHandler) throws IOException; + /** * Process the bind response command. * diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionUnbound.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionUnbound.java index e1e07bc..48f2956 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionUnbound.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionUnbound.java @@ -40,7 +40,13 @@ class SMPPSessionUnbound implements SMPPSessionState { public SessionState getSessionState() { return SessionState.UNBOUND; } - + + public void processBind(Command pduHeader, byte[] pdu, + ResponseHandler responseHandler) throws IOException + { + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); + } + public void processBindResp(Command pduHeader, byte[] pdu, ResponseHandler responseHandler) throws IOException { throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); diff --git a/jsmpp/src/test/java/org/jsmpp/session/DummyResponseHandler.java b/jsmpp/src/test/java/org/jsmpp/session/DummyResponseHandler.java index c779994..fd6eeb9 100644 --- a/jsmpp/src/test/java/org/jsmpp/session/DummyResponseHandler.java +++ b/jsmpp/src/test/java/org/jsmpp/session/DummyResponseHandler.java @@ -23,6 +23,7 @@ import org.jsmpp.bean.DataSm; import org.jsmpp.bean.InterfaceVersion; import org.jsmpp.bean.MessageState; +import org.jsmpp.bean.Outbind; import org.jsmpp.bean.QuerySm; import org.jsmpp.bean.ReplaceSm; import org.jsmpp.bean.SubmitMulti; @@ -66,6 +67,9 @@ public void sendUnbindResp(int sequenceNumber) throws IOException { public void processBind(Bind bind) { } + public void processOutbind(Outbind outbind) { + } + public QuerySmResult processQuerySm(QuerySm querySm) throws ProcessRequestException { return null; @@ -124,6 +128,7 @@ public void processReplaceSm(ReplaceSm replaceSm) public void sendReplaceSmResp(int sequenceNumber) throws IOException { } + public void closeConnection() { connectionClosed = true; } From 18e7aae630fe088aaa79f3c1f499af189eb57177 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sat, 9 Jul 2016 21:14:30 +0200 Subject: [PATCH 151/212] Prevent class instantiation --- jsmpp/src/main/java/org/jsmpp/util/StringValidator.java | 1 + 1 file changed, 1 insertion(+) diff --git a/jsmpp/src/main/java/org/jsmpp/util/StringValidator.java b/jsmpp/src/main/java/org/jsmpp/util/StringValidator.java index ba12574..4b88d3c 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/StringValidator.java +++ b/jsmpp/src/main/java/org/jsmpp/util/StringValidator.java @@ -29,6 +29,7 @@ public final class StringValidator { private static final String C_OCTET_STRING_VALUE = "C-Octet String value '"; private StringValidator() { + throw new InstantiationError("This class must not be instantiated"); } public static void validateString(String value, StringParameter param) From 8af0e011729d4fdc4abc21ff85bd198308fdf624 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sat, 9 Jul 2016 21:15:24 +0200 Subject: [PATCH 152/212] Fix typo --- jsmpp/src/main/java/org/jsmpp/PDUStringException.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsmpp/src/main/java/org/jsmpp/PDUStringException.java b/jsmpp/src/main/java/org/jsmpp/PDUStringException.java index 597358c..97e7a60 100644 --- a/jsmpp/src/main/java/org/jsmpp/PDUStringException.java +++ b/jsmpp/src/main/java/org/jsmpp/PDUStringException.java @@ -49,7 +49,7 @@ public StringParameter getParameter() { } /** - * Get the error code of the broken constaint. + * Get the error code of the broken constraint. * * @return the command status should be returned. */ From 1ba5b7e4a0b32e45a82479c1ade2a34fa16179fd Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Thu, 21 Jul 2016 21:29:59 +0200 Subject: [PATCH 153/212] Remove unnecessary public. --- .../src/main/java/org/jsmpp/session/SessionStateListener.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/SessionStateListener.java b/jsmpp/src/main/java/org/jsmpp/session/SessionStateListener.java index 2fccbc5..6e344ce 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/SessionStateListener.java +++ b/jsmpp/src/main/java/org/jsmpp/session/SessionStateListener.java @@ -33,6 +33,5 @@ public interface SessionStateListener { * @param oldState is the old state. * @param source is source of changed state. */ - public void onStateChange(SessionState newState, SessionState oldState, - Session source); + void onStateChange(SessionState newState, SessionState oldState, Session source); } From 080554a0ec8e74936a3ba99cdef5ca4fc229d6a8 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sat, 23 Jul 2016 16:21:03 +0200 Subject: [PATCH 154/212] Refactor the outbind functionality, needs some more abstraction. --- .../AsyncSubmitReceiveDeliverSmExample.java | 7 +- .../jsmpp/examples/OpenAndOutbindExample.java | 216 ++++++++ .../OutboundSMPPServerSimulatorTest.java | 152 ++++++ .../java/org/jsmpp/extra/PendingResponse.java | 1 + .../org/jsmpp/session/AbstractSession.java | 44 +- .../jsmpp/session/AbstractSessionContext.java | 2 +- .../jsmpp/session/BaseResponseHandler.java | 6 +- .../java/org/jsmpp/session/BindRequest.java | 14 +- .../jsmpp/session/BindRequestReceiver.java | 9 +- .../java/org/jsmpp/session/ClientSession.java | 55 -- .../session/GenericServerResponseHandler.java | 29 + .../jsmpp/session/OutbindRequestReceiver.java | 14 +- .../jsmpp/session/OutboundClientSession.java | 119 +++++ .../session/OutboundResponseHandler.java | 43 ++ .../OutboundSMPPServerSessionContext.java | 68 +++ .../OutboundSMPPServerSessionListener.java | 183 +++++++ ...OutboundServerMessageReceiverListener.java | 44 ++ .../OutboundServerResponseHandler.java | 61 +++ .../jsmpp/session/OutboundServerSession.java | 41 ++ .../jsmpp/session/OutboundSessionContext.java | 62 +++ .../session/PDUProcessOutboundServerTask.java | 108 ++++ .../jsmpp/session/PDUProcessOutboundTask.java | 96 ++++ .../jsmpp/session/PDUProcessServerTask.java | 4 - .../org/jsmpp/session/PDUProcessTask.java | 2 +- .../session/SMPPOutboundServerSession.java | 473 +++++++++++++++++ .../jsmpp/session/SMPPOutboundSession.java | 502 ++++++++++++++++++ .../session/SMPPOutboundSessionContext.java | 64 +++ .../org/jsmpp/session/SMPPServerSession.java | 11 +- .../java/org/jsmpp/session/SMPPSession.java | 265 +-------- .../jsmpp/session/ServerResponseHandler.java | 5 +- .../java/org/jsmpp/session/ServerSession.java | 4 +- .../state/GenericSMPPSessionState.java | 2 +- .../state/SMPPOutboundServerSessionBound.java | 44 ++ .../SMPPOutboundServerSessionBoundRX.java | 70 +++ .../SMPPOutboundServerSessionBoundTRX.java | 46 ++ .../SMPPOutboundServerSessionBoundTX.java | 58 ++ .../SMPPOutboundServerSessionClosed.java | 100 ++++ .../state/SMPPOutboundServerSessionOpen.java | 171 ++++++ .../SMPPOutboundServerSessionOutbound.java | 181 +++++++ .../state/SMPPOutboundServerSessionState.java | 57 ++ .../SMPPOutboundServerSessionUnbound.java | 106 ++++ .../state/SMPPOutboundSessionBound.java | 39 ++ .../state/SMPPOutboundSessionBoundRX.java | 61 +++ .../state/SMPPOutboundSessionBoundTRX.java | 44 ++ .../state/SMPPOutboundSessionBoundTX.java | 51 ++ .../state/SMPPOutboundSessionClosed.java | 97 ++++ .../state/SMPPOutboundSessionOpen.java | 146 +++++ .../state/SMPPOutboundSessionState.java | 47 ++ .../state/SMPPOutboundSessionUnbound.java | 94 ++++ .../session/state/SMPPServerSessionBound.java | 13 - .../state/SMPPServerSessionClosed.java | 10 - .../session/state/SMPPServerSessionOpen.java | 51 -- .../session/state/SMPPServerSessionState.java | 44 +- .../state/SMPPServerSessionUnbound.java | 11 - .../jsmpp/session/state/SMPPSessionBound.java | 7 - .../session/state/SMPPSessionBoundRX.java | 4 +- .../session/state/SMPPSessionBoundTX.java | 2 +- .../session/state/SMPPSessionClosed.java | 6 - .../jsmpp/session/state/SMPPSessionOpen.java | 36 -- .../jsmpp/session/state/SMPPSessionState.java | 24 +- .../session/state/SMPPSessionUnbound.java | 6 - .../org/jsmpp/util/DefaultDecomposer.java | 7 +- .../util/RandomDecimalMessageIDGenerator.java | 57 ++ .../jsmpp/session/DummyResponseHandler.java | 6 +- 64 files changed, 3861 insertions(+), 541 deletions(-) create mode 100644 jsmpp-examples/src/main/java/org/jsmpp/examples/OpenAndOutbindExample.java create mode 100644 jsmpp-examples/src/main/java/org/jsmpp/examples/OutboundSMPPServerSimulatorTest.java create mode 100644 jsmpp/src/main/java/org/jsmpp/session/GenericServerResponseHandler.java create mode 100644 jsmpp/src/main/java/org/jsmpp/session/OutboundClientSession.java create mode 100644 jsmpp/src/main/java/org/jsmpp/session/OutboundResponseHandler.java create mode 100644 jsmpp/src/main/java/org/jsmpp/session/OutboundSMPPServerSessionContext.java create mode 100644 jsmpp/src/main/java/org/jsmpp/session/OutboundSMPPServerSessionListener.java create mode 100644 jsmpp/src/main/java/org/jsmpp/session/OutboundServerMessageReceiverListener.java create mode 100644 jsmpp/src/main/java/org/jsmpp/session/OutboundServerResponseHandler.java create mode 100644 jsmpp/src/main/java/org/jsmpp/session/OutboundServerSession.java create mode 100644 jsmpp/src/main/java/org/jsmpp/session/OutboundSessionContext.java create mode 100644 jsmpp/src/main/java/org/jsmpp/session/PDUProcessOutboundServerTask.java create mode 100644 jsmpp/src/main/java/org/jsmpp/session/PDUProcessOutboundTask.java create mode 100644 jsmpp/src/main/java/org/jsmpp/session/SMPPOutboundServerSession.java create mode 100644 jsmpp/src/main/java/org/jsmpp/session/SMPPOutboundSession.java create mode 100644 jsmpp/src/main/java/org/jsmpp/session/SMPPOutboundSessionContext.java create mode 100644 jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionBound.java create mode 100644 jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionBoundRX.java create mode 100644 jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionBoundTRX.java create mode 100644 jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionBoundTX.java create mode 100644 jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionClosed.java create mode 100644 jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionOpen.java create mode 100644 jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionOutbound.java create mode 100644 jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionState.java create mode 100644 jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionUnbound.java create mode 100644 jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionBound.java create mode 100644 jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionBoundRX.java create mode 100644 jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionBoundTRX.java create mode 100644 jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionBoundTX.java create mode 100644 jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionClosed.java create mode 100644 jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionOpen.java create mode 100644 jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionState.java create mode 100644 jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionUnbound.java create mode 100644 jsmpp/src/main/java/org/jsmpp/util/RandomDecimalMessageIDGenerator.java diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/AsyncSubmitReceiveDeliverSmExample.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/AsyncSubmitReceiveDeliverSmExample.java index 9d24109..760e6d1 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/AsyncSubmitReceiveDeliverSmExample.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/AsyncSubmitReceiveDeliverSmExample.java @@ -52,7 +52,7 @@ * */ public class AsyncSubmitReceiveDeliverSmExample { - private static TimeFormatter timeFormatter = new AbsoluteTimeFormatter();; + private static TimeFormatter timeFormatter = new AbsoluteTimeFormatter(); public static void main(String[] args) { final AtomicInteger counter = new AtomicInteger(); @@ -140,7 +140,10 @@ public void run() { } while (counter.get() != maxMessage) { - try { Thread.sleep(1000); } catch (InterruptedException e) { } + try { Thread.sleep(1000); } + catch (InterruptedException e) { + System.err.println("Interrupted"); + } } session.unbindAndClose(); execService.shutdown(); diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/OpenAndOutbindExample.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/OpenAndOutbindExample.java new file mode 100644 index 0000000..a1d7ace --- /dev/null +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/OpenAndOutbindExample.java @@ -0,0 +1,216 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.examples; + +import java.io.IOException; +import java.util.Date; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.jsmpp.InvalidResponseException; +import org.jsmpp.PDUException; +import org.jsmpp.PDUStringException; +import org.jsmpp.SMPPConstant; +import org.jsmpp.bean.DataCodings; +import org.jsmpp.bean.DeliveryReceipt; +import org.jsmpp.bean.ESMClass; +import org.jsmpp.bean.GSMSpecificFeature; +import org.jsmpp.bean.InterfaceVersion; +import org.jsmpp.bean.MessageMode; +import org.jsmpp.bean.MessageType; +import org.jsmpp.bean.NumberingPlanIndicator; +import org.jsmpp.bean.PriorityFlag; +import org.jsmpp.bean.RegisteredDelivery; +import org.jsmpp.bean.TypeOfNumber; +import org.jsmpp.extra.NegativeResponseException; +import org.jsmpp.extra.ResponseTimeoutException; +import org.jsmpp.extra.SessionState; +import org.jsmpp.session.BindRequest; +import org.jsmpp.session.SMPPOutboundSession; +import org.jsmpp.session.Session; +import org.jsmpp.session.SessionStateListener; +import org.jsmpp.util.DeliveryReceiptState; +import org.jsmpp.util.MessageIDGenerator; +import org.jsmpp.util.MessageId; +import org.jsmpp.util.RandomDecimalMessageIDGenerator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author pmoerenhout + */ +public class OpenAndOutbindExample implements Runnable { + + private static final Logger LOG = LoggerFactory.getLogger(OpenAndOutbindExample.class); + private static final String DEFAULT_HOST = "localhost"; + private static final Integer DEFAULT_PORT = 8056; + private static final String DEFAULT_SYSID = "jsysid"; + private static final String DEFAULT_PASSWORD = "jpwd"; + private static final String DEFAULT_DESTADDR = "62161616"; + private static final String DEFAULT_SOURCEADDR = "1616"; + + private static final Long DEFAULT_TRANSACTIONTIMER = 2000L; + private static final Integer DEFAULT_PROCESSOR_DEGREE = 3; + + private SMPPOutboundSession session = new SMPPOutboundSession(); + private MessageIDGenerator messageIDGenerator = new RandomDecimalMessageIDGenerator(); + private String host; + private int port; + private int id; + private String systemId; + private String password; + private String sourceAddr; + private String destinationAddr; + + private AtomicBoolean exit = new AtomicBoolean(); + + private OpenAndOutbindExample(int id, String host, int port, + String systemId, String password, String sourceAddr, + String destinationAddr, long transactionTimer, + int pduProcessorDegree) { + this.id = id; + this.host = host; + this.port = port; + this.systemId = systemId; + this.password = password; + this.sourceAddr = sourceAddr; + this.destinationAddr = destinationAddr; + session.setPduProcessorDegree(pduProcessorDegree); + session.setTransactionTimer(transactionTimer); + } + + public static void main(String[] args) { + + String host = System.getProperty("jsmpp.client.host", DEFAULT_HOST); + String systemId = System.getProperty("jsmpp.client.systemId", DEFAULT_SYSID); + String password = System.getProperty("jsmpp.client.password", DEFAULT_PASSWORD); + String sourceAddr = System.getProperty("jsmpp.client.sourceAddr", DEFAULT_SOURCEADDR); + String destinationAddr = System.getProperty("jsmpp.client.destinationAddr", DEFAULT_DESTADDR); + + int port; + try { + port = Integer.parseInt(System.getProperty("jsmpp.client.port", DEFAULT_PORT.toString())); + } + catch (NumberFormatException e) { + port = DEFAULT_PORT; + } + + long transactionTimer; + try { + transactionTimer = Integer + .parseInt(System.getProperty("jsmpp.client.transactionTimer", DEFAULT_TRANSACTIONTIMER.toString())); + } + catch (NumberFormatException e) { + transactionTimer = DEFAULT_TRANSACTIONTIMER; + } + + int processorDegree; + try { + processorDegree = Integer + .parseInt(System.getProperty("jsmpp.server.procDegree", DEFAULT_PROCESSOR_DEGREE.toString())); + } + catch (NumberFormatException e) { + processorDegree = DEFAULT_PROCESSOR_DEGREE; + } + + LOG.info("Processor degree: " + processorDegree); + OpenAndOutbindExample openAndOutbindExample = new OpenAndOutbindExample(0, host, port, systemId, password, + sourceAddr, destinationAddr, transactionTimer, processorDegree); + openAndOutbindExample.run(); + } + + private void shutdown() { + exit.set(true); + } + + public void run() { + try { + session.setEnquireLinkTimer(30000); + session.setTransactionTimer(2000); + session.addSessionStateListener(new SessionStateListenerImpl()); + + LOG.info("Connect and outbind to {} port {}", host, port); + BindRequest bindRequest = session.connectAndOutbind(host, port, systemId, password); + LOG.info("Received bind request system_id:'{}' password:'{}", bindRequest.getSystemId(), bindRequest.getPassword()); + + try { + bindRequest.accept("sys", InterfaceVersion.IF_34); + } + catch (PDUStringException e) { + LOG.error("Invalid system id", e); + bindRequest.reject(SMPPConstant.STAT_ESME_RSYSERR); + } + + } + catch (IOException e) { + LOG.error("Failed initialize connection, outbind, or bind", e); + return; + } + + int deliverSmCount = 0; + while (!exit.get()) { + /* now send some deliver_sm receipts to the ESME */ + deliverSmCount++; + try { + MessageId messageId = messageIDGenerator.newMessageId(); + DeliveryReceipt delRec = new DeliveryReceipt(messageId.getValue(), 1, 1, new Date(), + new Date(), DeliveryReceiptState.DELIVRD, "000", "#" + deliverSmCount); + session.deliverShortMessage("cm", TypeOfNumber.INTERNATIONAL, NumberingPlanIndicator.ISDN, sourceAddr, + TypeOfNumber.INTERNATIONAL, NumberingPlanIndicator.ISDN, destinationAddr, + new ESMClass(MessageMode.DEFAULT, MessageType.SMSC_DEL_RECEIPT, GSMSpecificFeature.DEFAULT), + (byte) 0x00, PriorityFlag.GsmSms.NORMAL.value(), new RegisteredDelivery(0), + DataCodings.ZERO, delRec.toString().getBytes("ISO-8859-1")); + LOG.info("The deliver_sm request #{} was sent", deliverSmCount); + } + catch (IllegalStateException e) { + LOG.error("IllegalStateException error", e); + } + catch (PDUException e) { + LOG.error("PDUException error", e); + } + catch (ResponseTimeoutException e) { + LOG.warn("Response reached timeout", e); + } + catch (InvalidResponseException e) { + LOG.warn("Invalid response received", e); + } + catch (NegativeResponseException e) { + LOG.warn("Negative response received", e); + } + catch (IOException e) { + LOG.warn("IO exception", e); + } + + try { + Thread.sleep(500); + } + catch (InterruptedException e) { + LOG.error("Thread was interrupted", e); + } + + if (!session.getSessionState().isBound()) { + shutdown(); + } + } + LOG.info("Outbind session ended"); + session.unbindAndClose(); + } + + private class SessionStateListenerImpl implements SessionStateListener { + public void onStateChange(SessionState newState, SessionState oldState, Session source) { + LOG.info("Session state changed from " + oldState + " to " + newState); + } + } + +} diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/OutboundSMPPServerSimulatorTest.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/OutboundSMPPServerSimulatorTest.java new file mode 100644 index 0000000..92c1a3d --- /dev/null +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/OutboundSMPPServerSimulatorTest.java @@ -0,0 +1,152 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.examples; + +import java.io.IOException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.log4j.BasicConfigurator; +import org.jsmpp.bean.BindType; +import org.jsmpp.bean.DeliverSm; +import org.jsmpp.bean.NumberingPlanIndicator; +import org.jsmpp.bean.TypeOfNumber; +import org.jsmpp.extra.ProcessRequestException; +import org.jsmpp.extra.SessionState; +import org.jsmpp.session.BindParameter; +import org.jsmpp.session.OutbindRequest; +import org.jsmpp.session.OutboundSMPPServerSessionListener; +import org.jsmpp.session.OutboundServerMessageReceiverListener; +import org.jsmpp.session.SMPPOutboundServerSession; +import org.jsmpp.session.ServerResponseDeliveryAdapter; +import org.jsmpp.session.Session; +import org.jsmpp.session.SessionStateListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author uudashr + */ +public class OutboundSMPPServerSimulatorTest extends ServerResponseDeliveryAdapter + implements Runnable, OutboundServerMessageReceiverListener { + private static final Integer DEFAULT_PORT = 8056; + private static final Logger logger = LoggerFactory.getLogger(OutboundSMPPServerSimulatorTest.class); + private final ExecutorService execService = Executors.newFixedThreadPool(100); + private final ExecutorService execServiceDelReceipt = Executors.newFixedThreadPool(100); + private int port; + + private AtomicBoolean exit = new AtomicBoolean(); + + OutboundSMPPServerSimulatorTest(int port) { + this.port = port; + } + + public static void main(String[] args) { + int port; + try { + port = Integer.parseInt(System.getProperty("jsmpp.simulator.port", DEFAULT_PORT.toString())); + } + catch (NumberFormatException e) { + port = DEFAULT_PORT; + } + BasicConfigurator.configure(); + OutboundSMPPServerSimulatorTest smppServerSim = new OutboundSMPPServerSimulatorTest(port); + logger.info("run {}", smppServerSim); + smppServerSim.run(); + } + + private void shutdown() { + exit.set(true); + } + + public void run() { + try { + logger.info("OutboundSMPPServerSessionListener {}", port); + OutboundSMPPServerSessionListener sessionListener = new OutboundSMPPServerSessionListener(port); + + logger.info("Listening on port {}", port); + while (!exit.get()) { + final SMPPOutboundServerSession outboundServerSession = sessionListener.accept(); + logger.info("Accepting connection from {} for session {}", outboundServerSession.getInetAddress(), + outboundServerSession.getSessionId()); + outboundServerSession.setEnquireLinkTimer(30000); + outboundServerSession.addSessionStateListener(new SessionStateListenerImpl()); + outboundServerSession.setOutboundServerMessageReceiverListener(this); + + execService.execute(new OutboundSMPPServerSimulatorTest.WaitOutbindTask(outboundServerSession)); + + try { + Thread.sleep(60 * 60 * 1000L); + } + catch (InterruptedException e) { + logger.info("Thread was interrupted"); + shutdown(); + } + outboundServerSession.close(); + } + + logger.info("close listener {}", sessionListener); + sessionListener.close(); + execService.shutdown(); + } + catch (IOException e) { + logger.error("IO error occurred", e); + } + } + + public void onAcceptDeliverSm(DeliverSm deliverSm, SMPPOutboundServerSession source) + throws ProcessRequestException { + logger.info("deliver_sm: {} {} => {} {}", deliverSm.getSequenceNumber(), deliverSm.getSourceAddr(), + deliverSm.getDestAddress(), new String(deliverSm.getShortMessage())); + } + + private static class WaitOutbindTask implements Runnable { + private final SMPPOutboundServerSession serverSession; + + WaitOutbindTask(SMPPOutboundServerSession serverSession) { + this.serverSession = serverSession; + } + + public void run() { + try { + logger.info("Waiting for outbind request"); + OutbindRequest outbindRequest = serverSession.waitForOutbind(15000); + logger.info("Received outbind for session {}, systemid {}, password {}", serverSession.getSessionId(), + outbindRequest.getSystemId(), outbindRequest.getPassword()); + + serverSession.bind(new BindParameter(BindType.BIND_TRX, "test", "test", "cp", TypeOfNumber.UNKNOWN, + NumberingPlanIndicator.UNKNOWN, null), 60000); + } + catch (IllegalStateException e) { + logger.error("System error", e); + } + catch (TimeoutException e) { + logger.warn("Wait for outbind has reached timeout", e); + } + catch (IOException e) { + logger.warn("IO exception", e); + } + } + } + + private class SessionStateListenerImpl implements SessionStateListener { + public void onStateChange(SessionState newState, SessionState oldState, Session source) { + logger.info("Session state changed from " + oldState + " to " + newState); + } + } + +} diff --git a/jsmpp/src/main/java/org/jsmpp/extra/PendingResponse.java b/jsmpp/src/main/java/org/jsmpp/extra/PendingResponse.java index 63a1e8e..6e0bb7f 100644 --- a/jsmpp/src/main/java/org/jsmpp/extra/PendingResponse.java +++ b/jsmpp/src/main/java/org/jsmpp/extra/PendingResponse.java @@ -107,6 +107,7 @@ public void waitDone() throws ResponseTimeoutException, condition.await(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { Thread.currentThread().interrupt(); + throw new RuntimeException("Interrupted"); } } diff --git a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java index 477a50f..ee224c8 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java @@ -115,7 +115,8 @@ public SessionState getSessionState() { } protected synchronized boolean isReadPdu() { - return getSessionState().isBound() || getSessionState().equals(SessionState.OPEN); + SessionState sessionState = getSessionState(); + return sessionState.isBound() || sessionState.equals(SessionState.OPEN) || sessionState.equals(SessionState.OUTBOUND); } public void addSessionStateListener(SessionStateListener listener) { @@ -303,6 +304,30 @@ protected Command executeSendCommand(SendCommandTask task, long timeout) } + /** + * Execute send command command task. + * + * @param task is the task. + * @return the command response. + * @throws PDUException if there is invalid PDU parameter found. + * @throws ResponseTimeoutException if the response has reach it timeout. + * @throws InvalidResponseException if invalid response found. + * @throws NegativeResponseException if the negative response found. + * @throws IOException if there is an IO error found. + */ + protected void executeSendCommandWithNoResponse(SendCommandTask task) + throws PDUException, IOException { + + int seqNum = sequence.nextValue(); + try { + task.executeTask(connection().getOutputStream(), seqNum); + } catch (IOException e) { + logger.error("Failed sending " + task.getCommandName() + " command", e); + close(); + throw e; + } + } + private synchronized static final String generateSessionId() { return IntUtil.toHexString(random.nextInt()); } @@ -327,6 +352,21 @@ protected void sendEnquireLink() throws ResponseTimeoutException, InvalidRespons } } + public void sendOutbind(String systemId, String password) throws IOException { + if (sessionContext().getSessionState().equals(SessionState.CLOSED)) { + throw new IOException("Session " + sessionId + " is closed"); + } + + OutbindCommandTask task = new OutbindCommandTask(pduSender, systemId, password); + + try { + executeSendCommandWithNoResponse(task); + } catch (PDUException e) { + // exception should be never caught since we didn't send any string parameter. + logger.warn("PDU String should be always valid", e); + } + } + public void unbind() throws ResponseTimeoutException, InvalidResponseException, IOException { if (sessionContext().getSessionState().equals(SessionState.CLOSED)) { @@ -344,7 +384,6 @@ public void unbind() throws ResponseTimeoutException, // ignore the negative response logger.warn("Receive non-ok command_status ({}) for unbind_resp", e.getCommandStatus()); } - } public void unbindAndClose() { @@ -425,6 +464,7 @@ public void run() { sendingEnquireLink.wait(500); } catch (InterruptedException e) { Thread.currentThread().interrupt(); + throw new RuntimeException("Interrupted"); } } } diff --git a/jsmpp/src/main/java/org/jsmpp/session/AbstractSessionContext.java b/jsmpp/src/main/java/org/jsmpp/session/AbstractSessionContext.java index 2315778..9ca1714 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/AbstractSessionContext.java +++ b/jsmpp/src/main/java/org/jsmpp/session/AbstractSessionContext.java @@ -41,7 +41,7 @@ public AbstractSessionContext(SessionStateListener sessionStateListener) { public synchronized void open() { changeState(SessionState.OPEN); } - + public synchronized void bound(BindType bindType) { if (bindType.equals(BindType.BIND_TX)) { changeState(SessionState.BOUND_TX); diff --git a/jsmpp/src/main/java/org/jsmpp/session/BaseResponseHandler.java b/jsmpp/src/main/java/org/jsmpp/session/BaseResponseHandler.java index c41220c..0477dbb 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/BaseResponseHandler.java +++ b/jsmpp/src/main/java/org/jsmpp/session/BaseResponseHandler.java @@ -16,10 +16,8 @@ import java.io.IOException; -import org.jsmpp.bean.BindType; import org.jsmpp.bean.Command; import org.jsmpp.bean.DataSm; -import org.jsmpp.bean.InterfaceVersion; import org.jsmpp.extra.PendingResponse; import org.jsmpp.extra.ProcessRequestException; @@ -29,8 +27,8 @@ */ public interface BaseResponseHandler { - void sendBindResp(String systemId, InterfaceVersion interfaceVersion, BindType bindType, int sequenceNumber) - throws IOException; +// void sendBindResp(String systemId, InterfaceVersion interfaceVersion, BindType bindType, int sequenceNumber) +// throws IOException; /** * Remove the previously {@link PendingResponse} that set when the request diff --git a/jsmpp/src/main/java/org/jsmpp/session/BindRequest.java b/jsmpp/src/main/java/org/jsmpp/session/BindRequest.java index 164359d..abbeaff 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/BindRequest.java +++ b/jsmpp/src/main/java/org/jsmpp/session/BindRequest.java @@ -25,7 +25,6 @@ import org.jsmpp.bean.InterfaceVersion; import org.jsmpp.bean.NumberingPlanIndicator; import org.jsmpp.bean.TypeOfNumber; -import org.jsmpp.extra.ProcessRequestException; import org.jsmpp.util.StringParameter; import org.jsmpp.util.StringValidator; @@ -49,10 +48,10 @@ public class BindRequest { private final int originalSequenceNumber; private boolean done; - private final BaseResponseHandler responseHandler; + private final GenericServerResponseHandler responseHandler; public BindRequest(int sequenceNumber, BindType bindType, String systemId, String password, String systemType, TypeOfNumber addrTon, NumberingPlanIndicator addrNpi, - String addressRange, InterfaceVersion interfaceVersion, BaseResponseHandler responseHandler) { + String addressRange, InterfaceVersion interfaceVersion, GenericServerResponseHandler responseHandler) { this.originalSequenceNumber = sequenceNumber; this.responseHandler = responseHandler; @@ -66,7 +65,7 @@ public BindRequest(int sequenceNumber, BindType bindType, String systemId, Strin this.interfaceVersion = interfaceVersion; } - public BindRequest(Bind bind, BaseResponseHandler responseHandler) { + public BindRequest(Bind bind, GenericServerResponseHandler responseHandler) { this(bind.getSequenceNumber(), BindType.valueOf(bind.getCommandId()), bind.getSystemId(), bind.getPassword(), bind.getSystemType(), TypeOfNumber.valueOf(bind.getAddrTon()), @@ -110,6 +109,7 @@ public String getAddressRange() { public InterfaceVersion getInterfaceVersion() { return interfaceVersion; } + /** * Accept the bind request. Will not send the optional parameter sc_interface_version in * the bind response message. @@ -118,7 +118,7 @@ public InterfaceVersion getInterfaceVersion() { * @throws PDUStringException if the system id is not valid. * @throws IllegalStateException if the acceptance or rejection has been made. * @throws IOException is the connection already closed. - * @see #reject(ProcessRequestException) + * @see #reject(int errorCode) */ public void accept(String systemId) throws PDUStringException, IllegalStateException, IOException { accept(systemId, null); @@ -133,7 +133,7 @@ public void accept(String systemId) throws PDUStringException, IllegalStateExcep * @throws PDUStringException if the system id is not valid. * @throws IllegalStateException if the acceptance or rejection has been made. * @throws IOException is the connection already closed. - * @see #reject(ProcessRequestException) + * @see #reject(int errorCode) */ public void accept(String systemId, InterfaceVersion interfaceVersion) throws PDUStringException, IllegalStateException, IOException { StringValidator.validateString(systemId, StringParameter.SYSTEM_ID); @@ -161,7 +161,7 @@ public void accept(String systemId, InterfaceVersion interfaceVersion) throws PD * @param errorCode is the reason of rejection. * @throws IllegalStateException if the acceptance or rejection has been made. * @throws IOException if the connection already closed. - * @see {@link #accept()} + * @see {@link #accept(String systemId, InterfaceVersion interfaceVersion)} */ public void reject(int errorCode) throws IllegalStateException, IOException { lock.lock(); diff --git a/jsmpp/src/main/java/org/jsmpp/session/BindRequestReceiver.java b/jsmpp/src/main/java/org/jsmpp/session/BindRequestReceiver.java index f4e9f6a..3bfc456 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/BindRequestReceiver.java +++ b/jsmpp/src/main/java/org/jsmpp/session/BindRequestReceiver.java @@ -29,11 +29,11 @@ class BindRequestReceiver { private final Lock lock = new ReentrantLock(); private final Condition requestCondition = lock.newCondition(); - private final ServerResponseHandler responseHandler; + private final GenericServerResponseHandler responseHandler; private BindRequest request; private boolean alreadyWaitForRequest; - public BindRequestReceiver(ServerResponseHandler responseHandler) { + BindRequestReceiver(GenericServerResponseHandler responseHandler) { this.responseHandler = responseHandler; } @@ -43,7 +43,7 @@ public BindRequestReceiver(ServerResponseHandler responseHandler) { * @param timeout is the timeout. * @return the {@link BindRequest}. * @throws IllegalStateException if this method already called before. - * @throws TimeoutException if the timeout has been reach. + * @throws TimeoutException if the timeout has been reached. */ BindRequest waitForRequest(long timeout) throws IllegalStateException, TimeoutException { lock.lock(); @@ -55,6 +55,7 @@ BindRequest waitForRequest(long timeout) throws IllegalStateException, TimeoutEx requestCondition.await(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { Thread.currentThread().interrupt(); + throw new RuntimeException("Interrupted"); } } @@ -73,7 +74,7 @@ BindRequest waitForRequest(long timeout) throws IllegalStateException, TimeoutEx * Notify that the bind has accepted. * * @param bindParameter is the {@link Bind} command. - * @throws IllegalStateException if this method already called before. + * @throws IllegalStateException if this method is already called before. */ void notifyAcceptBind(Bind bindParameter) throws IllegalStateException { lock.lock(); diff --git a/jsmpp/src/main/java/org/jsmpp/session/ClientSession.java b/jsmpp/src/main/java/org/jsmpp/session/ClientSession.java index 0e4b136..ffcdc9b 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/ClientSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/ClientSession.java @@ -271,61 +271,6 @@ String connectAndBind(String host, int port, BindParameter bindParam, long timeout) throws IOException; - /***************************************************************/ - /** - * Open connection and outbind immediately. The default - * timeout is 1 minutes. - * - * @param host is the SMSC host address. - * @param port is the SMSC listen port. - * @param systemId is the system id. - * @param password is the password. - * @throws IOException if there is an IO error found. - */ - BindRequest connectAndOutbind(String host, int port, - String systemId, String password) throws IOException; - - /** - * Open connection and bind immediately with specified timeout. The default - * timeout is 1 minutes. - * - * @param host is the SMSC host address. - * @param port is the SMSC listen port. - * @param systemId is the system id. - * @param password is the password. - * @param timeout is the timeout. - * @throws IOException if there is an IO error found. - */ - BindRequest connectAndOutbind(String host, int port, - String systemId, String password, long timeout) throws IOException; - - /** - * Open connection and bind immediately. - * - * @param host is the SMSC host address. - * @param port is the SMSC listen port. - * @param outbindParam is the outbind parameters. - * @return the SMSC system id. - * @throws IOException if there is an IO error found. - */ - BindRequest connectAndOutbind(String host, int port, - OutbindParameter outbindParam) - throws IOException; - - /** - * Open connection and bind immediately. - * - * @param host is the SMSC host address. - * @param port is the SMSC listen port. - * @param outbindParam is the outbind parameters. - * @param timeout is the timeout. - * @return the SMSC system id. - * @throws IOException if there is an IO error found. - */ - BindRequest connectAndOutbind(String host, int port, - OutbindParameter outbindParam, long timeout) - throws IOException; - /** * Get the current message receiver listener that is currently registered for this smpp session. * @return The current message receiver listener diff --git a/jsmpp/src/main/java/org/jsmpp/session/GenericServerResponseHandler.java b/jsmpp/src/main/java/org/jsmpp/session/GenericServerResponseHandler.java new file mode 100644 index 0000000..ff630b8 --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/GenericServerResponseHandler.java @@ -0,0 +1,29 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session; + +import java.io.IOException; + +import org.jsmpp.bean.BindType; +import org.jsmpp.bean.InterfaceVersion; + +/** + * @author pmoerenhout + * + */ +interface GenericServerResponseHandler extends BaseResponseHandler { + void sendBindResp(String systemId, InterfaceVersion interfaceVersion, BindType bindType, int sequenceNumber) + throws IOException; +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/OutbindRequestReceiver.java b/jsmpp/src/main/java/org/jsmpp/session/OutbindRequestReceiver.java index 0856c88..add131a 100755 --- a/jsmpp/src/main/java/org/jsmpp/session/OutbindRequestReceiver.java +++ b/jsmpp/src/main/java/org/jsmpp/session/OutbindRequestReceiver.java @@ -23,20 +23,20 @@ /** * @author pmoerenhout */ -public class OutbindRequestReceiver { +class OutbindRequestReceiver { private final Lock lock = new ReentrantLock(); private final Condition requestCondition = this.lock.newCondition(); private OutbindRequest request; private boolean alreadyWaitForRequest; - public OutbindRequestReceiver() { + OutbindRequestReceiver() { } /** - * Wait until the bind request received for specified timeout. + * Wait until the outbind request received for specified timeout. * * @param timeout is the timeout. - * @return the {@link BindRequest}. + * @return the {@link OutbindRequest}. * @throws IllegalStateException if this method already called before. * @throws TimeoutException if the timeout has been reach. */ @@ -51,6 +51,8 @@ else if (this.request == null) { this.requestCondition.await(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException("waitForRequest was interrupted"); } } @@ -58,7 +60,7 @@ else if (this.request == null) { return this.request; } else { - throw new TimeoutException("Waiting for bind request take time too long"); + throw new TimeoutException("Waiting for outbind request take time too long"); } } finally { @@ -68,7 +70,7 @@ else if (this.request == null) { } /** - * Notify that the bind has accepted. + * Notify that the outbind was accepted. * * @param outbind is the {@link Outbind} command. * @throws IllegalStateException if this method already called before. diff --git a/jsmpp/src/main/java/org/jsmpp/session/OutboundClientSession.java b/jsmpp/src/main/java/org/jsmpp/session/OutboundClientSession.java new file mode 100644 index 0000000..5e975e2 --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/OutboundClientSession.java @@ -0,0 +1,119 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session; + +import java.io.IOException; + +import org.jsmpp.InvalidResponseException; +import org.jsmpp.PDUException; +import org.jsmpp.bean.DataCoding; +import org.jsmpp.bean.ESMClass; +import org.jsmpp.bean.NumberingPlanIndicator; +import org.jsmpp.bean.OptionalParameter; +import org.jsmpp.bean.RegisteredDelivery; +import org.jsmpp.bean.TypeOfNumber; +import org.jsmpp.extra.NegativeResponseException; +import org.jsmpp.extra.ResponseTimeoutException; + +/** + * This interface provides all operation that the outbound client session can do. It + * doesn't distinct the operation of specific session type (Transmitter, + * Receiver) it's just like Transceiver. The distinction might should be + * recognized in a different way, such as by user code when they do a binding or + * by throwing exception when invoking illegal operation. + * + * @author uudashr + */ +public interface OutboundClientSession extends Session { + + /** + * Open connection and outbind immediately. The default + * timeout is 1 minutes. + * + * @param host is the ESME host address. + * @param port is the ESME listen port. + * @param systemId is the system id. + * @param password is the password. + * @throws IOException if there is an IO error found. + */ + BindRequest connectAndOutbind(String host, int port, + String systemId, String password) throws IOException; + + /** + * Open connection and outbind immediately with specified timeout. The default + * timeout is 1 minutes. + * + * @param host is the ESME host address. + * @param port is the ESME listen port. + * @param systemId is the system id. + * @param password is the password. + * @param timeout is the timeout. + * @throws IOException if there is an IO error found. + */ + BindRequest connectAndOutbind(String host, int port, + String systemId, String password, long timeout) throws IOException; + + /** + * Open connection and outbind immediately. + * + * @param host is the ESME host address. + * @param port is the ESME listen port. + * @param outbindParam is the outbind parameters. + * @return the SMSC system id. + * @throws IOException if there is an IO error found. + */ + BindRequest connectAndOutbind(String host, int port, + OutbindParameter outbindParam) + throws IOException; + + /** + * Open connection and outbind immediately. + * + * @param host is the ESME host address. + * @param port is the ESME listen port. + * @param outbindParam is the outbind parameters. + * @param timeout is the timeout. + * @return the SMSC system id. + * @throws IOException if there is an IO error found. + */ + BindRequest connectAndOutbind(String host, int port, + OutbindParameter outbindParam, long timeout) + throws IOException; + + /** + * Get the current message receiver listener that is currently registered for this smpp session. + * + * @return The current message receiver listener + */ + MessageReceiverListener getMessageReceiverListener(); + + /** + * Sets a message receiver listener for this smpp session. + * + * @param messageReceiverListener is the new listener + */ + void setMessageReceiverListener( + MessageReceiverListener messageReceiverListener); + + void deliverShortMessage(String serviceType, + TypeOfNumber sourceAddrTon, NumberingPlanIndicator sourceAddrNpi, + String sourceAddr, TypeOfNumber destAddrTon, + NumberingPlanIndicator destAddrNpi, String destinationAddr, + ESMClass esmClass, byte protocoId, byte priorityFlag, + RegisteredDelivery registeredDelivery, DataCoding dataCoding, + byte[] shortMessage, OptionalParameter... optionalParameters) + throws PDUException, ResponseTimeoutException, + InvalidResponseException, NegativeResponseException, IOException; +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/OutboundResponseHandler.java b/jsmpp/src/main/java/org/jsmpp/session/OutboundResponseHandler.java new file mode 100644 index 0000000..4291fa0 --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/OutboundResponseHandler.java @@ -0,0 +1,43 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session; + +import java.io.IOException; + +import org.jsmpp.bean.Bind; + +/** + * ResponseHandler provide interface to handle response of the session + * routines. + * + * @author uudashr + * @version 1.0 + * @since 2.0 + * + */ +public interface OutboundResponseHandler extends GenericServerResponseHandler { + + void processBind(Bind bind); + + /** + * Response by sending DELIVER_SM_RESP to SMSC. + * + * @param sequenceNumber is the sequence number of original DELIVER_SM request. + * @throws IOException if an IO error occur. + */ + void sendDeliverSmResp(int commandStatus, int sequenceNumber, String messageId) throws IOException; + + +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/OutboundSMPPServerSessionContext.java b/jsmpp/src/main/java/org/jsmpp/session/OutboundSMPPServerSessionContext.java new file mode 100644 index 0000000..f8137c8 --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/OutboundSMPPServerSessionContext.java @@ -0,0 +1,68 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session; + +import org.jsmpp.extra.SessionState; +import org.jsmpp.session.state.SMPPOutboundServerSessionState; + +/** + * @author pmoerenhout + * + */ +class OutboundSMPPServerSessionContext extends AbstractSessionContext { + private SMPPOutboundServerSessionState stateProcessor = SMPPOutboundServerSessionState.CLOSED; + private final SMPPOutboundServerSession smppSession; + + public OutboundSMPPServerSessionContext(SMPPOutboundServerSession smppSession) { + this.smppSession = smppSession; + } + + public synchronized SMPPOutboundServerSessionState getStateProcessor() { + return stateProcessor; + } + + public synchronized SessionState getSessionState() { + return stateProcessor.getSessionState(); + } + + public synchronized void outbind() { + changeState(SessionState.OUTBOUND); + } + + @Override + protected void changeState(SessionState newState) { + if (!stateProcessor.getSessionState().equals(newState)) { + final SessionState oldState = stateProcessor.getSessionState(); + + // change the session state processor + if (newState == SessionState.OPEN) { + stateProcessor = SMPPOutboundServerSessionState.OPEN; + } else if (newState == SessionState.OUTBOUND) { + stateProcessor = SMPPOutboundServerSessionState.OUTBOUND; + } else if (newState == SessionState.BOUND_RX) { + stateProcessor = SMPPOutboundServerSessionState.BOUND_RX; + } else if (newState == SessionState.BOUND_TX) { + stateProcessor = SMPPOutboundServerSessionState.BOUND_TX; + } else if (newState == SessionState.BOUND_TRX) { + stateProcessor = SMPPOutboundServerSessionState.BOUND_TRX; + } else if (newState == SessionState.UNBOUND) { + stateProcessor = SMPPOutboundServerSessionState.UNBOUND; + } else if (newState == SessionState.CLOSED) { + stateProcessor = SMPPOutboundServerSessionState.CLOSED; + } + fireStateChanged(newState, oldState, smppSession); + } + } +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/OutboundSMPPServerSessionListener.java b/jsmpp/src/main/java/org/jsmpp/session/OutboundSMPPServerSessionListener.java new file mode 100644 index 0000000..ef7109b --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/OutboundSMPPServerSessionListener.java @@ -0,0 +1,183 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session; + +import java.io.IOException; +import java.net.SocketTimeoutException; + +import org.jsmpp.session.connection.Connection; +import org.jsmpp.session.connection.ServerConnection; +import org.jsmpp.session.connection.ServerConnectionFactory; +import org.jsmpp.session.connection.socket.ServerSocketConnectionFactory; + +/** + * This object responsible to for new SMPP Session request from ESME. It will + * listen on specified port. + * + *
+ * SMPPServerSession session = listener.accept();
+ * BindRequest bindReq = session.waitForBind(5000);
+ * 
+ * if (checkPassword(bindReq)) {
+ *     bindReq.accept("sys");
+ * } else {
+ *     bindReq.reject(SMPPConstant.STAT_ESME_RINVPASWD);
+ * }
+ * 
+ * + *

+ * The listening trough getting the bind request should take less than session + * initiation timer, otherwise if there is network open has been requested, ESME + * will close the connection. Accepting the bind request should take less than + * transaction timer or ESME will issued timeout. + *

+ * + * @author uudashr + * + */ +public class OutboundSMPPServerSessionListener { + private final int port; + private final ServerConnection serverConn; + private int initiationTimer = 5000; + private int pduProcessorDegree = 3; + private SessionStateListener sessionStateListener; + private GenericMessageReceiverListener messageReceiverListener; + private OutboundServerMessageReceiverListener outboundServerMessageReceiverListener; + //private ServerResponseDeliveryListener responseDeliveryListener; + + public OutboundSMPPServerSessionListener(int port) throws IOException { + this(port, new ServerSocketConnectionFactory()); + } + + public OutboundSMPPServerSessionListener(int port, + ServerConnectionFactory serverConnFactory) throws IOException { + this.port = port; + serverConn = serverConnFactory.listen(port); + } + + public OutboundSMPPServerSessionListener(int port, int timeout, + ServerConnectionFactory serverConnFactory) throws IOException { + this.port = port; + serverConn = serverConnFactory.listen(port, timeout); + } + + public OutboundSMPPServerSessionListener(int port, int timeout, int backlog, + ServerConnectionFactory serverConnFactory) throws IOException { + this.port = port; + serverConn = serverConnFactory.listen(port, timeout, backlog); + } + + public int getTimeout(int timeout) throws IOException { + return serverConn.getSoTimeout(); + } + + + /** + * Timeout listening. When timeout reach and connection request didn't + * arrive then {@link SocketTimeoutException} will be thrown but the + * listener still valid. + * + * @param timeout + * @throws IOException + */ + public void setTimeout(int timeout) throws IOException { + serverConn.setSoTimeout(timeout); + } + + public void setPduProcessorDegree(int pduProcessorDegree) { + this.pduProcessorDegree = pduProcessorDegree; + } + + public int getPduProcessorDegree() { + return pduProcessorDegree; + } + + public int getPort() { + return port; + } + + public int getInitiationTimer() { + return initiationTimer; + } + + public void setInitiationTimer(int initiationTimer) { + this.initiationTimer = initiationTimer; + } + + public SessionStateListener getSessionStateListener() { + return sessionStateListener; + } + + public void setSessionStateListener( + SessionStateListener sessionStateListener) { + this.sessionStateListener = sessionStateListener; + } + + public GenericMessageReceiverListener getMessageReceiverListener() { + return messageReceiverListener; + } + + public void setMessageReceiverListener( + GenericMessageReceiverListener messageReceiverListener) { + this.messageReceiverListener = messageReceiverListener; + } + + public OutboundServerMessageReceiverListener getOutboundServerMessageReceiverListener() { + return outboundServerMessageReceiverListener; + } + + public void setOutboundServerMessageReceiverListener( + OutboundServerMessageReceiverListener outboundServerMessageReceiverListener) { + this.outboundServerMessageReceiverListener = outboundServerMessageReceiverListener; + } + +// public void setResponseDeliveryListener( +// ServerResponseDeliveryListener responseDeliveryListener) { +// this.responseDeliveryListener = responseDeliveryListener; +// } + + /** + * Accept session request from client. The session state is still OPEN. To + * communicate with ESME properly binding request should be accepted. + * + *
+     * SMPPServerSession session = listener.accept();
+     * BindRequest bindReq = session.waitForBind(5000);
+     * 
+     * if (checkPassword(bindReq)) {
+     *     bindReq.accept("sys");
+     * } else {
+     *     bindReq.reject(SMPPConstant.STAT_ESME_RINVPASWD);
+     * }
+     * 
+ * + * @return the accepted {@link SMPPServerSession}. + * @throws SocketTimeoutException if timeout reach with no session accepted. + * @throws IOException if there is an IO error occur. + * @see SMPPServerSession + * @see BindRequest + */ + public SMPPOutboundServerSession accept() throws IOException { + Connection conn = serverConn.accept(); + conn.setSoTimeout(initiationTimer); + return new SMPPOutboundServerSession(conn, sessionStateListener, + messageReceiverListener, outboundServerMessageReceiverListener, + pduProcessorDegree); + } + + public void close() throws IOException { + serverConn.close(); + } +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/OutboundServerMessageReceiverListener.java b/jsmpp/src/main/java/org/jsmpp/session/OutboundServerMessageReceiverListener.java new file mode 100644 index 0000000..5ff3f9f --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/OutboundServerMessageReceiverListener.java @@ -0,0 +1,44 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session; + +import org.jsmpp.bean.DeliverSm; +import org.jsmpp.extra.ProcessRequestException; + +/** + * This listener will listen to every incoming short message, recognized by + * deliver_sm command. The logic on this listener should be accomplish in a + * short time, because the deliver_sm_resp will be processed after the logic + * executed. Normal logic will be return the deliver_sm_resp with zero valued + * command_status, or throw {@link ProcessRequestException} that gave non-zero + * valued command_status (in means negative response) depends on the given error + * code specified on the {@link ProcessRequestException}. + * + * @author pmoerenhout + * @version 1.0 + * @since 2.0 + */ +public interface OutboundServerMessageReceiverListener { + + /** + * This event raised when a short message received. + * + * @param deliverSm is the short message. + * @param source is the session. + * @throws ProcessRequestException throw if there should be return Non-OK command_status for the response. + */ + void onAcceptDeliverSm(DeliverSm deliverSm, SMPPOutboundServerSession source) + throws ProcessRequestException; +} \ No newline at end of file diff --git a/jsmpp/src/main/java/org/jsmpp/session/OutboundServerResponseHandler.java b/jsmpp/src/main/java/org/jsmpp/session/OutboundServerResponseHandler.java new file mode 100644 index 0000000..ad894f7 --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/OutboundServerResponseHandler.java @@ -0,0 +1,61 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session; + +import java.io.IOException; + +import org.jsmpp.bean.DeliverSm; +import org.jsmpp.bean.Outbind; +import org.jsmpp.extra.ProcessRequestException; + +/** + * OutboundServerResponseHandler provide interface to handle response of the session + * routines. + * + * @author uudashr + * @version 1.0 + * @since 2.0 + * + */ +public interface OutboundServerResponseHandler extends BaseResponseHandler { + + /** + * Process the outbind + * + * @param outbind + * @throws ProcessRequestException + */ + void processOutbind(Outbind outbind) + throws ProcessRequestException; + + /** + * Process the deliver + * + * @param deliverSm + * @throws ProcessRequestException + */ + void processDeliverSm(DeliverSm deliverSm) + throws ProcessRequestException; + + /** + * Response by sending DELIVER_SM_RESP to SMSC. + * + * @param commandStatus is the command_status. + * @param sequenceNumber is the sequence number of original DELIVER_SM request. + * @param messageId is the message_id. + * @throws IOException if an IO error occur. + */ + void sendDeliverSmResp(int commandStatus, int sequenceNumber, String messageId) throws IOException; +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/OutboundServerSession.java b/jsmpp/src/main/java/org/jsmpp/session/OutboundServerSession.java new file mode 100644 index 0000000..49d690a --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/OutboundServerSession.java @@ -0,0 +1,41 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session; + +/** + * This interface provides all operation that the client session can do. It + * doesn't distinct the operation of specific session type (Transmitter, + * Receiver) it's just like Transceiver. The distinction might should be + * recognized in a different way, such as by user code when they do a binding or + * by throwing exception when invoking illegal operation. + * + * @author uudashr + * + */ +public interface OutboundServerSession extends Session { + + /** + * Get the current message receiver listener that is currently registered for this smpp session. + * @return The current message receiver listener + */ + OutboundServerMessageReceiverListener getOutboundServerMessageReceiverListener(); + + /** + * Sets a message receiver listener for this smpp session. + * @param outboundServerMessageReceiverListener is the new listener + */ + void setOutboundServerMessageReceiverListener( + OutboundServerMessageReceiverListener outboundServerMessageReceiverListener); +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/OutboundSessionContext.java b/jsmpp/src/main/java/org/jsmpp/session/OutboundSessionContext.java new file mode 100644 index 0000000..600214e --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/OutboundSessionContext.java @@ -0,0 +1,62 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session; + +import org.jsmpp.bean.BindType; +import org.jsmpp.extra.SessionState; + +/** + * Context defined session life cycle.
+ * OPEN -> BOUND_TX | BOUND_RX | BOUND_TRX -> UNBOUND -> CLOSE. + * + * @author uudashr + * + */ +public interface OutboundSessionContext extends ActivityNotifier { + /** + * Change state to open. + */ + void open(); + + /** + * Change state to bound state. + * @param bindType + */ + void bound(BindType bindType); + + /** + * Change state to unbound. + */ + void unbound(); + + /** + * Change state to close. + */ + void close(); + + /** + * Get current session state. + * + * @return the current session state. + */ + SessionState getSessionState(); + + /** + * Get the last activity of a session. + * + * @return the last activity timestamp. + */ + long getLastActivityTimestamp(); +} \ No newline at end of file diff --git a/jsmpp/src/main/java/org/jsmpp/session/PDUProcessOutboundServerTask.java b/jsmpp/src/main/java/org/jsmpp/session/PDUProcessOutboundServerTask.java new file mode 100644 index 0000000..f0fd877 --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/PDUProcessOutboundServerTask.java @@ -0,0 +1,108 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session; + +import java.io.IOException; + +import org.jsmpp.SMPPConstant; +import org.jsmpp.bean.Command; +import org.jsmpp.util.HexUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author uudashr + * + */ +class PDUProcessOutboundServerTask implements Runnable { + private static final Logger logger = LoggerFactory.getLogger(PDUProcessOutboundServerTask.class); + + private final Command pduHeader; + private final byte[] pdu; + private final OutboundSMPPServerSessionContext sessionContext; + private final OutboundServerResponseHandler responseHandler; + private final ActivityNotifier activityNotifier; + private final Runnable onIOExceptionTask; + + PDUProcessOutboundServerTask(Command pduHeader, byte[] pdu, + OutboundSMPPServerSessionContext sessionContext, OutboundServerResponseHandler responseHandler, + ActivityNotifier activityNotifier, Runnable onIOExceptionTask) { + this.pduHeader = pduHeader; + this.pdu = pdu; + this.sessionContext = sessionContext; + this.responseHandler = responseHandler; + this.activityNotifier = activityNotifier; + this.onIOExceptionTask = onIOExceptionTask; + } + + @Override + public void run() { + try { + if(logger.isDebugEnabled()) { + logger.debug("Received SMPP message {} {}", pduHeader, + HexUtil.convertBytesToHexString(pdu, 16, pdu.length, " ")); + } + + switch (pduHeader.getCommandId()) { + case SMPPConstant.CID_BIND_RECEIVER_RESP: + case SMPPConstant.CID_BIND_TRANSMITTER_RESP: + case SMPPConstant.CID_BIND_TRANSCEIVER_RESP: + activityNotifier.notifyActivity(); + sessionContext.getStateProcessor().processBindResp(pduHeader, pdu, responseHandler); + break; + case SMPPConstant.CID_GENERIC_NACK: + activityNotifier.notifyActivity(); + sessionContext.getStateProcessor().processGenericNack(pduHeader, pdu, responseHandler); + break; + case SMPPConstant.CID_ENQUIRE_LINK: + activityNotifier.notifyActivity(); + sessionContext.getStateProcessor().processEnquireLink(pduHeader, pdu, responseHandler); + break; + case SMPPConstant.CID_ENQUIRE_LINK_RESP: + activityNotifier.notifyActivity(); + sessionContext.getStateProcessor().processEnquireLinkResp(pduHeader, pdu, responseHandler); + break; + case SMPPConstant.CID_DELIVER_SM: + activityNotifier.notifyActivity(); + sessionContext.getStateProcessor().processDeliverSm(pduHeader, pdu, responseHandler); + break; + case SMPPConstant.CID_DATA_SM: + activityNotifier.notifyActivity(); + sessionContext.getStateProcessor().processDataSm(pduHeader, pdu, responseHandler); + break; + case SMPPConstant.CID_DATA_SM_RESP: + activityNotifier.notifyActivity(); + sessionContext.getStateProcessor().processDataSmResp(pduHeader, pdu, responseHandler); + break; + case SMPPConstant.CID_UNBIND: + activityNotifier.notifyActivity(); + sessionContext.getStateProcessor().processUnbind(pduHeader, pdu, responseHandler); + break; + case SMPPConstant.CID_UNBIND_RESP: + activityNotifier.notifyActivity(); + sessionContext.getStateProcessor().processUnbindResp(pduHeader, pdu, responseHandler); + break; + case SMPPConstant.CID_OUTBIND: + activityNotifier.notifyActivity(); + sessionContext.getStateProcessor().processOutbind(pduHeader, pdu, responseHandler); + break; + default: + sessionContext.getStateProcessor().processUnknownCid(pduHeader, pdu, responseHandler); + } + } catch (IOException e) { + onIOExceptionTask.run(); + } + } +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/PDUProcessOutboundTask.java b/jsmpp/src/main/java/org/jsmpp/session/PDUProcessOutboundTask.java new file mode 100644 index 0000000..54953c8 --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/PDUProcessOutboundTask.java @@ -0,0 +1,96 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session; + +import java.io.IOException; + +import org.jsmpp.SMPPConstant; +import org.jsmpp.bean.Command; +import org.jsmpp.util.HexUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author uudashr + * + */ +class PDUProcessOutboundTask implements Runnable { + private static final Logger logger = LoggerFactory.getLogger(PDUProcessOutboundTask.class); + + private final Command pduHeader; + private final byte[] pdu; + private final SMPPOutboundSessionContext sessionContext; + private final OutboundResponseHandler responseHandler; + private final ActivityNotifier activityNotifier; + private final Runnable onIOExceptionTask; + + PDUProcessOutboundTask(Command pduHeader, byte[] pdu, + SMPPOutboundSessionContext sessionContext, OutboundResponseHandler responseHandler, + ActivityNotifier activityNotifier, Runnable onIOExceptionTask) { + this.pduHeader = pduHeader; + this.pdu = pdu; + this.sessionContext = sessionContext; + this.responseHandler = responseHandler; + this.activityNotifier = activityNotifier; + this.onIOExceptionTask = onIOExceptionTask; + } + + @Override + public void run() { + try { + if(logger.isDebugEnabled()) { + logger.debug("Received SMPP message {} {}", pduHeader, + HexUtil.convertBytesToHexString(pdu, 16, pdu.length, " ")); + } + + switch (pduHeader.getCommandId()) { + case SMPPConstant.CID_BIND_RECEIVER: + case SMPPConstant.CID_BIND_TRANSMITTER: + case SMPPConstant.CID_BIND_TRANSCEIVER: + activityNotifier.notifyActivity(); + sessionContext.getStateProcessor().processBind(pduHeader, pdu, responseHandler); + break; + case SMPPConstant.CID_GENERIC_NACK: + activityNotifier.notifyActivity(); + sessionContext.getStateProcessor().processGenericNack(pduHeader, pdu, responseHandler); + break; + case SMPPConstant.CID_ENQUIRE_LINK: + activityNotifier.notifyActivity(); + sessionContext.getStateProcessor().processEnquireLink(pduHeader, pdu, responseHandler); + break; + case SMPPConstant.CID_ENQUIRE_LINK_RESP: + activityNotifier.notifyActivity(); + sessionContext.getStateProcessor().processEnquireLinkResp(pduHeader, pdu, responseHandler); + break; + case SMPPConstant.CID_DELIVER_SM_RESP: + activityNotifier.notifyActivity(); + sessionContext.getStateProcessor().processDeliverSmResp(pduHeader, pdu, responseHandler); + break; + case SMPPConstant.CID_UNBIND: + activityNotifier.notifyActivity(); + sessionContext.getStateProcessor().processUnbind(pduHeader, pdu, responseHandler); + break; + case SMPPConstant.CID_UNBIND_RESP: + activityNotifier.notifyActivity(); + sessionContext.getStateProcessor().processUnbindResp(pduHeader, pdu, responseHandler); + break; + default: + sessionContext.getStateProcessor().processUnknownCid(pduHeader, pdu, responseHandler); + } + } catch (IOException e) { + onIOExceptionTask.run(); + } + } +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/PDUProcessServerTask.java b/jsmpp/src/main/java/org/jsmpp/session/PDUProcessServerTask.java index a7d7eea..b636c6d 100755 --- a/jsmpp/src/main/java/org/jsmpp/session/PDUProcessServerTask.java +++ b/jsmpp/src/main/java/org/jsmpp/session/PDUProcessServerTask.java @@ -64,10 +64,6 @@ public void run() { activityNotifier.notifyActivity(); stateProcessor.processBind(pduHeader, pdu, responseHandler); break; - case SMPPConstant.CID_OUTBIND: - this.activityNotifier.notifyActivity(); - this.stateProcessor.processOutbind(pduHeader, pdu, responseHandler); - break; case SMPPConstant.CID_GENERIC_NACK: activityNotifier.notifyActivity(); stateProcessor.processGenericNack(pduHeader, pdu, responseHandler); diff --git a/jsmpp/src/main/java/org/jsmpp/session/PDUProcessTask.java b/jsmpp/src/main/java/org/jsmpp/session/PDUProcessTask.java index 3ae9fef..dc1450f 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/PDUProcessTask.java +++ b/jsmpp/src/main/java/org/jsmpp/session/PDUProcessTask.java @@ -35,7 +35,7 @@ public class PDUProcessTask implements Runnable { private final ResponseHandler responseHandler; private final ActivityNotifier activityNotifier; private final Runnable onIOExceptionTask; - + public PDUProcessTask(Command pduHeader, byte[] pdu, SMPPSessionContext sessionContext, ResponseHandler responseHandler, ActivityNotifier activityNotifier, Runnable onIOExceptionTask) { diff --git a/jsmpp/src/main/java/org/jsmpp/session/SMPPOutboundServerSession.java b/jsmpp/src/main/java/org/jsmpp/session/SMPPOutboundServerSession.java new file mode 100644 index 0000000..10ff2c4 --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/SMPPOutboundServerSession.java @@ -0,0 +1,473 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session; + +import java.io.DataInputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.SocketTimeoutException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.jsmpp.DefaultPDUReader; +import org.jsmpp.DefaultPDUSender; +import org.jsmpp.InvalidCommandLengthException; +import org.jsmpp.InvalidResponseException; +import org.jsmpp.PDUException; +import org.jsmpp.PDUReader; +import org.jsmpp.PDUSender; +import org.jsmpp.PDUStringException; +import org.jsmpp.SMPPConstant; +import org.jsmpp.SynchronizedPDUSender; +import org.jsmpp.bean.BindResp; +import org.jsmpp.bean.BindType; +import org.jsmpp.bean.Command; +import org.jsmpp.bean.DataSm; +import org.jsmpp.bean.DeliverSm; +import org.jsmpp.bean.InterfaceVersion; +import org.jsmpp.bean.NumberingPlanIndicator; +import org.jsmpp.bean.OptionalParameter; +import org.jsmpp.bean.OptionalParameter.Sc_interface_version; +import org.jsmpp.bean.Outbind; +import org.jsmpp.bean.TypeOfNumber; +import org.jsmpp.extra.NegativeResponseException; +import org.jsmpp.extra.PendingResponse; +import org.jsmpp.extra.ProcessRequestException; +import org.jsmpp.extra.ResponseTimeoutException; +import org.jsmpp.extra.SessionState; +import org.jsmpp.session.connection.Connection; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * + * @author pmoerenhout + */ +public class SMPPOutboundServerSession extends AbstractSession implements OutboundServerSession { + private static final Logger logger = LoggerFactory.getLogger(SMPPOutboundServerSession.class); + + private final Connection conn; + private final DataInputStream in; + private final OutputStream out; + + private final PDUReader pduReader; + + private OutboundSMPPServerSessionContext sessionContext = new OutboundSMPPServerSessionContext(this); + private final OutboundServerResponseHandler responseHandler = new OutboundServerResponseHandlerImpl(); + + private GenericMessageReceiverListener messageReceiverListener; + private OutboundServerMessageReceiverListener outboundServerMessageReceiverListener; + private OutbindRequestReceiver outbindRequestReceiver = new OutbindRequestReceiver(); + + public SMPPOutboundServerSession(Connection conn, + SessionStateListener sessionStateListener, + GenericMessageReceiverListener messageReceiverListener, + OutboundServerMessageReceiverListener outboundServerMessageReceiverListener, + int pduProcessorDegree) { + this(conn, sessionStateListener, messageReceiverListener, + outboundServerMessageReceiverListener, pduProcessorDegree, + new SynchronizedPDUSender(new DefaultPDUSender()), + new DefaultPDUReader()); + } + + public SMPPOutboundServerSession(Connection conn, + SessionStateListener sessionStateListener, + GenericMessageReceiverListener messageReceiverListener, + OutboundServerMessageReceiverListener outboundServerMessageReceiverListener, + int pduProcessorDegree, PDUSender pduSender, PDUReader pduReader) { + super(pduSender); + this.conn = conn; + this.messageReceiverListener = messageReceiverListener; + this.outboundServerMessageReceiverListener = outboundServerMessageReceiverListener; + this.pduReader = pduReader; + this.in = new DataInputStream(conn.getInputStream()); + this.out = conn.getOutputStream(); + enquireLinkSender = new EnquireLinkSender(); + //addSessionStateListener(new OutboundSMPPServerSession.BoundStateListener()); + addSessionStateListener(sessionStateListener); + setPduProcessorDegree(pduProcessorDegree); + sessionContext.open(); + } + + public InetAddress getInetAddress() { + return connection().getInetAddress(); + } + + /** + * Sending bind. + * + * @param bindType is the bind type. + * @param systemId is the system id. + * @param password is the password. + * @param systemType is the system type. + * @param interfaceVersion is the interface version. + * @param addrTon is the address TON. + * @param addrNpi is the address NPI. + * @param addressRange is the address range. + * @param timeout is the max time waiting for bind response. + * @return SMSC system id. + * @throws PDUException if we enter invalid bind parameter(s). + * @throws ResponseTimeoutException if there is no valid response after defined millisecond. + * @throws InvalidResponseException if there is invalid response found. + * @throws NegativeResponseException if we receive negative response. + * @throws IOException if there is an IO error occur. + */ + private String sendBind(BindType bindType, String systemId, + String password, String systemType, + InterfaceVersion interfaceVersion, TypeOfNumber addrTon, + NumberingPlanIndicator addrNpi, String addressRange, long timeout) + throws PDUException, ResponseTimeoutException, + InvalidResponseException, NegativeResponseException, IOException { + + BindCommandTask task = new BindCommandTask(pduSender(), bindType, + systemId, password, systemType, interfaceVersion, addrTon, + addrNpi, addressRange); + + BindResp resp = (BindResp)executeSendCommand(task, timeout); + OptionalParameter.Sc_interface_version scVersion = resp.getOptionalParameter(Sc_interface_version.class); + if(scVersion != null) { + logger.debug("Other side reports SMPP interface version {}", scVersion); + } + + logger.info("Bind response systemId '{}'", resp.getSystemId()); + return resp.getSystemId(); + } + + /** + * Wait for outbind request. + * + * @param timeout is the timeout. + * @return the {@link OutbindRequest}. + * @throws IllegalStateException if this invocation of this method has been made or invoke when state is not OPEN. + * @throws TimeoutException if the timeout has been reach and {@link SMPPOutboundServerSession} are no more valid because + * the connection will be close automatically. + */ + public OutbindRequest waitForOutbind(long timeout) + throws IllegalStateException, TimeoutException { + SessionState currentSessionState = getSessionState(); + if (currentSessionState.equals(SessionState.OPEN)) { + new SMPPOutboundServerSession.PDUReaderWorker().start(); + try { + return outbindRequestReceiver.waitForRequest(timeout); + } + catch (IllegalStateException e) { + throw new IllegalStateException( + "Invocation of waitForOutbind() has been made", e); + } + catch (TimeoutException e) { + close(); + throw e; + } + } + else { + throw new IllegalStateException( + "waitForOutbind() should be invoked on OPEN state, actual state is " + + currentSessionState); + } + } + + @Override + protected Connection connection() { + return conn; + } + + @Override + protected AbstractSessionContext sessionContext() { + return sessionContext; + } + + @Override + protected GenericMessageReceiverListener messageReceiverListener() { + return messageReceiverListener; + } + + @Override + protected void finalize() throws Throwable { + close(); + super.finalize(); + } + + public OutboundServerMessageReceiverListener getOutboundServerMessageReceiverListener() { + return outboundServerMessageReceiverListener; + } + + /** + * Sets a message receiver listener for this smpp session. + * + * @param outboundServerMessageReceiverListener is the new listener + */ + public void setOutboundServerMessageReceiverListener( + OutboundServerMessageReceiverListener outboundServerMessageReceiverListener) { + this.outboundServerMessageReceiverListener = outboundServerMessageReceiverListener; + } + + private void fireAcceptDeliverSm(DeliverSm deliverSm) throws ProcessRequestException { + if (outboundServerMessageReceiverListener != null) { + outboundServerMessageReceiverListener.onAcceptDeliverSm(deliverSm, this); + } + else { + logger.warn("Receive deliver_sm but OutboundServerMessageReceiverListener is null. Short message = {}", + new String(deliverSm.getShortMessage())); + throw new ProcessRequestException("No message receiver listener registered", SMPPConstant.STAT_ESME_RX_T_APPN); + } + } + + /** + * Bind immediately. + * + * @param bindParam is the bind parameters. + * @param timeout is the timeout. + * @return the SMSC system id. + * @throws IOException if there is an IO error found. + */ + public String bind(BindParameter bindParam, long timeout) + throws IOException { + try { + String smscSystemId = sendBind(bindParam.getBindType(), bindParam.getSystemId(), bindParam.getPassword(), bindParam.getSystemType(), + bindParam.getInterfaceVersion(), bindParam.getAddrTon(), bindParam.getAddrNpi(), bindParam.getAddressRange(), timeout); + sessionContext.bound(bindParam.getBindType()); + + logger.info("Start EnquireLinkSender"); + enquireLinkSender = new EnquireLinkSender(); + enquireLinkSender.start(); + + return smscSystemId; + } catch (PDUException e) { + logger.error("Failed sending bind command", e); + throw new IOException("Failed sending bind since some string parameter area invalid: " + e.getMessage(), e); + } catch (NegativeResponseException e) { + String message = "Receive negative bind response"; + logger.error(message, e); + close(); + throw new IOException(message + ": " + e.getMessage(), e); + } catch (InvalidResponseException e) { + String message = "Receive invalid response of bind"; + logger.error(message, e); + close(); + throw new IOException(message + ": " + e.getMessage(), e); + } catch (ResponseTimeoutException e) { + String message = "Waiting bind response take time too long"; + logger.error(message, e); + close(); + throw new IOException(message + ": " + e.getMessage(), e); + } catch (IOException e) { + logger.error("IO error occurred", e); + close(); + throw e; + } + } + + private class OutboundServerResponseHandlerImpl implements OutboundServerResponseHandler { + + public void sendBindResp(String systemId, InterfaceVersion interfaceVersion, BindType bindType, int sequenceNumber) + throws IOException { + SMPPOutboundServerSession.this.sessionContext.bound(bindType); + sessionContext.bound(bindType); + logger.info("sendBindResp Bound!!!!!"); + try { + logger.info("OutboundServerResponseHandlerImpl sendBindResp"); + pduSender() + .sendBindResp(SMPPOutboundServerSession.this.out, bindType.responseCommandId(), sequenceNumber, systemId, + interfaceVersion); + } + catch (PDUStringException e) { + logger.error("Failed sending bind response", e); + // TODO uudashr: we have double checking when accept the bind request + } + } + + public void processOutbind(Outbind outbind) throws ProcessRequestException { + SMPPOutboundServerSession.this.outbindRequestReceiver.notifyAcceptOutbind(outbind); + sessionContext.outbind(); + } + + public void processDeliverSm(DeliverSm deliverSm) throws ProcessRequestException { + try { + fireAcceptDeliverSm(deliverSm); + } + catch (ProcessRequestException e) { + throw e; + } + catch (Exception e) { + String msg = "Invalid runtime exception thrown when processing deliver_sm"; + logger.error(msg, e); + throw new ProcessRequestException(msg, SMPPConstant.STAT_ESME_RX_T_APPN); + } + } + + /* not used in outbound session */ + public DataSmResult processDataSm(DataSm dataSm) + throws ProcessRequestException { + try { + return fireAcceptDataSm(dataSm); + } + catch (Exception e) { + String msg = "Invalid runtime exception thrown when processing DataSm"; + logger.error(msg, e); + throw new ProcessRequestException(msg, SMPPConstant.STAT_ESME_RSYSERR); + } + } + + /* not used in outbound session */ + public void sendDataSmResp(DataSmResult dataSmResult, int sequenceNumber) + throws IOException { + try { + pduSender().sendDataSmResp(out, sequenceNumber, + dataSmResult.getMessageId(), + dataSmResult.getOptionalParameters()); + } + catch (PDUStringException e) { + /* + * There should be no PDUStringException thrown since creation + * of MessageId should be save. + */ + logger.error("Failed sending data_sm_resp", e); + } + } + + public PendingResponse removeSentItem(int sequenceNumber) { + return removePendingResponse(sequenceNumber); + } + + public void notifyUnbonded() { + sessionContext.unbound(); + } + + @Override + public void sendDeliverSmResp(int commandStatus, int sequenceNumber, String messageId) throws IOException { + pduSender().sendDeliverSmResp(out, commandStatus, sequenceNumber, messageId); + logger.debug("deliver_sm_resp with seq_number {} has been sent", sequenceNumber); + } + + public void sendEnquireLinkResp(int sequenceNumber) throws IOException { + logger.debug("Sending enquire_link_resp"); + pduSender().sendEnquireLinkResp(out, sequenceNumber); + } + + public void sendGenerickNack(int commandStatus, int sequenceNumber) throws IOException { + pduSender().sendGenericNack(out, commandStatus, sequenceNumber); + } + + public void sendNegativeResponse(int originalCommandId, int commandStatus, int sequenceNumber) throws IOException { + pduSender().sendHeader(out, originalCommandId | SMPPConstant.MASK_CID_RESP, commandStatus, sequenceNumber); + } + + public void sendUnbindResp(int sequenceNumber) throws IOException { + pduSender().sendUnbindResp(out, SMPPConstant.STAT_ESME_ROK, sequenceNumber); + } + } + + /** + * Worker to read the PDU. + * + * @author uudashr + */ + private class PDUReaderWorker extends Thread { + // start with serial execution of pdu processing, when the session is bound the pool will be enlarge up to the PduProcessorDegree + private ExecutorService executorService = Executors.newFixedThreadPool(1); + private Runnable onIOExceptionTask = new Runnable() { + @Override + public void run() { + close(); + } + }; + + PDUReaderWorker() { + super("PDUReaderWorker: " + SMPPOutboundServerSession.this); + } + + @Override + public void run() { + logger.info("Starting PDUReaderWorker"); + while (isReadPdu()) { + readPDU(); + } + logger.info("Close PDUReaderWorker"); + close(); + executorService.shutdown(); + try { + executorService.awaitTermination(getTransactionTimer(), TimeUnit.MILLISECONDS); + } + catch (InterruptedException e) { + logger.warn("interrupted while waiting for executor service pool to finish"); + Thread.currentThread().interrupt(); + throw new RuntimeException("Interrupted"); + } + logger.info("PDUReaderWorker stop"); + } + + private void readPDU() { + try { + Command pduHeader = pduReader.readPDUHeader(in); + byte[] pdu = pduReader.readPDU(in, pduHeader); + /* + * When the processing PDU is need user interaction via event, + * the code on event might take non-short time, so we need to + * process it concurrently. + */ + PDUProcessOutboundServerTask task = new PDUProcessOutboundServerTask(pduHeader, pdu, + sessionContext, responseHandler, + sessionContext, onIOExceptionTask); + executorService.execute(task); + + } + catch (InvalidCommandLengthException e) { + logger.warn("Receive invalid command length", e); + try { + pduSender().sendGenericNack(out, SMPPConstant.STAT_ESME_RINVCMDLEN, 0); + } + catch (IOException ee) { + logger.warn("Failed sending generic nack", ee); + } + unbindAndClose(); + } + catch (SocketTimeoutException e) { + notifyNoActivity(); + } + catch (IOException e) { + logger.warn("IOException while reading: {}", e.getMessage()); + close(); + } + catch (RuntimeException e) { + logger.warn("RuntimeException: {}", e.getMessage()); + unbindAndClose(); + } + } + + /** + * Notify for no activity. + */ + private void notifyNoActivity() { + logger.debug("No activity notified, sending enquireLink"); + if (sessionContext().getSessionState().isBound()) { + enquireLinkSender.enquireLink(); + } + } + } + + private class BoundStateListener implements SessionStateListener { + public void onStateChange(SessionState newState, SessionState oldState, Session source) { + logger.info("Session state changed from " + oldState + " to " + newState); + if (newState.isBound()) { + logger.info("Start enquireLinkSender"); + enquireLinkSender.start(); + } + } + } +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/SMPPOutboundSession.java b/jsmpp/src/main/java/org/jsmpp/session/SMPPOutboundSession.java new file mode 100644 index 0000000..a0a1e6c --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/SMPPOutboundSession.java @@ -0,0 +1,502 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session; + +import java.io.DataInputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.SocketTimeoutException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.jsmpp.DefaultPDUReader; +import org.jsmpp.DefaultPDUSender; +import org.jsmpp.InvalidCommandLengthException; +import org.jsmpp.InvalidResponseException; +import org.jsmpp.PDUException; +import org.jsmpp.PDUReader; +import org.jsmpp.PDUSender; +import org.jsmpp.PDUStringException; +import org.jsmpp.SMPPConstant; +import org.jsmpp.SynchronizedPDUSender; +import org.jsmpp.bean.Bind; +import org.jsmpp.bean.BindType; +import org.jsmpp.bean.Command; +import org.jsmpp.bean.DataCoding; +import org.jsmpp.bean.DataSm; +import org.jsmpp.bean.ESMClass; +import org.jsmpp.bean.InterfaceVersion; +import org.jsmpp.bean.NumberingPlanIndicator; +import org.jsmpp.bean.OptionalParameter; +import org.jsmpp.bean.RegisteredDelivery; +import org.jsmpp.bean.TypeOfNumber; +import org.jsmpp.extra.NegativeResponseException; +import org.jsmpp.extra.PendingResponse; +import org.jsmpp.extra.ProcessRequestException; +import org.jsmpp.extra.ResponseTimeoutException; +import org.jsmpp.extra.SessionState; +import org.jsmpp.session.connection.Connection; +import org.jsmpp.session.connection.ConnectionFactory; +import org.jsmpp.session.connection.socket.SocketConnectionFactory; +import org.jsmpp.util.DefaultComposer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * This is an object that used to communicate with an ESME. It hide + * all un-needed SMPP operation that might harm if the user code use it such as : + *
    + *
  • DELIVER_SM_RESP, should be called only as response to DELIVER_SM
  • + *
  • UNBIND_RESP, should be called only as response to UNBIND_RESP
  • + *
  • DATA_SM_RESP, should be called only as response to DATA_SM
  • + *
  • ENQUIRE_LINK_RESP, should be called only as response to ENQUIRE_LINK
  • + *
  • GENERIC_NACK, should be called only as response to GENERIC_NACK
  • + *
+ * + * All SMPP operations (request-response) are blocking, for an example: DELIVER_SM + * will be blocked until DELIVER_SM_RESP received or timeout. This looks like + * synchronous communication, but the {@link SMPPOutboundSession} implementation give + * ability to the asynchronous way by executing the DELIVER_SM operation parallel + * on a different thread. The very simple implementation by using Thread pool, + * {@link ExecutorService} will do. + * + * @author pmoerenhout + */ +public class SMPPOutboundSession extends AbstractSession implements OutboundClientSession { + private static final Logger logger = LoggerFactory.getLogger(SMPPOutboundSession.class); + + /* Utility */ + private final PDUReader pduReader; + + /* Connection */ + private final ConnectionFactory connFactory; + private final OutboundResponseHandler responseHandler = new ResponseHandlerImpl(); + + private Connection conn; + private DataInputStream in; + private OutputStream out; + private PDUReaderWorker pduReaderWorker; + + private MessageReceiverListener messageReceiverListener; + private BoundSessionStateListener sessionStateListener = new BoundSessionStateListener(); + private SMPPOutboundSessionContext sessionContext = new SMPPOutboundSessionContext(this, sessionStateListener); + private BindRequestReceiver bindRequestReceiver = new BindRequestReceiver(responseHandler); + + /** + * Default constructor of {@link SMPPOutboundSession}. The next action might be + * connect and bind to a destination message center. + * + * @see #connectAndOutbind(String, int, String, String) + */ + public SMPPOutboundSession() { + this(new SynchronizedPDUSender(new DefaultPDUSender(new DefaultComposer())), + new DefaultPDUReader(), + SocketConnectionFactory.getInstance()); + } + + public SMPPOutboundSession(PDUSender pduSender, PDUReader pduReader, + ConnectionFactory connFactory) { + super(pduSender); + this.pduReader = pduReader; + this.connFactory = connFactory; + } + + public SMPPOutboundSession(String host, int port, OutbindParameter outbindParam, + PDUSender pduSender, PDUReader pduReader, + ConnectionFactory connFactory) throws IOException { + this(pduSender, pduReader, connFactory); + connectAndOutbind(host, port, outbindParam); + } + + @Override + public BindRequest connectAndOutbind(String host, int port, OutbindParameter outbindParam) + throws IOException { + return connectAndOutbind(host, port, outbindParam, 60000); + } + + /** + * Open connection and outbind immediately. The default timeout is 60 seconds. + * + * @param host is the ESME host address. + * @param port is the ESME listen port. + * @param systemId is the system id. + * @param password is the password. + * @throws IOException if there is an IO error found. + */ + @Override + public BindRequest connectAndOutbind(String host, int port, + String systemId, String password) throws IOException { + return connectAndOutbind(host, port, new OutbindParameter(systemId, password), 60000); + } + + /** + * Open connection and outbind immediately with specified timeout. The default timeout is 60 seconds. + * + * @param host is the ESME host address. + * @param port is the ESME listen port. + * @param systemId is the system id. + * @param password is the password. + * @param timeout is the timeout. + * @throws IOException if there is an IO error found. + */ + @Override + public BindRequest connectAndOutbind(String host, int port, + String systemId, String password, long timeout) throws IOException { + return connectAndOutbind(host, port, new OutbindParameter(systemId, password), timeout); + } + + /** + * Open connection and outbind immediately. + * + * @param host is the ESME host address. + * @param port is the ESME listen port. + * @param outbindParameter is the bind parameters. + * @param timeout is the timeout. + * @return the SMSC system id. + * @throws IOException if there is an IO error found. + */ + public BindRequest connectAndOutbind(String host, int port, OutbindParameter outbindParameter, long timeout) + throws IOException { + logger.debug("Connect and bind to {} port {}", host, port); + if (sequence().currentValue() != 1) { + throw new IOException("Connection is already used"); + } + + conn = connFactory.createConnection(host, port); + logger.info("Connected to {}", conn.getInetAddress()); + + conn.setSoTimeout(getEnquireLinkTimer()); + + sessionContext.open(); + try { + in = new DataInputStream(conn.getInputStream()); + out = conn.getOutputStream(); + + pduReaderWorker = new PDUReaderWorker(); + pduReaderWorker.start(); + sendOutbind(outbindParameter.getSystemId(), outbindParameter.getPassword()); + } + catch (IOException e) { + logger.error("IO error occurred", e); + close(); + throw e; + } + + try { + BindRequest bindRequest = waitForBind(timeout); + + logger.info("Start enquireLinkSender"); + enquireLinkSender = new EnquireLinkSender(); + enquireLinkSender.start(); + + return bindRequest; + } + catch (IllegalStateException e) { + String message = "System error"; + logger.error(message, e); + close(); + throw new IOException(message + ": " + e.getMessage(), e); + } + catch (TimeoutException e) { + String message = "Waiting bind response take time too long"; + logger.error(message, e); + throw new IOException(message + ": " + e.getMessage(), e); + } + } + + /** + * Wait for bind request. + * + * @param timeout is the timeout. + * @return the {@link BindRequest}. + * @throws IllegalStateException if this invocation of this method has been made or invoke when state is not OPEN. + * @throws TimeoutException if the timeout has been reach and {@link SMPPServerSession} are no more valid because + * the connection will be close automatically. + */ + private BindRequest waitForBind(long timeout) + throws IllegalStateException, TimeoutException { + SessionState currentSessionState = getSessionState(); + if (currentSessionState.equals(SessionState.OPEN)) { + try { + return bindRequestReceiver.waitForRequest(timeout); + } + catch (IllegalStateException e) { + throw new IllegalStateException( + "Invocation of waitForBind() has been made", e); + } + catch (TimeoutException e) { + close(); + throw e; + } + } + else { + throw new IllegalStateException( + "waitForBind() should be invoked on OPEN state, actual state is " + + currentSessionState); + } + } + + public void deliverShortMessage(String serviceType, + TypeOfNumber sourceAddrTon, NumberingPlanIndicator sourceAddrNpi, + String sourceAddr, TypeOfNumber destAddrTon, + NumberingPlanIndicator destAddrNpi, String destinationAddr, + ESMClass esmClass, byte protocoId, byte priorityFlag, + RegisteredDelivery registeredDelivery, DataCoding dataCoding, + byte[] shortMessage, OptionalParameter... optionalParameters) + throws PDUException, ResponseTimeoutException, + InvalidResponseException, NegativeResponseException, IOException { + + ensureReceivable("deliverShortMessage"); + + DeliverSmCommandTask task = new DeliverSmCommandTask(pduSender(), + serviceType, sourceAddrTon, sourceAddrNpi, sourceAddr, + destAddrTon, destAddrNpi, destinationAddr, esmClass, protocoId, + protocoId, registeredDelivery, dataCoding, shortMessage, + optionalParameters); + + executeSendCommand(task, getTransactionTimer()); + } + + public MessageReceiverListener getMessageReceiverListener() { + return messageReceiverListener; + } + + public void setMessageReceiverListener( + MessageReceiverListener messageReceiverListener) { + this.messageReceiverListener = messageReceiverListener; + } + + @Override + protected Connection connection() { + return conn; + } + + @Override + protected AbstractSessionContext sessionContext() { + return sessionContext; + } + + @Override + protected GenericMessageReceiverListener messageReceiverListener() { + return messageReceiverListener; + } + + @Override + protected void finalize() throws Throwable { + close(); + super.finalize(); + } + + private class ResponseHandlerImpl implements OutboundResponseHandler { + + public void sendBindResp(String systemId, InterfaceVersion interfaceVersion, BindType bindType, int sequenceNumber) + throws IOException { + SMPPOutboundSession.this.sessionContext.bound(bindType); + try { + pduSender().sendBindResp(SMPPOutboundSession.this.out, bindType.responseCommandId(), sequenceNumber, systemId, + interfaceVersion); + } + catch (PDUStringException e) { + logger.error("Failed sending bind response", e); + // TODO uudashr: we have double checking when accept the bind request + } + } + + public DataSmResult processDataSm(DataSm dataSm) + throws ProcessRequestException { + try { + return fireAcceptDataSm(dataSm); + } + catch (ProcessRequestException e) { + throw e; + } + catch (Exception e) { + String msg = "Invalid runtime exception thrown when processing data_sm"; + logger.error(msg, e); + throw new ProcessRequestException(msg, SMPPConstant.STAT_ESME_RX_T_APPN); + } + } + + public void sendDataSmResp(DataSmResult dataSmResult, int sequenceNumber) + throws IOException { + try { + pduSender().sendDataSmResp(out, sequenceNumber, + dataSmResult.getMessageId(), + dataSmResult.getOptionalParameters()); + } + catch (PDUStringException e) { + /* + * There should be no PDUStringException thrown since creation + * of MessageId should be save. + */ + logger.error("SYSTEM ERROR. Failed sending dataSmResp", e); + } + } + + public PendingResponse removeSentItem(int sequenceNumber) { + return removePendingResponse(sequenceNumber); + } + + public void notifyUnbonded() { + sessionContext.unbound(); + } + + @Override + public void sendDeliverSmResp(int commandStatus, int sequenceNumber, String messageId) throws IOException { + pduSender().sendDeliverSmResp(out, commandStatus, sequenceNumber, messageId); + logger.debug("deliver_sm_resp with seq_number {} has been sent", sequenceNumber); + } + + public void sendEnquireLinkResp(int sequenceNumber) throws IOException { + logger.debug("Sending enquire_link_resp"); + pduSender().sendEnquireLinkResp(out, sequenceNumber); + } + + public void sendGenerickNack(int commandStatus, int sequenceNumber) throws IOException { + pduSender().sendGenericNack(out, commandStatus, sequenceNumber); + } + + public void sendNegativeResponse(int originalCommandId, int commandStatus, int sequenceNumber) throws IOException { + pduSender().sendHeader(out, originalCommandId | SMPPConstant.MASK_CID_RESP, commandStatus, sequenceNumber); + } + + public void sendUnbindResp(int sequenceNumber) throws IOException { + pduSender().sendUnbindResp(out, SMPPConstant.STAT_ESME_ROK, sequenceNumber); + } + + public void processBind(Bind bind) { + SMPPOutboundSession.this.bindRequestReceiver.notifyAcceptBind(bind); + } + } + + /** + * Worker to read the PDU. + * + * @author uudashr + */ + private class PDUReaderWorker extends Thread { + // start with serial execution of pdu processing, when the session is bound the pool will be enlarge up to the PduProcessorDegree + private ExecutorService executorService = Executors.newFixedThreadPool(1); + private Runnable onIOExceptionTask = new Runnable() { + @Override + public void run() { + close(); + } + }; + + private PDUReaderWorker() { + super("PDUReaderWorker: " + SMPPOutboundSession.this); + } + + @Override + public void run() { + logger.info("Starting PDUReaderWorker"); + while (isReadPdu()) { + readPDU(); + } + close(); + executorService.shutdown(); + try { + executorService.awaitTermination(getTransactionTimer(), TimeUnit.MILLISECONDS); + } + catch (InterruptedException e) { + logger.warn("interrupted while waiting for executor service pool to finish"); + Thread.currentThread().interrupt(); + throw new RuntimeException("Interrupted"); + } + logger.info("PDUReaderWorker stop"); + } + + private void readPDU() { + try { + Command pduHeader = pduReader.readPDUHeader(in); + byte[] pdu = pduReader.readPDU(in, pduHeader); + /* + * When the processing PDU is need user interaction via event, + * the code on event might take non-short time, so we need to + * process it concurrently. + */ + PDUProcessOutboundTask task = new PDUProcessOutboundTask(pduHeader, pdu, + sessionContext, responseHandler, + sessionContext, onIOExceptionTask); + executorService.execute(task); + + } + catch (InvalidCommandLengthException e) { + logger.warn("Receive invalid command length", e); + try { + pduSender().sendGenericNack(out, SMPPConstant.STAT_ESME_RINVCMDLEN, 0); + } + catch (IOException ee) { + logger.warn("Failed sending generic nack", ee); + } + unbindAndClose(); + } + catch (SocketTimeoutException e) { + notifyNoActivity(); + } + catch (IOException e) { + logger.warn("IOException while reading: {}", e.getMessage()); + close(); + } + catch (RuntimeException e) { + logger.warn("RuntimeException: {}", e.getMessage()); + unbindAndClose(); + } + } + + /** + * Notify for no activity. + */ + private void notifyNoActivity() { + logger.debug("No activity notified, sending enquireLink"); + if (sessionContext().getSessionState().isBound()) { + enquireLinkSender.enquireLink(); + } + } + } + + /** + * Session state listener for internal class use. + * + * @author uudashr + */ + private class BoundSessionStateListener implements SessionStateListener { + public void onStateChange(SessionState newState, SessionState oldState, + Session source) { + /** + * We need to set SO_TIMEOUT to sessionTimer so when timeout occur, + * a SocketTimeoutException will be raised. When Exception raised we + * can send an enquireLinkCommand. + */ + if (newState.isBound()) { + try { + conn.setSoTimeout(getEnquireLinkTimer()); + } + catch (IOException e) { + logger.error("Failed setting so_timeout for session timer", e); + } + + logger.info("Changing processor degree to {}", getPduProcessorDegree()); + ((ThreadPoolExecutor) pduReaderWorker.executorService).setCorePoolSize(getPduProcessorDegree()); + ((ThreadPoolExecutor) pduReaderWorker.executorService).setMaximumPoolSize(getPduProcessorDegree()); + } + } + } +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/SMPPOutboundSessionContext.java b/jsmpp/src/main/java/org/jsmpp/session/SMPPOutboundSessionContext.java new file mode 100644 index 0000000..c80f6d4 --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/SMPPOutboundSessionContext.java @@ -0,0 +1,64 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session; + +import org.jsmpp.extra.SessionState; +import org.jsmpp.session.state.SMPPOutboundSessionState; + +/** + * @author uudashr + * + */ +public class SMPPOutboundSessionContext extends AbstractSessionContext { + private final SMPPOutboundSession smppSession; + private SMPPOutboundSessionState stateProcessor = SMPPOutboundSessionState.CLOSED; + + public SMPPOutboundSessionContext(SMPPOutboundSession smppSession, + SessionStateListener sessionStateListener) { + super(sessionStateListener); + this.smppSession = smppSession; + } + + public synchronized SMPPOutboundSessionState getStateProcessor() { + return stateProcessor; + } + + public synchronized SessionState getSessionState() { + return stateProcessor.getSessionState(); + } + + @Override + protected void changeState(SessionState newState) { + if (!stateProcessor.getSessionState().equals(newState)) { + final SessionState oldState = stateProcessor.getSessionState(); + + // change the session state processor + if (newState == SessionState.OPEN) { + stateProcessor = SMPPOutboundSessionState.OPEN; + } else if (newState == SessionState.BOUND_RX) { + stateProcessor = SMPPOutboundSessionState.BOUND_RX; + } else if (newState == SessionState.BOUND_TX) { + stateProcessor = SMPPOutboundSessionState.BOUND_TX; + } else if (newState == SessionState.BOUND_TRX) { + stateProcessor = SMPPOutboundSessionState.BOUND_TRX; + } else if (newState == SessionState.UNBOUND) { + stateProcessor = SMPPOutboundSessionState.UNBOUND; + } else if (newState == SessionState.CLOSED) { + stateProcessor = SMPPOutboundSessionState.CLOSED; + } + fireStateChanged(newState, oldState, smppSession); + } + } +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/SMPPServerSession.java b/jsmpp/src/main/java/org/jsmpp/session/SMPPServerSession.java index 419f79a..1972bd9 100755 --- a/jsmpp/src/main/java/org/jsmpp/session/SMPPServerSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/SMPPServerSession.java @@ -44,7 +44,6 @@ import org.jsmpp.bean.MessageState; import org.jsmpp.bean.NumberingPlanIndicator; import org.jsmpp.bean.OptionalParameter; -import org.jsmpp.bean.Outbind; import org.jsmpp.bean.QuerySm; import org.jsmpp.bean.RegisteredDelivery; import org.jsmpp.bean.ReplaceSm; @@ -84,8 +83,7 @@ public class SMPPServerSession extends AbstractSession implements ServerSession private ServerMessageReceiverListener messageReceiverListener; private ServerResponseDeliveryListener responseDeliveryListener; private BindRequestReceiver bindRequestReceiver = new BindRequestReceiver(responseHandler); - private OutbindRequestReceiver outbindRequestReceiver = new OutbindRequestReceiver(); - + public SMPPServerSession(Connection conn, SessionStateListener sessionStateListener, ServerMessageReceiverListener messageReceiverListener, @@ -337,11 +335,6 @@ public void processBind(Bind bind) { SMPPServerSession.this.bindRequestReceiver.notifyAcceptBind(bind); } - public void processOutbind(Outbind outbind) - { - SMPPServerSession.this.outbindRequestReceiver.notifyAcceptOutbind(outbind); - } - public MessageId processSubmitSm(SubmitSm submitSm) throws ProcessRequestException { try { @@ -510,7 +503,7 @@ private class PDUReaderWorker extends Thread { @Override public void run() { close(); - }; + } }; @Override diff --git a/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java b/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java index a26b456..b27ce6d 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java @@ -35,7 +35,6 @@ import org.jsmpp.SynchronizedPDUSender; import org.jsmpp.bean.Address; import org.jsmpp.bean.AlertNotification; -import org.jsmpp.bean.Bind; import org.jsmpp.bean.BindResp; import org.jsmpp.bean.BindType; import org.jsmpp.bean.Command; @@ -78,9 +77,9 @@ *
  • GENERIC_NACK, should be called only as response to GENERIC_NACK
  • * * - * All SMPP operation (request-response) is blocking, for an example: SUBMIT_SM + * All SMPP operations (request-response) are blocking, for an example: SUBMIT_SM * will be blocked until SUBMIT_SM_RESP received or timeout. This looks like - * synchronous communication, but the {@link SMPPClient} implementation give + * synchronous communication, but the {@link SMPPSession} implementation give * ability to the asynchronous way by executing the SUBMIT_SM operation parallel * on a different thread. The very simple implementation by using Thread pool, * {@link ExecutorService} will do. @@ -96,9 +95,9 @@ public class SMPPSession extends AbstractSession implements ClientSession { private static final Logger logger = LoggerFactory.getLogger(SMPPSession.class); /* Utility */ - private final PDUReader pduReader; + private final PDUReader pduReader; - /* Connection */ + /* Connection */ private final ConnectionFactory connFactory; private Connection conn; private DataInputStream in; @@ -107,8 +106,8 @@ public class SMPPSession extends AbstractSession implements ClientSession { private PDUReaderWorker pduReaderWorker; private final ResponseHandler responseHandler = new ResponseHandlerImpl(); private MessageReceiverListener messageReceiverListener; - private BoundSessionStateListener sessionStateListener = new BoundSessionStateListener(); - private SMPPSessionContext sessionContext = new SMPPSessionContext(this, sessionStateListener); + private BoundSessionStateListener sessionStateListener = new BoundSessionStateListener(); + private SMPPSessionContext sessionContext = new SMPPSessionContext(this, sessionStateListener); /** * Default constructor of {@link SMPPSession}. The next action might be @@ -221,7 +220,7 @@ public String connectAndBind(String host, int port, } conn = connFactory.createConnection(host, port); - logger.info("Connected"); + logger.info("Connected to {}", conn.getInetAddress()); conn.setSoTimeout(getEnquireLinkTimer()); @@ -302,210 +301,6 @@ private String sendBind(BindType bindType, String systemId, return resp.getSystemId(); } - - /***************************************************************/ - /** - * Open connection and outbind immediately. The default - * timeout is 1 minutes. - * - * @param host is the SMSC host address. - * @param port is the SMSC listen port. - * @param systemId is the system id. - * @param password is the password. - * @throws IOException if there is an IO error found. - */ - @Override - public BindRequest connectAndOutbind(String host, int port, - String systemId, String password) throws IOException - { - logger.debug("Connect and bind to {} port {}", host, port); - if (sequence().currentValue() > 1) - { - throw new IOException("Failed connecting"); - } - - this.conn = this.connFactory.createConnection(host, port); - logger.info("Connected"); - - this.conn.setSoTimeout(getEnquireLinkTimer()); - - this.sessionContext.open(); - return outbind(new OutbindParameter(systemId,password), 60000); - } - - /** - * Open connection and bind immediately with specified timeout. The default - * timeout is 1 minutes. - * - * @param host is the SMSC host address. - * @param port is the SMSC listen port. - * @param systemId is the system id. - * @param password is the password. - * @param timeout is the timeout. - * @throws IOException if there is an IO error found. - */ - @Override - public BindRequest connectAndOutbind(String host, int port, - String systemId, String password, long timeout) throws IOException - { - logger.debug("Connect and bind to {} port {}", host, port); - if (sequence().currentValue() > 1) - { - throw new IOException("Failed connecting"); - } - - this.conn = this.connFactory.createConnection(host, port); - logger.info("Connected"); - - this.conn.setSoTimeout(getEnquireLinkTimer()); - - this.sessionContext.open(); - return outbind(new OutbindParameter(systemId, - password), timeout); - } - - /** - * Open connection and bind immediately. - * - * @param host is the SMSC host addressm port - * @param port is the SMSC listen port. - * @param outbindParam is the outbind parameters. - * @return the SMSC system id. - * @throws IOException if there is an IO error found. - */ - @Override - public BindRequest connectAndOutbind(String host, int port, - OutbindParameter outbindParam) - throws IOException - { - logger.debug("Connect and bind to {} port {}", host, port); - if (sequence().currentValue() > 1) - { - throw new IOException("Failed connecting"); - } - - this.conn = this.connFactory.createConnection(host, port); - logger.info("Connected"); - - this.conn.setSoTimeout(getEnquireLinkTimer()); - - this.sessionContext.open(); - return outbind(outbindParam, 60000); - } - - /** - * Open connection and bind immediately. - * - * @param host SC host address. - * @param port is the SMSC listen port. - * @param outbindParam is the outbind parameters. - * @param timeout is the timeout. - * @return the SMSC system id. - * @throws IOException if there is an IO error found. - */ - @Override - public BindRequest connectAndOutbind(String host, int port, - OutbindParameter outbindParam, long timeout) - throws IOException - { - logger.debug("Connect and bind to {} port {}", host, port); - if (sequence().currentValue() > 1) - { - throw new IOException("Failed connecting"); - } - - this.conn = this.connFactory.createConnection(host, port); - logger.info("Connected"); - - this.conn.setSoTimeout(getEnquireLinkTimer()); - - this.sessionContext.open(); - return outbind(outbindParam, timeout); - } - - private BindRequest outbind(OutbindParameter outbindParam, long timeout) throws IOException - { - try - { - this.in = new DataInputStream(this.conn.getInputStream()); - this.out = this.conn.getOutputStream(); - - this.pduReaderWorker = new PDUReaderWorker(); - this.pduReaderWorker.start(); - BindRequest binrequest = sendOutbind(outbindParam.getSystemId(), outbindParam.getPassword(), timeout); - return binrequest; - } - catch (PDUException e) - { - logger.error("Failed sending bind command", e); - String message = "Failed sending bind since some string parameter area invalid: "; - throw new IOException(message - + ": " - + e.getMessage(), - e); - } - catch (NegativeResponseException e) - { - String message = "Receive negative bind response"; - logger.error(message, e); - close(); - throw new IOException(message - + ": " - + e.getMessage(), - e); - } - catch (InvalidResponseException e) - { - String message = "Receive invalid response of bind"; - logger.error(message, e); - close(); - throw new IOException(message - + ": " - + e.getMessage(), - e); - } - catch (ResponseTimeoutException e) - { - String message = "Waiting bind response take time too long"; - logger.error(message, e); - close(); - throw new IOException(message - + ": " - + e.getMessage(), - e); - } - catch (IOException e) - { - logger.error("IO error occurred", e); - close(); - throw e; - } - } - - /** - * Sending outbind. - * - * - * @param systemId is the system id. - * @param password is the password. - * @param timeout is the max time waiting for bind response. - * @return BindRequest. - * @throws PDUException if we enter invalid bind parameter(s). - * @throws ResponseTimeoutException if there is no valid response after defined millisecond. - * @throws InvalidResponseException if there is invalid response found. - * @throws NegativeResponseException if we receive negative response. - * @throws IOException if there is an IO error occur. - */ - private BindRequest sendOutbind(String systemId, String password, long timeout) - throws PDUException, ResponseTimeoutException, InvalidResponseException, NegativeResponseException, IOException - { - OutbindCommandTask task = new OutbindCommandTask(pduSender(), systemId, password); - - Bind bind = (Bind) executeSendCommand(task, timeout); - - return new BindRequest(bind, this.responseHandler); - } - /* (non-Javadoc) * @see org.jsmpp.session.ClientSession#submitShortMessage(java.lang.String, org.jsmpp.bean.TypeOfNumber, org.jsmpp.bean.NumberingPlanIndicator, java.lang.String, org.jsmpp.bean.TypeOfNumber, org.jsmpp.bean.NumberingPlanIndicator, java.lang.String, org.jsmpp.bean.ESMClass, byte, byte, java.lang.String, java.lang.String, org.jsmpp.bean.RegisteredDelivery, byte, org.jsmpp.bean.DataCoding, byte, byte[], org.jsmpp.bean.OptionalParameter[]) */ @@ -658,6 +453,7 @@ protected GenericMessageReceiverListener messageReceiverListener() { @Override protected void finalize() throws Throwable { close(); + super.finalize(); } private void fireAcceptDeliverSm(DeliverSm deliverSm) throws ProcessRequestException { @@ -679,21 +475,6 @@ private void fireAcceptAlertNotification(AlertNotification alertNotification) { private class ResponseHandlerImpl implements ResponseHandler { - public void sendBindResp(String systemId, InterfaceVersion interfaceVersion, BindType bindType, int sequenceNumber) - throws IOException - { - SMPPSession.this.sessionContext.bound(bindType); - try - { - pduSender().sendBindResp(SMPPSession.this.out, bindType.responseCommandId(), sequenceNumber, systemId, interfaceVersion); - } - catch (PDUStringException e) - { - logger.error("Failed sending bind response", e); - // TODO uudashr: we have double checking when accept the bind request - } - } - public void processDeliverSm(DeliverSm deliverSm) throws ProcessRequestException { try { fireAcceptDeliverSm(deliverSm); @@ -730,16 +511,16 @@ public void processAlertNotification(AlertNotification alertNotification) { public void sendDataSmResp(DataSmResult dataSmResult, int sequenceNumber) throws IOException { try { - pduSender().sendDataSmResp(out, sequenceNumber, - dataSmResult.getMessageId(), - dataSmResult.getOptionalParameters()); - } catch (PDUStringException e) { - /* - * There should be no PDUStringException thrown since creation - * of MessageId should be save. - */ - logger.error("SYSTEM ERROR. Failed sending dataSmResp", e); - } + pduSender().sendDataSmResp(out, sequenceNumber, + dataSmResult.getMessageId(), + dataSmResult.getOptionalParameters()); + } catch (PDUStringException e) { + /* + * There should be no PDUStringException thrown since creation + * of MessageId should be save. + */ + logger.error("SYSTEM ERROR. Failed sending dataSmResp", e); + } } public PendingResponse removeSentItem(int sequenceNumber) { @@ -787,14 +568,14 @@ private class PDUReaderWorker extends Thread { @Override public void run() { close(); - }; + } }; - public PDUReaderWorker() { + private PDUReaderWorker() { super("PDUReaderWorker: " + SMPPSession.this); } - @Override + @Override public void run() { logger.info("Starting PDUReaderWorker"); while (isReadPdu()) { @@ -805,8 +586,9 @@ public void run() { try { executorService.awaitTermination(getTransactionTimer(), TimeUnit.MILLISECONDS); } catch (InterruptedException e) { - Thread.currentThread().interrupt(); logger.warn("interrupted while waiting for executor service pool to finish"); + Thread.currentThread().interrupt(); + throw new RuntimeException("Interrupted"); } logger.info("PDUReaderWorker stop"); } @@ -856,7 +638,6 @@ private void notifyNoActivity() { } } - /** * Session state listener for internal class use. * diff --git a/jsmpp/src/main/java/org/jsmpp/session/ServerResponseHandler.java b/jsmpp/src/main/java/org/jsmpp/session/ServerResponseHandler.java index af6b618..92f4a37 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/ServerResponseHandler.java +++ b/jsmpp/src/main/java/org/jsmpp/session/ServerResponseHandler.java @@ -19,7 +19,6 @@ import org.jsmpp.bean.Bind; import org.jsmpp.bean.CancelSm; import org.jsmpp.bean.MessageState; -import org.jsmpp.bean.Outbind; import org.jsmpp.bean.QuerySm; import org.jsmpp.bean.ReplaceSm; import org.jsmpp.bean.SubmitMulti; @@ -32,15 +31,13 @@ * @author uudashr * */ -public interface ServerResponseHandler extends BaseResponseHandler { +public interface ServerResponseHandler extends GenericServerResponseHandler { void sendSubmitSmResponse(MessageId messageId, int sequenceNumber) throws IOException; void processBind(Bind bind); - void processOutbind(Outbind outbind); - MessageId processSubmitSm(SubmitSm submitSm) throws ProcessRequestException; SubmitMultiResult processSubmitMulti(SubmitMulti submitMulti) throws ProcessRequestException; diff --git a/jsmpp/src/main/java/org/jsmpp/session/ServerSession.java b/jsmpp/src/main/java/org/jsmpp/session/ServerSession.java index 22816f5..24ce58e 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/ServerSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/ServerSession.java @@ -39,12 +39,12 @@ * */ public interface ServerSession { - + /** * Submit a short message to specified destination address (ESME). This method will * blocks until response received or timeout reached. This method simplify * operations of sending DELIVER_SM command and receiving the DELIVER_SM_RESP. - * + * * @param serviceType is the service_type. * @param sourceAddrTon is the source_addr_ton. * @param sourceAddrNpi is the source_addr_npi. diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/GenericSMPPSessionState.java b/jsmpp/src/main/java/org/jsmpp/session/state/GenericSMPPSessionState.java index 1f7c823..0d0d47d 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/GenericSMPPSessionState.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/GenericSMPPSessionState.java @@ -98,7 +98,7 @@ void processUnbindResp(Command pduHeader, byte[] pdu, */ void processUnknownCid(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException; - + /** * Process the data short message request command. * diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionBound.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionBound.java new file mode 100644 index 0000000..45d69aa --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionBound.java @@ -0,0 +1,44 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session.state; + +import java.io.IOException; + +import org.jsmpp.SMPPConstant; +import org.jsmpp.bean.Command; +import org.jsmpp.session.OutboundServerResponseHandler; + +/** + * This class is general bound state implementation of {@link SMPPOutboundServerSessionState}. + * + * @author uudashr + * @version 1.0 + * @since 2.3 + */ +abstract class SMPPOutboundServerSessionBound extends AbstractGenericSMPPSessionBound + implements SMPPOutboundServerSessionState { + + public void processOutbind(Command pduHeader, byte[] pdu, + OutboundServerResponseHandler responseHandler) throws IOException { + responseHandler.sendNegativeResponse(pduHeader.getCommandId(), + SMPPConstant.STAT_ESME_RINVBNDSTS, pduHeader.getSequenceNumber()); + } + + public void processBindResp(Command pduHeader, byte[] pdu, + OutboundServerResponseHandler responseHandler) throws IOException { + responseHandler.sendNegativeResponse(pduHeader.getCommandId(), + SMPPConstant.STAT_ESME_RALYBND, pduHeader.getSequenceNumber()); + } +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionBoundRX.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionBoundRX.java new file mode 100644 index 0000000..71cb6c5 --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionBoundRX.java @@ -0,0 +1,70 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session.state; + +import java.io.IOException; + +import org.jsmpp.PDUStringException; +import org.jsmpp.bean.Command; +import org.jsmpp.bean.DeliverSm; +import org.jsmpp.extra.ProcessRequestException; +import org.jsmpp.extra.SessionState; +import org.jsmpp.session.OutboundServerResponseHandler; +import org.jsmpp.util.DefaultDecomposer; +import org.jsmpp.util.PDUDecomposer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class is bound_rx state implementation of {@link SMPPOutboundServerSessionState}. + * Response to receiver related transaction. + * + * @author uudashr + * @version 1.0 + * @since 2.3 + * + */ +class SMPPOutboundServerSessionBoundRX extends SMPPOutboundServerSessionBound + implements SMPPOutboundServerSessionState { + private static final Logger logger = LoggerFactory.getLogger(SMPPOutboundServerSessionBoundRX.class); + private static final PDUDecomposer pduDecomposer = new DefaultDecomposer(); + + public SessionState getSessionState() { + return SessionState.BOUND_RX; + } + + public void processDeliverSm(Command pduHeader, byte[] pdu, + OutboundServerResponseHandler responseHandler) throws IOException { + processDeliverSm0(pduHeader, pdu, responseHandler); + } + + static void processDeliverSm0(Command pduHeader, byte[] pdu, + OutboundServerResponseHandler responseHandler) throws IOException { + try { + DeliverSm deliverSm = pduDecomposer.deliverSm(pdu); + responseHandler.processDeliverSm(deliverSm); + responseHandler.sendDeliverSmResp(0, pduHeader.getSequenceNumber(), deliverSm.getId()); + } catch (PDUStringException e) { + logger.error("Failed decomposing deliver_sm", e); + responseHandler.sendGenerickNack(e.getErrorCode(), pduHeader + .getSequenceNumber()); + } catch (ProcessRequestException e) { + logger.error("Failed processing deliver_sm", e); + responseHandler.sendDeliverSmResp(e.getErrorCode(), pduHeader.getSequenceNumber(), null); + } + } + + +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionBoundTRX.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionBoundTRX.java new file mode 100644 index 0000000..37f0f8f --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionBoundTRX.java @@ -0,0 +1,46 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session.state; + +import java.io.IOException; + +import org.jsmpp.bean.Command; +import org.jsmpp.extra.SessionState; +import org.jsmpp.session.OutboundServerResponseHandler; + +/** + * This class is bound_trx state implementation of {@link SMPPOutboundServerSessionState}. + * Response both to transmit and receive related transaction. + * + * @author uudashr + * @version 1.0 + * @since 2.3 + * + */ +class SMPPOutboundServerSessionBoundTRX extends SMPPOutboundServerSessionBoundTX + implements SMPPOutboundServerSessionState { + + @Override + public SessionState getSessionState() { + return SessionState.BOUND_TRX; + } + + @Override + public void processDeliverSm(Command pduHeader, byte[] pdu, + OutboundServerResponseHandler responseHandler) throws IOException { + SMPPOutboundServerSessionBoundRX.processDeliverSm0(pduHeader, pdu, responseHandler); + } + +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionBoundTX.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionBoundTX.java new file mode 100644 index 0000000..b3167b7 --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionBoundTX.java @@ -0,0 +1,58 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session.state; + +import java.io.IOException; + +import org.jsmpp.SMPPConstant; +import org.jsmpp.bean.Command; +import org.jsmpp.extra.SessionState; +import org.jsmpp.session.OutboundServerResponseHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class is bound_tx state implementation of {@link SMPPOutboundServerSessionState}. This + * class give specific response to a transmit related transaction, otherwise + * it always give negative response. + * + * @author uudashr + * @version 1.0 + * @since 2.3 + * + */ +class SMPPOutboundServerSessionBoundTX extends SMPPOutboundServerSessionBound + implements SMPPOutboundServerSessionState { + private static final String NO_REQUEST_FIND_FOR_SEQUENCE_NUMBER = "No request find for sequence number "; + private static final Logger logger = LoggerFactory.getLogger(SMPPOutboundServerSessionBoundTX.class); + + public SessionState getSessionState() { + return SessionState.BOUND_TX; + } + +// public void processBind(Command pduHeader, byte[] pdu, +// OutboundServerResponseHandler responseHandler) throws IOException +// { +// responseHandler.sendNegativeResponse(pduHeader.getCommandId(), +// SMPPConstant.STAT_ESME_RALYBND, pduHeader.getSequenceNumber()); +// } + + public void processDeliverSm(Command pduHeader, byte[] pdu, + OutboundServerResponseHandler responseHandler) throws IOException { + responseHandler.sendNegativeResponse(pduHeader.getCommandId(), + SMPPConstant.STAT_ESME_RINVBNDSTS, pduHeader + .getSequenceNumber()); + } +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionClosed.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionClosed.java new file mode 100644 index 0000000..6376b66 --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionClosed.java @@ -0,0 +1,100 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session.state; + +import java.io.IOException; + +import org.jsmpp.bean.Command; +import org.jsmpp.extra.SessionState; +import org.jsmpp.session.BaseResponseHandler; +import org.jsmpp.session.OutboundServerResponseHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class is closed state implementation of {@link SMPPOutboundServerSessionState}. This + * session state on SMPP specification context, implemented on since version 5.0, + * but we can also use this. + * + * @author uudashr + * @version 1.0 + * @since 2.3 + * + */ +class SMPPOutboundServerSessionClosed implements SMPPOutboundServerSessionState { + private static final String INVALID_PROCESS_FOR_CLOSED_SESSION = "Invalid process for closed session state"; + private static final Logger logger = LoggerFactory.getLogger(SMPPOutboundServerSessionClosed.class); + + public SessionState getSessionState() { + return SessionState.CLOSED; + } + + public void processOutbind(Command pduHeader, byte[] pdu, + OutboundServerResponseHandler responseHandler) throws IOException + { + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); + } + + public void processBindResp(Command pduHeader, byte[] pdu, + OutboundServerResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); + } + + public void processDeliverSm(Command pduHeader, byte[] pdu, + OutboundServerResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); + } + + public void processEnquireLink(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); + } + + public void processEnquireLinkResp(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); + } + + public void processGenericNack(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); + } + + public void processUnbind(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); + } + + public void processUnbindResp(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); + } + + public void processUnknownCid(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); + } + + public void processDataSm(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); + } + + public void processDataSmResp(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); + } + +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionOpen.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionOpen.java new file mode 100644 index 0000000..23d3b04 --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionOpen.java @@ -0,0 +1,171 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session.state; + +import java.io.IOException; + +import org.jsmpp.InvalidResponseException; +import org.jsmpp.PDUStringException; +import org.jsmpp.bean.Command; +import org.jsmpp.bean.Outbind; +import org.jsmpp.extra.PendingResponse; +import org.jsmpp.extra.ProcessRequestException; +import org.jsmpp.extra.SessionState; +import org.jsmpp.session.BaseResponseHandler; +import org.jsmpp.session.OutboundServerResponseHandler; +import org.jsmpp.session.ResponseHandler; +import org.jsmpp.util.DefaultDecomposer; +import org.jsmpp.util.PDUDecomposer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class is open state implementation of {@link SMPPOutboundServerSessionState}. When + * the session state is open, we only give positive response to bind related intention. + * + * @author uudashr + * @version 1.0 + * @since 2.3 + * + */ +class SMPPOutboundServerSessionOpen implements SMPPOutboundServerSessionState { + private static final Logger logger = LoggerFactory.getLogger(SMPPOutboundServerSessionOpen.class); + private static final PDUDecomposer pduDecomposer = new DefaultDecomposer(); + private static final String INVALID_PROCESS_FOR_OPEN_SESSION = "Invalid process for open session state"; + + public SessionState getSessionState() { + return SessionState.OPEN; + } + + public void processOutbind(Command pduHeader, byte[] pdu, + OutboundServerResponseHandler responseHandler) throws IOException { + logger.info("processOutbind"); + try { + Outbind outbind = pduDecomposer.outbind(pdu); + responseHandler.processOutbind(outbind); + logger.debug("Received outbind with {} and {}", outbind.getSystemId(), outbind.getPassword()); + } catch (PDUStringException e) { + responseHandler.sendNegativeResponse(pduHeader.getCommandId(), e.getErrorCode(), pduHeader.getSequenceNumber()); + } catch (ProcessRequestException e) { + responseHandler.sendNegativeResponse(pduHeader.getCommandId(), e.getErrorCode(), pduHeader.getSequenceNumber()); + } + } + + public void processBindResp(Command pduHeader, byte[] pdu, + OutboundServerResponseHandler responseHandler) throws IOException { + logger.info("processBindResp"); + throw new IOException(INVALID_PROCESS_FOR_OPEN_SESSION); + } + + public void processDeliverSm(Command pduHeader, byte[] pdu, + OutboundServerResponseHandler responseHandler) throws IOException { + PendingResponse pendingResp = responseHandler + .removeSentItem(1); + if (pendingResp != null) { + pendingResp.doneWithInvalidResponse(new InvalidResponseException( + "Receive unexpected deliver_sm")); + } + } + + public void processEnquireLink(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + PendingResponse pendingResp = responseHandler + .removeSentItem(1); + if (pendingResp != null) { + pendingResp.doneWithInvalidResponse(new InvalidResponseException( + "Receive unexpected enquire_link")); + } + } + + public void processEnquireLinkResp(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + PendingResponse pendingResp = responseHandler + .removeSentItem(1); + if (pendingResp != null) { + pendingResp.doneWithInvalidResponse(new InvalidResponseException( + "Receive unexpected enquire_link_resp")); + } + } + + public void processGenericNack(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) { + PendingResponse pendingResp = responseHandler + .removeSentItem(1); + if (pendingResp != null) { + pendingResp.doneWithInvalidResponse(new InvalidResponseException( + "Receive unexpected generic_nack")); + } + } + + public void processUnbind(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + PendingResponse pendingResp = responseHandler + .removeSentItem(1); + if (pendingResp != null) { + pendingResp.doneWithInvalidResponse(new InvalidResponseException( + "Receive unexpected unbind")); + } + } + + public void processUnbindResp(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + PendingResponse pendingResp = responseHandler + .removeSentItem(1); + if (pendingResp != null) { + pendingResp.doneWithInvalidResponse(new InvalidResponseException( + "Receive unexpected unbind_resp")); + } + } + + public void processUnknownCid(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + PendingResponse pendingResp = responseHandler + .removeSentItem(1); + if (pendingResp != null) { + pendingResp.doneWithInvalidResponse(new InvalidResponseException( + "Receive unknown command_id")); + } + } + + public void processDataSm(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + PendingResponse pendingResp = responseHandler + .removeSentItem(1); + if (pendingResp != null) { + pendingResp.doneWithInvalidResponse(new InvalidResponseException( + "Receive unexpected data_sm")); + } + } + + public void processDataSmResp(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + PendingResponse pendingResp = responseHandler + .removeSentItem(1); + if (pendingResp != null) { + pendingResp.doneWithInvalidResponse(new InvalidResponseException( + "Receive unexpected data_sm_resp")); + } + } + + public void processAlertNotification(Command pduHeader, byte[] pdu, + ResponseHandler responseHandler) { + PendingResponse pendingResp = responseHandler + .removeSentItem(1); + if (pendingResp != null) { + pendingResp.doneWithInvalidResponse(new InvalidResponseException( + "Receive unexpected alert_notification")); + } + } +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionOutbound.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionOutbound.java new file mode 100644 index 0000000..e1e185d --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionOutbound.java @@ -0,0 +1,181 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session.state; + +import java.io.IOException; + +import org.jsmpp.InvalidResponseException; +import org.jsmpp.PDUStringException; +import org.jsmpp.SMPPConstant; +import org.jsmpp.bean.BindResp; +import org.jsmpp.bean.Command; +import org.jsmpp.extra.PendingResponse; +import org.jsmpp.extra.SessionState; +import org.jsmpp.session.BaseResponseHandler; +import org.jsmpp.session.OutboundServerResponseHandler; +import org.jsmpp.session.ResponseHandler; +import org.jsmpp.util.DefaultDecomposer; +import org.jsmpp.util.PDUDecomposer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class is outbound state implementation of {@link SMPPOutboundServerSessionState}. When + * the session state is outbound, we only give positive response to bind related intention. + * + * @author pmoerenhout + * @version 1.0 + * @since 2.3 + * + */ +class SMPPOutboundServerSessionOutbound implements SMPPOutboundServerSessionState { + private static final Logger logger = LoggerFactory.getLogger(SMPPOutboundServerSessionOutbound.class); + private static final PDUDecomposer pduDecomposer = new DefaultDecomposer(); + + public SessionState getSessionState() { + return SessionState.OUTBOUND; + } + + public void processOutbind(Command pduHeader, byte[] pdu, + OutboundServerResponseHandler responseHandler) throws IOException { + responseHandler.sendNegativeResponse(pduHeader.getCommandId(), + SMPPConstant.STAT_ESME_RINVBNDSTS, pduHeader.getSequenceNumber()); + } + + public void processBindResp(Command pduHeader, byte[] pdu, + OutboundServerResponseHandler responseHandler) throws IOException { + PendingResponse pendingResp = responseHandler + .removeSentItem(pduHeader.getSequenceNumber()); + if (pendingResp != null) { + try { + BindResp resp = pduDecomposer.bindResp(pdu); + pendingResp.done(resp); + } catch (PDUStringException e) { + String message = "Failed decomposing submit_sm_resp"; + logger.error(message, e); + responseHandler.sendGenerickNack(e.getErrorCode(), pduHeader + .getSequenceNumber()); + pendingResp + .doneWithInvalidResponse(new InvalidResponseException( + message, e)); + } + } else { + logger.error("No request with sequence number {} found", pduHeader.getSequenceNumber() ); + responseHandler.sendGenerickNack( + SMPPConstant.STAT_ESME_RINVDFTMSGID, pduHeader + .getSequenceNumber()); + } + } + + public void processDeliverSm(Command pduHeader, byte[] pdu, + OutboundServerResponseHandler responseHandler) throws IOException { + PendingResponse pendingResp = responseHandler + .removeSentItem(1); + if (pendingResp != null) { + pendingResp.doneWithInvalidResponse(new InvalidResponseException( + "Receive unexpected deliver_sm")); + } + } + + public void processEnquireLink(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + PendingResponse pendingResp = responseHandler + .removeSentItem(1); + if (pendingResp != null) { + pendingResp.doneWithInvalidResponse(new InvalidResponseException( + "Receive unexpected enquire_link")); + } + } + + public void processEnquireLinkResp(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + PendingResponse pendingResp = responseHandler + .removeSentItem(1); + if (pendingResp != null) { + pendingResp.doneWithInvalidResponse(new InvalidResponseException( + "Receive unexpected enquire_link_resp")); + } + } + + public void processGenericNack(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) { + PendingResponse pendingResp = responseHandler + .removeSentItem(1); + if (pendingResp != null) { + pendingResp.doneWithInvalidResponse(new InvalidResponseException( + "Receive unexpected generic_nack")); + } + } + + public void processUnbind(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + PendingResponse pendingResp = responseHandler + .removeSentItem(1); + if (pendingResp != null) { + pendingResp.doneWithInvalidResponse(new InvalidResponseException( + "Receive unexpected unbind")); + } + } + + public void processUnbindResp(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + PendingResponse pendingResp = responseHandler + .removeSentItem(1); + if (pendingResp != null) { + pendingResp.doneWithInvalidResponse(new InvalidResponseException( + "Receive unexpected unbind_resp")); + } + } + + public void processUnknownCid(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + PendingResponse pendingResp = responseHandler + .removeSentItem(1); + if (pendingResp != null) { + pendingResp.doneWithInvalidResponse(new InvalidResponseException( + "Receive unknown command_id")); + } + } + + public void processDataSm(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + PendingResponse pendingResp = responseHandler + .removeSentItem(1); + if (pendingResp != null) { + pendingResp.doneWithInvalidResponse(new InvalidResponseException( + "Receive unexpected data_sm")); + } + } + + public void processDataSmResp(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + PendingResponse pendingResp = responseHandler + .removeSentItem(1); + if (pendingResp != null) { + pendingResp.doneWithInvalidResponse(new InvalidResponseException( + "Receive unexpected data_sm_resp")); + } + } + + public void processAlertNotification(Command pduHeader, byte[] pdu, + ResponseHandler responseHandler) { + PendingResponse pendingResp = responseHandler + .removeSentItem(1); + if (pendingResp != null) { + pendingResp.doneWithInvalidResponse(new InvalidResponseException( + "Receive unexpected alert_notification")); + } + } +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionState.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionState.java new file mode 100644 index 0000000..d004db6 --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionState.java @@ -0,0 +1,57 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session.state; + +import java.io.IOException; + +import org.jsmpp.bean.Command; +import org.jsmpp.session.OutboundServerResponseHandler; + +/** + * This class is provide interface to response to every incoming SMPP Commands. + * How the the response behavior is depends to it's states, or the + * implementation of this class. + * + * @author uudashr + * @version 1.0 + * @since 2.3 + */ +public interface SMPPOutboundServerSessionState extends GenericSMPPSessionState { + + SMPPOutboundServerSessionState OPEN = new SMPPOutboundServerSessionOpen(); + SMPPOutboundServerSessionState OUTBOUND = new SMPPOutboundServerSessionOutbound(); + SMPPOutboundServerSessionState BOUND_RX = new SMPPOutboundServerSessionBoundRX(); + SMPPOutboundServerSessionState BOUND_TX = new SMPPOutboundServerSessionBoundTX(); + SMPPOutboundServerSessionState BOUND_TRX = new SMPPOutboundServerSessionBoundTRX(); + SMPPOutboundServerSessionState UNBOUND = new SMPPOutboundServerSessionUnbound(); + public static final SMPPOutboundServerSessionState CLOSED = new SMPPOutboundServerSessionClosed(); + + void processOutbind(Command pduHeader, byte[] pdu, OutboundServerResponseHandler responseHandler) + throws IOException; + + /** + * Process the bind response command. + * + * @param pduHeader is the PDU header. + * @param pdu is the complete PDU. + * @param responseHandler is the session handler. + * @throws IOException throw if there is an IO error occur. + */ + void processBindResp(Command pduHeader, byte[] pdu, OutboundServerResponseHandler responseHandler) + throws IOException; + + void processDeliverSm(Command pduHeader, byte[] pdu, OutboundServerResponseHandler responseHandler) + throws IOException; +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionUnbound.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionUnbound.java new file mode 100644 index 0000000..5f57b3f --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionUnbound.java @@ -0,0 +1,106 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session.state; + +import java.io.IOException; + +import org.jsmpp.bean.Command; +import org.jsmpp.extra.SessionState; +import org.jsmpp.session.BaseResponseHandler; +import org.jsmpp.session.OutboundServerResponseHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class is unbound state implementation of {@link SMPPSessionState}. All + * this method is throw {@link IOException} since when the state is unbound we + * should not give any positive response. + * + * @author uudashr + * @version 1.0 + * @since 2.3 + * + */ +class SMPPOutboundServerSessionUnbound implements SMPPOutboundServerSessionState { + private static final String INVALID_PROCESS_FOR_UNBOUND_SESSION = "Invalid process for unbound session state"; + private static final Logger logger = LoggerFactory.getLogger(SMPPOutboundServerSessionUnbound.class); + + public SessionState getSessionState() { + return SessionState.UNBOUND; + } + + public void processOutbind(Command pduHeader, byte[] pdu, + OutboundServerResponseHandler responseHandler) throws IOException + { + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); + } + + public void processBind(Command pduHeader, byte[] pdu, + OutboundServerResponseHandler responseHandler) throws IOException + { + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); + } + + public void processBindResp(Command pduHeader, byte[] pdu, + OutboundServerResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); + } + + public void processDeliverSm(Command pduHeader, byte[] pdu, + OutboundServerResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); + } + + public void processEnquireLink(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); + } + + public void processEnquireLinkResp(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); + } + + public void processGenericNack(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); + } + + public void processUnbind(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); + } + + public void processUnbindResp(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); + } + + public void processUnknownCid(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); + } + + public void processDataSm(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); + } + + public void processDataSmResp(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); + } + +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionBound.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionBound.java new file mode 100644 index 0000000..a726a66 --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionBound.java @@ -0,0 +1,39 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session.state; + +import java.io.IOException; + +import org.jsmpp.SMPPConstant; +import org.jsmpp.bean.Command; +import org.jsmpp.session.OutboundResponseHandler; + +/** + * This class is general bound state implementation of {@link SMPPOutboundSessionState}. + * + * @author pmoerenhout + * @version 1.0 + * @since 2.3 + * + */ +abstract class SMPPOutboundSessionBound extends AbstractGenericSMPPSessionBound implements SMPPOutboundSessionState { + + public void processBind(Command pduHeader, byte[] pdu, + OutboundResponseHandler responseHandler) throws IOException { + responseHandler.sendNegativeResponse(pduHeader.getCommandId(), + SMPPConstant.STAT_ESME_RALYBND, pduHeader.getSequenceNumber()); + } + +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionBoundRX.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionBoundRX.java new file mode 100644 index 0000000..cc5aa01 --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionBoundRX.java @@ -0,0 +1,61 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session.state; + +import java.io.IOException; + +import org.jsmpp.bean.Command; +import org.jsmpp.bean.DeliverSmResp; +import org.jsmpp.extra.PendingResponse; +import org.jsmpp.extra.SessionState; +import org.jsmpp.session.OutboundResponseHandler; +import org.jsmpp.util.DefaultDecomposer; +import org.jsmpp.util.PDUDecomposer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class is bound_rx state implementation of {@link SMPPOutboundSessionState}. + * Response to receiver related transaction. + * + * @author uudashr + * @version 1.0 + * @since 2.3 + * + */ +class SMPPOutboundSessionBoundRX extends SMPPOutboundSessionBound implements SMPPOutboundSessionState { + private static final Logger logger = LoggerFactory.getLogger(SMPPOutboundSessionBoundRX.class); + private static final PDUDecomposer pduDecomposer = new DefaultDecomposer(); + + public SessionState getSessionState() { + return SessionState.BOUND_RX; + } + + public void processDeliverSmResp(Command pduHeader, byte[] pdu, + OutboundResponseHandler responseHandler) throws IOException { + processDeliverSmResp0(pduHeader, pdu, responseHandler); + } + + static final void processDeliverSmResp0(Command pduHeader, byte[] pdu, + OutboundResponseHandler responseHandler) throws IOException { + PendingResponse pendingResp = responseHandler.removeSentItem(pduHeader.getSequenceNumber()); + if (pendingResp != null) { + DeliverSmResp resp = pduDecomposer.deliverSmResp(pdu); + pendingResp.done(resp); + } else { + logger.warn("No request with sequence number {} found", pduHeader.getSequenceNumber()); + } + } +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionBoundTRX.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionBoundTRX.java new file mode 100644 index 0000000..5ee28f5 --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionBoundTRX.java @@ -0,0 +1,44 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session.state; + +import java.io.IOException; + +import org.jsmpp.bean.Command; +import org.jsmpp.extra.SessionState; +import org.jsmpp.session.OutboundResponseHandler; + +/** + * This class is bound_trx state implementation of {@link SMPPOutboundSessionState}. + * Response both to transmit and receive related transaction. + * + * @author uudashr + * @version 1.0 + * @since 2.3 + * + */ +class SMPPOutboundSessionBoundTRX extends SMPPOutboundSessionBoundTX implements SMPPOutboundSessionState { + + @Override + public SessionState getSessionState() { + return SessionState.BOUND_TRX; + } + + @Override + public void processDeliverSmResp(Command pduHeader, byte[] pdu, + OutboundResponseHandler responseHandler) throws IOException { + SMPPOutboundSessionBoundRX.processDeliverSmResp0(pduHeader, pdu, responseHandler); + } +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionBoundTX.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionBoundTX.java new file mode 100644 index 0000000..7c4008a --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionBoundTX.java @@ -0,0 +1,51 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session.state; + +import java.io.IOException; + +import org.jsmpp.SMPPConstant; +import org.jsmpp.bean.Command; +import org.jsmpp.extra.SessionState; +import org.jsmpp.session.OutboundResponseHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class is bound_tx state implementation of {@link SMPPOutboundSessionState}. This + * class give specific response to a transmit related transaction, otherwise + * it always give negative response. + * + * @author uudashr + * @version 1.0 + * @since 2.3 + * + */ +class SMPPOutboundSessionBoundTX extends SMPPOutboundSessionBound implements SMPPOutboundSessionState { + private static final String NO_REQUEST_FIND_FOR_SEQUENCE_NUMBER = "No request find for sequence number "; + private static final Logger logger = LoggerFactory.getLogger(SMPPOutboundSessionBoundTX.class); + + public SessionState getSessionState() { + return SessionState.BOUND_TX; + } + + public void processDeliverSmResp(Command pduHeader, byte[] pdu, + OutboundResponseHandler responseHandler) throws IOException { + responseHandler.sendNegativeResponse(pduHeader.getCommandId(), + SMPPConstant.STAT_ESME_RINVBNDSTS, pduHeader + .getSequenceNumber()); + } + +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionClosed.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionClosed.java new file mode 100644 index 0000000..08dfffd --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionClosed.java @@ -0,0 +1,97 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session.state; + +import java.io.IOException; + +import org.jsmpp.bean.Command; +import org.jsmpp.extra.SessionState; +import org.jsmpp.session.BaseResponseHandler; +import org.jsmpp.session.OutboundResponseHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class is closed state implementation of {@link SMPPOutboundSessionState}. This + * session state on SMPP specification context, implemented on since version 5.0, + * but we can also use this. + * + * @author uudashr + * @version 1.0 + * @since 2.3 + * + */ +class SMPPOutboundSessionClosed implements SMPPOutboundSessionState { + private static final String INVALID_PROCESS_FOR_CLOSED_SESSION = "Invalid process for closed session state"; + private static final Logger logger = LoggerFactory.getLogger(SMPPOutboundSessionClosed.class); + + public SessionState getSessionState() { + return SessionState.CLOSED; + } + + public void processBind(Command pduHeader, byte[] pdu, + OutboundResponseHandler responseHandler) throws IOException + { + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); + } + + public void processEnquireLink(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); + } + + public void processEnquireLinkResp(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); + } + + public void processGenericNack(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); + } + + public void processUnbind(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); + } + + public void processUnbindResp(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); + } + + public void processUnknownCid(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); + } + + public void processDataSm(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); + } + + public void processDataSmResp(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); + } + + public void processDeliverSmResp(Command pduHeader, byte[] pdu, + OutboundResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); + } + + + +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionOpen.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionOpen.java new file mode 100644 index 0000000..208fd80 --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionOpen.java @@ -0,0 +1,146 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session.state; + +import java.io.IOException; + +import org.jsmpp.InvalidResponseException; +import org.jsmpp.PDUStringException; +import org.jsmpp.SMPPConstant; +import org.jsmpp.bean.Bind; +import org.jsmpp.bean.Command; +import org.jsmpp.extra.PendingResponse; +import org.jsmpp.extra.SessionState; +import org.jsmpp.session.BaseResponseHandler; +import org.jsmpp.session.OutboundResponseHandler; +import org.jsmpp.util.DefaultDecomposer; +import org.jsmpp.util.PDUDecomposer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class is open state implementation of {@link SMPPOutboundSessionState}. When + * the session state is open, we only give positive response to bind related intention. + * + * @author uudashr + * @version 1.0 + * @since 2.3 + */ +class SMPPOutboundSessionOpen implements SMPPOutboundSessionState { + private static final Logger logger = LoggerFactory.getLogger(SMPPOutboundSessionOpen.class); + private static final String INVALID_PROCESS_FOR_OPEN_SESSION = "Invalid process for open session state"; + private static final PDUDecomposer pduDecomposer = new DefaultDecomposer(); + + public SessionState getSessionState() { + return SessionState.OPEN; + } + + public void processBind(Command pduHeader, byte[] pdu, + OutboundResponseHandler responseHandler) throws IOException { + try { + Bind bind = pduDecomposer.bind(pdu); + responseHandler.processBind(bind); + } catch (PDUStringException e) { + responseHandler.sendNegativeResponse(pduHeader.getCommandId(), e.getErrorCode(), pduHeader.getSequenceNumber()); + } catch (IllegalArgumentException e) { + responseHandler.sendNegativeResponse(pduHeader.getCommandId(), SMPPConstant.STAT_ESME_RINVCMDID, pduHeader.getSequenceNumber()); + } + } + + public void processDeliverSmResp(Command pduHeader, byte[] pdu, + OutboundResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_OPEN_SESSION); + } + + public void processEnquireLink(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + PendingResponse pendingResp = responseHandler + .removeSentItem(1); + if (pendingResp != null) { + pendingResp.doneWithInvalidResponse(new InvalidResponseException( + "Receive unexpected enquire_link")); + } + } + + public void processEnquireLinkResp(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + PendingResponse pendingResp = responseHandler + .removeSentItem(1); + if (pendingResp != null) { + pendingResp.doneWithInvalidResponse(new InvalidResponseException( + "Receive unexpected enquire_link_resp")); + } + } + + public void processGenericNack(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) { + PendingResponse pendingResp = responseHandler + .removeSentItem(1); + if (pendingResp != null) { + pendingResp.doneWithInvalidResponse(new InvalidResponseException( + "Receive unexpected generic_nack")); + } + } + + public void processUnbind(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + PendingResponse pendingResp = responseHandler + .removeSentItem(1); + if (pendingResp != null) { + pendingResp.doneWithInvalidResponse(new InvalidResponseException( + "Receive unexpected unbind")); + } + } + + public void processUnbindResp(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + PendingResponse pendingResp = responseHandler + .removeSentItem(1); + if (pendingResp != null) { + pendingResp.doneWithInvalidResponse(new InvalidResponseException( + "Receive unexpected unbind_resp")); + } + } + + public void processUnknownCid(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + PendingResponse pendingResp = responseHandler + .removeSentItem(1); + if (pendingResp != null) { + pendingResp.doneWithInvalidResponse(new InvalidResponseException( + "Receive unknown command_id")); + } + } + + public void processDataSm(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + PendingResponse pendingResp = responseHandler + .removeSentItem(1); + if (pendingResp != null) { + pendingResp.doneWithInvalidResponse(new InvalidResponseException( + "Receive unexpected data_sm")); + } + } + + public void processDataSmResp(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + PendingResponse pendingResp = responseHandler + .removeSentItem(1); + if (pendingResp != null) { + pendingResp.doneWithInvalidResponse(new InvalidResponseException( + "Receive unexpected data_sm_resp")); + } + } +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionState.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionState.java new file mode 100644 index 0000000..02ca582 --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionState.java @@ -0,0 +1,47 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session.state; + +import java.io.IOException; + +import org.jsmpp.bean.Command; +import org.jsmpp.session.OutboundResponseHandler; + +/** + * @author uudashr + */ +public interface SMPPOutboundSessionState extends GenericSMPPSessionState { + + SMPPOutboundSessionState OPEN = new SMPPOutboundSessionOpen(); + SMPPOutboundSessionState BOUND_RX = new SMPPOutboundSessionBoundRX(); + SMPPOutboundSessionState BOUND_TX = new SMPPOutboundSessionBoundTX(); + SMPPOutboundSessionState BOUND_TRX = new SMPPOutboundSessionBoundTRX(); + SMPPOutboundSessionState UNBOUND = new SMPPOutboundSessionUnbound(); + SMPPOutboundSessionState CLOSED = new SMPPOutboundSessionClosed(); + + /** + * Process the bind command received after outbind request. + * + * @param pduHeader is the PDU header. + * @param pdu is the complete PDU. + * @param responseHandler is the session handler. + * @throws IOException throw if there is an IO error occur. + */ + void processBind(Command pduHeader, byte[] pdu, + OutboundResponseHandler responseHandler) throws IOException; + + void processDeliverSmResp(Command pduHeader, byte[] pdu, + OutboundResponseHandler responseHandler) throws IOException; +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionUnbound.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionUnbound.java new file mode 100644 index 0000000..1639e82 --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionUnbound.java @@ -0,0 +1,94 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.session.state; + +import java.io.IOException; + +import org.jsmpp.bean.Command; +import org.jsmpp.extra.SessionState; +import org.jsmpp.session.BaseResponseHandler; +import org.jsmpp.session.OutboundResponseHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class is unbound state implementation of {@link SMPPOutboundSessionState}. All + * this method is throw {@link IOException} since when the state is unbound we + * should not give any positive response. + * + * @author uudashr + * @version 1.0 + * @since 2.3 + * + */ +class SMPPOutboundSessionUnbound implements SMPPOutboundSessionState { + private static final String INVALID_PROCESS_FOR_UNBOUND_SESSION = "Invalid process for unbound session state"; + private static final Logger logger = LoggerFactory.getLogger(SMPPOutboundSessionUnbound.class); + + public SessionState getSessionState() { + return SessionState.UNBOUND; + } + + public void processBind(Command pduHeader, byte[] pdu, + OutboundResponseHandler responseHandler) throws IOException + { + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); + } + + public void processEnquireLink(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); + } + + public void processEnquireLinkResp(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); + } + + public void processGenericNack(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); + } + + public void processUnbind(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); + } + + public void processUnbindResp(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); + } + + public void processUnknownCid(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); + } + + public void processDataSm(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); + } + + public void processDataSmResp(Command pduHeader, byte[] pdu, + BaseResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); + } + + public void processDeliverSmResp(Command pduHeader, byte[] pdu, + OutboundResponseHandler responseHandler) throws IOException { + throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); + } +} diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionBound.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionBound.java index 9270ee7..7d8c894 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionBound.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionBound.java @@ -29,23 +29,10 @@ abstract class SMPPServerSessionBound extends private static final String INVALID_PROCESS_FOR_BOUND_SESSION = "Invalid process for bound session state"; - @Override public void processBind(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException { responseHandler.sendNegativeResponse(pduHeader.getCommandId(), SMPPConstant.STAT_ESME_RALYBND, pduHeader.getSequenceNumber()); } - @Override - public void processBindResp(Command pduHeader, byte[] pdu, - ServerResponseHandler responseHandler) throws IOException { - throw new IOException(INVALID_PROCESS_FOR_BOUND_SESSION); - } - - @Override - public void processOutbind(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException - { - responseHandler.sendNegativeResponse(pduHeader.getCommandId(), - SMPPConstant.STAT_ESME_RALYBND, pduHeader.getSequenceNumber()); - } } diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionClosed.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionClosed.java index 7cf638f..1acc3b3 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionClosed.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionClosed.java @@ -38,16 +38,6 @@ public void processBind(Command pduHeader, byte[] pdu, throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); } - public void processBindResp(Command pduHeader, byte[] pdu, - ServerResponseHandler responseHandler) throws IOException { - throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); - } - - public void processOutbind(Command pduHeader, byte[] pdu, - ServerResponseHandler responseHandler) throws IOException { - throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); - } - public void processDeliverSmResp(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException { throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionOpen.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionOpen.java index 28902b4..a32f5da 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionOpen.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionOpen.java @@ -16,19 +16,14 @@ import java.io.IOException; -import org.jsmpp.InvalidResponseException; import org.jsmpp.PDUStringException; import org.jsmpp.SMPPConstant; import org.jsmpp.bean.Bind; -import org.jsmpp.bean.BindResp; import org.jsmpp.bean.Command; -import org.jsmpp.bean.Outbind; -import org.jsmpp.extra.PendingResponse; import org.jsmpp.extra.SessionState; import org.jsmpp.session.BaseResponseHandler; import org.jsmpp.session.ServerResponseHandler; import org.jsmpp.util.DefaultDecomposer; -import org.jsmpp.util.IntUtil; import org.jsmpp.util.PDUDecomposer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -60,52 +55,6 @@ public void processBind(Command pduHeader, byte[] pdu, } } - public void processBindResp(Command pduHeader, byte[] pdu, - ServerResponseHandler responseHandler) throws IOException - { - PendingResponse pendingResp = responseHandler.removeSentItem(pduHeader.getSequenceNumber()); - if (pendingResp != null) { - try { - logger.debug("Bind Response header ({}, {}, {}, {})", - pduHeader.getCommandLength(), - pduHeader.getCommandIdAsHex(), - IntUtil.toHexString(pduHeader.getCommandStatus()), - pduHeader.getSequenceNumber()); - BindResp resp = pduDecomposer.bindResp(pdu); - pendingResp.done(resp); - } catch (PDUStringException e) { - String message = "Failed decomposing submit_sm_resp"; - logger.error(message, e); - responseHandler.sendGenerickNack(e.getErrorCode(), pduHeader - .getSequenceNumber()); - pendingResp - .doneWithInvalidResponse(new InvalidResponseException(message, e)); - } - } else { - logger.error("No request with sequence number {} found", pduHeader.getSequenceNumber() ); - responseHandler.sendGenerickNack( - SMPPConstant.STAT_ESME_RINVDFTMSGID, pduHeader.getSequenceNumber()); - } - } - - public void processOutbind(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) - throws IOException - { - try - { - Outbind outbind = pduDecomposer.outbind(pdu); - responseHandler.processOutbind(outbind);; - } - catch (PDUStringException e) - { - responseHandler.sendNegativeResponse(pduHeader.getCommandId(), e.getErrorCode(), pduHeader.getSequenceNumber()); - } - catch (IllegalArgumentException e) - { - responseHandler.sendNegativeResponse(pduHeader.getCommandId(), SMPPConstant.STAT_ESME_RINVCMDID, pduHeader.getSequenceNumber()); - } - } - public void processDeliverSmResp(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException { throw new IOException(INVALID_PROCESS_FOR_OPEN_SESSION); diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionState.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionState.java index 1481299..bc38e92 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionState.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionState.java @@ -24,12 +24,12 @@ * */ public interface SMPPServerSessionState extends GenericSMPPSessionState { - public static final SMPPServerSessionState OPEN = new SMPPServerSessionOpen(); - public static final SMPPServerSessionState BOUND_RX = new SMPPServerSessionBoundRX(); - public static final SMPPServerSessionState BOUND_TX = new SMPPServerSessionBoundTX(); - public static final SMPPServerSessionState BOUND_TRX = new SMPPServerSessionTRX(); - public static final SMPPServerSessionState UNBOUND = new SMPPServerSessionUnbound(); - public static final SMPPServerSessionState CLOSED = new SMPPServerSessionClosed(); + SMPPServerSessionState OPEN = new SMPPServerSessionOpen(); + SMPPServerSessionState BOUND_RX = new SMPPServerSessionBoundRX(); + SMPPServerSessionState BOUND_TX = new SMPPServerSessionBoundTX(); + SMPPServerSessionState BOUND_TRX = new SMPPServerSessionTRX(); + SMPPServerSessionState UNBOUND = new SMPPServerSessionUnbound(); + SMPPServerSessionState CLOSED = new SMPPServerSessionClosed(); /** * Process the bind request command. @@ -42,28 +42,6 @@ public interface SMPPServerSessionState extends GenericSMPPSessionState { void processBind(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException; - /** - * Process the bind resp command. - * - * @param pduHeader is the PDU header. - * @param pdu is the complete PDU. - * @param responseHandler is the response handler. - * @throws IOException if there is an IO error occur. - */ - void processBindResp(Command pduHeader, byte[] pdu, - ServerResponseHandler responseHandler) throws IOException; - - /** - * Process the outbind request command. - * - * @param pduHeader is the PDU header. - * @param pdu is the complete PDU. - * @param responseHandler is the response handler. - * @throws IOException if there is an IO error occur. - */ - void processOutbind(Command pduHeader, byte[] pdu, - ServerResponseHandler responseHandler) throws IOException; - /** * Process the submit short message request command. * @@ -94,7 +72,15 @@ void processDeliverSmResp(Command pduHeader, byte[] pdu, */ void processCancelSm(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException; - + + /** + * Process the replace short message request command. + * + * @param pduHeader is the PDU header. + * @param pdu is the complete PDU. + * @param responseHandler is the session handler. + * @throws IOException throw if there is an IO error occur. + */ void processReplaceSm(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException; } diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionUnbound.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionUnbound.java index f3051f6..8992513 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionUnbound.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionUnbound.java @@ -39,17 +39,6 @@ public void processBind(Command pduHeader, byte[] pdu, throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); } - public void processBindResp(Command pduHeader, byte[] pdu, - ServerResponseHandler responseHandler) throws IOException { - throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); - } - - public void processOutbind(Command pduHeader, byte[] pdu, - ServerResponseHandler responseHandler) - throws IOException { - throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); - } - public void processDeliverSmResp(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException { throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionBound.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionBound.java index 7498d00..fed8bbb 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionBound.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionBound.java @@ -30,13 +30,6 @@ */ abstract class SMPPSessionBound extends AbstractGenericSMPPSessionBound implements SMPPSessionState { - public void processBind(Command pduHeader, byte[] pdu, - ResponseHandler responseHandler) throws IOException - { - responseHandler.sendNegativeResponse(pduHeader.getCommandId(), - SMPPConstant.STAT_ESME_RALYBND, pduHeader.getSequenceNumber()); - } - public void processBindResp(Command pduHeader, byte[] pdu, ResponseHandler responseHandler) throws IOException { responseHandler.sendNegativeResponse(pduHeader.getCommandId(), diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionBoundRX.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionBoundRX.java index a659f0e..31c8313 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionBoundRX.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionBoundRX.java @@ -30,7 +30,7 @@ import org.slf4j.LoggerFactory; /** - * This class is bound_tx state implementation of {@link SMPPSessionState}. + * This class is bound_rx state implementation of {@link SMPPSessionState}. * Response to receiver related transaction. * * @author uudashr @@ -111,7 +111,7 @@ static void processDeliverSm0(Command pduHeader, byte[] pdu, } catch (PDUStringException e) { logger.error("Failed decomposing deliver_sm", e); responseHandler.sendGenerickNack(e.getErrorCode(), pduHeader - .getSequenceNumber()); + .getSequenceNumber()); } catch (ProcessRequestException e) { logger.error("Failed processing deliver_sm", e); responseHandler.sendDeliverSmResp(e.getErrorCode(), pduHeader.getSequenceNumber(), null); diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionBoundTX.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionBoundTX.java index f339a18..1193453 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionBoundTX.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionBoundTX.java @@ -31,7 +31,7 @@ import org.slf4j.LoggerFactory; /** - * This class is unbound state implementation of {@link SMPPSessionState}. This + * This class is bound_tx state implementation of {@link SMPPSessionState}. This * class give specific response to a transmit related transaction, otherwise * it always give negative response. * diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionClosed.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionClosed.java index 899d482..d14ce62 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionClosed.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionClosed.java @@ -41,12 +41,6 @@ public SessionState getSessionState() { return SessionState.CLOSED; } - public void processBind(Command pduHeader, byte[] pdu, - ResponseHandler responseHandler) throws IOException - { - throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); - } - public void processBindResp(Command pduHeader, byte[] pdu, ResponseHandler responseHandler) throws IOException { throw new IOException(INVALID_PROCESS_FOR_CLOSED_SESSION); diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionOpen.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionOpen.java index 61403da..e67e698 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionOpen.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionOpen.java @@ -19,7 +19,6 @@ import org.jsmpp.InvalidResponseException; import org.jsmpp.PDUStringException; import org.jsmpp.SMPPConstant; -import org.jsmpp.bean.Bind; import org.jsmpp.bean.BindResp; import org.jsmpp.bean.Command; import org.jsmpp.extra.PendingResponse; @@ -49,41 +48,6 @@ public SessionState getSessionState() { return SessionState.OPEN; } - public void processBind(Command pduHeader, byte[] pdu, - ResponseHandler responseHandler) throws IOException { - - PendingResponse pendingResp = responseHandler - .removeSentItem(pduHeader.getSequenceNumber()); - - if (null==pendingResp) - { - logger.debug("No pending response found for sequence number {} try to found with previous {}", - pduHeader.getSequenceNumber(), pduHeader.getSequenceNumber() - 1); - pendingResp = responseHandler.removeSentItem(pduHeader.getSequenceNumber() - 1); - } - if (pendingResp != null) { - try { - logger.debug("Bind header ({}, {}, {}, {})", - pduHeader.getCommandLength(), - pduHeader.getCommandIdAsHex(), - IntUtil.toHexString(pduHeader.getCommandStatus()), - pduHeader.getSequenceNumber()); - Bind bind = pduDecomposer.bind(pdu); - pendingResp.done(bind); - } catch (PDUStringException e) { - String message = "Failed decomposing bind_resp"; - logger.error(message, e); - responseHandler.sendNegativeResponse(pduHeader.getCommandId(), e.getErrorCode(), pduHeader.getSequenceNumber()); - pendingResp - .doneWithInvalidResponse(new InvalidResponseException( - message, e)); - } - } else { - logger.error("No request with sequence number {} found", pduHeader.getSequenceNumber() ); - responseHandler.sendNegativeResponse(pduHeader.getCommandId(), SMPPConstant.STAT_ESME_RINVDFTMSGID, pduHeader.getSequenceNumber()); - } - } - public void processBindResp(Command pduHeader, byte[] pdu, ResponseHandler responseHandler) throws IOException { PendingResponse pendingResp = responseHandler diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionState.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionState.java index c98b7e9..337f984 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionState.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionState.java @@ -29,27 +29,17 @@ * @since 2.0 */ public interface SMPPSessionState extends GenericSMPPSessionState { - public static final SMPPSessionState OPEN = new SMPPSessionOpen(); - public static final SMPPSessionState BOUND_RX = new SMPPSessionBoundRX(); - public static final SMPPSessionState BOUND_TX = new SMPPSessionBoundTX(); - public static final SMPPSessionState BOUND_TRX = new SMPPSessionBoundTRX(); - public static final SMPPSessionState UNBOUND = new SMPPSessionUnbound(); - public static final SMPPSessionState CLOSED = new SMPPSessionClosed(); + SMPPSessionState OPEN = new SMPPSessionOpen(); + SMPPSessionState BOUND_RX = new SMPPSessionBoundRX(); + SMPPSessionState BOUND_TX = new SMPPSessionBoundTX(); + SMPPSessionState BOUND_TRX = new SMPPSessionBoundTRX(); + SMPPSessionState UNBOUND = new SMPPSessionUnbound(); + SMPPSessionState CLOSED = new SMPPSessionClosed(); - /** - * Process the bind command received after outbind request. - * - * @param pduHeader is the PDU header. - * @param pdu is the complete PDU. - * @param responseHandler is the session handler. - * @throws IOException throw if there is an IO error occur. - */ - void processBind(Command pduHeader, byte[] pdu, - ResponseHandler responseHandler) throws IOException; /** * Process the bind response command. - * + * * @param pduHeader is the PDU header. * @param pdu is the complete PDU. * @param responseHandler is the session handler. diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionUnbound.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionUnbound.java index 48f2956..80360e0 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionUnbound.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionUnbound.java @@ -41,12 +41,6 @@ public SessionState getSessionState() { return SessionState.UNBOUND; } - public void processBind(Command pduHeader, byte[] pdu, - ResponseHandler responseHandler) throws IOException - { - throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); - } - public void processBindResp(Command pduHeader, byte[] pdu, ResponseHandler responseHandler) throws IOException { throw new IOException(INVALID_PROCESS_FOR_UNBOUND_SESSION); diff --git a/jsmpp/src/main/java/org/jsmpp/util/DefaultDecomposer.java b/jsmpp/src/main/java/org/jsmpp/util/DefaultDecomposer.java index 591d591..ffc9603 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/DefaultDecomposer.java +++ b/jsmpp/src/main/java/org/jsmpp/util/DefaultDecomposer.java @@ -32,6 +32,7 @@ import org.jsmpp.bean.DeliverSmResp; import org.jsmpp.bean.DeliveryReceipt; import org.jsmpp.bean.DestinationAddress; +import org.jsmpp.bean.DestinationAddress.Flag; import org.jsmpp.bean.DistributionList; import org.jsmpp.bean.EnquireLink; import org.jsmpp.bean.EnquireLinkResp; @@ -51,7 +52,6 @@ import org.jsmpp.bean.Unbind; import org.jsmpp.bean.UnbindResp; import org.jsmpp.bean.UnsuccessDelivery; -import org.jsmpp.bean.DestinationAddress.Flag; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -631,9 +631,10 @@ private static OptionalParameter[] readOptionalParameters( private static void assignHeader(Command pdu, SequentialBytesReader seqBytesReader) { int commandLength = seqBytesReader.readInt(); - if (seqBytesReader.getBytes().length != commandLength) - logger.error("SYSTEM BUGS, the command_length ({}) not equals with the byte array length ({})", + if (seqBytesReader.getBytes().length != commandLength) { + logger.error("The command_length ({}) not equals the byte array length ({})", commandLength, seqBytesReader.getBytes().length); + } pdu.setCommandLength(commandLength); pdu.setCommandId(seqBytesReader.readInt()); pdu.setCommandStatus(seqBytesReader.readInt()); diff --git a/jsmpp/src/main/java/org/jsmpp/util/RandomDecimalMessageIDGenerator.java b/jsmpp/src/main/java/org/jsmpp/util/RandomDecimalMessageIDGenerator.java new file mode 100644 index 0000000..9a2573a --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/util/RandomDecimalMessageIDGenerator.java @@ -0,0 +1,57 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.util; + +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.Random; + +import org.jsmpp.PDUStringException; + +/** + * Generate random numeric message id + * + * @author pmoerenhout + * @version 1.0 + * @since 2.5 + * + */ +public class RandomDecimalMessageIDGenerator implements MessageIDGenerator { + private Random random; + + public RandomDecimalMessageIDGenerator() { + try { + random = SecureRandom.getInstance("SHA1PRNG"); + } catch (NoSuchAlgorithmException e) { + random = new Random(); + } + } + + /* (non-Javadoc) + * @see org.jsmpp.util.MessageIDGenerator#newMessageId() + */ + public MessageId newMessageId() { + /* + * use random into decimal representation + */ + try { + synchronized (random) { + return new MessageId(String.format("%010d", random.nextInt(Integer.MAX_VALUE), 10)); + } + } catch (PDUStringException e) { + throw new RuntimeException("Failed creating message id", e); + } + } +} \ No newline at end of file diff --git a/jsmpp/src/test/java/org/jsmpp/session/DummyResponseHandler.java b/jsmpp/src/test/java/org/jsmpp/session/DummyResponseHandler.java index fd6eeb9..a3f5c86 100644 --- a/jsmpp/src/test/java/org/jsmpp/session/DummyResponseHandler.java +++ b/jsmpp/src/test/java/org/jsmpp/session/DummyResponseHandler.java @@ -23,7 +23,6 @@ import org.jsmpp.bean.DataSm; import org.jsmpp.bean.InterfaceVersion; import org.jsmpp.bean.MessageState; -import org.jsmpp.bean.Outbind; import org.jsmpp.bean.QuerySm; import org.jsmpp.bean.ReplaceSm; import org.jsmpp.bean.SubmitMulti; @@ -67,9 +66,6 @@ public void sendUnbindResp(int sequenceNumber) throws IOException { public void processBind(Bind bind) { } - public void processOutbind(Outbind outbind) { - } - public QuerySmResult processQuerySm(QuerySm querySm) throws ProcessRequestException { return null; @@ -129,7 +125,7 @@ public void processReplaceSm(ReplaceSm replaceSm) public void sendReplaceSmResp(int sequenceNumber) throws IOException { } - public void closeConnection() { + void closeConnection() { connectionClosed = true; } } \ No newline at end of file From 5f85b5fc4b380d71485ea14de82e76096df21808 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Mon, 25 Jul 2016 09:31:44 +0200 Subject: [PATCH 155/212] Renamed file --- ....java => SMPPOutboundServerSimulator.java} | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) rename jsmpp-examples/src/main/java/org/jsmpp/examples/{OutboundSMPPServerSimulatorTest.java => SMPPOutboundServerSimulator.java} (89%) diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/OutboundSMPPServerSimulatorTest.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPOutboundServerSimulator.java similarity index 89% rename from jsmpp-examples/src/main/java/org/jsmpp/examples/OutboundSMPPServerSimulatorTest.java rename to jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPOutboundServerSimulator.java index 92c1a3d..7e6fe85 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/OutboundSMPPServerSimulatorTest.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPOutboundServerSimulator.java @@ -39,19 +39,20 @@ import org.slf4j.LoggerFactory; /** - * @author uudashr + * + * @author pmoerenhout + * */ -public class OutboundSMPPServerSimulatorTest extends ServerResponseDeliveryAdapter +public class SMPPOutboundServerSimulator extends ServerResponseDeliveryAdapter implements Runnable, OutboundServerMessageReceiverListener { private static final Integer DEFAULT_PORT = 8056; - private static final Logger logger = LoggerFactory.getLogger(OutboundSMPPServerSimulatorTest.class); + private static final Logger logger = LoggerFactory.getLogger(SMPPOutboundServerSimulator.class); private final ExecutorService execService = Executors.newFixedThreadPool(100); - private final ExecutorService execServiceDelReceipt = Executors.newFixedThreadPool(100); private int port; private AtomicBoolean exit = new AtomicBoolean(); - OutboundSMPPServerSimulatorTest(int port) { + SMPPOutboundServerSimulator(int port) { this.port = port; } @@ -64,7 +65,8 @@ public static void main(String[] args) { port = DEFAULT_PORT; } BasicConfigurator.configure(); - OutboundSMPPServerSimulatorTest smppServerSim = new OutboundSMPPServerSimulatorTest(port); + + SMPPOutboundServerSimulator smppServerSim = new SMPPOutboundServerSimulator(port); logger.info("run {}", smppServerSim); smppServerSim.run(); } @@ -75,10 +77,9 @@ private void shutdown() { public void run() { try { - logger.info("OutboundSMPPServerSessionListener {}", port); + logger.info("Listening on port {}", port); OutboundSMPPServerSessionListener sessionListener = new OutboundSMPPServerSessionListener(port); - logger.info("Listening on port {}", port); while (!exit.get()) { final SMPPOutboundServerSession outboundServerSession = sessionListener.accept(); logger.info("Accepting connection from {} for session {}", outboundServerSession.getInetAddress(), @@ -87,7 +88,7 @@ public void run() { outboundServerSession.addSessionStateListener(new SessionStateListenerImpl()); outboundServerSession.setOutboundServerMessageReceiverListener(this); - execService.execute(new OutboundSMPPServerSimulatorTest.WaitOutbindTask(outboundServerSession)); + execService.execute(new SMPPOutboundServerSimulator.WaitOutbindTask(outboundServerSession)); try { Thread.sleep(60 * 60 * 1000L); From 915f6956247e8eea82ddc6b9ca2549799766380a Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Wed, 27 Jul 2016 17:53:36 +0200 Subject: [PATCH 156/212] Remove redundant private declaration for enum. --- .../java/org/jsmpp/bean/GSMSpecificFeature.java | 2 +- .../org/jsmpp/bean/IntermediateNotification.java | 2 +- .../java/org/jsmpp/bean/OptionalParameter.java | 15 ++++++++++----- .../java/org/jsmpp/util/DeliveryReceiptState.java | 2 +- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/GSMSpecificFeature.java b/jsmpp/src/main/java/org/jsmpp/bean/GSMSpecificFeature.java index 28d237a..b273abe 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/GSMSpecificFeature.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/GSMSpecificFeature.java @@ -41,7 +41,7 @@ public enum GSMSpecificFeature { private final byte value; - private GSMSpecificFeature(byte value) { + GSMSpecificFeature(byte value) { this.value = value; } diff --git a/jsmpp/src/main/java/org/jsmpp/bean/IntermediateNotification.java b/jsmpp/src/main/java/org/jsmpp/bean/IntermediateNotification.java index d67f66d..2d87590 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/IntermediateNotification.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/IntermediateNotification.java @@ -28,7 +28,7 @@ public enum IntermediateNotification { private final byte value; - private IntermediateNotification(byte value) { + IntermediateNotification(byte value) { this.value = value; } diff --git a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java index b9e5fb2..c58636c 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java @@ -318,7 +318,8 @@ public enum Addr_subunit{ RESERVED(0x05); protected byte value; - private Addr_subunit(int value) { + + Addr_subunit(int value) { this.value = (byte)value; } @@ -461,7 +462,8 @@ public enum Bearer_type { RESERVED(0x09); protected byte value; - private Bearer_type(int value) { + + Bearer_type(int value) { this.value = (byte)value; } @@ -722,7 +724,8 @@ public enum Payload_type_enum { RESERVED(255); protected byte value; - private Payload_type_enum(int value) { + + Payload_type_enum(int value) { this.value = (byte)value; } @@ -822,7 +825,8 @@ public enum Ms_msg_wait_facilities_type { UNKNOWN(4); protected byte value; - private Ms_msg_wait_facilities_type(int value) { + + Ms_msg_wait_facilities_type(int value) { this.value = (byte)value; } @@ -1142,7 +1146,8 @@ public enum Language_indicator_enum { RESERVED(255); protected byte value; - private Language_indicator_enum(int value) { + + Language_indicator_enum(int value) { this.value = (byte)value; } diff --git a/jsmpp/src/main/java/org/jsmpp/util/DeliveryReceiptState.java b/jsmpp/src/main/java/org/jsmpp/util/DeliveryReceiptState.java index accab45..e5beed6 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/DeliveryReceiptState.java +++ b/jsmpp/src/main/java/org/jsmpp/util/DeliveryReceiptState.java @@ -52,7 +52,7 @@ public enum DeliveryReceiptState { private int value; - private DeliveryReceiptState(int value) { + DeliveryReceiptState(int value) { this.value = value; } From 1f9496ad443641ad2e88af389dd3da853561fb90 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Wed, 27 Jul 2016 17:55:23 +0200 Subject: [PATCH 157/212] Remove redundant private declaration for enum. --- jsmpp/src/main/java/org/jsmpp/bean/InterfaceVersion.java | 2 +- jsmpp/src/main/java/org/jsmpp/util/StringParameter.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/InterfaceVersion.java b/jsmpp/src/main/java/org/jsmpp/bean/InterfaceVersion.java index f560df0..d570a43 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/InterfaceVersion.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/InterfaceVersion.java @@ -42,7 +42,7 @@ public enum InterfaceVersion { private byte value; - private InterfaceVersion(byte value) { + InterfaceVersion(byte value) { this.value = value; } diff --git a/jsmpp/src/main/java/org/jsmpp/util/StringParameter.java b/jsmpp/src/main/java/org/jsmpp/util/StringParameter.java index d49d415..b1e8ba3 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/StringParameter.java +++ b/jsmpp/src/main/java/org/jsmpp/util/StringParameter.java @@ -81,7 +81,7 @@ public enum StringParameter { * @param rangeMinAndMax * @param errCode AKA error code on command_status. */ - private StringParameter(StringType type, int min, int max, boolean rangeMinAndMax, int errCode) { + StringParameter(StringType type, int min, int max, boolean rangeMinAndMax, int errCode) { this.type = type; this.min = min; this.max = max; From dffb4c578b2841ff6b4868feecdbf3cf9ec465fa Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Fri, 16 Sep 2016 09:58:48 +0200 Subject: [PATCH 158/212] Prepare for release 2.3.0 --- CHANGES.txt | 2 +- jsmpp-examples/pom.xml | 2 +- jsmpp/pom.xml | 2 +- .../org/jsmpp/bean/OptionalParameter.java | 27 ++++++++++++------- pom.xml | 2 +- 5 files changed, 21 insertions(+), 14 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 976ce7b..fa603ad 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,6 +1,6 @@ Changes: -2.2.5 +2.3.0 - Add outbind processing 2.2.4 diff --git a/jsmpp-examples/pom.xml b/jsmpp-examples/pom.xml index a25e53c..b220231 100644 --- a/jsmpp-examples/pom.xml +++ b/jsmpp-examples/pom.xml @@ -3,7 +3,7 @@ jsmpp-pom org.jsmpp - 2.2.5-SNAPSHOT + 2.3.0 4.0.0 diff --git a/jsmpp/pom.xml b/jsmpp/pom.xml index cb64492..31591f6 100644 --- a/jsmpp/pom.xml +++ b/jsmpp/pom.xml @@ -3,7 +3,7 @@ org.jsmpp jsmpp-pom - 2.2.5-SNAPSHOT + 2.3.0 4.0.0 bundle diff --git a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java index c58636c..1ab0a52 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java @@ -390,7 +390,8 @@ public enum Network_type { RESERVED(0x09); protected byte value; - private Network_type(int value) { + + Network_type(int value) { this.value = (byte)value; } @@ -1327,7 +1328,8 @@ public enum Presentation_Indicator { RESERVED(3); protected byte value; - private Presentation_Indicator(int value) { + + Presentation_Indicator(int value) { this.value = (byte)value; } @@ -1363,7 +1365,8 @@ public enum Screening_Indicator { NETWORK_PROVIDED(3); protected byte value; - private Screening_Indicator(int value) { + + Screening_Indicator(int value) { this.value = (byte)value; } @@ -1591,7 +1594,8 @@ public enum Ms_availability_status_enum { RESERVED(3); protected byte value; - private Ms_availability_status_enum(int value) { + + Ms_availability_status_enum(int value) { this.value = (byte)value; } @@ -1694,7 +1698,8 @@ public enum Network_error_code_type { RESERVED(9); protected byte value; - private Network_error_code_type(int value) { + + Network_error_code_type(int value) { this.value = (byte)value; } @@ -1791,7 +1796,8 @@ public enum Delivery_failure_reason_enum { RESERVED(4); protected byte value; - private Delivery_failure_reason_enum(int value) { + + Delivery_failure_reason_enum(int value) { this.value = (byte)value; } @@ -1854,7 +1860,8 @@ public enum More_messages_to_send_enum { RESERVED(2); protected byte value; - private More_messages_to_send_enum(int value) { + + More_messages_to_send_enum(int value) { this.value = (byte)value; } @@ -1914,8 +1921,8 @@ public enum Message_state_enum { REJECTED(8); private byte value; - - private Message_state_enum(int value) { + + Message_state_enum(int value) { this.value = (byte)value; } @@ -2265,7 +2272,7 @@ public enum Tag { private final short code; final Class type; - private Tag(int code, Class type) { + Tag(int code, Class type) { this.code = (short)code; this.type = type; } diff --git a/pom.xml b/pom.xml index 01c51c5..26175dd 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.jsmpp jsmpp-pom - 2.2.5-SNAPSHOT + 2.3.0 pom jSMPP - Parent From bb9f9911d1a1c6368d79c029e7d6ce5006708bb2 Mon Sep 17 00:00:00 2001 From: vkosharskyi Date: Fri, 16 Sep 2016 22:49:06 +0300 Subject: [PATCH 159/212] Update DeliveryReceiptState.java Fix for java.lang.IllegalArgumentException: No enum constant org.jsmpp.util.DeliveryReceiptState.ENROUTE: Added ENROUTE state --- jsmpp/src/main/java/org/jsmpp/util/DeliveryReceiptState.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/jsmpp/src/main/java/org/jsmpp/util/DeliveryReceiptState.java b/jsmpp/src/main/java/org/jsmpp/util/DeliveryReceiptState.java index e5beed6..72d06f6 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/DeliveryReceiptState.java +++ b/jsmpp/src/main/java/org/jsmpp/util/DeliveryReceiptState.java @@ -21,6 +21,10 @@ * */ public enum DeliveryReceiptState { + /** + * ENROUTE + */ + ENROUTE(0), /** * DELIVERED */ From 1b4e458cbe9ccad9af527295d30e92ead640ff56 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Mon, 26 Sep 2016 15:55:41 +0200 Subject: [PATCH 160/212] Allow replace_sm for state OUTBOUND_TRX (allowed in SMPP 5.0) --- CHANGES.txt | 3 +++ jsmpp-examples/pom.xml | 2 +- jsmpp/pom.xml | 2 +- jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java | 2 +- pom.xml | 2 +- 5 files changed, 7 insertions(+), 4 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index fa603ad..355b8ab 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,8 @@ Changes: +2.3.1 +- Allow replace_sm for state OUTBOUND_TRX + 2.3.0 - Add outbind processing diff --git a/jsmpp-examples/pom.xml b/jsmpp-examples/pom.xml index b220231..d733f7e 100644 --- a/jsmpp-examples/pom.xml +++ b/jsmpp-examples/pom.xml @@ -3,7 +3,7 @@ jsmpp-pom org.jsmpp - 2.3.0 + 2.3.1-SNAPSHOT 4.0.0 diff --git a/jsmpp/pom.xml b/jsmpp/pom.xml index 31591f6..702403d 100644 --- a/jsmpp/pom.xml +++ b/jsmpp/pom.xml @@ -3,7 +3,7 @@ org.jsmpp jsmpp-pom - 2.3.0 + 2.3.1-SNAPSHOT 4.0.0 bundle diff --git a/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java b/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java index b27ce6d..7b97351 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java @@ -397,7 +397,7 @@ public void replaceShortMessage(String messageId, ResponseTimeoutException, InvalidResponseException, NegativeResponseException, IOException { - ensureTransmittable("replaceShortMessage", true); + ensureTransmittable("replaceShortMessage"); ReplaceSmCommandTask replaceSmTask = new ReplaceSmCommandTask( pduSender(), messageId, sourceAddrTon, sourceAddrNpi, diff --git a/pom.xml b/pom.xml index 26175dd..7f3650c 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.jsmpp jsmpp-pom - 2.3.0 + 2.3.1-SNAPSHOT pom jSMPP - Parent From 4251dc13e07af0b95674d87fae24ba5385dbf590 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Mon, 26 Sep 2016 16:13:09 +0200 Subject: [PATCH 161/212] Fix Java doc annotations --- jsmpp/src/main/java/org/jsmpp/bean/DataCodingFactory.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/DataCodingFactory.java b/jsmpp/src/main/java/org/jsmpp/bean/DataCodingFactory.java index ef0e42f..eb5c210 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/DataCodingFactory.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/DataCodingFactory.java @@ -23,13 +23,13 @@ public interface DataCodingFactory { /** * @param dataCoding - * @return + * @return true if dataCoding is recognized */ boolean isRecognized(byte dataCoding); /** * @param dataCoding - * @return + * @return new DataCoding object */ DataCoding newInstance(byte dataCoding); From 22eb9faa4abfd7db878ca59c35162b09ab31cc38 Mon Sep 17 00:00:00 2001 From: Engin Dumlu Date: Mon, 28 Nov 2016 11:30:41 +0300 Subject: [PATCH 162/212] OptionalParameter:deserialize log level changed to DEBUG. INFO makes too much noise for LOG4J when delivery report has unknown tag --- jsmpp/src/main/java/org/jsmpp/bean/OptionalParameters.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameters.java b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameters.java index 234bdce..7e9fd05 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameters.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameters.java @@ -110,7 +110,7 @@ public static OptionalParameter.Byte newSarTotalSegments(int value) { public static OptionalParameter deserialize(short tagCode, byte[] content) { Tag tag = Tag.valueOf(tagCode); if (tag == null) { - logger.info("Optional Parameter Tag not recognized for deserialization: {}", tagCode); + logger.debug("Optional Parameter Tag not recognized for deserialization: {}", tagCode); return new OctetString(tagCode, content); } From 9926681a4b3e6fd31467ffd3d2bb49b9608feda4 Mon Sep 17 00:00:00 2001 From: Engin Dumlu Date: Mon, 28 Nov 2016 17:53:57 +0300 Subject: [PATCH 163/212] Some SMSC supports seconds precision in submit and done date --- .../java/org/jsmpp/bean/DeliveryReceipt.java | 6 ++++- .../jsmpp/util/DeliveryReceiptParserTest.java | 24 ++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java b/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java index 0ecd3bb..42714d3 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java @@ -418,8 +418,12 @@ private static Date string2Date(String date) { int day = Integer.parseInt(date.substring(4, 6)); int hour = Integer.parseInt(date.substring(6, 8)); int minute = Integer.parseInt(date.substring(8, 10)); + int second = 0; + if (date.length() >= 12){ + second = Integer.parseInt(date.substring(10, 12)); + } Calendar cal = Calendar.getInstance(); - cal.set(convertTwoDigitYear(year), month - 1, day, hour, minute, 0); + cal.set(convertTwoDigitYear(year), month - 1, day, hour, minute, second); cal.set(Calendar.MILLISECOND, 0); return cal.getTime(); } diff --git a/jsmpp/src/test/java/org/jsmpp/util/DeliveryReceiptParserTest.java b/jsmpp/src/test/java/org/jsmpp/util/DeliveryReceiptParserTest.java index 1cf88ef..ff92ed7 100644 --- a/jsmpp/src/test/java/org/jsmpp/util/DeliveryReceiptParserTest.java +++ b/jsmpp/src/test/java/org/jsmpp/util/DeliveryReceiptParserTest.java @@ -71,10 +71,32 @@ public void parseWithNoTextAttribute() { fail("Failed parsing delivery receipt:" + e.getMessage()); } } + + @Test + public void parseWithSecondInDate() { + try { + DeliveryReceipt delReceipt = decomposer.deliveryReceipt("id:0123456789 sub:001 dlvrd:001 submit date:080901113012 done date:080901113147 stat:DELIVRD err:000 " + ORIGINAL_MESSAGE); + assertEquals(delReceipt.getText(), null); + + Date submitDate = delReceipt.getSubmitDate(); + Date expectedSubmitDate = createDate(2008, 9, 1, 11, 30, 12); + assertEquals(submitDate, expectedSubmitDate); + + Date doneDate = delReceipt.getDoneDate(); + Date expectedDoneDate = createDate(2008, 9, 1, 11, 31, 47); + assertEquals(doneDate, expectedDoneDate); + } catch (InvalidDeliveryReceiptException e) { + e.printStackTrace(); + fail("Failed parsing delivery receipt:" + e.getMessage()); + } + } private static Date createDate(int year, int month, int day, int hour, int minute) { + return createDate(year, month, day, hour, minute, 0); + } + private static Date createDate(int year, int month, int day, int hour, int minute, int second) { Calendar cal = Calendar.getInstance(); - cal.set(year, month - 1, day, hour, minute, 0); + cal.set(year, month - 1, day, hour, minute, second); cal.set(Calendar.MILLISECOND, 0); return cal.getTime(); } From 0c7138677542c28b5ca1bba5b3727633d6d7f688 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Mon, 5 Dec 2016 00:03:19 +0100 Subject: [PATCH 164/212] Add SMPP 5.0 message_state values --- jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java index 1ab0a52..3b95384 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/OptionalParameter.java @@ -1911,6 +1911,7 @@ public static class Message_state extends OptionalParameter.Byte { * */ public enum Message_state_enum { + SCHEDULED(0), ENROUTE(1), DELIVERED(2), EXPIRED(3), @@ -1918,7 +1919,8 @@ public enum Message_state_enum { UNDELIVERABLE(5), ACCEPTED(6), UNKNOWN(7), - REJECTED(8); + REJECTED(8), + SKIPPED(9); private byte value; @@ -1997,7 +1999,6 @@ public static class Billing_identification extends OptionalParameter.OctetString public Billing_identification(byte[] value) { super(Tag.BILLING_IDENTIFICATION.code, value); } - } From 9b4150743802fb50faf7a8aba9cd9fba8c360c45 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Mon, 5 Dec 2016 00:04:37 +0100 Subject: [PATCH 165/212] Prepare for 2.3.2 release --- CHANGES.txt | 7 +++++++ jsmpp-examples/pom.xml | 2 +- jsmpp/pom.xml | 2 +- pom.xml | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 355b8ab..972d5b4 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,12 @@ Changes: +2.3.2 +- Process optional seconds in delivery receipt +- Change log level for not recognized optional parameter +- Allow replace_sm in state OUTBOUND_TRX (as it is allowed in SMPP 5.0) +- Add ENROUTE inf DeliveryReceiptState enum +- Add SCHEDULED and SKIPPED (SMPP 5.0) message_state + 2.3.1 - Allow replace_sm for state OUTBOUND_TRX diff --git a/jsmpp-examples/pom.xml b/jsmpp-examples/pom.xml index d733f7e..f896506 100644 --- a/jsmpp-examples/pom.xml +++ b/jsmpp-examples/pom.xml @@ -3,7 +3,7 @@ jsmpp-pom org.jsmpp - 2.3.1-SNAPSHOT + 2.3.2 4.0.0 diff --git a/jsmpp/pom.xml b/jsmpp/pom.xml index 702403d..a1be082 100644 --- a/jsmpp/pom.xml +++ b/jsmpp/pom.xml @@ -3,7 +3,7 @@ org.jsmpp jsmpp-pom - 2.3.1-SNAPSHOT + 2.3.2 4.0.0 bundle diff --git a/pom.xml b/pom.xml index 7f3650c..4942497 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.jsmpp jsmpp-pom - 2.3.1-SNAPSHOT + 2.3.2 pom jSMPP - Parent From eac80074a0bb1fa127cc76acf0ba7865df6f2907 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Mon, 5 Dec 2016 00:21:12 +0100 Subject: [PATCH 166/212] Fix typo. --- CHANGES.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index 972d5b4..39a6de1 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -4,7 +4,7 @@ Changes: - Process optional seconds in delivery receipt - Change log level for not recognized optional parameter - Allow replace_sm in state OUTBOUND_TRX (as it is allowed in SMPP 5.0) -- Add ENROUTE inf DeliveryReceiptState enum +- Add ENROUTE in DeliveryReceiptState enum - Add SCHEDULED and SKIPPED (SMPP 5.0) message_state 2.3.1 From 92be910d858efc19160146ae4f81c474f918c420 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 11 Dec 2016 21:23:53 +0100 Subject: [PATCH 167/212] Update the version to 2.3.3-SNAPSHOT --- README.md | 2 +- jsmpp-examples/pom.xml | 2 +- jsmpp/pom.xml | 2 +- pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9a2db6a..3ff6465 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ It is now a community project maintained at http://jsmpp.org Release procedure ----------------- - mvn deploy -DperformRelease=true -Durl=https://oss.sonatype.org/service/local/staging/deploy/maven2/ -DrepositoryId=sonatype-nexus-staging + mvn deploy -DperformRelease=true -Durl=https://oss.sonatype.org/service/local/staging/deploy/maven2/ -DrepositoryId=sonatype-nexus-staging -Dgpg.passphrase=\ * log in here: https://oss.sonatype.org * click the 'Staging Repositories' link diff --git a/jsmpp-examples/pom.xml b/jsmpp-examples/pom.xml index f896506..1711092 100644 --- a/jsmpp-examples/pom.xml +++ b/jsmpp-examples/pom.xml @@ -3,7 +3,7 @@ jsmpp-pom org.jsmpp - 2.3.2 + 2.3.3-SNAPSHOT 4.0.0 diff --git a/jsmpp/pom.xml b/jsmpp/pom.xml index a1be082..fe5f8c1 100644 --- a/jsmpp/pom.xml +++ b/jsmpp/pom.xml @@ -3,7 +3,7 @@ org.jsmpp jsmpp-pom - 2.3.2 + 2.3.3-SNAPSHOT 4.0.0 bundle diff --git a/pom.xml b/pom.xml index 4942497..9d2e638 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.jsmpp jsmpp-pom - 2.3.2 + 2.3.3-SNAPSHOT pom jSMPP - Parent From bb11d4dc766dd4974b44a6bc2ebd7725c20a5265 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Mon, 12 Dec 2016 00:33:49 +0100 Subject: [PATCH 168/212] Interrupt the enquireLinkSender thread before join, for Apache Camel to not block and some minor log changes. --- .../org/jsmpp/session/AbstractSession.java | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java index ee224c8..84865d8 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java @@ -213,15 +213,14 @@ public void close() { // Make sure the enquireLinkThread doesn't wait for itself if (Thread.currentThread() != enquireLinkSender) { - logger.info("Closing enquireLinkSender for session {}", enquireLinkSender, sessionId); + logger.debug("Closing enquireLinkSender for session {}", sessionId); if (enquireLinkSender != null) { - while(enquireLinkSender.isAlive()) { - try { - enquireLinkSender.join(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - logger.warn("Interrupted while waiting for enquireLinkSender thread to exit"); - } + enquireLinkSender.interrupt(); + try { + enquireLinkSender.join(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + logger.warn("Interrupted while waiting for enquireLinkSender thread to exit"); } } } @@ -474,14 +473,14 @@ public void run() { try { sendEnquireLink(); } catch (ResponseTimeoutException e) { - logger.error("EnquireLinkSender.run() ResponseTimeoutException", e); + logger.error("Response timeout on enquireLink", e); close(); } catch (InvalidResponseException e) { - logger.error("EnquireLinkSender.run() InvalidResponseException", e); + logger.error("Invalid response on enquireLink", e); // lets unbind gracefully unbindAndClose(); } catch (IOException e) { - logger.error("EnquireLinkSender.run() IOException", e); + logger.error("I/O exception on enquireLink", e); close(); } } From aa94239b5e8d8ae04cca133e4e40a525d665e26a Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Tue, 13 Dec 2016 00:14:32 +0100 Subject: [PATCH 169/212] Set synchronized for the close method and modified the stopping of the EnquireLinkSender, to fix deadlock in Apache Camel. --- .../org/jsmpp/session/AbstractSession.java | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java index 84865d8..65c35a6 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java @@ -200,23 +200,24 @@ public DataSmResult dataShortMessage(String serviceType, return new DataSmResult(resp.getMessageId(), resp.getOptionalParameters()); } - public void close() { + public synchronized void close() { logger.debug("Close session {}", sessionId); SessionContext ctx = sessionContext(); - if (!ctx.getSessionState().equals(SessionState.CLOSED)) { - ctx.close(); + SessionState sessionState = ctx.getSessionState(); + if (!sessionState.equals(SessionState.CLOSED)) { try { connection().close(); } catch (IOException e) { + logger.warn("Failed to close connection: {}", e.getMessage()); } } // Make sure the enquireLinkThread doesn't wait for itself if (Thread.currentThread() != enquireLinkSender) { - logger.debug("Closing enquireLinkSender for session {}", sessionId); + logger.debug("Stop enquireLinkSender for session {}", sessionId); if (enquireLinkSender != null) { - enquireLinkSender.interrupt(); try { + enquireLinkSender.interrupt(); enquireLinkSender.join(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); @@ -225,6 +226,11 @@ public void close() { } } + if (!sessionState.equals(SessionState.CLOSED)) { + logger.debug("Close session context {} in state {}", sessionId, sessionState); + ctx.close(); + } + logger.debug("Session {} is closed and enquireLinkSender stopped", sessionId); } @@ -457,17 +463,17 @@ public EnquireLinkSender() public void run() { logger.info("Starting EnquireLinkSender for session {}", sessionId); while (isReadPdu()) { - while (!sendingEnquireLink.compareAndSet(true, false) && isReadPdu()) { + while (!sendingEnquireLink.compareAndSet(true, false) && !Thread.currentThread().isInterrupted() && isReadPdu()) { synchronized (sendingEnquireLink) { try { sendingEnquireLink.wait(500); } catch (InterruptedException e) { Thread.currentThread().interrupt(); - throw new RuntimeException("Interrupted"); + break; } } } - if (!isReadPdu()) { + if (Thread.currentThread().isInterrupted() || !isReadPdu()) { break; } try { From 4adf074b4b24400d76e7c65ce38000f7b6407eb2 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Tue, 13 Dec 2016 08:14:30 +0100 Subject: [PATCH 170/212] Update Maven plugin and OSS parent versions. --- pom.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 9d2e638..f2bc7dd 100644 --- a/pom.xml +++ b/pom.xml @@ -106,7 +106,7 @@ org.sonatype.oss oss-parent - 7 + 9 @@ -114,19 +114,19 @@ org.apache.maven.wagon wagon-ssh - 2.8 + 2.10 org.apache.maven.wagon wagon-ssh-external - 2.8 + 2.10 org.apache.maven.plugins maven-compiler-plugin - 3.5.1 + 3.6.0 1.6 1.6 @@ -148,7 +148,7 @@ org.apache.felix maven-bundle-plugin - 2.5.4 + 3.2.0 maven-source-plugin From 84e1a98bbb67d155c76eb3984c31638a44f9d7ac Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Tue, 13 Dec 2016 08:17:32 +0100 Subject: [PATCH 171/212] Revert Felix plugin to JDK6 compatible. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f2bc7dd..f036863 100644 --- a/pom.xml +++ b/pom.xml @@ -148,7 +148,7 @@ org.apache.felix maven-bundle-plugin - 3.2.0 + 2.5.4 maven-source-plugin From 83dfa846c1149465f6878cc88ba2b088e541342b Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Wed, 14 Dec 2016 23:30:28 +0100 Subject: [PATCH 172/212] Minor log change and set enquireLinkSender to null after join. --- jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java index 65c35a6..a2389d8 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java @@ -214,11 +214,12 @@ public synchronized void close() { // Make sure the enquireLinkThread doesn't wait for itself if (Thread.currentThread() != enquireLinkSender) { - logger.debug("Stop enquireLinkSender for session {}", sessionId); if (enquireLinkSender != null) { + logger.debug("Stop enquireLinkSender for session {}", sessionId); try { enquireLinkSender.interrupt(); enquireLinkSender.join(); + enquireLinkSender = null; } catch (InterruptedException e) { Thread.currentThread().interrupt(); logger.warn("Interrupted while waiting for enquireLinkSender thread to exit"); @@ -230,8 +231,6 @@ public synchronized void close() { logger.debug("Close session context {} in state {}", sessionId, sessionState); ctx.close(); } - - logger.debug("Session {} is closed and enquireLinkSender stopped", sessionId); } /** From 5328c1367ab191c7b5f411a477f647783426dd02 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Wed, 14 Dec 2016 23:33:45 +0100 Subject: [PATCH 173/212] Prepare for 2.3.3 release --- CHANGES.txt | 3 +++ jsmpp-examples/pom.xml | 2 +- jsmpp/pom.xml | 2 +- pom.xml | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 39a6de1..f9cdc8e 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,8 @@ Changes: +2.3.3 +- Change the close of session method, to fix deadlock in Apache Camel SMPP component + 2.3.2 - Process optional seconds in delivery receipt - Change log level for not recognized optional parameter diff --git a/jsmpp-examples/pom.xml b/jsmpp-examples/pom.xml index 1711092..8cd9a7e 100644 --- a/jsmpp-examples/pom.xml +++ b/jsmpp-examples/pom.xml @@ -3,7 +3,7 @@ jsmpp-pom org.jsmpp - 2.3.3-SNAPSHOT + 2.3.3 4.0.0 diff --git a/jsmpp/pom.xml b/jsmpp/pom.xml index fe5f8c1..697ba57 100644 --- a/jsmpp/pom.xml +++ b/jsmpp/pom.xml @@ -3,7 +3,7 @@ org.jsmpp jsmpp-pom - 2.3.3-SNAPSHOT + 2.3.3 4.0.0 bundle diff --git a/pom.xml b/pom.xml index f036863..7c7eedf 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.jsmpp jsmpp-pom - 2.3.3-SNAPSHOT + 2.3.3 pom jSMPP - Parent From cae4a557e02a2c0a037e4357c44ac635bddc75f8 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Wed, 14 Dec 2016 23:51:00 +0100 Subject: [PATCH 174/212] Fix Javadoc errors --- .../src/main/java/org/jsmpp/SMPPConstant.java | 16 +++++++------- .../org/jsmpp/bean/AbstractSmCommand.java | 21 ++++++++----------- .../org/jsmpp/bean/DataCodingFactory.java | 4 ++-- .../org/jsmpp/session/AbstractSession.java | 4 ---- 4 files changed, 19 insertions(+), 26 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/SMPPConstant.java b/jsmpp/src/main/java/org/jsmpp/SMPPConstant.java index ec741a6..87a31e5 100644 --- a/jsmpp/src/main/java/org/jsmpp/SMPPConstant.java +++ b/jsmpp/src/main/java/org/jsmpp/SMPPConstant.java @@ -199,49 +199,49 @@ public interface SMPPConstant { public static final byte ESMCLS_ESME_MANUAL_ACK = 0x10; /** - * Encoded esm_class parameter for deliver_sm or data_sm (SMSC -> ESME)
    + * Encoded esm_class parameter for deliver_sm or data_sm (SMSC -> ESME) * xx0001xx Short Message contains SMSC Delivery Receipt. */ public static final byte ESMCLS_SMSC_DELIV_RECEIPT = 0x04; /** - * Encoded esm_class parameter for deliver_sm or data_sm (SMSC -> ESME)
    + * Encoded esm_class parameter for deliver_sm or data_sm (SMSC -> ESME) * xx0001xx Short Message contains SME Delivery Acknowledgment. */ public static final byte ESMCLS_SME_DELIV_ACK = 0x08; /** - * Encoded esm_class parameter for deliver_sm or data_sm (SMSC -> ESME)
    + * Encoded esm_class parameter for deliver_sm or data_sm (SMSC -> ESME) * xx0100xx Short Message contains SME Manual/User Acknowledgment. */ public static final byte ESMCLS_SME_MANUAL_ACK = 0x10; /** - * Encoded esm_class parameter for deliver_sm or data_sm (SMSC -> ESME)
    + * Encoded esm_class parameter for deliver_sm or data_sm (SMSC -> ESME) * xx0110xx Short Message contains Conversation Abort (Korean CDMA). */ public static final byte ESMCLS_CONV_ABORT = 0x18; /** - * Encoded esm_class parameter for deliver_sm or data_sm (SMSC -> ESME)
    + * Encoded esm_class parameter for deliver_sm or data_sm (SMSC -> ESME) * xx1000xx Short Message contains Intermediate Delivery Notification. */ public static final byte ESMCLS_INTRMD_DELIV_NOTIF = 0x20; /** - * Encoded esm_class parameter for deliver_sm or data_sm (SMSC -> ESME)
    + * Encoded esm_class parameter for deliver_sm or data_sm (SMSC -> ESME) * 01xxxxxx UDHI Indicator set. */ public static final byte ESMCLS_UDHI_INDICATOR_SET = 0x40; /** - * Encoded esm_class parameter for deliver_sm or data_sm (SMSC -> ESME)
    + * Encoded esm_class parameter for deliver_sm or data_sm (SMSC -> ESME) * 10xxxxxx Reply Path. */ public static final byte ESMCLS_REPLY_PATH = (byte)0x80; /** - * Encoded esm_class parameter for deliver_sm or data_sm (SMSC -> ESME)
    + * Encoded esm_class parameter for deliver_sm or data_sm (SMSC -> ESME) * 11xxxxxx UDHI and Reply Path can use. */ public static final byte ESMCLS_UDHI_REPLY_PATH = (byte)0xc0; diff --git a/jsmpp/src/main/java/org/jsmpp/bean/AbstractSmCommand.java b/jsmpp/src/main/java/org/jsmpp/bean/AbstractSmCommand.java index 04f914f..2f66063 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/AbstractSmCommand.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/AbstractSmCommand.java @@ -45,7 +45,7 @@ public AbstractSmCommand() { /** * Message Type. * - * @return + * @return if the esmClass is the default message type (00) */ public boolean isDefaultMessageType() { return isDefaultMessageType(esmClass); @@ -61,7 +61,7 @@ public void setDefaultMessageType() { /** * Specific Features. * - * @return + * @return if the esmClass contains the User Data Header Indicator */ public boolean isUdhi() { return isUdhi(esmClass); @@ -289,7 +289,7 @@ public static boolean isReplyPath(byte esmClass) { * Specific Features. * * @param esmClass - * @return + * @return the esmClass with Reply Path */ public static byte composeReplyPath(byte esmClass) { return composeSpecificFeatures(esmClass, SMPPConstant.ESMCLS_REPLY_PATH); @@ -299,7 +299,7 @@ public static byte composeReplyPath(byte esmClass) { * Specific Features. * * @param esmClass - * @return + * @return if the esmClass has User Data Header Indicator and Reply Path */ public static boolean isUdhiAndReplyPath(byte esmClass) { return isSpecificFeatures(esmClass, SMPPConstant.ESMCLS_UDHI_REPLY_PATH); @@ -309,7 +309,7 @@ public static boolean isUdhiAndReplyPath(byte esmClass) { * Specific Features. * * @param esmClass - * @return + * @return the esmClass with User Data Header Indicator and Reply Path */ public static byte composeUdhiAndReplyPath(byte esmClass) { return composeSpecificFeatures(esmClass, @@ -342,7 +342,7 @@ protected final static byte composeMessagingMode(byte esmClass, * Clean the Messaging Mode or clean the ESM Class at bits 1 - 0. * * @param esmClass - * @return + * @return the esmClass without the Messaging Mode bits */ protected final static byte cleanMessagingMode(byte esmClass) { /* @@ -453,20 +453,17 @@ protected static final byte cleanSmscDeliveryReceipt(byte registeredDelivery) { return (byte)(registeredDelivery & 0x0fc); } - /* - * SME originated Acknowledgement. - */ /** * SME originated Acknowledgement. * - * @param registeredDeliery + * @param registeredDelivery * @param smeOriginatedAckValue * @return */ - protected static final boolean isSmeAck(byte registeredDeliery, + protected static final boolean isSmeAck(byte registeredDelivery, byte smeOriginatedAckValue) { // xxxx11xx = 0x0c mask bits 3 - 2 - return (registeredDeliery & 0x0c) == smeOriginatedAckValue; + return (registeredDelivery & 0x0c) == smeOriginatedAckValue; } protected static final byte composeSmeAck(byte registeredDelivery, diff --git a/jsmpp/src/main/java/org/jsmpp/bean/DataCodingFactory.java b/jsmpp/src/main/java/org/jsmpp/bean/DataCodingFactory.java index eb5c210..d23710f 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/DataCodingFactory.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/DataCodingFactory.java @@ -22,13 +22,13 @@ public interface DataCodingFactory { /** - * @param dataCoding + * @param dataCoding The data coding scheme * @return true if dataCoding is recognized */ boolean isRecognized(byte dataCoding); /** - * @param dataCoding + * @param dataCoding The data coding scheme * @return new DataCoding object */ DataCoding newInstance(byte dataCoding); diff --git a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java index a2389d8..d4bd4a2 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java @@ -312,11 +312,7 @@ protected Command executeSendCommand(SendCommandTask task, long timeout) * Execute send command command task. * * @param task is the task. - * @return the command response. * @throws PDUException if there is invalid PDU parameter found. - * @throws ResponseTimeoutException if the response has reach it timeout. - * @throws InvalidResponseException if invalid response found. - * @throws NegativeResponseException if the negative response found. * @throws IOException if there is an IO error found. */ protected void executeSendCommandWithNoResponse(SendCommandTask task) From 4ea1d26fb41458b9109542d5d0aa2fa7e7fbb6f8 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sat, 14 Jan 2017 18:56:37 +0100 Subject: [PATCH 175/212] Lower log level for enquiry starting message --- jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java index d4bd4a2..1a47a25 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java @@ -456,7 +456,7 @@ public EnquireLinkSender() @Override public void run() { - logger.info("Starting EnquireLinkSender for session {}", sessionId); + logger.debug("Starting EnquireLinkSender for session {}", sessionId); while (isReadPdu()) { while (!sendingEnquireLink.compareAndSet(true, false) && !Thread.currentThread().isInterrupted() && isReadPdu()) { synchronized (sendingEnquireLink) { From d16ec39021b95e7ae1e5be6c7ab34d4de4eea693 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sat, 14 Jan 2017 21:27:35 +0100 Subject: [PATCH 176/212] Add stress/logs/ to be ignored by Git. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 771dd6a..48e6a2b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ target/ out/ classes/ +stress/logs/ syntax:glob *.swp From 9aeb3abf6af9d0fcde3ea214e8fe912371ff70a9 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sat, 14 Jan 2017 21:52:13 +0100 Subject: [PATCH 177/212] Add out-commented Log4j configuration for file appender --- stress/client-log4j.properties | 1 + stress/server-log4j.properties | 1 + 2 files changed, 2 insertions(+) diff --git a/stress/client-log4j.properties b/stress/client-log4j.properties index 7a34441..21c2dcf 100644 --- a/stress/client-log4j.properties +++ b/stress/client-log4j.properties @@ -1,4 +1,5 @@ log4j.rootLogger=INFO, STDOUT +# log4j.rootLogger=INFO, STDOUT, FILE log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout diff --git a/stress/server-log4j.properties b/stress/server-log4j.properties index fc801e2..13fd3ae 100644 --- a/stress/server-log4j.properties +++ b/stress/server-log4j.properties @@ -1,4 +1,5 @@ log4j.rootLogger=INFO, STDOUT +# log4j.rootLogger=INFO, STDOUT, FILE log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout From 90970a2798390678dd5d27b87e3f627b10fe47d2 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sat, 14 Jan 2017 21:58:50 +0100 Subject: [PATCH 178/212] Added standard Log4j appender to stdout for examples. --- jsmpp-examples/src/main/resources/log4j.properties | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 jsmpp-examples/src/main/resources/log4j.properties diff --git a/jsmpp-examples/src/main/resources/log4j.properties b/jsmpp-examples/src/main/resources/log4j.properties new file mode 100644 index 0000000..720ca29 --- /dev/null +++ b/jsmpp-examples/src/main/resources/log4j.properties @@ -0,0 +1,6 @@ +log4j.rootLogger=INFO, STDOUT + +log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender +log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout +# Pattern to output the caller's file name and line number. +log4j.appender.STDOUT.layout.ConversionPattern=%d [%t] %-5p %c - %m%n From 868ef9a2ee278ed8ebff318194d106a6ba54574e Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sat, 14 Jan 2017 22:09:26 +0100 Subject: [PATCH 179/212] Update to 2.3.4, use slf4j-simple for test, use slf4j-api in examples, with log4j as slf4j log implementation. --- jsmpp-examples/pom.xml | 6 +++--- jsmpp/pom.xml | 7 ++++++- pom.xml | 4 ++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/jsmpp-examples/pom.xml b/jsmpp-examples/pom.xml index 8cd9a7e..be53933 100644 --- a/jsmpp-examples/pom.xml +++ b/jsmpp-examples/pom.xml @@ -3,7 +3,7 @@ jsmpp-pom org.jsmpp - 2.3.3 + 2.3.4 4.0.0 @@ -19,8 +19,8 @@
    org.slf4j - slf4j-simple - compile + slf4j-log4j12 + ${slf4j.version} log4j diff --git a/jsmpp/pom.xml b/jsmpp/pom.xml index 697ba57..514285a 100644 --- a/jsmpp/pom.xml +++ b/jsmpp/pom.xml @@ -3,7 +3,7 @@ org.jsmpp jsmpp-pom - 2.3.3 + 2.3.4 4.0.0 bundle @@ -25,6 +25,11 @@ testng test + + org.slf4j + slf4j-simple + test + diff --git a/pom.xml b/pom.xml index 7c7eedf..89c35bd 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.jsmpp jsmpp-pom - 2.3.3 + 2.3.4 pom jSMPP - Parent @@ -46,7 +46,7 @@ yyyyMMddHHmm ${maven.build.timestamp} UTF-8 - 1.7.21 + 1.7.22 1.2.17 4.12 6.8.21 From 5fc2bc652d325b3bd38226d3c6ececb9eaa884c8 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sat, 14 Jan 2017 22:10:33 +0100 Subject: [PATCH 180/212] Update examples to use slf4j-api. --- .../AcceptingConnectionAndBindExample.java | 29 ++- .../AsyncSubmitReceiveDeliverSmExample.java | 40 ++-- .../examples/MessageReceiverListenerImpl.java | 20 +- .../jsmpp/examples/OpenAndBindExample.java | 13 +- .../ReceiveSubmittedMessageExample.java | 40 ++-- .../examples/SMPPOutboundServerSimulator.java | 30 ++- .../jsmpp/examples/SMPPServerSimulator.java | 172 ++++++++++-------- .../jsmpp/examples/SimpleSubmitExample.java | 68 +++---- .../SimpleSubmitRegisteredExample.java | 81 +++++---- .../SimpleSubmitSimpleReceiveExample.java | 145 +++++++-------- .../java/org/jsmpp/examples/StressClient.java | 55 +++--- .../java/org/jsmpp/examples/StressServer.java | 66 ++++--- .../examples/SubmitLongMessageExample.java | 58 +++--- .../jsmpp/examples/SubmitMultiExample.java | 81 ++++----- .../SubmitMultipartMultilangualExample.java | 34 ++-- .../gateway/AutoReconnectGateway.java | 16 +- .../src/main/java/org/jsmpp/SMPPConstant.java | 1 - 17 files changed, 480 insertions(+), 469 deletions(-) diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/AcceptingConnectionAndBindExample.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/AcceptingConnectionAndBindExample.java index c546fcc..7f7c687 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/AcceptingConnectionAndBindExample.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/AcceptingConnectionAndBindExample.java @@ -17,61 +17,60 @@ import java.io.IOException; import java.util.concurrent.TimeoutException; -import org.apache.log4j.BasicConfigurator; import org.jsmpp.PDUStringException; import org.jsmpp.SMPPConstant; import org.jsmpp.session.BindRequest; import org.jsmpp.session.SMPPServerSession; import org.jsmpp.session.SMPPServerSessionListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @author uudashr * */ public class AcceptingConnectionAndBindExample { + private static final Logger LOGGER = LoggerFactory.getLogger(AcceptingConnectionAndBindExample.class); public static void main(String[] args) { - BasicConfigurator.configure(); try { - System.out.println("Listening ..."); + LOGGER.info("Listening ..."); SMPPServerSessionListener sessionListener = new SMPPServerSessionListener(8056); // accepting connection, session still in OPEN state SMPPServerSession session = sessionListener.accept(); - System.out.println("Accept connection"); + LOGGER.info("Accept connection"); try { BindRequest request = session.waitForBind(5000); - System.out.println("Receive bind request"); + LOGGER.info("Receive bind request"); if ("test".equals(request.getSystemId()) && "test".equals(request.getPassword())) { - + // accepting request and send bind response immediately - System.out.println("Accepting bind request, interface version is " + request.getInterfaceVersion()); + LOGGER.info("Accepting bind request, interface version is " + request.getInterfaceVersion()); request.accept("sys"); try { Thread.sleep(20000); } catch (InterruptedException e) {} } else { - System.out.println("Rejecting bind request"); + LOGGER.info("Rejecting bind request"); request.reject(SMPPConstant.STAT_ESME_RINVPASWD); } } catch (TimeoutException e) { - System.out.println("No binding request made after 5000 millisecond"); - e.printStackTrace(); + LOGGER.error("No binding request made after 5000 millisecond", e); } - if (session.getSessionState().isBound()) { - System.out.println("Closing session"); + LOGGER.info("Closing session"); session.unbindAndClose(); } - System.out.println("Closing session listener"); + LOGGER.info("Closing session listener"); sessionListener.close(); } catch (PDUStringException e) { - e.printStackTrace(); + LOGGER.error("PDUStringException", e); } catch (IOException e) { - e.printStackTrace(); + LOGGER.error("IOException", e); } } diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/AsyncSubmitReceiveDeliverSmExample.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/AsyncSubmitReceiveDeliverSmExample.java index 760e6d1..1d1fe01 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/AsyncSubmitReceiveDeliverSmExample.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/AsyncSubmitReceiveDeliverSmExample.java @@ -20,7 +20,6 @@ import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicInteger; -import org.apache.log4j.BasicConfigurator; import org.jsmpp.InvalidResponseException; import org.jsmpp.PDUException; import org.jsmpp.bean.AlertNotification; @@ -46,23 +45,25 @@ import org.jsmpp.util.AbsoluteTimeFormatter; import org.jsmpp.util.InvalidDeliveryReceiptException; import org.jsmpp.util.TimeFormatter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @author uudashr * */ public class AsyncSubmitReceiveDeliverSmExample { - private static TimeFormatter timeFormatter = new AbsoluteTimeFormatter(); + private static final Logger LOGGER = LoggerFactory.getLogger(AsyncSubmitReceiveDeliverSmExample.class); + private static final TimeFormatter TIME_FORMATTER = new AbsoluteTimeFormatter(); + public static void main(String[] args) { final AtomicInteger counter = new AtomicInteger(); - BasicConfigurator.configure(); final SMPPSession session = new SMPPSession(); try { session.connectAndBind("localhost", 8056, new BindParameter(BindType.BIND_TRX, "test", "test", "cp", TypeOfNumber.UNKNOWN, NumberingPlanIndicator.UNKNOWN, null)); } catch (IOException e) { - System.err.println("Failed connect and bind to host"); - e.printStackTrace(); + LOGGER.error("Failed connect and bind to host", e); } // Set listener to receive deliver_sm @@ -76,14 +77,13 @@ public void onAcceptDeliverSm(DeliverSm deliverSm) DeliveryReceipt delReceipt = deliverSm.getShortMessageAsDeliveryReceipt(); long id = Long.parseLong(delReceipt.getId()) & 0xffffffff; String messageId = Long.toString(id, 16).toUpperCase(); - System.out.println("Receiving delivery receipt for message '" + messageId + "' : " + delReceipt); + LOGGER.info("Receiving delivery receipt for message '{}' : {}", messageId, delReceipt); } catch (InvalidDeliveryReceiptException e) { - System.err.println("Failed getting delivery receipt"); - e.printStackTrace(); + LOGGER.error("Failed getting delivery receipt", e); } } else { // regular short message - System.out.println("Receiving message : " + new String(deliverSm.getShortMessage())); + LOGGER.info("Receiving message : {}", new String(deliverSm.getShortMessage())); } } @@ -110,29 +110,25 @@ public DataSmResult onAcceptDataSm(DataSm dataSm, Session source) execService.execute(new Runnable() { public void run() { try { - String messageId = session.submitShortMessage("CMT", TypeOfNumber.INTERNATIONAL, NumberingPlanIndicator.UNKNOWN, "1616", TypeOfNumber.INTERNATIONAL, NumberingPlanIndicator.UNKNOWN, "628176504657", new ESMClass(), (byte)0, (byte)1, timeFormatter.format(new Date()), null, registeredDelivery, (byte)0, DataCodings.ZERO, (byte)0, "jSMPP simplify SMPP on Java platform".getBytes()); - System.out.println("Message submitted, message_id is " + messageId); + String messageId = session.submitShortMessage("CMT", TypeOfNumber.INTERNATIONAL, NumberingPlanIndicator.UNKNOWN, "1616", TypeOfNumber.INTERNATIONAL, NumberingPlanIndicator.UNKNOWN, "628176504657", new ESMClass(), (byte)0, (byte)1, TIME_FORMATTER + .format(new Date()), null, registeredDelivery, (byte)0, DataCodings.ZERO, (byte)0, "jSMPP simplify SMPP on Java platform".getBytes()); + LOGGER.info("Message submitted, message_id is {}", messageId); } catch (PDUException e) { - System.err.println("Invalid PDU parameter"); - e.printStackTrace(); + LOGGER.error("Invalid PDU parameter", e); counter.incrementAndGet(); } catch (ResponseTimeoutException e) { - System.err.println("Response timeout"); - e.printStackTrace(); + LOGGER.error("Response timeout", e); counter.incrementAndGet(); } catch (InvalidResponseException e) { // Invalid response - System.err.println("Receive invalid respose"); - e.printStackTrace(); + LOGGER.error("Receive invalid respose", e); counter.incrementAndGet(); } catch (NegativeResponseException e) { // Receiving negative response (non-zero command_status) - System.err.println("Receive negative response"); - e.printStackTrace(); + LOGGER.error("Receive negative response", e); counter.incrementAndGet(); } catch (IOException e) { - System.err.println("IO error occur"); - e.printStackTrace(); + LOGGER.error("I/O error occured", e); counter.incrementAndGet(); } } @@ -142,7 +138,7 @@ public void run() { while (counter.get() != maxMessage) { try { Thread.sleep(1000); } catch (InterruptedException e) { - System.err.println("Interrupted"); + LOGGER.error("Interrupted"); } } session.unbindAndClose(); diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/MessageReceiverListenerImpl.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/MessageReceiverListenerImpl.java index aa5e9f5..80a6b9f 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/MessageReceiverListenerImpl.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/MessageReceiverListenerImpl.java @@ -14,6 +14,7 @@ */ package org.jsmpp.examples; +import org.jsmpp.SMPPConstant; import org.jsmpp.bean.AlertNotification; import org.jsmpp.bean.DataSm; import org.jsmpp.bean.DeliverSm; @@ -24,12 +25,17 @@ import org.jsmpp.session.MessageReceiverListener; import org.jsmpp.session.Session; import org.jsmpp.util.InvalidDeliveryReceiptException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @author uudashr * */ public class MessageReceiverListenerImpl implements MessageReceiverListener { + private static final Logger LOGGER = LoggerFactory.getLogger(MessageReceiverListenerImpl.class); + private static final String DATASM_NOT_IMPLEMENTED = "data_sm not implemented"; + public void onAcceptDeliverSm(DeliverSm deliverSm) throws ProcessRequestException { @@ -46,11 +52,11 @@ public void onAcceptDeliverSm(DeliverSm deliverSm) * you can update the status of your submitted message on the * database based on messageId */ - - System.out.println("Receiving delivery receipt for message '" + messageId + " ' from " + deliverSm.getSourceAddr() + " to " + deliverSm.getDestAddress() + " : " + delReceipt); + + LOGGER.info("Receiving delivery receipt for message '{}' from {} to {}: {}", + messageId, deliverSm.getSourceAddr(), deliverSm.getDestAddress(), delReceipt); } catch (InvalidDeliveryReceiptException e) { - System.err.println("Failed getting delivery receipt"); - e.printStackTrace(); + LOGGER.error("Failed getting delivery receipt", e); } } else { // this message is regular short message @@ -59,15 +65,17 @@ public void onAcceptDeliverSm(DeliverSm deliverSm) * you can save the incoming message to database. */ - System.out.println("Receiving message : " + new String(deliverSm.getShortMessage())); + LOGGER.info("Receiving message : {}", new String(deliverSm.getShortMessage())); } } public void onAcceptAlertNotification(AlertNotification alertNotification) { + LOGGER.info("AlertNotification not implemented"); } public DataSmResult onAcceptDataSm(DataSm dataSm, Session source) throws ProcessRequestException { - return null; + LOGGER.info("DataSm not implemented"); + throw new ProcessRequestException(DATASM_NOT_IMPLEMENTED, SMPPConstant.STAT_ESME_RINVCMDID); } } diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/OpenAndBindExample.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/OpenAndBindExample.java index 22db25f..9208363 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/OpenAndBindExample.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/OpenAndBindExample.java @@ -16,35 +16,34 @@ import java.io.IOException; -import org.apache.log4j.BasicConfigurator; import org.jsmpp.bean.BindType; import org.jsmpp.bean.NumberingPlanIndicator; import org.jsmpp.bean.TypeOfNumber; import org.jsmpp.session.BindParameter; import org.jsmpp.session.SMPPSession; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @author uudashr * */ public class OpenAndBindExample { + private static final Logger LOGGER = LoggerFactory.getLogger(OpenAndBindExample.class); public static void main(String[] args) { - BasicConfigurator.configure(); String host = "localhost"; int port = 8056; SMPPSession session = new SMPPSession(); try { - System.out.println("Connect and bind to " + host + " port " + port); + LOGGER.info("Connect and bind to {} port {}", host, port); session.connectAndBind(host, port, new BindParameter(BindType.BIND_TRX, "test", "test", "cp", TypeOfNumber.UNKNOWN, NumberingPlanIndicator.UNKNOWN, null)); } catch (IOException e) { // Failed connect and bind to SMSC - System.err.println("Failed connect and bind to host"); - e.printStackTrace(); + LOGGER.error("Failed connect and bind to host", e); } try { Thread.sleep(10000); } catch (InterruptedException e) {} session.unbindAndClose(); } - - + } diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/ReceiveSubmittedMessageExample.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/ReceiveSubmittedMessageExample.java index 3c25358..0e21c8d 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/ReceiveSubmittedMessageExample.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/ReceiveSubmittedMessageExample.java @@ -17,7 +17,6 @@ import java.io.IOException; import java.util.concurrent.TimeoutException; -import org.apache.log4j.BasicConfigurator; import org.jsmpp.PDUStringException; import org.jsmpp.SMPPConstant; import org.jsmpp.bean.CancelSm; @@ -38,27 +37,28 @@ import org.jsmpp.util.MessageIDGenerator; import org.jsmpp.util.MessageId; import org.jsmpp.util.RandomMessageIDGenerator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @author uudashr * */ public class ReceiveSubmittedMessageExample { + + private static final Logger LOGGER = LoggerFactory.getLogger(ReceiveSubmittedMessageExample.class); public static void main(String[] args) { - BasicConfigurator.configure(); try { - - + // prepare generator of Message ID final MessageIDGenerator messageIdGenerator = new RandomMessageIDGenerator(); // prepare the message receiver ServerMessageReceiverListener messageReceiverListener = new ServerMessageReceiverListener() { - public MessageId onAcceptSubmitSm(SubmitSm submitSm, - SMPPServerSession source) + public MessageId onAcceptSubmitSm(SubmitSm submitSm, SMPPServerSession source) throws ProcessRequestException { - System.out.println("Receiving message : " + new String(submitSm.getShortMessage())); + LOGGER.info("Receiving message : {}", new String(submitSm.getShortMessage())); // need message_id to response submit_sm return messageIdGenerator.newMessageId(); } @@ -91,7 +91,7 @@ public void onAcceptReplaceSm(ReplaceSm replaceSm, } }; - System.out.println("Listening ..."); + LOGGER.info("Listening ..."); SMPPServerSessionListener sessionListener = new SMPPServerSessionListener(8056); // set all default ServerMessageReceiverListener for all accepted SMPPServerSessionListener sessionListener.setMessageReceiverListener(messageReceiverListener); @@ -99,38 +99,36 @@ public void onAcceptReplaceSm(ReplaceSm replaceSm, // accepting connection, session still in OPEN state SMPPServerSession session = sessionListener.accept(); // or we can set for each accepted session session.setMessageReceiverListener(messageReceiverListener) - System.out.println("Accept connection"); + LOGGER.info("Accept connection"); try { BindRequest request = session.waitForBind(5000); - System.out.println("Receive bind request"); + LOGGER.info("Receive bind request for system id {} and password {}", request.getSystemId(), request.getSystemId(), request.getPassword()); if ("test".equals(request.getSystemId()) && "test".equals(request.getPassword())) { // accepting request and send bind response immediately - System.out.println("Accepting bind request"); + LOGGER.info("Accepting bind request"); request.accept("sys"); - - + try { Thread.sleep(20000); } catch (InterruptedException e) {} } else { - System.out.println("Rejecting bind request"); + LOGGER.info("Rejecting bind request"); request.reject(SMPPConstant.STAT_ESME_RINVPASWD); } } catch (TimeoutException e) { - System.out.println("No binding request made after 5000 millisecond"); - e.printStackTrace(); + LOGGER.error("No binding request made after 5000 millisecond", e); } - - System.out.println("Closing session"); + + LOGGER.info("Closing session"); session.unbindAndClose(); - System.out.println("Closing session listener"); + LOGGER.info("Closing session listener"); sessionListener.close(); } catch (PDUStringException e) { - e.printStackTrace(); + LOGGER.error("PDUString exception", e); } catch (IOException e) { - e.printStackTrace(); + LOGGER.error("I/O exception", e); } } } diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPOutboundServerSimulator.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPOutboundServerSimulator.java index 7e6fe85..297e199 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPOutboundServerSimulator.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPOutboundServerSimulator.java @@ -20,7 +20,6 @@ import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; -import org.apache.log4j.BasicConfigurator; import org.jsmpp.bean.BindType; import org.jsmpp.bean.DeliverSm; import org.jsmpp.bean.NumberingPlanIndicator; @@ -45,8 +44,8 @@ */ public class SMPPOutboundServerSimulator extends ServerResponseDeliveryAdapter implements Runnable, OutboundServerMessageReceiverListener { + private static final Logger LOGGER = LoggerFactory.getLogger(SMPPOutboundServerSimulator.class); private static final Integer DEFAULT_PORT = 8056; - private static final Logger logger = LoggerFactory.getLogger(SMPPOutboundServerSimulator.class); private final ExecutorService execService = Executors.newFixedThreadPool(100); private int port; @@ -64,10 +63,9 @@ public static void main(String[] args) { catch (NumberFormatException e) { port = DEFAULT_PORT; } - BasicConfigurator.configure(); SMPPOutboundServerSimulator smppServerSim = new SMPPOutboundServerSimulator(port); - logger.info("run {}", smppServerSim); + LOGGER.info("run {}", smppServerSim); smppServerSim.run(); } @@ -77,12 +75,12 @@ private void shutdown() { public void run() { try { - logger.info("Listening on port {}", port); + LOGGER.info("Listening on port {}", port); OutboundSMPPServerSessionListener sessionListener = new OutboundSMPPServerSessionListener(port); while (!exit.get()) { final SMPPOutboundServerSession outboundServerSession = sessionListener.accept(); - logger.info("Accepting connection from {} for session {}", outboundServerSession.getInetAddress(), + LOGGER.info("Accepting connection from {} for session {}", outboundServerSession.getInetAddress(), outboundServerSession.getSessionId()); outboundServerSession.setEnquireLinkTimer(30000); outboundServerSession.addSessionStateListener(new SessionStateListenerImpl()); @@ -94,24 +92,24 @@ public void run() { Thread.sleep(60 * 60 * 1000L); } catch (InterruptedException e) { - logger.info("Thread was interrupted"); + LOGGER.info("Thread was interrupted"); shutdown(); } outboundServerSession.close(); } - logger.info("close listener {}", sessionListener); + LOGGER.info("close listener {}", sessionListener); sessionListener.close(); execService.shutdown(); } catch (IOException e) { - logger.error("IO error occurred", e); + LOGGER.error("IO error occurred", e); } } public void onAcceptDeliverSm(DeliverSm deliverSm, SMPPOutboundServerSession source) throws ProcessRequestException { - logger.info("deliver_sm: {} {} => {} {}", deliverSm.getSequenceNumber(), deliverSm.getSourceAddr(), + LOGGER.info("deliver_sm: {} {} => {} {}", deliverSm.getSequenceNumber(), deliverSm.getSourceAddr(), deliverSm.getDestAddress(), new String(deliverSm.getShortMessage())); } @@ -124,29 +122,29 @@ private static class WaitOutbindTask implements Runnable { public void run() { try { - logger.info("Waiting for outbind request"); + LOGGER.info("Waiting for outbind request"); OutbindRequest outbindRequest = serverSession.waitForOutbind(15000); - logger.info("Received outbind for session {}, systemid {}, password {}", serverSession.getSessionId(), + LOGGER.info("Received outbind for session {}, systemid {}, password {}", serverSession.getSessionId(), outbindRequest.getSystemId(), outbindRequest.getPassword()); serverSession.bind(new BindParameter(BindType.BIND_TRX, "test", "test", "cp", TypeOfNumber.UNKNOWN, NumberingPlanIndicator.UNKNOWN, null), 60000); } catch (IllegalStateException e) { - logger.error("System error", e); + LOGGER.error("System error", e); } catch (TimeoutException e) { - logger.warn("Wait for outbind has reached timeout", e); + LOGGER.warn("Wait for outbind has reached timeout", e); } catch (IOException e) { - logger.warn("IO exception", e); + LOGGER.warn("IO exception", e); } } } private class SessionStateListenerImpl implements SessionStateListener { public void onStateChange(SessionState newState, SessionState oldState, Session source) { - logger.info("Session state changed from " + oldState + " to " + newState); + LOGGER.info("Session state changed from " + oldState + " to " + newState); } } diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java index ef0a76e..d7d09b0 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java @@ -20,7 +20,6 @@ import java.util.concurrent.Executors; import java.util.concurrent.TimeoutException; -import org.apache.log4j.BasicConfigurator; import org.jsmpp.PDUStringException; import org.jsmpp.SMPPConstant; import org.jsmpp.bean.CancelSm; @@ -64,61 +63,67 @@ * */ public class SMPPServerSimulator extends ServerResponseDeliveryAdapter implements Runnable, ServerMessageReceiverListener { + private static final Logger LOGGER = LoggerFactory.getLogger(SMPPServerSimulator.class); + private static final String QUERYSM_NOT_IMPLEMENTED = "query_sm not implemented"; + private static final String DATASM_NOT_IMPLEMENTED = "data_sm not implemented"; private static final Integer DEFAULT_PORT = 8056; - private static final Logger logger = LoggerFactory.getLogger(SMPPServerSimulator.class); + private static final String DEFAULT_SYSID = "j"; + private static final String DEFAULT_PASSWORD = "jpwd"; + private static final String SMSC_SYSTEMID = "sys"; private final ExecutorService execService = Executors.newFixedThreadPool(5); private final ExecutorService execServiceDelReceipt = Executors.newFixedThreadPool(100); private final MessageIDGenerator messageIDGenerator = new RandomMessageIDGenerator(); private int port; - - public SMPPServerSimulator(int port) { + private String systemId; + private String password; + + public SMPPServerSimulator(int port, String systemId, String password) { this.port = port; + this.systemId = systemId; + this.password = password; } - + public void run() { try { SMPPServerSessionListener sessionListener = new SMPPServerSessionListener(port); - - logger.info("Listening on port {}", port); + LOGGER.info("Listening on port {}", port); while (true) { SMPPServerSession serverSession = sessionListener.accept(); - logger.info("Accepting connection for session {}", serverSession.getSessionId()); + LOGGER.info("Accepting connection for session {}", serverSession.getSessionId()); serverSession.setMessageReceiverListener(this); serverSession.setResponseDeliveryListener(this); - execService.execute(new WaitBindTask(serverSession)); + execService.execute(new WaitBindTask(serverSession, systemId, password)); } } catch (IOException e) { - logger.error("IO error occurred", e); + LOGGER.error("IO error occurred", e); } } - - public QuerySmResult onAcceptQuerySm(QuerySm querySm, - SMPPServerSession source) throws ProcessRequestException { - logger.info("Accepting query_sm, but not implemented"); - return null; + + public QuerySmResult onAcceptQuerySm(QuerySm querySm, SMPPServerSession source) throws ProcessRequestException { + LOGGER.info("QuerySm not implemented"); + throw new ProcessRequestException(QUERYSM_NOT_IMPLEMENTED, SMPPConstant.STAT_ESME_RINVCMDID); } - + public MessageId onAcceptSubmitSm(SubmitSm submitSm, SMPPServerSession source) throws ProcessRequestException { MessageId messageId = messageIDGenerator.newMessageId(); - logger.debug("Receiving submit_sm '{}', and return message id {}", new String(submitSm.getShortMessage()), messageId); + LOGGER.info("Receiving submit_sm '{}', and return message id {}", new String(submitSm.getShortMessage()), messageId); if (SMSCDeliveryReceipt.FAILURE.containedIn(submitSm.getRegisteredDelivery()) || SMSCDeliveryReceipt.SUCCESS_FAILURE.containedIn(submitSm.getRegisteredDelivery())) { execServiceDelReceipt.execute(new DeliveryReceiptTask(source, submitSm, messageId)); } return messageId; } - + public void onSubmitSmRespSent(MessageId messageId, SMPPServerSession source) { - logger.debug("submit_sm_resp with message_id {} has been sent", messageId); + LOGGER.debug("submit_sm_resp with message_id {} has been sent", messageId); } - - public SubmitMultiResult onAcceptSubmitMulti(SubmitMulti submitMulti, - SMPPServerSession source) throws ProcessRequestException { + + public SubmitMultiResult onAcceptSubmitMulti(SubmitMulti submitMulti, SMPPServerSession source) + throws ProcessRequestException { MessageId messageId = messageIDGenerator.newMessageId(); - logger.debug("Receiving submit_multi_sm '{}', and return message id {}", - new String(submitMulti.getShortMessage()), - messageId); + LOGGER.debug("Receiving submit_multi_sm '{}', and return message id {}", + new String(submitMulti.getShortMessage()), messageId); if (SMSCDeliveryReceipt.FAILURE.containedIn(submitMulti.getRegisteredDelivery()) || SMSCDeliveryReceipt.SUCCESS_FAILURE.containedIn(submitMulti.getRegisteredDelivery())) { execServiceDelReceipt.execute(new DeliveryReceiptTask(source, submitMulti, messageId)); @@ -126,151 +131,166 @@ public SubmitMultiResult onAcceptSubmitMulti(SubmitMulti submitMulti, return new SubmitMultiResult(messageId.getValue(), new UnsuccessDelivery[0]); } - + public DataSmResult onAcceptDataSm(DataSm dataSm, Session source) throws ProcessRequestException { - return null; + LOGGER.info("DataSm not implemented"); + throw new ProcessRequestException(DATASM_NOT_IMPLEMENTED, SMPPConstant.STAT_ESME_RINVCMDID); } - + public void onAcceptCancelSm(CancelSm cancelSm, SMPPServerSession source) throws ProcessRequestException { } - + public void onAcceptReplaceSm(ReplaceSm replaceSm, SMPPServerSession source) throws ProcessRequestException { } - + private static class WaitBindTask implements Runnable { private final SMPPServerSession serverSession; - - public WaitBindTask(SMPPServerSession serverSession) { + private String systemId; + private String password; + + public WaitBindTask(SMPPServerSession serverSession, String systemId, String password) { this.serverSession = serverSession; + this.systemId = systemId; + this.password = password; } public void run() { try { BindRequest bindRequest = serverSession.waitForBind(1000); - logger.info("Accepting bind for session {}, interface version {}", serverSession.getSessionId(), bindRequest.getInterfaceVersion()); try { - bindRequest.accept("sys", InterfaceVersion.IF_34); + if (systemId.equals(bindRequest.getSystemId())) { + if (password.equals(bindRequest.getPassword())) { + LOGGER.info("Accepting bind for session {}, interface version {}", serverSession.getSessionId(), bindRequest.getInterfaceVersion()); + // The systemId identifies the SMSC to the ESME. + bindRequest.accept(SMSC_SYSTEMID, InterfaceVersion.IF_34); + } + else { + LOGGER.info("Rejecting bind for session {}, interface version {}, invalid password", serverSession.getSessionId(), bindRequest.getInterfaceVersion()); + bindRequest.reject(SMPPConstant.STAT_ESME_RINVPASWD); + } + } + else { + LOGGER.info("Rejecting bind for session {}, interface version {}, invalid system id", serverSession.getSessionId(), bindRequest.getInterfaceVersion()); + bindRequest.reject(SMPPConstant.STAT_ESME_RINVSYSID); + } } catch (PDUStringException e) { - logger.error("Invalid system id", e); - bindRequest.reject(SMPPConstant.STAT_ESME_RSYSERR); + LOGGER.error("Invalid system id", e); + bindRequest.reject(SMPPConstant.STAT_ESME_RSYSERR); } - + } catch (IllegalStateException e) { - logger.error("System error", e); + LOGGER.error("System error", e); } catch (TimeoutException e) { - logger.warn("Wait for bind has reach timeout", e); + LOGGER.warn("Wait for bind has reach timeout", e); } catch (IOException e) { - logger.error("Failed accepting bind request for session {}", serverSession.getSessionId()); + LOGGER.error("Failed accepting bind request for session {}", serverSession.getSessionId()); } } } - + private static class DeliveryReceiptTask implements Runnable { private final SMPPServerSession session; private final MessageId messageId; - + private final TypeOfNumber sourceAddrTon; private final NumberingPlanIndicator sourceAddrNpi; private final String sourceAddress; - + private final TypeOfNumber destAddrTon; private final NumberingPlanIndicator destAddrNpi; private final String destAddress; - + private final int totalSubmitted; private final int totalDelivered; - + private final byte[] shortMessage; - + public DeliveryReceiptTask(SMPPServerSession session, SubmitSm submitSm, MessageId messageId) { this.session = session; this.messageId = messageId; - + // reversing destination to source sourceAddrTon = TypeOfNumber.valueOf(submitSm.getDestAddrTon()); sourceAddrNpi = NumberingPlanIndicator.valueOf(submitSm.getDestAddrNpi()); sourceAddress = submitSm.getDestAddress(); - + // reversing source to destination destAddrTon = TypeOfNumber.valueOf(submitSm.getSourceAddrTon()); destAddrNpi = NumberingPlanIndicator.valueOf(submitSm.getSourceAddrNpi()); destAddress = submitSm.getSourceAddr(); - + totalSubmitted = totalDelivered = 1; - + shortMessage = submitSm.getShortMessage(); } - + public DeliveryReceiptTask(SMPPServerSession session, SubmitMulti submitMulti, MessageId messageId) { this.session = session; this.messageId = messageId; - + // set to unknown and null, since it was submit_multi sourceAddrTon = TypeOfNumber.UNKNOWN; sourceAddrNpi = NumberingPlanIndicator.UNKNOWN; sourceAddress = null; - + // reversing source to destination destAddrTon = TypeOfNumber.valueOf(submitMulti.getSourceAddrTon()); destAddrNpi = NumberingPlanIndicator.valueOf(submitMulti.getSourceAddrNpi()); destAddress = submitMulti.getSourceAddr(); - + // distribution list assumed only contains single address totalSubmitted = totalDelivered = submitMulti.getDestAddresses().length; - + shortMessage = submitMulti.getShortMessage(); } - + public void run() { try { Thread.sleep(1000); } catch (InterruptedException e1) { - e1.printStackTrace(); + LOGGER.error("Interupted", e1); } SessionState state = session.getSessionState(); if (!state.isReceivable()) { - logger.debug("Not sending delivery receipt for message id {} since session state is {}", messageId, state); + LOGGER.debug("Not sending delivery receipt for message id {} since session state is {}", messageId, state); return; } String stringValue = Integer.valueOf(messageId.getValue(), 16).toString(); try { - + DeliveryReceipt delRec = new DeliveryReceipt(stringValue, totalSubmitted, totalDelivered, new Date(), new Date(), DeliveryReceiptState.DELIVRD, "000", new String(shortMessage)); session.deliverShortMessage( - "mc", - sourceAddrTon, - sourceAddrNpi, - sourceAddress, - destAddrTon, - destAddrNpi, - destAddress, - new ESMClass(MessageMode.DEFAULT, MessageType.SMSC_DEL_RECEIPT, GSMSpecificFeature.DEFAULT), - (byte)0, - (byte)0, - new RegisteredDelivery(0), - DataCodings.ZERO, + "mc", + sourceAddrTon, sourceAddrNpi, sourceAddress, + destAddrTon, destAddrNpi, destAddress, + new ESMClass(MessageMode.DEFAULT, MessageType.SMSC_DEL_RECEIPT, GSMSpecificFeature.DEFAULT), + (byte)0, + (byte)0, + new RegisteredDelivery(0), + DataCodings.ZERO, delRec.toString().getBytes()); - logger.debug("Sending delivery receipt for message id {}: {}", messageId, stringValue); + LOGGER.debug("Sending delivery receipt for message id {}: {}", messageId, stringValue); } catch (Exception e) { - logger.error("Failed sending delivery_receipt for message id " + messageId + ":" + stringValue, e); + LOGGER.error("Failed sending delivery_receipt for message id " + messageId + ":" + stringValue, e); } } } - + public static void main(String[] args) { + String systemId = System.getProperty("jsmpp.client.systemId", DEFAULT_SYSID); + String password = System.getProperty("jsmpp.client.password", DEFAULT_PASSWORD); int port; try { port = Integer.parseInt(System.getProperty("jsmpp.simulator.port", DEFAULT_PORT.toString())); } catch (NumberFormatException e) { port = DEFAULT_PORT; } - BasicConfigurator.configure(); - SMPPServerSimulator smppServerSim = new SMPPServerSimulator(port); + SMPPServerSimulator smppServerSim = new SMPPServerSimulator(port, systemId, password); smppServerSim.run(); } } diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/SimpleSubmitExample.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/SimpleSubmitExample.java index 973bfa9..0dfce20 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/SimpleSubmitExample.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/SimpleSubmitExample.java @@ -34,49 +34,53 @@ import org.jsmpp.session.SMPPSession; import org.jsmpp.util.AbsoluteTimeFormatter; import org.jsmpp.util.TimeFormatter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @author uudashr * */ public class SimpleSubmitExample { - private static TimeFormatter timeFormatter = new AbsoluteTimeFormatter();; + private static final Logger LOGGER = LoggerFactory.getLogger(SimpleSubmitExample.class); + private static final TimeFormatter TIME_FORMATTER = new AbsoluteTimeFormatter();; public static void main(String[] args) { SMPPSession session = new SMPPSession(); try { - session.connectAndBind("localhost", 8056, new BindParameter(BindType.BIND_TX, "test", "test", "cp", TypeOfNumber.UNKNOWN, NumberingPlanIndicator.UNKNOWN, null)); - } catch (IOException e) { - System.err.println("Failed connect and bind to host"); - e.printStackTrace(); - } - - try { - String messageId = session.submitShortMessage("CMT", TypeOfNumber.INTERNATIONAL, NumberingPlanIndicator.UNKNOWN, "1616", TypeOfNumber.INTERNATIONAL, NumberingPlanIndicator.UNKNOWN, "628176504657", new ESMClass(), (byte)0, (byte)1, timeFormatter.format(new Date()), null, new RegisteredDelivery(SMSCDeliveryReceipt.DEFAULT), (byte)0, new GeneralDataCoding(Alphabet.ALPHA_DEFAULT, MessageClass.CLASS1, false), (byte)0, "jSMPP simplify SMPP on Java platform".getBytes()); - System.out.println("Message submitted, message_id is " + messageId); - } catch (PDUException e) { - // Invalid PDU parameter - System.err.println("Invalid PDU parameter"); - e.printStackTrace(); - } catch (ResponseTimeoutException e) { - // Response timeout - System.err.println("Response timeout"); - e.printStackTrace(); - } catch (InvalidResponseException e) { - // Invalid response - System.err.println("Receive invalid respose"); - e.printStackTrace(); - } catch (NegativeResponseException e) { - // Receiving negative response (non-zero command_status) - System.err.println("Receive negative response"); - e.printStackTrace(); + LOGGER.info("Connecting"); + String systemId = session.connectAndBind("localhost", 8056, new BindParameter(BindType.BIND_TX, "j", "jpwda", "cp", TypeOfNumber.UNKNOWN, NumberingPlanIndicator.UNKNOWN, null)); + LOGGER.info("Connected with SMSC with system id {}", systemId); + + try { + String messageId = session.submitShortMessage("CMT", + TypeOfNumber.INTERNATIONAL, NumberingPlanIndicator.UNKNOWN, "1616", + TypeOfNumber.INTERNATIONAL, NumberingPlanIndicator.UNKNOWN, "628176504657", + new ESMClass(), (byte)0, (byte)1, TIME_FORMATTER.format(new Date()), null, + new RegisteredDelivery(SMSCDeliveryReceipt.DEFAULT), (byte)0, new GeneralDataCoding(Alphabet.ALPHA_DEFAULT, MessageClass.CLASS1, false), (byte)0, + "jSMPP simplify SMPP on Java platform".getBytes()); + LOGGER.info("Message submitted, message_id is {}", messageId); + } catch (PDUException e) { + // Invalid PDU parameter + LOGGER.error("Invalid PDU parameter", e); + } catch (ResponseTimeoutException e) { + // Response timeout + LOGGER.error("Response timeout", e); + } catch (InvalidResponseException e) { + // Invalid response + LOGGER.error("Receive invalid response", e); + } catch (NegativeResponseException e) { + // Receiving negative response (non-zero command_status) + LOGGER.error("Receive negative response, e"); + } catch (IOException e) { + LOGGER.error("IO error occured", e); + } + + session.unbindAndClose(); + } catch (IOException e) { - System.err.println("IO error occur"); - e.printStackTrace(); + LOGGER.error("Failed connect and bind to host", e); } - - session.unbindAndClose(); } - - + } diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/SimpleSubmitRegisteredExample.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/SimpleSubmitRegisteredExample.java index 5d6d524..626feea 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/SimpleSubmitRegisteredExample.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/SimpleSubmitRegisteredExample.java @@ -32,61 +32,62 @@ import org.jsmpp.session.SMPPSession; import org.jsmpp.util.AbsoluteTimeFormatter; import org.jsmpp.util.TimeFormatter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @author uudashr * */ public class SimpleSubmitRegisteredExample { - private static TimeFormatter timeFormatter = new AbsoluteTimeFormatter();; + private static final Logger LOGGER = LoggerFactory.getLogger(SimpleSubmitExample.class); + private static final TimeFormatter TIME_FORMATTER = new AbsoluteTimeFormatter();; public static void main(String[] args) { SMPPSession session = new SMPPSession(); // Set listener to receive deliver_sm session.setMessageReceiverListener(new MessageReceiverListenerImpl()); - - try { - session.connectAndBind("localhost", 8056, new BindParameter(BindType.BIND_TRX, "test", "test", "cp", TypeOfNumber.UNKNOWN, NumberingPlanIndicator.UNKNOWN, null)); - } catch (IOException e) { - System.err.println("Failed connect and bind to host"); - e.printStackTrace(); - } - try { - String messageId = session.submitShortMessage("CMT", TypeOfNumber.INTERNATIONAL, NumberingPlanIndicator.UNKNOWN, "1616", TypeOfNumber.INTERNATIONAL, NumberingPlanIndicator.UNKNOWN, "628176504657", new ESMClass(), (byte)0, (byte)1, timeFormatter.format(new Date()), null, new RegisteredDelivery(SMSCDeliveryReceipt.SUCCESS_FAILURE), (byte)0, DataCodings.ZERO, (byte)0, "jSMPP simplify SMPP on Java platform".getBytes()); - - /* - * you can save the submitted message to database. - */ - - System.out.println("Message submitted, message_id is " + messageId); - Thread.sleep(2000); - } catch (PDUException e) { - // Invalid PDU parameter - System.err.println("Invalid PDU parameter"); - e.printStackTrace(); - } catch (ResponseTimeoutException e) { - // Response timeout - System.err.println("Response timeout"); - e.printStackTrace(); - } catch (InvalidResponseException e) { - // Invalid response - System.err.println("Receive invalid respose"); - e.printStackTrace(); - } catch (NegativeResponseException e) { - // Receiving negative response (non-zero command_status) - System.err.println("Receive negative response"); - e.printStackTrace(); + String systemId = session.connectAndBind("localhost", 8056, new BindParameter(BindType.BIND_TRX, "test", "test", "cp", TypeOfNumber.UNKNOWN, NumberingPlanIndicator.UNKNOWN, null)); + LOGGER.info("Connected with SMSC with system id {}", systemId); + + try { + String messageId = session.submitShortMessage("CMT", + TypeOfNumber.INTERNATIONAL, NumberingPlanIndicator.UNKNOWN, "1616", + TypeOfNumber.INTERNATIONAL, NumberingPlanIndicator.UNKNOWN, "628176504657", + new ESMClass(), (byte)0, (byte)1, TIME_FORMATTER.format(new Date()), null, + new RegisteredDelivery(SMSCDeliveryReceipt.SUCCESS_FAILURE), (byte)0, DataCodings.ZERO, (byte)0, "jSMPP simplify SMPP on Java platform".getBytes()); + + /* + * you can save the submitted message to database. + */ + LOGGER.info("Message submitted, message_id is {}", messageId); + Thread.sleep(2000); + } catch (PDUException e) { + // Invalid PDU parameter + LOGGER.error("Invalid PDU parameter", e); + } catch (ResponseTimeoutException e) { + // Response timeout + LOGGER.error("Response timeout", e); + } catch (InvalidResponseException e) { + // Invalid response + LOGGER.error("Receive invalid response", e); + } catch (NegativeResponseException e) { + // Receiving negative response (non-zero command_status) + LOGGER.error("Receive negative response", e); + } catch (IOException e) { + LOGGER.error("I/O error occured", e); + } catch (InterruptedException e) { + LOGGER.error("Thread interrupted", e); + } + + session.unbindAndClose(); + } catch (IOException e) { - System.err.println("IO error occur"); - e.printStackTrace(); - } catch (InterruptedException e) { - System.err.println("Thread interrupted"); - e.printStackTrace(); + LOGGER.error("Failed connect and bind to host", e); } - - session.unbindAndClose(); + } diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/SimpleSubmitSimpleReceiveExample.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/SimpleSubmitSimpleReceiveExample.java index a855fb6..06a4bc1 100755 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/SimpleSubmitSimpleReceiveExample.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/SimpleSubmitSimpleReceiveExample.java @@ -17,7 +17,6 @@ import java.io.IOException; import java.util.Date; -import org.apache.log4j.BasicConfigurator; import org.jsmpp.InvalidResponseException; import org.jsmpp.PDUException; import org.jsmpp.bean.AlertNotification; @@ -45,109 +44,103 @@ import org.jsmpp.util.AbsoluteTimeFormatter; import org.jsmpp.util.InvalidDeliveryReceiptException; import org.jsmpp.util.TimeFormatter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @author terukizm * */ public class SimpleSubmitSimpleReceiveExample { - private static TimeFormatter timeFormatter = new AbsoluteTimeFormatter();; + private static final Logger LOGGER = LoggerFactory.getLogger(SimpleSubmitExample.class); + private static final TimeFormatter TIME_FORMATTER = new AbsoluteTimeFormatter();; public static void main(String[] args) { String server = "localhost"; int port = 8056; String message = "jSMPP simplify SMPP on Java platform"; - // bind(connect) SMPPSession session = new SMPPSession(); try { - session.connectAndBind(server, port, new BindParameter(BindType.BIND_TRX, "test", "test", "cp", + String systemId = session.connectAndBind(server, port, new BindParameter(BindType.BIND_TRX, "test", "test", "cp", TypeOfNumber.UNKNOWN, NumberingPlanIndicator.UNKNOWN, null)); - } catch (IOException e) { - System.err.println("Failed connect and bind to host"); - e.printStackTrace(); - } + LOGGER.info("Connected with SMSC with system id {}", systemId); - // send Message - try { - // set RegisteredDelivery - final RegisteredDelivery registeredDelivery = new RegisteredDelivery(); - registeredDelivery.setSMSCDeliveryReceipt(SMSCDeliveryReceipt.SUCCESS_FAILURE); + // send Message + try { + // set RegisteredDelivery + final RegisteredDelivery registeredDelivery = new RegisteredDelivery(); + registeredDelivery.setSMSCDeliveryReceipt(SMSCDeliveryReceipt.SUCCESS_FAILURE); - String messageId = session.submitShortMessage("CMT", TypeOfNumber.INTERNATIONAL, + String messageId = session.submitShortMessage("CMT", TypeOfNumber.INTERNATIONAL, NumberingPlanIndicator.UNKNOWN, "1616", TypeOfNumber.INTERNATIONAL, NumberingPlanIndicator.UNKNOWN, - "628176504657", new ESMClass(), (byte)0, (byte)1, timeFormatter.format(new Date()), null, + "628176504657", new ESMClass(), (byte)0, (byte)1, TIME_FORMATTER.format(new Date()), null, registeredDelivery, (byte)0, new GeneralDataCoding(Alphabet.ALPHA_DEFAULT, MessageClass.CLASS1, - false), (byte)0, message.getBytes()); - - System.out.println("Message submitted, message_id is " + messageId); - - } catch (PDUException e) { - // Invalid PDU parameter - System.err.println("Invalid PDU parameter"); - e.printStackTrace(); - } catch (ResponseTimeoutException e) { - // Response timeout - System.err.println("Response timeout"); - e.printStackTrace(); - } catch (InvalidResponseException e) { - // Invalid response - System.err.println("Receive invalid respose"); - e.printStackTrace(); - } catch (NegativeResponseException e) { - // Receiving negative response (non-zero command_status) - System.err.println("Receive negative response"); - e.printStackTrace(); - } catch (IOException e) { - System.err.println("IO error occur"); - e.printStackTrace(); - } + false), (byte)0, message.getBytes()); + + LOGGER.info("Message submitted, message_id is {}", messageId); + + } catch (PDUException e) { + // Invalid PDU parameter + LOGGER.error("Invalid PDU parameter", e); + } catch (ResponseTimeoutException e) { + // Response timeout + LOGGER.error("Response timeout", e); + } catch (InvalidResponseException e) { + // Invalid response + LOGGER.error("Receive invalid response", e); + } catch (NegativeResponseException e) { + // Receiving negative response (non-zero command_status) + LOGGER.error("Receive negative response", e); + } catch (IOException e) { + LOGGER.error("I/O error occured", e); + } - // receive Message - BasicConfigurator.configure(); - - // Set listener to receive deliver_sm - session.setMessageReceiverListener(new MessageReceiverListener() { - - public void onAcceptDeliverSm(DeliverSm deliverSm) throws ProcessRequestException { - if (MessageType.SMSC_DEL_RECEIPT.containedIn(deliverSm.getEsmClass())) { - // delivery receipt - try { - DeliveryReceipt delReceipt = deliverSm.getShortMessageAsDeliveryReceipt(); - long id = Long.parseLong(delReceipt.getId()) & 0xffffffff; - String messageId = Long.toString(id, 16).toUpperCase(); - System.out.println("received '" + messageId + "' : " + delReceipt); - } catch (InvalidDeliveryReceiptException e) { - System.err.println("receive faild"); - e.printStackTrace(); + // Set listener to receive deliver_sm + session.setMessageReceiverListener(new MessageReceiverListener() { + + public void onAcceptDeliverSm(DeliverSm deliverSm) throws ProcessRequestException { + if (MessageType.SMSC_DEL_RECEIPT.containedIn(deliverSm.getEsmClass())) { + // delivery receipt + try { + DeliveryReceipt delReceipt = deliverSm.getShortMessageAsDeliveryReceipt(); + long id = Long.parseLong(delReceipt.getId()) & 0xffffffff; + String messageId = Long.toString(id, 16).toUpperCase(); + LOGGER.info("received '{}' : {}", messageId, delReceipt); + } catch (InvalidDeliveryReceiptException e) { + LOGGER.error("receive failed, e"); + } + } else { + // regular short message + LOGGER.info("Receiving message : {}", new String(deliverSm.getShortMessage())); } - } else { - // regular short message - System.out.println("Receiving message : " + new String(deliverSm.getShortMessage())); } - } - public void onAcceptAlertNotification(AlertNotification alertNotification) { - System.out.println("onAcceptAlertNotification"); - } + public void onAcceptAlertNotification(AlertNotification alertNotification) { + LOGGER.info("onAcceptAlertNotification"); + } + + public DataSmResult onAcceptDataSm(DataSm dataSm, Session source) throws ProcessRequestException { + LOGGER.info("onAcceptDataSm"); + return null; + } + }); - public DataSmResult onAcceptDataSm(DataSm dataSm, Session source) throws ProcessRequestException { - System.out.println("onAcceptDataSm"); - return null; + // wait 3 second + try { + Thread.sleep(3000); + } catch (InterruptedException e) { + LOGGER.info("Interrupted exception", e); } - }); - // wait 3 second - try { - Thread.sleep(3000); - } catch (InterruptedException e) { - e.printStackTrace(); - } + // unbind(disconnect) + session.unbindAndClose(); - // unbind(disconnect) - session.unbindAndClose(); + } catch (IOException e) { + LOGGER.error("Failed connect and bind to host", e); + } - System.out.println("finish!"); + LOGGER.info("Finish!"); } } diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/StressClient.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/StressClient.java index d2b8f0c..1bbaf30 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/StressClient.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/StressClient.java @@ -57,11 +57,11 @@ * */ public class StressClient implements Runnable { - private static final String DEFAULT_PASSWORD = "jpwd"; + private static final Logger LOGGER = LoggerFactory.getLogger(StressClient.class); private static final String DEFAULT_SYSID = "j"; - private static final String DEFAULT_DESTADDR = "62161616"; + private static final String DEFAULT_PASSWORD = "jpwd"; private static final String DEFAULT_SOURCEADDR = "1616"; - private static final Logger logger = LoggerFactory.getLogger(StressClient.class); + private static final String DEFAULT_DESTADDR = "62161616"; private static final String DEFAULT_LOG4J_PATH = "stress/client-log4j.properties"; private static final String DEFAULT_HOST = "localhost"; private static final Integer DEFAULT_PORT = 8056; @@ -114,14 +114,14 @@ public void run() { smppSession.connectAndBind(host, port, BindType.BIND_TRX, systemId, password, "cln", TypeOfNumber.UNKNOWN, NumberingPlanIndicator.UNKNOWN, null); - logger.info("Bound to {}:{}", host, port); + LOGGER.info("Bound to {}:{}", host, port); } catch (IOException e) { - logger.error("Failed initialize connection or bind", e); + LOGGER.error("Failed initialize connection or bind", e); return; } new TrafficWatcherThread().start(); - logger.info("Starting to send {} bulk messages", bulkSize); + LOGGER.info("Starting to send {} bulk messages", bulkSize); for (int i = 0; i < bulkSize && !exit.get(); i++) { execService.execute(newSendTask("Hello " + id + " idx=" + i)); } @@ -132,7 +132,7 @@ public void run() { } catch (InterruptedException e) { } } - logger.info("Done"); + LOGGER.info("Done"); smppSession.unbindAndClose(); } @@ -155,19 +155,19 @@ null, null, new RegisteredDelivery(0), maxDelay.set(delay); } } catch (PDUException e) { - logger.error("Failed submit short message '" + message + "'", e); + LOGGER.error("Failed submit short message '" + message + "'", e); shutdown(); } catch (ResponseTimeoutException e) { - logger.error("Failed submit short message '" + message + "'", e); + LOGGER.error("Failed submit short message '" + message + "'", e); shutdown(); } catch (InvalidResponseException e) { - logger.error("Failed submit short message '" + message + "'", e); + LOGGER.error("Failed submit short message '" + message + "'", e); shutdown(); } catch (NegativeResponseException e) { - logger.error("Failed submit short message '" + message + "'", e); + LOGGER.error("Failed submit short message '" + message + "'", e); shutdown(); } catch (IOException e) { - logger.error("Failed submit short message '" + message + "'", e); + LOGGER.error("Failed submit short message '" + message + "'", e); shutdown(); } } @@ -177,7 +177,7 @@ null, null, new RegisteredDelivery(0), private class TrafficWatcherThread extends Thread { @Override public void run() { - logger.info("Starting traffic watcher..."); + LOGGER.info("Starting traffic watcher..."); while (!exit.get()) { try { Thread.sleep(1000); @@ -188,7 +188,7 @@ public void run() { long maxDelayPerSecond = maxDelay.getAndSet(0); totalRequestCounter.addAndGet(requestPerSecond); int total = totalResponseCounter.addAndGet(responsePerSecond); - logger.info("Request/Response per second: {}/{} of {} maxDelay={}", + LOGGER.info("Request/Response per second: {}/{} of {} maxDelay={}", requestPerSecond, responsePerSecond, total, maxDelayPerSecond); if (total == bulkSize) { shutdown(); @@ -198,6 +198,9 @@ public void run() { } public static void main(String[] args) { + + PropertyConfigurator.configure(System.getProperty("jsmpp.server.log4jPath", DEFAULT_LOG4J_PATH)); + String host = System.getProperty("jsmpp.client.host", DEFAULT_HOST); String systemId = System.getProperty("jsmpp.client.systemId", DEFAULT_SYSID); String password = System.getProperty("jsmpp.client.password", DEFAULT_PASSWORD); @@ -238,20 +241,16 @@ public static void main(String[] args) { } catch (NumberFormatException e) { maxOutstanding = DEFAULT_MAX_OUTSTANDING; } - - String log4jPath = System.getProperty("jsmpp.client.log4jPath", DEFAULT_LOG4J_PATH); - PropertyConfigurator.configure(log4jPath); - - - logger.info("Target server {}:{}", host, port); - logger.info("System ID: {}", systemId); - logger.info("Password: {}", password); - logger.info("Source address: {}", sourceAddr); - logger.info("Destination address: {}", destinationAddr); - logger.info("Transaction timer: {}", transactionTimer); - logger.info("Bulk size: {}", bulkSize); - logger.info("Max outstanding: {}", maxOutstanding); - logger.info("Processor degree: {}", processorDegree); + + LOGGER.info("Target server {}:{}", host, port); + LOGGER.info("System ID: {}", systemId); + LOGGER.info("Password: {}", password); + LOGGER.info("Source address: {}", sourceAddr); + LOGGER.info("Destination address: {}", destinationAddr); + LOGGER.info("Transaction timer: {}", transactionTimer); + LOGGER.info("Bulk size: {}", bulkSize); + LOGGER.info("Max outstanding: {}", maxOutstanding); + LOGGER.info("Processor degree: {}", processorDegree); StressClient stressClient = new StressClient(0, host, port, bulkSize, systemId, password, sourceAddr, destinationAddr, diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/StressServer.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/StressServer.java index c0f8ae3..cff7b55 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/StressServer.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/StressServer.java @@ -63,11 +63,16 @@ * */ public class StressServer implements Runnable, ServerMessageReceiverListener { + private static final Logger LOGGER = LoggerFactory.getLogger(StressServer.class); private static final int DEFAULT_MAX_WAIT_BIND = 10; private static final String DEFAULT_LOG4J_PATH = "stress/server-log4j.properties"; private static final Integer DEFAULT_PORT = 8056; private static final Integer DEFAULT_PROCESSOR_DEGREE = 3; - private static final Logger logger = LoggerFactory.getLogger(StressServer.class); + private static final String CANCELSM_NOT_IMPLEMENTED = "cancel_sm not implemented"; + private static final String DATASM_NOT_IMPLEMENTED = "data_sm not implemented"; + private static final String QUERYSM_NOT_IMPLEMENTED = "query_sm not implemented"; + private static final String REPLACESM_NOT_IMPLEMENTED = "replace_sm not implemented"; + private static final String SUBMITMULTI_NOT_IMPLEMENTED = "submit_multi not implemented"; private final ExecutorService waitBindExecService = Executors.newFixedThreadPool(DEFAULT_MAX_WAIT_BIND); private final MessageIDGenerator messageIDGenerator = new RandomMessageIDGenerator(); private final AtomicInteger requestCounter = new AtomicInteger(); @@ -85,54 +90,60 @@ public void run() { sessionListener.setSessionStateListener(new SessionStateListenerImpl()); sessionListener.setPduProcessorDegree(processorDegree); new TrafficWatcherThread().start(); - logger.info("Listening on port {}", port); + LOGGER.info("Listening on port {}", port); while (true) { SMPPServerSession serverSession = sessionListener.accept(); - logger.info("Accepting connection for session {}", serverSession.getSessionId()); + LOGGER.info("Accepting connection for session {}", serverSession.getSessionId()); serverSession.setMessageReceiverListener(this); waitBindExecService.execute(new WaitBindTask(serverSession)); } } catch (IOException e) { - logger.error("IO error occurred", e); + LOGGER.error("I/O error occurred", e); } } public QuerySmResult onAcceptQuerySm(QuerySm querySm, SMPPServerSession source) throws ProcessRequestException { - return null; + LOGGER.warn("QuerySm not implemented"); + throw new ProcessRequestException(QUERYSM_NOT_IMPLEMENTED, SMPPConstant.STAT_ESME_RINVCMDID); } public MessageId onAcceptSubmitSm(SubmitSm submitSm, SMPPServerSession source) throws ProcessRequestException { MessageId messageId = messageIDGenerator.newMessageId(); - logger.debug("Receiving submit_sm {}, and return message id {}", new String(submitSm.getShortMessage()), messageId.getValue()); + LOGGER.info("Receiving submit_sm {}, and return message id {}", new String(submitSm.getShortMessage()), messageId.getValue()); requestCounter.incrementAndGet(); return messageId; } public SubmitMultiResult onAcceptSubmitMulti(SubmitMulti submitMulti, SMPPServerSession source) throws ProcessRequestException { - return null; + LOGGER.warn("SubmitMulti not implemented"); + throw new ProcessRequestException(SUBMITMULTI_NOT_IMPLEMENTED, SMPPConstant.STAT_ESME_RINVCMDID); } public DataSmResult onAcceptDataSm(DataSm dataSm, Session source) throws ProcessRequestException { - return null; + LOGGER.warn("DataSm not implemented"); + throw new ProcessRequestException(DATASM_NOT_IMPLEMENTED, SMPPConstant.STAT_ESME_RINVCMDID); } public void onAcceptCancelSm(CancelSm cancelSm, SMPPServerSession source) throws ProcessRequestException { + LOGGER.warn("CancelSm not implemented"); + throw new ProcessRequestException(CANCELSM_NOT_IMPLEMENTED, SMPPConstant.STAT_ESME_RCANCELFAIL); } public void onAcceptReplaceSm(ReplaceSm replaceSm, SMPPServerSession source) throws ProcessRequestException { + LOGGER.warn("ReplaceSm not implemented"); + throw new ProcessRequestException(REPLACESM_NOT_IMPLEMENTED, SMPPConstant.STAT_ESME_RREPLACEFAIL); } private class SessionStateListenerImpl implements SessionStateListener { - public void onStateChange(SessionState newState, SessionState oldState, - Session source) { + public void onStateChange(SessionState newState, SessionState oldState, Session source) { SMPPServerSession session = (SMPPServerSession)source; - logger.info("New state of " + session.getSessionId() + " is " + newState); + LOGGER.info("New state of {} is {}" , session.getSessionId(), newState); } } @@ -146,19 +157,19 @@ public WaitBindTask(SMPPServerSession serverSession) { public void run() { try { BindRequest bindRequest = serverSession.waitForBind(1000); - logger.debug("Accepting bind for session {}", serverSession.getSessionId()); + LOGGER.debug("Accepting bind for session {}", serverSession.getSessionId()); try { bindRequest.accept("sys", InterfaceVersion.IF_34); } catch (PDUStringException e) { - logger.error("Invalid system id", e); + LOGGER.error("Invalid system id", e); bindRequest.reject(SMPPConstant.STAT_ESME_RSYSERR); } } catch (IllegalStateException e) { - logger.error("System error", e); + LOGGER.error("System error", e); } catch (TimeoutException e) { - logger.warn("Wait for bind has reach timeout", e); + LOGGER.warn("Wait for bind has reach timeout", e); } catch (IOException e) { - logger.error("Failed accepting bind request for session {}", serverSession.getSessionId()); + LOGGER.error("Failed accepting bind request for session {}", serverSession.getSessionId()); } } } @@ -168,8 +179,7 @@ private class DeliveryReceiptTask implements Runnable { private final SubmitSm submitSm; private MessageId messageId; - public DeliveryReceiptTask(SMPPServerSession session, - SubmitSm submitSm, MessageId messageId) { + public DeliveryReceiptTask(SMPPServerSession session, SubmitSm submitSm, MessageId messageId) { this.session = session; this.submitSm = submitSm; this.messageId = messageId; @@ -199,30 +209,31 @@ public void run() { new RegisteredDelivery(0), DataCodings.ZERO, delRec.toString().getBytes()); - logger.debug("Sending delivery receipt for message id " + messageId + ":" + stringValue); + LOGGER.debug("Sending delivery receipt for message id " + messageId + ":" + stringValue); } catch (Exception e) { - logger.error("Failed sending delivery_receipt for message id " + messageId + ":" + stringValue, e); + LOGGER.error("Failed sending delivery_receipt for message id " + messageId + ":" + stringValue, e); } } } - - + private class TrafficWatcherThread extends Thread { @Override public void run() { - logger.info("Starting traffic watcher..."); + LOGGER.info("Starting traffic watcher..."); while (true) { try { Thread.sleep(1000); } catch (InterruptedException e) { } int trafficPerSecond = requestCounter.getAndSet(0); - logger.info("Traffic per second : " + trafficPerSecond); + LOGGER.info("Traffic per second : " + trafficPerSecond); } } } public static void main(String[] args) { + PropertyConfigurator.configure(System.getProperty("jsmpp.server.log4jPath", DEFAULT_LOG4J_PATH)); + int port; try { port = Integer.parseInt(System.getProperty("jsmpp.server.port", DEFAULT_PORT.toString())); @@ -236,11 +247,8 @@ public static void main(String[] args) { } catch (NumberFormatException e) { processorDegree = DEFAULT_PROCESSOR_DEGREE; } - - String log4jPath = System.getProperty("jsmpp.server.log4jPath", DEFAULT_LOG4J_PATH); - PropertyConfigurator.configure(log4jPath); - - logger.info("Processor degree: " + processorDegree); + + LOGGER.info("Processor degree: " + processorDegree); StressServer stressServer = new StressServer(port, processorDegree); stressServer.run(); } diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/SubmitLongMessageExample.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/SubmitLongMessageExample.java index 32bf712..c85b898 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/SubmitLongMessageExample.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/SubmitLongMessageExample.java @@ -35,62 +35,62 @@ import org.jsmpp.session.SMPPSession; import org.jsmpp.util.AbsoluteTimeFormatter; import org.jsmpp.util.TimeFormatter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @author uudashr * */ public class SubmitLongMessageExample { - private static TimeFormatter timeFormatter = new AbsoluteTimeFormatter();; + private static final Logger LOGGER = LoggerFactory.getLogger(SubmitLongMessageExample.class); + private static final TimeFormatter TIME_FORMATTER = new AbsoluteTimeFormatter();; public static void main(String[] args) { SMPPSession session = new SMPPSession(); try { session.connectAndBind("localhost", 8056, new BindParameter(BindType.BIND_TX, "test", "test", "cp", TypeOfNumber.UNKNOWN, NumberingPlanIndicator.UNKNOWN, null)); + + Random random = new Random(); + + final int totalSegments = 3; + OptionalParameter sarMsgRefNum = OptionalParameters.newSarMsgRefNum((short)random.nextInt()); + OptionalParameter sarTotalSegments = OptionalParameters.newSarTotalSegments(totalSegments); + + for (int i = 0; i < totalSegments; i++) { + final int seqNum = i + 1; + String message = "Message part " + seqNum + " of " + totalSegments + " "; + OptionalParameter sarSegmentSeqnum = OptionalParameters.newSarSegmentSeqnum(seqNum); + String messageId = submitMessage(session, message, sarMsgRefNum, sarSegmentSeqnum, sarTotalSegments); + LOGGER.info("Message submitted, message_id is {}", messageId); + } + + session.unbindAndClose(); + } catch (IOException e) { - System.err.println("Failed connect and bind to host"); - e.printStackTrace(); - } - Random random = new Random(); - - final int totalSegments = 3; - OptionalParameter sarMsgRefNum = OptionalParameters.newSarMsgRefNum((short)random.nextInt()); - OptionalParameter sarTotalSegments = OptionalParameters.newSarTotalSegments(totalSegments); - - for (int i = 0; i < totalSegments; i++) { - final int seqNum = i + 1; - String message = "Message part " + seqNum + " of " + totalSegments + " "; - OptionalParameter sarSegmentSeqnum = OptionalParameters.newSarSegmentSeqnum(seqNum); - String messageId = submitMessage(session, message, sarMsgRefNum, sarSegmentSeqnum, sarTotalSegments); - System.out.println("Message submitted, message_id is " + messageId); + LOGGER.error("Failed connect and bind to host", e); } - - session.unbindAndClose(); } public static String submitMessage(SMPPSession session, String message, OptionalParameter sarMsgRefNum, OptionalParameter sarSegmentSeqnum, OptionalParameter sarTotalSegments) { String messageId = null; try { - messageId = session.submitShortMessage("CMT", TypeOfNumber.INTERNATIONAL, NumberingPlanIndicator.UNKNOWN, "1616", TypeOfNumber.INTERNATIONAL, NumberingPlanIndicator.UNKNOWN, "628176504657", new ESMClass(), (byte)0, (byte)1, timeFormatter.format(new Date()), null, new RegisteredDelivery(SMSCDeliveryReceipt.DEFAULT), (byte)0, DataCodings.ZERO, (byte)0, message.getBytes(), sarMsgRefNum, sarSegmentSeqnum, sarTotalSegments);; + messageId = session.submitShortMessage("CMT", TypeOfNumber.INTERNATIONAL, NumberingPlanIndicator.UNKNOWN, "1616", TypeOfNumber.INTERNATIONAL, NumberingPlanIndicator.UNKNOWN, "628176504657", new ESMClass(), (byte)0, (byte)1, TIME_FORMATTER + .format(new Date()), null, new RegisteredDelivery(SMSCDeliveryReceipt.DEFAULT), (byte)0, DataCodings.ZERO, (byte)0, message.getBytes(), sarMsgRefNum, sarSegmentSeqnum, sarTotalSegments);; } catch (PDUException e) { // Invalid PDU parameter - System.err.println("Invalid PDU parameter"); - e.printStackTrace(); + LOGGER.error("Invalid PDU parameter", e); } catch (ResponseTimeoutException e) { // Response timeout - System.err.println("Response timeout"); - e.printStackTrace(); + LOGGER.error("Response timeout", e); } catch (InvalidResponseException e) { // Invalid response - System.err.println("Receive invalid respose"); - e.printStackTrace(); + LOGGER.error("Receive invalid response", e); } catch (NegativeResponseException e) { // Receiving negative response (non-zero command_status) - System.err.println("Receive negative response"); - e.printStackTrace(); + LOGGER.error("Receive negative response", e); } catch (IOException e) { - System.err.println("IO error occur"); - e.printStackTrace(); + LOGGER.error("I/O error occured", e); } return messageId; } diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/SubmitMultiExample.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/SubmitMultiExample.java index 4032814..0e1bb18 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/SubmitMultiExample.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/SubmitMultiExample.java @@ -37,6 +37,8 @@ import org.jsmpp.session.SMPPSession; import org.jsmpp.util.AbsoluteTimeFormatter; import org.jsmpp.util.TimeFormatter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @@ -44,65 +46,58 @@ * */ public class SubmitMultiExample { - - private static TimeFormatter timeFormatter = new AbsoluteTimeFormatter(); + private static final Logger LOGGER = LoggerFactory.getLogger(SubmitMultiExample.class); + private static final TimeFormatter TIME_FORMATTER = new AbsoluteTimeFormatter(); public static void main(String[] args) { // Create a new SMPP Session SMPPSession session = new SMPPSession(); try { - session.setMessageReceiverListener(new MessageReceiverListenerImpl()); // Bind to the Server - session.connectAndBind("localhost", 8056, + String systemId = session.connectAndBind("localhost", 8056, new BindParameter(BindType.BIND_TRX, "test", "test", "cp", TypeOfNumber.UNKNOWN, NumberingPlanIndicator.UNKNOWN, null)); - - } catch (IOException e) { - System.err.println("Failed connect and bind to host"); - e.printStackTrace(); - } + LOGGER.info("Connected with SMSC with system id {}", systemId); - try { - Address address1 = new Address(TypeOfNumber.INTERNATIONAL, NumberingPlanIndicator.UNKNOWN, "628176504657"); - Address address2 = new Address(TypeOfNumber.INTERNATIONAL, NumberingPlanIndicator.UNKNOWN, "628176504658"); - Address[] addresses = new Address[] {address1, address2}; - SubmitMultiResult result = session.submitMultiple("CMT", TypeOfNumber.INTERNATIONAL, NumberingPlanIndicator.UNKNOWN, "1616", - addresses, new ESMClass(), (byte)0, (byte)1, timeFormatter.format(new Date()), null, - new RegisteredDelivery(SMSCDeliveryReceipt.FAILURE), ReplaceIfPresentFlag.REPLACE, - new GeneralDataCoding(Alphabet.ALPHA_DEFAULT, MessageClass.CLASS1, false), (byte)0, - "jSMPP simplify SMPP on Java platform".getBytes()); - System.out.println("Messages submitted, result is " + result); - Thread.sleep(2000); - } catch (PDUException e) { - // Invalid PDU parameter - System.err.println("Invalid PDU parameter"); - e.printStackTrace(); - } catch (ResponseTimeoutException e) { - // Response timeout - System.err.println("Response timeout"); - e.printStackTrace(); - } catch (InvalidResponseException e) { - // Invalid response - System.err.println("Receive invalid respose"); - e.printStackTrace(); - } catch (NegativeResponseException e) { - // Receiving negative response (non-zero command_status) - System.err.println("Receive negative response"); - e.printStackTrace(); + try { + Address address1 = new Address(TypeOfNumber.INTERNATIONAL, NumberingPlanIndicator.UNKNOWN, "628176504657"); + Address address2 = new Address(TypeOfNumber.INTERNATIONAL, NumberingPlanIndicator.UNKNOWN, "628176504658"); + Address[] addresses = new Address[] {address1, address2}; + SubmitMultiResult result = session.submitMultiple("CMT", TypeOfNumber.INTERNATIONAL, NumberingPlanIndicator.UNKNOWN, "1616", + addresses, new ESMClass(), (byte)0, (byte)1, TIME_FORMATTER.format(new Date()), null, + new RegisteredDelivery(SMSCDeliveryReceipt.FAILURE), ReplaceIfPresentFlag.REPLACE, + new GeneralDataCoding(Alphabet.ALPHA_DEFAULT, MessageClass.CLASS1, false), (byte)0, + "jSMPP simplify SMPP on Java platform".getBytes()); + LOGGER.info("Messages submitted, result is {}", result); + Thread.sleep(2000); + } catch (PDUException e) { + // Invalid PDU parameter + LOGGER.error("Invalid PDU parameter", e); + } catch (ResponseTimeoutException e) { + // Response timeout + LOGGER.error("Response timeout", e); + } catch (InvalidResponseException e) { + // Invalid response + LOGGER.error("Receive invalid response", e); + } catch (NegativeResponseException e) { + // Receiving negative response (non-zero command_status) + LOGGER.error("Receive negative response", e); + } catch (IOException e) { + LOGGER.error("I/O error occured", e); + } catch (InterruptedException e) { + LOGGER.error("Thread interrupted", e); + } + + session.unbindAndClose(); + } catch (IOException e) { - System.err.println("IO error occur"); - e.printStackTrace(); - } catch (InterruptedException e) { - System.err.println("Thread interrupted"); - e.printStackTrace(); + LOGGER.error("Failed connect and bind to host", e); } - - session.unbindAndClose(); } } diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/SubmitMultipartMultilangualExample.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/SubmitMultipartMultilangualExample.java index c6b0036..082437a 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/SubmitMultipartMultilangualExample.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/SubmitMultipartMultilangualExample.java @@ -38,6 +38,8 @@ import org.jsmpp.session.SMPPSession; import org.jsmpp.session.Session; import org.jsmpp.session.SessionStateListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @@ -45,6 +47,7 @@ * */ public class SubmitMultipartMultilangualExample { + private static final Logger LOGGER = LoggerFactory.getLogger(SubmitMultipartMultilangualExample.class); private static final int MAX_MULTIPART_MSG_SEGMENT_SIZE_UCS2 = 134; private static final int MAX_SINGLE_MSG_SEGMENT_SIZE_UCS2 = 70; @@ -53,7 +56,7 @@ public class SubmitMultipartMultilangualExample { private class SessionStateListenerImpl implements SessionStateListener { public void onStateChange(SessionState newState, SessionState oldState, Session source) { - System.out.println("Session state changed from " + oldState + " to " + newState); + LOGGER.info("Session state changed from {} to {}", oldState , newState); } } @@ -130,8 +133,7 @@ private void sendAndWait() throws IOException, InterruptedException { session.connectAndBind("localhost", 2775, new BindParameter(BindType.BIND_TRX, "smppclient", "password", "cp", TypeOfNumber.UNKNOWN, NumberingPlanIndicator.UNKNOWN, null)); } catch (IOException e) { - System.err.println("Failed connect and bind to host"); - e.printStackTrace(); + LOGGER.error("Failed connect and bind to host", e); } // configure variables according to if message contains national @@ -165,24 +167,23 @@ private void sendAndWait() throws IOException, InterruptedException { esmClass = new ESMClass(); } - System.out.println("Sending message " + messageBody); - System.out.printf("Message is %d characters long and will be sent as %d messages with params: %s %s ", + LOGGER.info("Sending message {}", messageBody); + LOGGER.info("Message is {} characters long and will be sent as {} messages with params: {} {}", messageBody.length(), byteMessagesArray.length, alphabet, messageClass); - System.out.println(); // submit all messages for (int i = 0; i < byteMessagesArray.length; i++) { String messageId = submitMessage(session, byteMessagesArray[i], sourceMsisdn, destinationMsisdn, messageClass, alphabet, esmClass); - System.out.println("Message submitted, message_id is " + messageId); + LOGGER.info("Message submitted, message_id is {}", messageId); } - System.out.println("Entering listening mode. Press enter to finish..."); + LOGGER.info("Entering listening mode. Press enter to finish..."); try { System.in.read(); } catch (IOException e) { - e.printStackTrace(); + LOGGER.error("I/O error occured", e); } session.unbindAndClose(); @@ -198,23 +199,18 @@ private String submitMessage(SMPPSession session, byte[] message, String sourceM (byte) 0, new GeneralDataCoding(alphabet, esmClass), (byte) 0, message); } catch (PDUException e) { // Invalid PDU parameter - System.err.println("Invalid PDU parameter"); - e.printStackTrace(); + LOGGER.error("Invalid PDU parameter", e); } catch (ResponseTimeoutException e) { // Response timeout - System.err.println("Response timeout"); - e.printStackTrace(); + LOGGER.error("Response timeout", e); } catch (InvalidResponseException e) { // Invalid response - System.err.println("Receive invalid respose"); - e.printStackTrace(); + LOGGER.error("Receive invalid response", e); } catch (NegativeResponseException e) { // Receiving negative response (non-zero command_status) - System.err.println("Receive negative response"); - e.printStackTrace(); + LOGGER.error("Receive negative response", e); } catch (IOException e) { - System.err.println("IO error occur"); - e.printStackTrace(); + LOGGER.error("I/O error occured", e); } return messageId; } diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/gateway/AutoReconnectGateway.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/gateway/AutoReconnectGateway.java index 7dde946..a8f4a82 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/gateway/AutoReconnectGateway.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/gateway/AutoReconnectGateway.java @@ -16,7 +16,6 @@ import java.io.IOException; -import org.apache.log4j.BasicConfigurator; import org.jsmpp.InvalidResponseException; import org.jsmpp.PDUException; import org.jsmpp.bean.BindType; @@ -44,7 +43,7 @@ */ public class AutoReconnectGateway implements Gateway { - private static final Logger logger = LoggerFactory.getLogger(AutoReconnectGateway.class); + private static final Logger LOGGER = LoggerFactory.getLogger(AutoReconnectGateway.class); private SMPPSession session = null; private String remoteIpAddress; private int remotePort; @@ -67,11 +66,9 @@ public AutoReconnectGateway(String remoteIpAddress, int remotePort, } public static void main(String[] args) throws IOException { - BasicConfigurator.configure(); Gateway gateway = new AutoReconnectGateway("localhost", 8056, new BindParameter(BindType.BIND_TRX, "sms", "sms", "sms", TypeOfNumber.UNKNOWN, NumberingPlanIndicator.ISDN, "8080")); - while (true) { try { Thread.sleep(1000); @@ -124,7 +121,7 @@ private SMPPSession newSession() throws IOException { */ private SMPPSession getSession() throws IOException { if (session == null) { - logger.info("Initiate session for the first time to {}:{}", remoteIpAddress, remotePort); + LOGGER.info("Initiate session for the first time to {}:{}", remoteIpAddress, remotePort); session = newSession(); } else if (!session.getSessionState().isBound()) { @@ -142,7 +139,7 @@ private void reconnectAfter(final long timeInMillis) { new Thread() { @Override public void run() { - logger.info("Schedule reconnect after {} millis", timeInMillis); + LOGGER.info("Schedule reconnect after {} millis", timeInMillis); try { Thread.sleep(timeInMillis); } @@ -152,11 +149,11 @@ public void run() { int attempt = 0; while (session == null || session.getSessionState().equals(SessionState.CLOSED)) { try { - logger.info("Reconnecting attempt #{} ...", ++attempt); + LOGGER.info("Reconnecting attempt #{} ...", ++attempt); session = newSession(); } catch (IOException e) { - logger.error("Failed opening connection and bind to " + remoteIpAddress + ":" + remotePort, e); + LOGGER.error("Failed opening connection and bind to " + remoteIpAddress + ":" + remotePort, e); // wait for a second try { Thread.sleep(1000); @@ -177,8 +174,9 @@ public void run() { */ private class SessionStateListenerImpl implements SessionStateListener { public void onStateChange(SessionState newState, SessionState oldState, Session source) { + LOGGER.debug("State changed from {} to {}",oldState , newState); if (newState.equals(SessionState.CLOSED)) { - logger.info("Session {} closed", source.getSessionId()); + LOGGER.info("Session {} closed", source.getSessionId()); reconnectAfter(reconnectInterval); } } diff --git a/jsmpp/src/main/java/org/jsmpp/SMPPConstant.java b/jsmpp/src/main/java/org/jsmpp/SMPPConstant.java index 87a31e5..566c994 100644 --- a/jsmpp/src/main/java/org/jsmpp/SMPPConstant.java +++ b/jsmpp/src/main/java/org/jsmpp/SMPPConstant.java @@ -75,7 +75,6 @@ public interface SMPPConstant { /* * Command Status constants (STAT prefix). */ - public static final int STAT_ESME_ROK = 0x00000000; public static final int STAT_ESME_RINVMSGLEN = 0x00000001; public static final int STAT_ESME_RINVCMDLEN = 0x00000002; From 03a034975f9ac61961ae4c6f4922d243fba40843 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sat, 14 Jan 2017 22:25:19 +0100 Subject: [PATCH 181/212] Return negative reponses. --- .../java/org/jsmpp/examples/OpenAndBindExample.java | 5 +++-- .../java/org/jsmpp/examples/SMPPServerSimulator.java | 10 ++++++++-- .../src/main/java/org/jsmpp/examples/StressServer.java | 6 +++--- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/OpenAndBindExample.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/OpenAndBindExample.java index 9208363..53c2d64 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/OpenAndBindExample.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/OpenAndBindExample.java @@ -37,12 +37,13 @@ public static void main(String[] args) { SMPPSession session = new SMPPSession(); try { LOGGER.info("Connect and bind to {} port {}", host, port); - session.connectAndBind(host, port, new BindParameter(BindType.BIND_TRX, "test", "test", "cp", TypeOfNumber.UNKNOWN, NumberingPlanIndicator.UNKNOWN, null)); + String systemId = session.connectAndBind(host, port, new BindParameter(BindType.BIND_TRX, "test", "test", "cp", TypeOfNumber.UNKNOWN, NumberingPlanIndicator.UNKNOWN, null)); + LOGGER.info("Connected with SMSC with system id {}", systemId); + try { Thread.sleep(10000); } catch (InterruptedException e) {} } catch (IOException e) { // Failed connect and bind to SMSC LOGGER.error("Failed connect and bind to host", e); } - try { Thread.sleep(10000); } catch (InterruptedException e) {} session.unbindAndClose(); } diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java index d7d09b0..256766a 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java @@ -65,7 +65,9 @@ public class SMPPServerSimulator extends ServerResponseDeliveryAdapter implements Runnable, ServerMessageReceiverListener { private static final Logger LOGGER = LoggerFactory.getLogger(SMPPServerSimulator.class); private static final String QUERYSM_NOT_IMPLEMENTED = "query_sm not implemented"; + private static final String CANCELSM_NOT_IMPLEMENTED = "cancel_sm not implemented"; private static final String DATASM_NOT_IMPLEMENTED = "data_sm not implemented"; + private static final String REPLACESM_NOT_IMPLEMENTED = "replace_sm not implemented"; private static final Integer DEFAULT_PORT = 8056; private static final String DEFAULT_SYSID = "j"; private static final String DEFAULT_PASSWORD = "jpwd"; @@ -134,16 +136,20 @@ public SubmitMultiResult onAcceptSubmitMulti(SubmitMulti submitMulti, SMPPServer public DataSmResult onAcceptDataSm(DataSm dataSm, Session source) throws ProcessRequestException { - LOGGER.info("DataSm not implemented"); - throw new ProcessRequestException(DATASM_NOT_IMPLEMENTED, SMPPConstant.STAT_ESME_RINVCMDID); + LOGGER.info("Accepting DataSm, but not implemented"); + throw new ProcessRequestException(DATASM_NOT_IMPLEMENTED, SMPPConstant.STAT_ESME_RSYSERR); } public void onAcceptCancelSm(CancelSm cancelSm, SMPPServerSession source) throws ProcessRequestException { + LOGGER.info("Accepting CancelSm, but not implemented"); + throw new ProcessRequestException(CANCELSM_NOT_IMPLEMENTED, SMPPConstant.STAT_ESME_RCANCELFAIL); } public void onAcceptReplaceSm(ReplaceSm replaceSm, SMPPServerSession source) throws ProcessRequestException { + LOGGER.info("AcceptingReplaceSm, but not implemented"); + throw new ProcessRequestException(REPLACESM_NOT_IMPLEMENTED, SMPPConstant.STAT_ESME_RREPLACEFAIL); } private static class WaitBindTask implements Runnable { diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/StressServer.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/StressServer.java index cff7b55..7ef2c82 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/StressServer.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/StressServer.java @@ -105,7 +105,7 @@ public void run() { public QuerySmResult onAcceptQuerySm(QuerySm querySm, SMPPServerSession source) throws ProcessRequestException { LOGGER.warn("QuerySm not implemented"); - throw new ProcessRequestException(QUERYSM_NOT_IMPLEMENTED, SMPPConstant.STAT_ESME_RINVCMDID); + throw new ProcessRequestException(QUERYSM_NOT_IMPLEMENTED, SMPPConstant.STAT_ESME_RQUERYFAIL); } public MessageId onAcceptSubmitSm(SubmitSm submitSm, @@ -119,13 +119,13 @@ public MessageId onAcceptSubmitSm(SubmitSm submitSm, public SubmitMultiResult onAcceptSubmitMulti(SubmitMulti submitMulti, SMPPServerSession source) throws ProcessRequestException { LOGGER.warn("SubmitMulti not implemented"); - throw new ProcessRequestException(SUBMITMULTI_NOT_IMPLEMENTED, SMPPConstant.STAT_ESME_RINVCMDID); + throw new ProcessRequestException(SUBMITMULTI_NOT_IMPLEMENTED, SMPPConstant.STAT_ESME_RSYSERR); } public DataSmResult onAcceptDataSm(DataSm dataSm, Session source) throws ProcessRequestException { LOGGER.warn("DataSm not implemented"); - throw new ProcessRequestException(DATASM_NOT_IMPLEMENTED, SMPPConstant.STAT_ESME_RINVCMDID); + throw new ProcessRequestException(DATASM_NOT_IMPLEMENTED, SMPPConstant.STAT_ESME_RSYSERR); } public void onAcceptCancelSm(CancelSm cancelSm, SMPPServerSession source) From 5ad967528e4d7eea89a492d5a98c92cbefd23505 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 15 Jan 2017 15:27:59 +0100 Subject: [PATCH 182/212] Only allow transceiver in SMPPServerSimulator. --- .../jsmpp/examples/SMPPServerSimulator.java | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java index 256766a..db69b88 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/SMPPServerSimulator.java @@ -22,6 +22,7 @@ import org.jsmpp.PDUStringException; import org.jsmpp.SMPPConstant; +import org.jsmpp.bean.BindType; import org.jsmpp.bean.CancelSm; import org.jsmpp.bean.DataCodings; import org.jsmpp.bean.DataSm; @@ -165,25 +166,28 @@ public WaitBindTask(SMPPServerSession serverSession, String systemId, String pas public void run() { try { - BindRequest bindRequest = serverSession.waitForBind(1000); + BindRequest bindRequest = serverSession.waitForBind(5000); try { - if (systemId.equals(bindRequest.getSystemId())) { - if (password.equals(bindRequest.getPassword())) { - LOGGER.info("Accepting bind for session {}, interface version {}", serverSession.getSessionId(), bindRequest.getInterfaceVersion()); - // The systemId identifies the SMSC to the ESME. - bindRequest.accept(SMSC_SYSTEMID, InterfaceVersion.IF_34); + if (BindType.BIND_TRX.equals(bindRequest.getBindType())) { + if (systemId.equals(bindRequest.getSystemId())) { + if (password.equals(bindRequest.getPassword())) { + LOGGER.info("Accepting bind for session {}, interface version {}", serverSession.getSessionId(), bindRequest.getInterfaceVersion()); + // The systemId identifies the SMSC to the ESME. + bindRequest.accept(SMSC_SYSTEMID, InterfaceVersion.IF_34); + } else { + LOGGER.info("Rejecting bind for session {}, interface version {}, invalid password", serverSession.getSessionId(), bindRequest.getInterfaceVersion()); + bindRequest.reject(SMPPConstant.STAT_ESME_RINVPASWD); + } + } else { + LOGGER.info("Rejecting bind for session {}, interface version {}, invalid system id", serverSession.getSessionId(), bindRequest.getInterfaceVersion()); + bindRequest.reject(SMPPConstant.STAT_ESME_RINVSYSID); } - else { - LOGGER.info("Rejecting bind for session {}, interface version {}, invalid password", serverSession.getSessionId(), bindRequest.getInterfaceVersion()); - bindRequest.reject(SMPPConstant.STAT_ESME_RINVPASWD); - } - } - else { - LOGGER.info("Rejecting bind for session {}, interface version {}, invalid system id", serverSession.getSessionId(), bindRequest.getInterfaceVersion()); - bindRequest.reject(SMPPConstant.STAT_ESME_RINVSYSID); + } else { + LOGGER.info("Rejecting bind for session {}, interface version {}, only accept transceiver", serverSession.getSessionId(), bindRequest.getInterfaceVersion()); + bindRequest.reject(SMPPConstant.STAT_ESME_RBINDFAIL); } } catch (PDUStringException e) { - LOGGER.error("Invalid system id", e); + LOGGER.error("Invalid system id: " + SMSC_SYSTEMID, e); bindRequest.reject(SMPPConstant.STAT_ESME_RSYSERR); } From 6cfa2821c6e387cc5067b9e7217d44c398c765a4 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 15 Jan 2017 16:49:04 +0100 Subject: [PATCH 183/212] Fixed typo --- .../org/jsmpp/examples/AsyncSubmitReceiveDeliverSmExample.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/AsyncSubmitReceiveDeliverSmExample.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/AsyncSubmitReceiveDeliverSmExample.java index 1d1fe01..1b74225 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/AsyncSubmitReceiveDeliverSmExample.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/AsyncSubmitReceiveDeliverSmExample.java @@ -121,7 +121,7 @@ public void run() { counter.incrementAndGet(); } catch (InvalidResponseException e) { // Invalid response - LOGGER.error("Receive invalid respose", e); + LOGGER.error("Receive invalid response", e); counter.incrementAndGet(); } catch (NegativeResponseException e) { // Receiving negative response (non-zero command_status) From fa730844b2b3d55e54496e1f44e4f6d7080925f4 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Wed, 25 Jan 2017 12:12:14 +0100 Subject: [PATCH 184/212] Removed synchronized for close to prevent deadlock. --- jsmpp/src/main/java/org/jsmpp/extra/PendingResponse.java | 6 +++--- .../src/main/java/org/jsmpp/session/AbstractSession.java | 8 +++----- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/extra/PendingResponse.java b/jsmpp/src/main/java/org/jsmpp/extra/PendingResponse.java index 6e0bb7f..bf06c0a 100644 --- a/jsmpp/src/main/java/org/jsmpp/extra/PendingResponse.java +++ b/jsmpp/src/main/java/org/jsmpp/extra/PendingResponse.java @@ -93,10 +93,10 @@ public T getResponse() { } /** - * Wait until response receive or timeout already reach. + * Wait until response received or timeout already reached. * - * @throws ResponseTimeoutException if timeout reach. - * @throws InvalidResponseException if receive invalid response. + * @throws ResponseTimeoutException if timeout reached. + * @throws InvalidResponseException if received invalid response. */ public void waitDone() throws ResponseTimeoutException, InvalidResponseException { diff --git a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java index 1a47a25..7b8f0e0 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java @@ -200,7 +200,7 @@ public DataSmResult dataShortMessage(String serviceType, return new DataSmResult(resp.getMessageId(), resp.getOptionalParameters()); } - public synchronized void close() { + public void close() { logger.debug("Close session {}", sessionId); SessionContext ctx = sessionContext(); SessionState sessionState = ctx.getSessionState(); @@ -214,12 +214,11 @@ public synchronized void close() { // Make sure the enquireLinkThread doesn't wait for itself if (Thread.currentThread() != enquireLinkSender) { - if (enquireLinkSender != null) { + if (enquireLinkSender != null && enquireLinkSender.isAlive()) { logger.debug("Stop enquireLinkSender for session {}", sessionId); try { enquireLinkSender.interrupt(); enquireLinkSender.join(); - enquireLinkSender = null; } catch (InterruptedException e) { Thread.currentThread().interrupt(); logger.warn("Interrupted while waiting for enquireLinkSender thread to exit"); @@ -290,7 +289,7 @@ protected Command executeSendCommand(SendCommandTask task, long timeout) try { pendingResp.waitDone(); - logger.debug("{} response received for session {}", task.getCommandName(), sessionId); + logger.debug("{} response with sequence {} received for session {}", task.getCommandName(), seqNum, sessionId); } catch (ResponseTimeoutException e) { pendingResponse.remove(seqNum); throw new ResponseTimeoutException("No response after waiting for " @@ -305,7 +304,6 @@ protected Command executeSendCommand(SendCommandTask task, long timeout) Command resp = pendingResp.getResponse(); validateResponse(resp); return resp; - } /** From 9ad13562d4ccba98a75cdcd339a1af9f60180cf2 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Wed, 25 Jan 2017 14:48:28 +0100 Subject: [PATCH 185/212] Updated for 2.3.4 release. --- CHANGES.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index f9cdc8e..eaab79d 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,11 @@ Changes: +2.3.4 +- Removed synchronized from close to prevent deadlock +- When stopping the enquire_link sender, only stop when still alive +- Use slf4j-simple in test case, instead of log4j and System.Out +- Improve the SMPP server simulator example + 2.3.3 - Change the close of session method, to fix deadlock in Apache Camel SMPP component From cdfaa64517d27bdc0a58d066571397d1da668974 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Wed, 25 Jan 2017 14:57:26 +0100 Subject: [PATCH 186/212] Updated to 2.3.5-SNAPSHOT. --- jsmpp-examples/pom.xml | 2 +- jsmpp/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/jsmpp-examples/pom.xml b/jsmpp-examples/pom.xml index be53933..1174157 100644 --- a/jsmpp-examples/pom.xml +++ b/jsmpp-examples/pom.xml @@ -3,7 +3,7 @@ jsmpp-pom org.jsmpp - 2.3.4 + 2.3.5-SNAPSHOT 4.0.0 diff --git a/jsmpp/pom.xml b/jsmpp/pom.xml index 514285a..39710b3 100644 --- a/jsmpp/pom.xml +++ b/jsmpp/pom.xml @@ -3,7 +3,7 @@ org.jsmpp jsmpp-pom - 2.3.4 + 2.3.5-SNAPSHOT 4.0.0 bundle diff --git a/pom.xml b/pom.xml index 89c35bd..4379118 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.jsmpp jsmpp-pom - 2.3.4 + 2.3.5-SNAPSHOT pom jSMPP - Parent From d168a5c9669e26e71ddd043bfb146e4820059283 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Thu, 26 Jan 2017 13:29:16 +0100 Subject: [PATCH 187/212] Add example of custom delivery receipt, accept by default delivery receipt without sub and dlvrd with value -1. --- .../ExampleDeliveryReceiptStripperTest.java | 63 +++++++++++++++++++ .../java/org/jsmpp/bean/DeliveryReceipt.java | 21 ++++--- .../jsmpp/util/DeliveryReceiptParserTest.java | 24 ++++++- 3 files changed, 99 insertions(+), 9 deletions(-) create mode 100644 jsmpp-examples/src/main/test/org/jsmpp/examples/receipts/ExampleDeliveryReceiptStripperTest.java diff --git a/jsmpp-examples/src/main/test/org/jsmpp/examples/receipts/ExampleDeliveryReceiptStripperTest.java b/jsmpp-examples/src/main/test/org/jsmpp/examples/receipts/ExampleDeliveryReceiptStripperTest.java new file mode 100644 index 0000000..0cf52b4 --- /dev/null +++ b/jsmpp-examples/src/main/test/org/jsmpp/examples/receipts/ExampleDeliveryReceiptStripperTest.java @@ -0,0 +1,63 @@ +package org.jsmpp.examples.receipts; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.util.Calendar; +import java.util.Date; + +import org.jsmpp.bean.DeliverSm; +import org.jsmpp.bean.DeliveryReceipt; +import org.jsmpp.bean.ESMClass; +import org.jsmpp.bean.GSMSpecificFeature; +import org.jsmpp.bean.MessageMode; +import org.jsmpp.bean.MessageType; +import org.jsmpp.util.InvalidDeliveryReceiptException; +import org.junit.Before; +import org.junit.Test; + +public class ExampleDeliveryReceiptStripperTest { + + private ExampleDeliveryReceiptStripper exampleDeliveryReceiptStripper; + + @Before + public void setUp() throws Exception { + exampleDeliveryReceiptStripper = new ExampleDeliveryReceiptStripper(); + } + + @Test + public void testParseValid() { + try { + DeliverSm deliverSm = new DeliverSm(); + deliverSm.setEsmClass(new ESMClass(MessageMode.DEFAULT, MessageType.SMSC_DEL_RECEIPT, GSMSpecificFeature.DEFAULT).value()); + deliverSm.setShortMessage( + ("id:0123456789 sub:001 dlvrd:001 submit date:0809011130 done date:0809021131 stat:DELIVRD").getBytes()); + DeliveryReceipt delReceipt = exampleDeliveryReceiptStripper.strip(deliverSm); + assertEquals("", delReceipt.getText()); + + assertEquals(1, delReceipt.getSubmitted()); + + Date submitDate = delReceipt.getSubmitDate(); + Date expectedSubmitDate = createDate(2008, 9, 1, 11, 30); + assertEquals(expectedSubmitDate, submitDate); + + Date doneDate = delReceipt.getDoneDate(); + Date expectedDoneDate = createDate(2008, 9, 2, 11, 31); + assertEquals(expectedDoneDate, doneDate); + } catch (InvalidDeliveryReceiptException e) { + fail("Failed parsing delivery receipt:" + e.getMessage()); + } + } + + private Date createDate(int year, int month, int day, int hour, int minute) { + return createDate(year, month, day, hour, minute, 0); + } + + private Date createDate(int year, int month, int day, int hour, int minute, int second) { + Calendar cal = Calendar.getInstance(); + cal.set(year, month - 1, day, hour, minute, second); + cal.set(Calendar.MILLISECOND, 0); + return cal.getTime(); + } + +} \ No newline at end of file diff --git a/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java b/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java index 42714d3..47b79b6 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java @@ -44,8 +44,8 @@ public class DeliveryReceipt { "yyMMddHHmm"); private String id; - private int submitted; - private int delivered; + private Integer submitted; + private Integer delivered; private Date submitDate; private Date doneDate; private DeliveryReceiptState finalStatus; @@ -63,10 +63,8 @@ public DeliveryReceipt(String formattedDeliveryReceipt) */ try { id = getDeliveryReceiptValue(DeliveryReceipt.DELREC_ID, formattedDeliveryReceipt); - submitted = Integer.parseInt(getDeliveryReceiptValue( - DeliveryReceipt.DELREC_SUB, formattedDeliveryReceipt)); - delivered = Integer.parseInt(getDeliveryReceiptValue( - DeliveryReceipt.DELREC_DLVRD, formattedDeliveryReceipt)); + submitted = getDeliveryReceiptIntValue(DeliveryReceipt.DELREC_SUB, formattedDeliveryReceipt); + delivered = getDeliveryReceiptIntValue(DeliveryReceipt.DELREC_DLVRD, formattedDeliveryReceipt); submitDate = string2Date(getDeliveryReceiptValue( DeliveryReceipt.DELREC_SUBMIT_DATE, formattedDeliveryReceipt)); doneDate = string2Date(getDeliveryReceiptValue( @@ -77,8 +75,7 @@ public DeliveryReceipt(String formattedDeliveryReceipt) error = getDeliveryReceiptValue(DeliveryReceipt.DELREC_ERR, formattedDeliveryReceipt); text = getDeliveryReceiptTextValue(formattedDeliveryReceipt); } catch (Exception e) { - throw new InvalidDeliveryReceiptException( - "There is an error found when parsing delivery receipt", e); + throw new InvalidDeliveryReceiptException("There is an error found when parsing delivery receipt", e); } } @@ -457,4 +454,12 @@ private static String getDeliveryReceiptTextValue(String source) { startIndex = startIndex + tmpAttr.length(); return source.substring(startIndex); } + + private static int getDeliveryReceiptIntValue(String attrName, String formattedDeliveryReceipt){ + String value = getDeliveryReceiptValue(attrName, formattedDeliveryReceipt); + if (value != null) { + return Integer.parseInt(value); + } + return -1; + } } diff --git a/jsmpp/src/test/java/org/jsmpp/util/DeliveryReceiptParserTest.java b/jsmpp/src/test/java/org/jsmpp/util/DeliveryReceiptParserTest.java index ff92ed7..fe5f6aa 100644 --- a/jsmpp/src/test/java/org/jsmpp/util/DeliveryReceiptParserTest.java +++ b/jsmpp/src/test/java/org/jsmpp/util/DeliveryReceiptParserTest.java @@ -15,7 +15,7 @@ */ public class DeliveryReceiptParserTest { private PDUDecomposer decomposer = new DefaultDecomposer(); - private static final String ORIGINAL_MESSAGE = "testing jsmpp bow"; + private static final String ORIGINAL_MESSAGE = "testing jSMPP bow"; @Test public void parseTextWithLowerCase() { @@ -90,6 +90,28 @@ public void parseWithSecondInDate() { fail("Failed parsing delivery receipt:" + e.getMessage()); } } + + @Test + public void parseWithoutSubAndDelivered() { + try { + DeliveryReceipt delReceipt = decomposer.deliveryReceipt("id:1526758174 submit date:1701240904 done date:1701250907 stat:DELIVRD err:000 text:" + ORIGINAL_MESSAGE); + assertEquals(delReceipt.getText(), ORIGINAL_MESSAGE); + + Date submitDate = delReceipt.getSubmitDate(); + Date expectedSubmitDate = createDate(2017, 1, 24, 9, 4, 0); + assertEquals(submitDate, expectedSubmitDate); + + Date doneDate = delReceipt.getDoneDate(); + Date expectedDoneDate = createDate(2017, 1, 25, 9, 7, 0); + assertEquals(doneDate, expectedDoneDate); + + assertEquals(delReceipt.getSubmitted(), -1); + assertEquals(delReceipt.getDelivered(), -1); + } catch (InvalidDeliveryReceiptException e) { + e.printStackTrace(); + fail("Failed parsing delivery receipt:" + e.getMessage()); + } + } private static Date createDate(int year, int month, int day, int hour, int minute) { return createDate(year, month, day, hour, minute, 0); From b801dc39093699673e898aeaed4723e49a313134 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Thu, 16 Feb 2017 22:43:22 +0100 Subject: [PATCH 188/212] Update Slf4j to 1.7.23 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4379118..3a35ca2 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ yyyyMMddHHmm ${maven.build.timestamp} UTF-8 - 1.7.22 + 1.7.23 1.2.17 4.12 6.8.21 From d90a9284c70c665eb6ef1f2fc7b8848d231a61ae Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Tue, 13 Jun 2017 14:48:50 +0200 Subject: [PATCH 189/212] Update Slf4j to 1.7.25 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3a35ca2..338c008 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ yyyyMMddHHmm ${maven.build.timestamp} UTF-8 - 1.7.23 + 1.7.25 1.2.17 4.12 6.8.21 From 1624a5e1f4c69819822269240b9aff0960c7c67e Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 13 Aug 2017 13:09:30 +0200 Subject: [PATCH 190/212] Update Maven plugins. --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 338c008..7103460 100644 --- a/pom.xml +++ b/pom.xml @@ -126,7 +126,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.6.0 + 3.6.2 1.6 1.6 @@ -152,7 +152,7 @@ maven-source-plugin - 3.0.0 + 3.0.1 verify From 274668d62e79ad726eaf9dadf317bb36b3c7a0d7 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sun, 13 Aug 2017 13:20:30 +0200 Subject: [PATCH 191/212] Rewrite the GSM 03.38 class, and add unit tests. --- .../SubmitMultipartMultilangualExample.java | 43 +------------- .../java/org/jsmpp/examples/util/Gsm0338.java | 57 +++++++++++++++++++ .../org/jsmpp/examples/util/Gsm0338Test.java | 55 ++++++++++++++++++ 3 files changed, 115 insertions(+), 40 deletions(-) create mode 100644 jsmpp-examples/src/main/java/org/jsmpp/examples/util/Gsm0338.java create mode 100644 jsmpp-examples/src/main/test/org/jsmpp/examples/util/Gsm0338Test.java diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/SubmitMultipartMultilangualExample.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/SubmitMultipartMultilangualExample.java index 082437a..9817f27 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/SubmitMultipartMultilangualExample.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/SubmitMultipartMultilangualExample.java @@ -31,6 +31,7 @@ import org.jsmpp.bean.RegisteredDelivery; import org.jsmpp.bean.SMSCDeliveryReceipt; import org.jsmpp.bean.TypeOfNumber; +import org.jsmpp.examples.util.Gsm0338; import org.jsmpp.extra.NegativeResponseException; import org.jsmpp.extra.ResponseTimeoutException; import org.jsmpp.extra.SessionState; @@ -136,13 +137,12 @@ private void sendAndWait() throws IOException, InterruptedException { LOGGER.error("Failed connect and bind to host", e); } - // configure variables according to if message contains national - // characters + // configure variables according to if message contains non-basic characters Alphabet alphabet = null; int maximumSingleMessageSize = 0; int maximumMultipartMessageSegmentSize = 0; byte[] byteSingleMessage = null; - if (Gsm0338.isEncodeableInGsm0338(messageBody)) { + if (Gsm0338.isBasicEncodeable(messageBody)) { byteSingleMessage = messageBody.getBytes(); alphabet = Alphabet.ALPHA_DEFAULT; maximumSingleMessageSize = MAX_SINGLE_MSG_SEGMENT_SIZE_7BIT; @@ -219,40 +219,3 @@ public static void main(String[] args) throws IOException, InterruptedException new SubmitMultipartMultilangualExample().sendAndWait(); } } - -/** - * Based on http://www.smsitaly.com/Download/ETSI_GSM_03.38.pdf - */ -class Gsm0338 { - - private static final short ESC_CHARACTER = (short) 27; - - private static final short[] isoGsm0338Array = { 64, 163, 36, 165, 232, 233, 249, 236, 242, 199, 10, 216, 248, 13, - 197, 229, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, 230, 223, 201, 32, 33, 34, 35, 164, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 161, 65, 66, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 196, 214, 209, - 220, 167, 191, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, 117, 118, 119, 120, 121, 122, 228, 246, 241, 252, 224 }; - - private static final short[][] extendedIsoGsm0338Array = { { 10, 12 }, { 20, 94 }, { 40, 123 }, { 41, 125 }, - { 47, 92 }, { 60, 91 }, { 61, 126 }, { 62, 93 }, { 64, 124 }, { 101, 164 } }; - - public static boolean isEncodeableInGsm0338(String isoString) { - byte[] isoBytes = isoString.getBytes(); - outer: for (int i = 0; i < isoBytes.length; i++) { - for (int j = 0; j < isoGsm0338Array.length; j++) { - if (isoGsm0338Array[j] == isoBytes[i]) { - continue outer; - } - } - for (int j = 0; j < extendedIsoGsm0338Array.length; j++) { - if (extendedIsoGsm0338Array[j][1] == isoBytes[i]) { - continue outer; - } - } - return false; - } - return true; - } - -} diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/util/Gsm0338.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/util/Gsm0338.java new file mode 100644 index 0000000..c254a19 --- /dev/null +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/util/Gsm0338.java @@ -0,0 +1,57 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.examples.util; + + +/** + * Based on https://en.wikipedia.org/wiki/GSM_03.38 + */ +public class Gsm0338 { + + private static final char[] BASIC_CHARS = { + // Basic Character Set + '@', '£', '$', '¥', 'è', 'é', 'ù', 'ì', 'ò', 'Ç', '\n', 'Ø', 'ø', '\r', 'Å', 'å', + 'Δ', '_', 'Φ', 'Γ', 'Λ', 'Ω', 'Π', 'Ψ', 'Σ', 'Θ', 'Ξ', 'Æ', 'æ', 'ß', 'É', + ' ', '!', '"', '#', '¤', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', + '¡', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'Ä', 'Ö', 'Ñ', 'Ü', '§', + '¿', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'ä', 'ö', 'ñ', 'ü', 'à', + // Basic Character Set Extension + '\f', '^', '{', '}', '\\', '[', '~', ']', '|', '€' + }; + + public static boolean isBasicEncodeable(String javaString) { + char[] javaChars = javaString.toCharArray(); + for(char c: javaChars) { + if (isBasicEncodeable(c)) { + continue; + } + return false; + } + return true; + } + + public static boolean isBasicEncodeable(char javaChar){ + for (char basicChar: BASIC_CHARS) { + if (basicChar == javaChar) { + return true; + } + } + return false; + } + +} diff --git a/jsmpp-examples/src/main/test/org/jsmpp/examples/util/Gsm0338Test.java b/jsmpp-examples/src/main/test/org/jsmpp/examples/util/Gsm0338Test.java new file mode 100644 index 0000000..ad645ad --- /dev/null +++ b/jsmpp-examples/src/main/test/org/jsmpp/examples/util/Gsm0338Test.java @@ -0,0 +1,55 @@ +package org.jsmpp.examples.util; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class Gsm0338Test { + + @Test + public void test_basic_chars() throws Exception { + assertTrue(Gsm0338 + .isBasicEncodeable("@£$¥èéùìòÇØøÅåΔ_ΦΓΛΩΠΨΣΘΞÆæßÉ !\"#¤%&\'()*+,-./0123456789:;<=>?¡ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÑܧ¿abcdefghijklmnopqrstuvwxyzäöñüà")); + } + + @Test + public void test_cr() throws Exception { + assertTrue(Gsm0338.isBasicEncodeable("\r")); + } + + @Test + public void test_cr_char() throws Exception { + assertTrue(Gsm0338.isBasicEncodeable('\r')); + } + + @Test + public void test_lf() throws Exception { + assertTrue(Gsm0338.isBasicEncodeable("\n")); + } + + @Test + public void test_lf_char() throws Exception { + assertTrue(Gsm0338.isBasicEncodeable('\n')); + } + + @Test + public void test_basic_extended_chars() throws Exception { + assertTrue(Gsm0338.isBasicEncodeable("^{}\\[~]|€")); + } + + @Test + public void test_null_string() throws Exception { + assertFalse(Gsm0338.isBasicEncodeable("\000")); + } + + @Test + public void test_null_char() throws Exception { + assertFalse(Gsm0338.isBasicEncodeable('\000')); + } + + @Test + public void test_non_gsm_0338_basic_chars() throws Exception { + assertFalse(Gsm0338.isBasicEncodeable("⺴⻤")); + } +} From bc8b11ca8b6c3fc03d79318ca307a30897701278 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Thu, 21 Sep 2017 23:59:42 +0200 Subject: [PATCH 192/212] Don't check the sequence number, but the session state. --- .../main/java/org/jsmpp/session/SMPPOutboundSession.java | 4 ++-- jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/SMPPOutboundSession.java b/jsmpp/src/main/java/org/jsmpp/session/SMPPOutboundSession.java index a0a1e6c..36e667b 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/SMPPOutboundSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/SMPPOutboundSession.java @@ -174,8 +174,8 @@ public BindRequest connectAndOutbind(String host, int port, public BindRequest connectAndOutbind(String host, int port, OutbindParameter outbindParameter, long timeout) throws IOException { logger.debug("Connect and bind to {} port {}", host, port); - if (sequence().currentValue() != 1) { - throw new IOException("Connection is already used"); + if (getSessionState() != SessionState.CLOSED) { + throw new IOException("Session state is not closed"); } conn = connFactory.createConnection(host, port); diff --git a/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java b/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java index 7b97351..2898bd2 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java @@ -214,11 +214,11 @@ public String connectAndBind(String host, int port, public String connectAndBind(String host, int port, BindParameter bindParam, long timeout) throws IOException { - logger.debug("Connect and bind to {} port {}", host, port); - if (sequence().currentValue() != 1) { - throw new IOException("Failed connecting"); + logger.debug("Connect and bind to {} port {}", host, port); + if (getSessionState() != SessionState.CLOSED) { + throw new IOException("Session state is not closed"); } - + conn = connFactory.createConnection(host, port); logger.info("Connected to {}", conn.getInetAddress()); From f1c516879e06071e57e59822de8092ec28e0045c Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Fri, 22 Sep 2017 15:27:02 +0200 Subject: [PATCH 193/212] Travis CI doesn't support openjdk6 anymore. --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d67d8f6..f98e5fc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: java jdk: + - oraclejdk9 - oraclejdk8 - - oraclejdk7 - - openjdk6 + - openjdk7 \ No newline at end of file From df92f39782400a21703b1ff0ef229a240adfeaac Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Sat, 23 Sep 2017 21:51:50 +0200 Subject: [PATCH 194/212] Update Maven plugins to compile under Java 9 --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 7103460..d97c5ec 100644 --- a/pom.xml +++ b/pom.xml @@ -114,12 +114,12 @@ org.apache.maven.wagon wagon-ssh - 2.10 + 3.0.0 org.apache.maven.wagon wagon-ssh-external - 2.10 + 3.0.0 @@ -165,7 +165,7 @@ pl.project13.maven git-commit-id-plugin - 2.1.15 + 2.2.3 initialize @@ -212,7 +212,7 @@ maven-jar-plugin - 2.6 + 3.0.2 From 16147aa21d6d0894ef11c7d68312a8c8f411ab9a Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Thu, 28 Sep 2017 00:57:20 +0200 Subject: [PATCH 195/212] Add custom Delivery Receipt stripper. --- .../CustomDeliveryReceiptStripper.java | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 jsmpp-examples/src/main/java/org/jsmpp/examples/receipts/CustomDeliveryReceiptStripper.java diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/receipts/CustomDeliveryReceiptStripper.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/receipts/CustomDeliveryReceiptStripper.java new file mode 100644 index 0000000..04ae419 --- /dev/null +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/receipts/CustomDeliveryReceiptStripper.java @@ -0,0 +1,113 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.examples.receipts; + +import java.util.Calendar; +import java.util.Date; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.jsmpp.bean.DeliverSm; +import org.jsmpp.bean.DeliveryReceipt; +import org.jsmpp.bean.DeliveryReceiptStrip; +import org.jsmpp.bean.MessageType; +import org.jsmpp.util.DeliveryReceiptState; +import org.jsmpp.util.InvalidDeliveryReceiptException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This is an example delivery receipt stripper. + * It also parses the final status "Successful". + * Use with DeliverSm.getDeliveryReceipt() + * + * @author pmoerenhout + */ +public class CustomDeliveryReceiptStripper implements DeliveryReceiptStrip { + + private static final Logger LOG = LoggerFactory.getLogger(CustomDeliveryReceiptStripper.class); + + private static final Pattern PATTERN = Pattern + .compile("^id:([0-9]*) sub:([0-9]{3}) dlvrd:([0-9]{3}) submit date:([0-9]{10}) done date:([0-9]{10}) stat:([a-zA-Z]*)$"); + + private static final CustomDeliveryReceiptStripper instance = new CustomDeliveryReceiptStripper(); + + public static CustomDeliveryReceiptStripper getInstance() { + return instance; + } + + private static Date string2Date(String date) { + int year = Integer.parseInt(date.substring(0, 2)); + int month = Integer.parseInt(date.substring(2, 4)); + int day = Integer.parseInt(date.substring(4, 6)); + int hour = Integer.parseInt(date.substring(6, 8)); + int minute = Integer.parseInt(date.substring(8, 10)); + Calendar cal = Calendar.getInstance(); + cal.set(convertTwoDigitYear(year), month - 1, day, hour, minute, 0); + cal.set(Calendar.MILLISECOND, 0); + return cal.getTime(); + } + + private static int convertTwoDigitYear(int year) { + if (year >= 0 && year <= 37) { + return 2000 + year; + } else if (year >= 38 && year <= 99) { + return 1900 + year; + } else { + // should never happen + return year; + } + } + + public DeliveryReceipt strip(DeliverSm deliverSm) throws InvalidDeliveryReceiptException { + if (MessageType.SMSC_DEL_RECEIPT.containedIn(deliverSm.getEsmClass()) || MessageType.SME_DEL_ACK.containedIn(deliverSm.getEsmClass())) { + LOG.info("Strip {}", new String(deliverSm.getShortMessage())); + return getDeliveryReceipt(deliverSm.getShortMessage()); + } else { + throw new InvalidDeliveryReceiptException( + "deliver_sm is not a Delivery Receipt since esm_class value = " + deliverSm.getEsmClass()); + } + } + + private DeliveryReceipt getDeliveryReceipt(byte[] shortMessage) throws InvalidDeliveryReceiptException { + DeliveryReceipt deliveryReceipt = new DeliveryReceipt(); + Matcher matcher = PATTERN.matcher(new String(shortMessage)); + if (matcher.find()) { + final String id = matcher.group(1); + final String submitted = matcher.group(2); + final String delivered = matcher.group(3); + final String submitDate = matcher.group(4); + final String doneDate = matcher.group(5); + final String status = matcher.group(6); + + deliveryReceipt.setId(id); + deliveryReceipt.setSubmitted(Integer.parseInt(submitted)); + deliveryReceipt.setDelivered(Integer.parseInt(delivered)); + deliveryReceipt.setSubmitDate(string2Date(submitDate)); + deliveryReceipt.setDoneDate(string2Date(doneDate)); + deliveryReceipt.setError("000"); + deliveryReceipt.setText(""); + if ("Successful".equals(status)) { + deliveryReceipt.setFinalStatus(DeliveryReceiptState.DELIVRD); + } else { + deliveryReceipt.setFinalStatus(DeliveryReceiptState.valueOf(status)); + } + } else { + throw new InvalidDeliveryReceiptException("The delivery receipt was not in expected regex format"); + } + return deliveryReceipt; + } + +} From d58d535299356d8ee1ea1cb0201b391d8b442c95 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Thu, 28 Sep 2017 00:57:46 +0200 Subject: [PATCH 196/212] Add custom Delivery Receipt stripper. --- ...erTest.java => CustomDeliveryReceiptStripperTest.java} | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) rename jsmpp-examples/src/main/test/org/jsmpp/examples/receipts/{ExampleDeliveryReceiptStripperTest.java => CustomDeliveryReceiptStripperTest.java} (86%) diff --git a/jsmpp-examples/src/main/test/org/jsmpp/examples/receipts/ExampleDeliveryReceiptStripperTest.java b/jsmpp-examples/src/main/test/org/jsmpp/examples/receipts/CustomDeliveryReceiptStripperTest.java similarity index 86% rename from jsmpp-examples/src/main/test/org/jsmpp/examples/receipts/ExampleDeliveryReceiptStripperTest.java rename to jsmpp-examples/src/main/test/org/jsmpp/examples/receipts/CustomDeliveryReceiptStripperTest.java index 0cf52b4..1b1acee 100644 --- a/jsmpp-examples/src/main/test/org/jsmpp/examples/receipts/ExampleDeliveryReceiptStripperTest.java +++ b/jsmpp-examples/src/main/test/org/jsmpp/examples/receipts/CustomDeliveryReceiptStripperTest.java @@ -16,13 +16,13 @@ import org.junit.Before; import org.junit.Test; -public class ExampleDeliveryReceiptStripperTest { +public class CustomDeliveryReceiptStripperTest { - private ExampleDeliveryReceiptStripper exampleDeliveryReceiptStripper; + private CustomDeliveryReceiptStripper customDeliveryReceiptStripper; @Before public void setUp() throws Exception { - exampleDeliveryReceiptStripper = new ExampleDeliveryReceiptStripper(); + customDeliveryReceiptStripper = new CustomDeliveryReceiptStripper(); } @Test @@ -32,7 +32,7 @@ public void testParseValid() { deliverSm.setEsmClass(new ESMClass(MessageMode.DEFAULT, MessageType.SMSC_DEL_RECEIPT, GSMSpecificFeature.DEFAULT).value()); deliverSm.setShortMessage( ("id:0123456789 sub:001 dlvrd:001 submit date:0809011130 done date:0809021131 stat:DELIVRD").getBytes()); - DeliveryReceipt delReceipt = exampleDeliveryReceiptStripper.strip(deliverSm); + DeliveryReceipt delReceipt = customDeliveryReceiptStripper.strip(deliverSm); assertEquals("", delReceipt.getText()); assertEquals(1, delReceipt.getSubmitted()); From edaa437d050cbdd1772679bf38d603e748fcd314 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Thu, 28 Sep 2017 00:58:09 +0200 Subject: [PATCH 197/212] Update to 2.3.5. --- jsmpp-examples/pom.xml | 2 +- jsmpp/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/jsmpp-examples/pom.xml b/jsmpp-examples/pom.xml index 1174157..a781c83 100644 --- a/jsmpp-examples/pom.xml +++ b/jsmpp-examples/pom.xml @@ -3,7 +3,7 @@ jsmpp-pom org.jsmpp - 2.3.5-SNAPSHOT + 2.3.5 4.0.0 diff --git a/jsmpp/pom.xml b/jsmpp/pom.xml index 39710b3..bd2e461 100644 --- a/jsmpp/pom.xml +++ b/jsmpp/pom.xml @@ -3,7 +3,7 @@ org.jsmpp jsmpp-pom - 2.3.5-SNAPSHOT + 2.3.5 4.0.0 bundle diff --git a/pom.xml b/pom.xml index d97c5ec..f4ecebc 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.jsmpp jsmpp-pom - 2.3.5-SNAPSHOT + 2.3.5 pom jSMPP - Parent From d0c3357dbec1ac75760c7eb829d7d9c61cdcaa99 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Thu, 28 Sep 2017 01:10:23 +0200 Subject: [PATCH 198/212] Update to 2.3.5. --- CHANGES.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index eaab79d..166c176 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,10 @@ Changes: +2.3.5 +- Rewrote the GSM 03.38 class +- Don't check explicitly the sequence 1, but the session state +- Add custom delivery receipt stripper + 2.3.4 - Removed synchronized from close to prevent deadlock - When stopping the enquire_link sender, only stop when still alive From 61acb94d13d26a07e730639b424ba82d3f48c2ad Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Thu, 28 Sep 2017 07:30:36 +0200 Subject: [PATCH 199/212] Update to 2.3.6-SNAPSHOT --- jsmpp-examples/pom.xml | 2 +- jsmpp/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/jsmpp-examples/pom.xml b/jsmpp-examples/pom.xml index a781c83..44b8ff6 100644 --- a/jsmpp-examples/pom.xml +++ b/jsmpp-examples/pom.xml @@ -3,7 +3,7 @@ jsmpp-pom org.jsmpp - 2.3.5 + 2.3.6-SNAPSHOT 4.0.0 diff --git a/jsmpp/pom.xml b/jsmpp/pom.xml index bd2e461..c90b8e1 100644 --- a/jsmpp/pom.xml +++ b/jsmpp/pom.xml @@ -3,7 +3,7 @@ org.jsmpp jsmpp-pom - 2.3.5 + 2.3.6-SNAPSHOT 4.0.0 bundle diff --git a/pom.xml b/pom.xml index f4ecebc..a8e131f 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.jsmpp jsmpp-pom - 2.3.5 + 2.3.6-SNAPSHOT pom jSMPP - Parent From 5525812212e6a5756febc27040a5d8658e52f7ff Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Mon, 9 Oct 2017 11:34:27 +0200 Subject: [PATCH 200/212] Remove extra semicolumn. --- .../src/main/java/org/jsmpp/examples/SimpleSubmitExample.java | 2 +- .../java/org/jsmpp/examples/SimpleSubmitRegisteredExample.java | 2 +- .../org/jsmpp/examples/SimpleSubmitSimpleReceiveExample.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/SimpleSubmitExample.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/SimpleSubmitExample.java index 0dfce20..a9c5502 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/SimpleSubmitExample.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/SimpleSubmitExample.java @@ -43,7 +43,7 @@ */ public class SimpleSubmitExample { private static final Logger LOGGER = LoggerFactory.getLogger(SimpleSubmitExample.class); - private static final TimeFormatter TIME_FORMATTER = new AbsoluteTimeFormatter();; + private static final TimeFormatter TIME_FORMATTER = new AbsoluteTimeFormatter(); public static void main(String[] args) { SMPPSession session = new SMPPSession(); diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/SimpleSubmitRegisteredExample.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/SimpleSubmitRegisteredExample.java index 626feea..c671625 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/SimpleSubmitRegisteredExample.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/SimpleSubmitRegisteredExample.java @@ -41,7 +41,7 @@ */ public class SimpleSubmitRegisteredExample { private static final Logger LOGGER = LoggerFactory.getLogger(SimpleSubmitExample.class); - private static final TimeFormatter TIME_FORMATTER = new AbsoluteTimeFormatter();; + private static final TimeFormatter TIME_FORMATTER = new AbsoluteTimeFormatter(); public static void main(String[] args) { SMPPSession session = new SMPPSession(); diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/SimpleSubmitSimpleReceiveExample.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/SimpleSubmitSimpleReceiveExample.java index 06a4bc1..0cee7e6 100755 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/SimpleSubmitSimpleReceiveExample.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/SimpleSubmitSimpleReceiveExample.java @@ -53,7 +53,7 @@ */ public class SimpleSubmitSimpleReceiveExample { private static final Logger LOGGER = LoggerFactory.getLogger(SimpleSubmitExample.class); - private static final TimeFormatter TIME_FORMATTER = new AbsoluteTimeFormatter();; + private static final TimeFormatter TIME_FORMATTER = new AbsoluteTimeFormatter(); public static void main(String[] args) { String server = "localhost"; From 74052af2f238502542df1b0ebdc6a3066f06871e Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Thu, 19 Oct 2017 17:44:04 +0200 Subject: [PATCH 201/212] Custom delivery receipt implementation plus example. Fix typo in method name composeSmeManualAcknowledment. --- .../receipts/CustomDeliveryReceipt.java | 415 ++++++++++++++++++ .../receipts/CustomDeliveryReceiptState.java | 84 ++++ .../CustomDeliveryReceiptStripper.java | 77 +--- .../CustomDeliveryReceiptStripperTest.java | 29 +- .../main/java/org/jsmpp/bean/DeliverSm.java | 8 +- .../java/org/jsmpp/bean/DeliveryReceipt.java | 2 +- .../jsmpp/bean/DeliveryReceiptInterface.java | 23 + 7 files changed, 546 insertions(+), 92 deletions(-) create mode 100644 jsmpp-examples/src/main/java/org/jsmpp/examples/receipts/CustomDeliveryReceipt.java create mode 100644 jsmpp-examples/src/main/java/org/jsmpp/examples/receipts/CustomDeliveryReceiptState.java create mode 100644 jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceiptInterface.java diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/receipts/CustomDeliveryReceipt.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/receipts/CustomDeliveryReceipt.java new file mode 100644 index 0000000..efff447 --- /dev/null +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/receipts/CustomDeliveryReceipt.java @@ -0,0 +1,415 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.examples.receipts; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.jsmpp.bean.DeliveryReceiptInterface; +import org.jsmpp.util.InvalidDeliveryReceiptException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author pmoerenhout + */ +public class CustomDeliveryReceipt implements DeliveryReceiptInterface { + private static final Logger LOG = LoggerFactory.getLogger(CustomDeliveryReceipt.class); + + private static final Pattern PATTERN = Pattern.compile( + "^id:([0-9]*) sub:([0-9]{3}) dlvrd:([0-9]{3}) submit date:([0-9]{10}) done date:([0-9]{10}) err:([0-9]{3}) stat:([a-zA-Z_]*) text:(.*)$"); + + // attributes of the custom delivery receipt + private static final String DELREC_ID = "id"; + private static final String DELREC_SUB = "sub"; + private static final String DELREC_DLVRD = "dlvrd"; + private static final String DELREC_SUBMIT_DATE = "submit date"; + private static final String DELREC_DONE_DATE = "done date"; + private static final String DELREC_ERR = "err"; + private static final String DELREC_STAT = "stat"; + private static final String DELREC_TEXT = "text"; + + /** + * Date format for the submit date and done date attribute + */ + private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyMMddHHmm"); + + private String id; + private Integer submitted; + private Integer delivered; + private Date submitDate; + private Date doneDate; + private CustomDeliveryReceiptState finalStatus; + private String error; + private String text; + + public CustomDeliveryReceipt() { + } + + public CustomDeliveryReceipt(String formattedDeliveryReceipt) + throws InvalidDeliveryReceiptException { + /* + * id:IIIIIIIIII sub:SSS dlvrd:DDD submit date:YYMMDDhhmm done + * date:YYMMDDhhmm stat:DDDDDDD err:E text: .......... + */ + try { + Matcher matcher = PATTERN.matcher(formattedDeliveryReceipt); + if (matcher.find()) { + id = matcher.group(1); + submitted = Integer.parseInt(matcher.group(2)); + delivered = Integer.parseInt(matcher.group(3)); + submitDate = string2Date(matcher.group(4)); + doneDate = string2Date(matcher.group(5)); + error = matcher.group(6); + finalStatus = CustomDeliveryReceiptState.valueOf(matcher.group(7)); + text = matcher.group(8); + } + } catch (Exception e) { + LOG.error("Parse error", e); + throw new InvalidDeliveryReceiptException("There is an error found when parsing custom delivery receipt", e); + } + } + + public CustomDeliveryReceipt(String id, int submitted, int delivered, + Date submitDate, Date doneDate, CustomDeliveryReceiptState finalStatus, + String error, String text) { + this.id = id; + this.submitted = submitted; + this.delivered = delivered; + this.submitDate = submitDate; + this.doneDate = doneDate; + this.finalStatus = finalStatus; + this.error = error; + if (text.length() > 20) { + this.text = text.substring(0, 20); + } else { + this.text = text; + } + } + + /** + * Create String representation of integer. Preceding 0 will be add as needed. + * + * @param value is the value. + * @param digit is the digit should be shown. + * @return the String representation of int value. + */ + + private static String intToString(int value, int digit) { + StringBuilder stringBuilder = new StringBuilder(digit); + stringBuilder.append(Integer.toString(value)); + while (stringBuilder.length() < digit) { + stringBuilder.insert(0, "0"); + } + return stringBuilder.toString(); + } + + /** + * YYMMDDhhmm where:
    • YY = last two digits of the year (00-99)
    • MM = month (01-12)
    • DD = day (01-31)
    • hh = hour (00-23)
    • + *
    • mm = minute (00-59)
    + * + * Java format is (yyMMddHHmm). + * + * @param date in String format. + * @throws NumberFormatException if there is contains non number on date parameter. + * @throws IndexOutOfBoundsException if the date length in String format is less than 10. + */ + private static Date string2Date(String date) { + int year = Integer.parseInt(date.substring(0, 2)); + int month = Integer.parseInt(date.substring(2, 4)); + int day = Integer.parseInt(date.substring(4, 6)); + int hour = Integer.parseInt(date.substring(6, 8)); + int minute = Integer.parseInt(date.substring(8, 10)); + int second = 0; + if (date.length() >= 12) { + second = Integer.parseInt(date.substring(10, 12)); + } + Calendar cal = Calendar.getInstance(); + cal.set(convertTwoDigitYear(year), month - 1, day, hour, minute, second); + cal.set(Calendar.MILLISECOND, 0); + return cal.getTime(); + } + + private static int convertTwoDigitYear(int year) { + if (year >= 0 && year <= 37) { + return 2000 + year; + } else if (year >= 38 && year <= 99) { + return 1900 + year; + } else { + // should never happen + return year; + } + } + + /** + * @return Returns the delivered. + */ + public int getDelivered() { + return delivered; + } + + /** + * @param delivered The delivered to set. + */ + public void setDelivered(int delivered) { + this.delivered = delivered; + } + + /** + * @return Returns the doneDate. + */ + public Date getDoneDate() { + return doneDate; + } + + /** + * @param doneDate The doneDate to set. + */ + public void setDoneDate(Date doneDate) { + this.doneDate = doneDate; + } + + /** + * @return Returns the error. + */ + public String getError() { + return error; + } + + /** + * @param error The error to set. + */ + public void setError(String error) { + this.error = error; + } + + /** + * @return Returns the finalStatus. + */ + public CustomDeliveryReceiptState getFinalStatus() { + return finalStatus; + } + + /** + * @param finalStatus The customFinalStatus to set. + */ + public void setFinalStatus(CustomDeliveryReceiptState finalStatus) { + this.finalStatus = finalStatus; + } + + + /** + * @return Returns the id. + */ + public String getId() { + return id; + } + + /** + * @param id The id to set. + */ + public void setId(String id) { + this.id = id; + } + + /** + * @return Returns the submitDate. + */ + public Date getSubmitDate() { + return submitDate; + } + + /** + * @param submitDate The submitDate to set. + */ + public void setSubmitDate(Date submitDate) { + this.submitDate = submitDate; + } + + /** + * @return Returns the submitted. + */ + public int getSubmitted() { + return submitted; + } + + /** + * @param submitted The submitted to set. + */ + public void setSubmitted(int submitted) { + this.submitted = submitted; + } + + /** + * @return Returns the text. + */ + public String getText() { + return text; + } + + /** + * Set the text of delivery receipt. Text more than 20 characters will be trim automatically. + * + * @param text the text to set. + */ + public void setText(String text) { + if (text != null && text.length() > 20) { + this.text = text.substring(0, 20); + } else { + this.text = text; + } + } + + @Override + public String toString() { + /* + * id:IIIIIIIIII sub:SSS dlvrd:DDD submit date:YYMMDDhhmm done + * date:YYMMDDhhmm stat:DDDDDDD err:E Text: . . . . . . . . . + */ + StringBuilder stringBuilder = new StringBuilder(120); + stringBuilder.append(DELREC_ID + ":" + id) + .append(" ") + .append(DELREC_SUB + ":" + intToString(submitted, 3)) + .append(" ") + .append(DELREC_DLVRD + ":" + intToString(delivered, 3)) + .append(" ") + .append(DELREC_SUBMIT_DATE + ":" + dateFormat.format(submitDate)) + .append(" ") + .append(DELREC_DONE_DATE + ":" + dateFormat.format(doneDate)) + .append(" ") + .append(DELREC_STAT + ":" + finalStatus) + .append(" ") + .append(DELREC_ERR + ":" + error) + .append(" ") + .append(DELREC_TEXT + ":" + text); + return stringBuilder.toString(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((dateFormat == null) ? 0 : dateFormat.hashCode()); + result = prime * result + delivered; + result = prime * result + + ((doneDate == null) ? 0 : doneDate.hashCode()); + result = prime * result + ((error == null) ? 0 : error.hashCode()); + result = prime * result + + ((finalStatus == null) ? 0 : finalStatus.hashCode()); + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + + ((submitDate == null) ? 0 : submitDate.hashCode()); + result = prime * result + submitted; + result = prime * result + ((text == null) ? 0 : text.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final CustomDeliveryReceipt other = (CustomDeliveryReceipt) obj; + if (!hasEqualId(other)) { + return false; + } + if (submitted != other.submitted) { + return false; + } + if (delivered != other.delivered) { + return false; + } + if (!hasEqualSubmitDate(other)) { + return false; + } + if (!hasEqualDoneDate(other)) { + return false; + } + if (!hasEqualFinalStatus(other)) { + return false; + } + if (!hasEqualError(other)) { + return false; + } + if (!hasEqualText(other)) { + return false; + } + return true; + } + + private boolean hasEqualId(CustomDeliveryReceipt other) { + if (id == null) { + if (other.id != null) { + return false; + } + } + return id.equals(other.id); + } + + private boolean hasEqualDoneDate(CustomDeliveryReceipt other) { + if (doneDate == null) { + if (other.doneDate != null) { + return false; + } + } + return doneDate.equals(other.doneDate); + } + + private boolean hasEqualError(CustomDeliveryReceipt other) { + if (error == null) { + if (other.error != null) { + return false; + } + } + return error.equals(other.error); + } + + private boolean hasEqualFinalStatus(CustomDeliveryReceipt other) { + if (finalStatus == null) { + if (other.finalStatus != null) { + return false; + } + } + return finalStatus.equals(other.finalStatus); + } + + private boolean hasEqualSubmitDate(CustomDeliveryReceipt other) { + if (submitDate == null) { + if (other.submitDate != null) { + return false; + } + } + return submitDate.equals(other.submitDate); + } + + private boolean hasEqualText(CustomDeliveryReceipt other) { + if (text == null) { + if (other.text != null) { + return false; + } + } + return text.equals(other.text); + } +} diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/receipts/CustomDeliveryReceiptState.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/receipts/CustomDeliveryReceiptState.java new file mode 100644 index 0000000..3cbcb32 --- /dev/null +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/receipts/CustomDeliveryReceiptState.java @@ -0,0 +1,84 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.examples.receipts; + +/** + * @author pmoerenhout * + */ +public enum CustomDeliveryReceiptState { + + /* the value could be use to store in database */ + /** + * ENROUTE + */ + ENROUTE(0), + /** + * DELIVERED + */ + DELIVRD(1), + /** + * EXPIRED + */ + EXPIRED(2), + /** + * DELETED + */ + DELETED(3), + /** + * UNDELIVERABLE + */ + UNDELIV(4), + /** + * ACCEPTED + */ + ACCEPTD(5), + /** + * UNKNOWN + */ + UNKNOWN(6), + /** + * REJECTED + */ + REJECTD(7), + /** + * DO NOT DISTURB REJECTED + */ + DND_REJECTED(9); + + private int value; + + CustomDeliveryReceiptState(int value) { + this.value = value; + } + + public static CustomDeliveryReceiptState getByName(String name) { + return valueOf(CustomDeliveryReceiptState.class, name.toUpperCase()); + } + + public static CustomDeliveryReceiptState valueOf(int value) + throws IllegalArgumentException { + for (CustomDeliveryReceiptState item : values()) { + if (item.value() == value) { + return item; + } + } + throw new IllegalArgumentException( + "No enum const CustomDeliveryReceiptState with value " + value); + } + + public int value() { + return value; + } +} diff --git a/jsmpp-examples/src/main/java/org/jsmpp/examples/receipts/CustomDeliveryReceiptStripper.java b/jsmpp-examples/src/main/java/org/jsmpp/examples/receipts/CustomDeliveryReceiptStripper.java index 04ae419..e13596c 100644 --- a/jsmpp-examples/src/main/java/org/jsmpp/examples/receipts/CustomDeliveryReceiptStripper.java +++ b/jsmpp-examples/src/main/java/org/jsmpp/examples/receipts/CustomDeliveryReceiptStripper.java @@ -14,33 +14,19 @@ */ package org.jsmpp.examples.receipts; -import java.util.Calendar; -import java.util.Date; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import java.nio.charset.Charset; import org.jsmpp.bean.DeliverSm; -import org.jsmpp.bean.DeliveryReceipt; import org.jsmpp.bean.DeliveryReceiptStrip; import org.jsmpp.bean.MessageType; -import org.jsmpp.util.DeliveryReceiptState; import org.jsmpp.util.InvalidDeliveryReceiptException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** - * This is an example delivery receipt stripper. - * It also parses the final status "Successful". - * Use with DeliverSm.getDeliveryReceipt() + * This is an example delivery receipt stripper. It also parses the custom final status. Use with DeliverSm.getDeliveryReceipt() * * @author pmoerenhout */ -public class CustomDeliveryReceiptStripper implements DeliveryReceiptStrip { - - private static final Logger LOG = LoggerFactory.getLogger(CustomDeliveryReceiptStripper.class); - - private static final Pattern PATTERN = Pattern - .compile("^id:([0-9]*) sub:([0-9]{3}) dlvrd:([0-9]{3}) submit date:([0-9]{10}) done date:([0-9]{10}) stat:([a-zA-Z]*)$"); +public class CustomDeliveryReceiptStripper implements DeliveryReceiptStrip { private static final CustomDeliveryReceiptStripper instance = new CustomDeliveryReceiptStripper(); @@ -48,66 +34,13 @@ public static CustomDeliveryReceiptStripper getInstance() { return instance; } - private static Date string2Date(String date) { - int year = Integer.parseInt(date.substring(0, 2)); - int month = Integer.parseInt(date.substring(2, 4)); - int day = Integer.parseInt(date.substring(4, 6)); - int hour = Integer.parseInt(date.substring(6, 8)); - int minute = Integer.parseInt(date.substring(8, 10)); - Calendar cal = Calendar.getInstance(); - cal.set(convertTwoDigitYear(year), month - 1, day, hour, minute, 0); - cal.set(Calendar.MILLISECOND, 0); - return cal.getTime(); - } - - private static int convertTwoDigitYear(int year) { - if (year >= 0 && year <= 37) { - return 2000 + year; - } else if (year >= 38 && year <= 99) { - return 1900 + year; - } else { - // should never happen - return year; - } - } - - public DeliveryReceipt strip(DeliverSm deliverSm) throws InvalidDeliveryReceiptException { + public CustomDeliveryReceipt strip(DeliverSm deliverSm) throws InvalidDeliveryReceiptException { if (MessageType.SMSC_DEL_RECEIPT.containedIn(deliverSm.getEsmClass()) || MessageType.SME_DEL_ACK.containedIn(deliverSm.getEsmClass())) { - LOG.info("Strip {}", new String(deliverSm.getShortMessage())); - return getDeliveryReceipt(deliverSm.getShortMessage()); + return new CustomDeliveryReceipt(new String(deliverSm.getShortMessage(), Charset.forName("US-ASCII"))); } else { throw new InvalidDeliveryReceiptException( "deliver_sm is not a Delivery Receipt since esm_class value = " + deliverSm.getEsmClass()); } } - private DeliveryReceipt getDeliveryReceipt(byte[] shortMessage) throws InvalidDeliveryReceiptException { - DeliveryReceipt deliveryReceipt = new DeliveryReceipt(); - Matcher matcher = PATTERN.matcher(new String(shortMessage)); - if (matcher.find()) { - final String id = matcher.group(1); - final String submitted = matcher.group(2); - final String delivered = matcher.group(3); - final String submitDate = matcher.group(4); - final String doneDate = matcher.group(5); - final String status = matcher.group(6); - - deliveryReceipt.setId(id); - deliveryReceipt.setSubmitted(Integer.parseInt(submitted)); - deliveryReceipt.setDelivered(Integer.parseInt(delivered)); - deliveryReceipt.setSubmitDate(string2Date(submitDate)); - deliveryReceipt.setDoneDate(string2Date(doneDate)); - deliveryReceipt.setError("000"); - deliveryReceipt.setText(""); - if ("Successful".equals(status)) { - deliveryReceipt.setFinalStatus(DeliveryReceiptState.DELIVRD); - } else { - deliveryReceipt.setFinalStatus(DeliveryReceiptState.valueOf(status)); - } - } else { - throw new InvalidDeliveryReceiptException("The delivery receipt was not in expected regex format"); - } - return deliveryReceipt; - } - } diff --git a/jsmpp-examples/src/main/test/org/jsmpp/examples/receipts/CustomDeliveryReceiptStripperTest.java b/jsmpp-examples/src/main/test/org/jsmpp/examples/receipts/CustomDeliveryReceiptStripperTest.java index 1b1acee..4ce8005 100644 --- a/jsmpp-examples/src/main/test/org/jsmpp/examples/receipts/CustomDeliveryReceiptStripperTest.java +++ b/jsmpp-examples/src/main/test/org/jsmpp/examples/receipts/CustomDeliveryReceiptStripperTest.java @@ -1,13 +1,14 @@ package org.jsmpp.examples.receipts; +import static org.jsmpp.examples.receipts.CustomDeliveryReceiptState.DND_REJECTED; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; +import java.nio.charset.Charset; import java.util.Calendar; import java.util.Date; import org.jsmpp.bean.DeliverSm; -import org.jsmpp.bean.DeliveryReceipt; import org.jsmpp.bean.ESMClass; import org.jsmpp.bean.GSMSpecificFeature; import org.jsmpp.bean.MessageMode; @@ -31,21 +32,19 @@ public void testParseValid() { DeliverSm deliverSm = new DeliverSm(); deliverSm.setEsmClass(new ESMClass(MessageMode.DEFAULT, MessageType.SMSC_DEL_RECEIPT, GSMSpecificFeature.DEFAULT).value()); deliverSm.setShortMessage( - ("id:0123456789 sub:001 dlvrd:001 submit date:0809011130 done date:0809021131 stat:DELIVRD").getBytes()); - DeliveryReceipt delReceipt = customDeliveryReceiptStripper.strip(deliverSm); - assertEquals("", delReceipt.getText()); - - assertEquals(1, delReceipt.getSubmitted()); - - Date submitDate = delReceipt.getSubmitDate(); - Date expectedSubmitDate = createDate(2008, 9, 1, 11, 30); - assertEquals(expectedSubmitDate, submitDate); - - Date doneDate = delReceipt.getDoneDate(); - Date expectedDoneDate = createDate(2008, 9, 2, 11, 31); - assertEquals(expectedDoneDate, doneDate); + ("id:0123456789 sub:002 dlvrd:003 submit date:0809011130 done date:0809021131 err:123 stat:DND_REJECTED text:Hello World") + .getBytes(Charset.forName("US-ASCII"))); + CustomDeliveryReceipt delReceipt = customDeliveryReceiptStripper.strip(deliverSm); + assertEquals("0123456789", delReceipt.getId()); + assertEquals(2, delReceipt.getSubmitted()); + assertEquals(3, delReceipt.getDelivered()); + assertEquals(createDate(2008, 9, 1, 11, 30), delReceipt.getSubmitDate()); + assertEquals(createDate(2008, 9, 2, 11, 31), delReceipt.getDoneDate()); + assertEquals("123", delReceipt.getError()); + assertEquals(DND_REJECTED, delReceipt.getFinalStatus()); + assertEquals("Hello World", delReceipt.getText()); } catch (InvalidDeliveryReceiptException e) { - fail("Failed parsing delivery receipt:" + e.getMessage()); + fail("Failed parsing delivery receipt: " + e.getMessage()); } } diff --git a/jsmpp/src/main/java/org/jsmpp/bean/DeliverSm.java b/jsmpp/src/main/java/org/jsmpp/bean/DeliverSm.java index 0d71075..ac009c4 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/DeliverSm.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/DeliverSm.java @@ -73,7 +73,7 @@ public boolean isSmscDeliveryReceipt() { /** * Message Type. - * @param value + * @return */ public void setSmscDeliveryReceipt() { esmClass = composeSmscDeliveryReceipt(esmClass); @@ -91,7 +91,7 @@ public boolean isSmeManualAcknowledgment() { * Message Type. */ public void setSmeManualAcknowledgment() { - esmClass = composeSmeManualAcknowledment(esmClass); + esmClass = composeSmeManualAcknowledgment(esmClass); } /** @@ -219,7 +219,7 @@ public static final boolean isSmeDeliveryAcknowledgment(byte esmClass) { * @param esmClass * @return */ - public static final byte composeSmeDeliveryAcknowledment(byte esmClass) { + public static final byte composeSmeDeliveryAcknowledgment(byte esmClass) { return composeMessageType(esmClass, SMPPConstant.ESMCLS_SME_DELIV_ACK); } @@ -237,7 +237,7 @@ public static final boolean isSmeManualAcknowledgment(byte esmClass) { * @param esmClass * @return */ - public static final byte composeSmeManualAcknowledment(byte esmClass) { + public static final byte composeSmeManualAcknowledgment(byte esmClass) { return composeMessageType(esmClass, SMPPConstant.ESMCLS_SME_MANUAL_ACK); } diff --git a/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java b/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java index 47b79b6..900cdd7 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java @@ -26,7 +26,7 @@ * @author uudashr * */ -public class DeliveryReceipt { +public class DeliveryReceipt implements DeliveryReceiptInterface { // attributes of delivery receipt public static final String DELREC_ID = "id"; public static final String DELREC_SUB = "sub"; diff --git a/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceiptInterface.java b/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceiptInterface.java new file mode 100644 index 0000000..424dc9b --- /dev/null +++ b/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceiptInterface.java @@ -0,0 +1,23 @@ +package org.jsmpp.bean; + +import java.util.Date; + +public interface DeliveryReceiptInterface { + + String getId(); + + int getSubmitted(); + + int getDelivered(); + + Date getSubmitDate(); + + Date getDoneDate(); + + T getFinalStatus(); + + String getError(); + + String getText(); + +} From 6638fd8aad81ab0c6cd83902f8f658b95c103aff Mon Sep 17 00:00:00 2001 From: Pascal Schumacher Date: Fri, 20 Oct 2017 17:14:41 +0200 Subject: [PATCH 202/212] Always log caught exceptions when logging warn messages. --- jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java | 2 +- .../java/org/jsmpp/session/SMPPOutboundServerSession.java | 4 ++-- .../src/main/java/org/jsmpp/session/SMPPOutboundSession.java | 4 ++-- jsmpp/src/main/java/org/jsmpp/session/SMPPServerSession.java | 4 ++-- jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java index 7b8f0e0..2e8bd24 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java @@ -208,7 +208,7 @@ public void close() { try { connection().close(); } catch (IOException e) { - logger.warn("Failed to close connection: {}", e.getMessage()); + logger.warn("Failed to close connection:", e); } } diff --git a/jsmpp/src/main/java/org/jsmpp/session/SMPPOutboundServerSession.java b/jsmpp/src/main/java/org/jsmpp/session/SMPPOutboundServerSession.java index 10ff2c4..e90ff24 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/SMPPOutboundServerSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/SMPPOutboundServerSession.java @@ -441,11 +441,11 @@ private void readPDU() { notifyNoActivity(); } catch (IOException e) { - logger.warn("IOException while reading: {}", e.getMessage()); + logger.warn("IOException while reading:", e); close(); } catch (RuntimeException e) { - logger.warn("RuntimeException: {}", e.getMessage()); + logger.warn("RuntimeException:", e); unbindAndClose(); } } diff --git a/jsmpp/src/main/java/org/jsmpp/session/SMPPOutboundSession.java b/jsmpp/src/main/java/org/jsmpp/session/SMPPOutboundSession.java index 36e667b..edb02fa 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/SMPPOutboundSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/SMPPOutboundSession.java @@ -452,11 +452,11 @@ private void readPDU() { notifyNoActivity(); } catch (IOException e) { - logger.warn("IOException while reading: {}", e.getMessage()); + logger.warn("IOException while reading:", e); close(); } catch (RuntimeException e) { - logger.warn("RuntimeException: {}", e.getMessage()); + logger.warn("RuntimeException:", e); unbindAndClose(); } } diff --git a/jsmpp/src/main/java/org/jsmpp/session/SMPPServerSession.java b/jsmpp/src/main/java/org/jsmpp/session/SMPPServerSession.java index 1972bd9..9a6b605 100755 --- a/jsmpp/src/main/java/org/jsmpp/session/SMPPServerSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/SMPPServerSession.java @@ -537,10 +537,10 @@ private void readPDU() { } catch (SocketTimeoutException e) { notifyNoActivity(); } catch (IOException e) { - logger.warn("IOException while reading: {}", e.getMessage()); + logger.warn("IOException while reading:", e); close(); } catch (RuntimeException e) { - logger.warn("RuntimeException: {}", e.getMessage()); + logger.warn("RuntimeException:", e); unbindAndClose(); } } diff --git a/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java b/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java index 2898bd2..ca45661 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/SMPPSession.java @@ -619,10 +619,10 @@ private void readPDU() { } catch (SocketTimeoutException e) { notifyNoActivity(); } catch (IOException e) { - logger.warn("IOException while reading: {}", e.getMessage()); + logger.warn("IOException while reading:", e); close(); } catch (RuntimeException e) { - logger.warn("RuntimeException: {}", e.getMessage()); + logger.warn("RuntimeException:", e); unbindAndClose(); } } From 4f3aed2b847ce146fe5dfe10c6a3044b37ac2376 Mon Sep 17 00:00:00 2001 From: Pascal Schumacher Date: Fri, 20 Oct 2017 17:20:05 +0200 Subject: [PATCH 203/212] remove unused import statements --- .../main/java/org/jsmpp/session/DefaultSMPPClientOperation.java | 1 - .../main/java/org/jsmpp/session/DefaultSMPPServerOperation.java | 1 - jsmpp/src/main/java/org/jsmpp/session/SMPPClientOperation.java | 1 - 3 files changed, 3 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/DefaultSMPPClientOperation.java b/jsmpp/src/main/java/org/jsmpp/session/DefaultSMPPClientOperation.java index f42e262..63d6a8a 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/DefaultSMPPClientOperation.java +++ b/jsmpp/src/main/java/org/jsmpp/session/DefaultSMPPClientOperation.java @@ -19,7 +19,6 @@ import org.jsmpp.InvalidResponseException; import org.jsmpp.PDUException; import org.jsmpp.PDUSender; -import org.jsmpp.PDUStringException; import org.jsmpp.bean.Address; import org.jsmpp.bean.BindResp; import org.jsmpp.bean.BindType; diff --git a/jsmpp/src/main/java/org/jsmpp/session/DefaultSMPPServerOperation.java b/jsmpp/src/main/java/org/jsmpp/session/DefaultSMPPServerOperation.java index 12f851a..5f10252 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/DefaultSMPPServerOperation.java +++ b/jsmpp/src/main/java/org/jsmpp/session/DefaultSMPPServerOperation.java @@ -19,7 +19,6 @@ import org.jsmpp.InvalidResponseException; import org.jsmpp.PDUException; import org.jsmpp.PDUSender; -import org.jsmpp.PDUStringException; import org.jsmpp.bean.DataCoding; import org.jsmpp.bean.ESMClass; import org.jsmpp.bean.MessageState; diff --git a/jsmpp/src/main/java/org/jsmpp/session/SMPPClientOperation.java b/jsmpp/src/main/java/org/jsmpp/session/SMPPClientOperation.java index 44e0190..a26c390 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/SMPPClientOperation.java +++ b/jsmpp/src/main/java/org/jsmpp/session/SMPPClientOperation.java @@ -18,7 +18,6 @@ import org.jsmpp.InvalidResponseException; import org.jsmpp.PDUException; -import org.jsmpp.PDUStringException; import org.jsmpp.bean.Address; import org.jsmpp.bean.BindType; import org.jsmpp.bean.DataCoding; From 0ed0746f688396d0df633f360c3bb44dce58e249 Mon Sep 17 00:00:00 2001 From: Pascal Schumacher Date: Fri, 20 Oct 2017 17:28:57 +0200 Subject: [PATCH 204/212] remove unused non-visible code --- .../src/main/java/org/jsmpp/bean/LongSMS.java | 73 ------------------- .../session/SMPPOutboundServerSession.java | 27 ------- .../SMPPOutboundServerSessionBoundTX.java | 11 --- .../SMPPOutboundServerSessionClosed.java | 3 - .../SMPPOutboundServerSessionUnbound.java | 3 - .../state/SMPPOutboundSessionBoundTX.java | 6 +- .../state/SMPPOutboundSessionClosed.java | 3 - .../state/SMPPOutboundSessionOpen.java | 3 - .../state/SMPPOutboundSessionUnbound.java | 3 - .../session/state/SMPPServerSessionBound.java | 2 - .../session/state/SMPPServerSessionOpen.java | 3 - .../org/jsmpp/bean/SimpleDataCodingTest.java | 2 +- .../session/BindRequestReceiverTest.java | 6 +- .../jsmpp/util/RelativeTimeFormatterTest.java | 2 +- 14 files changed, 6 insertions(+), 141 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/LongSMS.java b/jsmpp/src/main/java/org/jsmpp/bean/LongSMS.java index e08f358..9cc3a76 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/LongSMS.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/LongSMS.java @@ -21,7 +21,6 @@ public class LongSMS { private static final Logger logger = LoggerFactory.getLogger(LongSMS.class); private final static int MAX_MESSAGE_SEGMENT_8BIT = 133; // 140-7 - private final static int MAX_MESSAGE_SEGMENT_7BIT = 152; private final static byte UDHIE_IDENTIFIER_SAR = 0x08; private final static byte UDHIE_SAR_LENGTH = 0x04; private static int referenceNumber = 0; @@ -91,76 +90,4 @@ public static byte[][] splitMessage8Bit(byte[] aMessage) { return segments; } - - private static byte[][] splitMessage7Bit(byte[] aMessage) { - // determine how many messages - int segmentNum = aMessage.length / MAX_MESSAGE_SEGMENT_7BIT; - int messageLength = aMessage.length; - if (segmentNum > 255) { - // this is too long, can't fit, so chop - segmentNum = 255; - messageLength = segmentNum * MAX_MESSAGE_SEGMENT_7BIT; - } - if ((messageLength % MAX_MESSAGE_SEGMENT_7BIT) > 0) - segmentNum++; - - byte[][] segments = new byte[segmentNum][]; - - int lengthOfData; - byte[] data7Bit; - byte[] tempBytes = new byte[MAX_MESSAGE_SEGMENT_7BIT]; - byte[] referenceNumber = copyShort2Bytes(getReferenceNumber()); - for (int i = 0; i < segmentNum; i++) { - if (segmentNum - i == 1) - lengthOfData = messageLength - i * MAX_MESSAGE_SEGMENT_7BIT; - else - lengthOfData = MAX_MESSAGE_SEGMENT_7BIT; - System.arraycopy(aMessage, i * MAX_MESSAGE_SEGMENT_7BIT, tempBytes, - 0, lengthOfData); - data7Bit = encode7Bit(new String(tempBytes, 0, lengthOfData)); - segments[i] = new byte[7 + data7Bit.length]; - - segments[i][0] = 6; // doesn't include itself - // SAR identifier - segments[i][1] = UDHIE_IDENTIFIER_SAR; - // SAR length - segments[i][2] = UDHIE_SAR_LENGTH; - // DATAGRAM REFERENCE NUMBER - System.arraycopy(referenceNumber, 0, segments[i], 3, 2); - // total number of segments - segments[i][5] = (byte) segmentNum; - // segment # - segments[i][6] = (byte) (i + 1); - // now copy the data - System.arraycopy(data7Bit, 0, segments[i], 7, data7Bit.length); - } - - return segments; - } - - private static byte[] encode7Bit(String aString) { - int i, j, power; - int length = aString.length(); - char[] tempChars = new char[length + 1]; - byte[] tempBytes = new byte[length]; - - aString.getChars(0, length, tempChars, 0); - tempChars[length] = 0; - - for (i = 0, j = 0, power = 1; i < length; i++, j++, power++) { - if (power == 8) { - i++; - if (i >= length) - break; - power = 1; - } - tempBytes[j] = (byte) ((tempChars[i] & ((1 << (8 - power)) - 1)) | ((tempChars[i + 1] & ((1 << power) - 1)) << (8 - power))); - tempChars[i + 1] = (char) (tempChars[i + 1] >> power); - } - - byte[] bytes = new byte[j]; - System.arraycopy(tempBytes, 0, bytes, 0, j); - - return bytes; - } } diff --git a/jsmpp/src/main/java/org/jsmpp/session/SMPPOutboundServerSession.java b/jsmpp/src/main/java/org/jsmpp/session/SMPPOutboundServerSession.java index 10ff2c4..4af1caa 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/SMPPOutboundServerSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/SMPPOutboundServerSession.java @@ -275,23 +275,6 @@ public String bind(BindParameter bindParam, long timeout) private class OutboundServerResponseHandlerImpl implements OutboundServerResponseHandler { - public void sendBindResp(String systemId, InterfaceVersion interfaceVersion, BindType bindType, int sequenceNumber) - throws IOException { - SMPPOutboundServerSession.this.sessionContext.bound(bindType); - sessionContext.bound(bindType); - logger.info("sendBindResp Bound!!!!!"); - try { - logger.info("OutboundServerResponseHandlerImpl sendBindResp"); - pduSender() - .sendBindResp(SMPPOutboundServerSession.this.out, bindType.responseCommandId(), sequenceNumber, systemId, - interfaceVersion); - } - catch (PDUStringException e) { - logger.error("Failed sending bind response", e); - // TODO uudashr: we have double checking when accept the bind request - } - } - public void processOutbind(Outbind outbind) throws ProcessRequestException { SMPPOutboundServerSession.this.outbindRequestReceiver.notifyAcceptOutbind(outbind); sessionContext.outbind(); @@ -460,14 +443,4 @@ private void notifyNoActivity() { } } } - - private class BoundStateListener implements SessionStateListener { - public void onStateChange(SessionState newState, SessionState oldState, Session source) { - logger.info("Session state changed from " + oldState + " to " + newState); - if (newState.isBound()) { - logger.info("Start enquireLinkSender"); - enquireLinkSender.start(); - } - } - } } diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionBoundTX.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionBoundTX.java index b3167b7..0a8732b 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionBoundTX.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionBoundTX.java @@ -20,8 +20,6 @@ import org.jsmpp.bean.Command; import org.jsmpp.extra.SessionState; import org.jsmpp.session.OutboundServerResponseHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * This class is bound_tx state implementation of {@link SMPPOutboundServerSessionState}. This @@ -35,20 +33,11 @@ */ class SMPPOutboundServerSessionBoundTX extends SMPPOutboundServerSessionBound implements SMPPOutboundServerSessionState { - private static final String NO_REQUEST_FIND_FOR_SEQUENCE_NUMBER = "No request find for sequence number "; - private static final Logger logger = LoggerFactory.getLogger(SMPPOutboundServerSessionBoundTX.class); public SessionState getSessionState() { return SessionState.BOUND_TX; } -// public void processBind(Command pduHeader, byte[] pdu, -// OutboundServerResponseHandler responseHandler) throws IOException -// { -// responseHandler.sendNegativeResponse(pduHeader.getCommandId(), -// SMPPConstant.STAT_ESME_RALYBND, pduHeader.getSequenceNumber()); -// } - public void processDeliverSm(Command pduHeader, byte[] pdu, OutboundServerResponseHandler responseHandler) throws IOException { responseHandler.sendNegativeResponse(pduHeader.getCommandId(), diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionClosed.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionClosed.java index 6376b66..827af98 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionClosed.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionClosed.java @@ -20,8 +20,6 @@ import org.jsmpp.extra.SessionState; import org.jsmpp.session.BaseResponseHandler; import org.jsmpp.session.OutboundServerResponseHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * This class is closed state implementation of {@link SMPPOutboundServerSessionState}. This @@ -35,7 +33,6 @@ */ class SMPPOutboundServerSessionClosed implements SMPPOutboundServerSessionState { private static final String INVALID_PROCESS_FOR_CLOSED_SESSION = "Invalid process for closed session state"; - private static final Logger logger = LoggerFactory.getLogger(SMPPOutboundServerSessionClosed.class); public SessionState getSessionState() { return SessionState.CLOSED; diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionUnbound.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionUnbound.java index 5f57b3f..c322ef0 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionUnbound.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundServerSessionUnbound.java @@ -20,8 +20,6 @@ import org.jsmpp.extra.SessionState; import org.jsmpp.session.BaseResponseHandler; import org.jsmpp.session.OutboundServerResponseHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * This class is unbound state implementation of {@link SMPPSessionState}. All @@ -35,7 +33,6 @@ */ class SMPPOutboundServerSessionUnbound implements SMPPOutboundServerSessionState { private static final String INVALID_PROCESS_FOR_UNBOUND_SESSION = "Invalid process for unbound session state"; - private static final Logger logger = LoggerFactory.getLogger(SMPPOutboundServerSessionUnbound.class); public SessionState getSessionState() { return SessionState.UNBOUND; diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionBoundTX.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionBoundTX.java index 7c4008a..4ac5676 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionBoundTX.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionBoundTX.java @@ -20,8 +20,6 @@ import org.jsmpp.bean.Command; import org.jsmpp.extra.SessionState; import org.jsmpp.session.OutboundResponseHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * This class is bound_tx state implementation of {@link SMPPOutboundSessionState}. This @@ -34,9 +32,7 @@ * */ class SMPPOutboundSessionBoundTX extends SMPPOutboundSessionBound implements SMPPOutboundSessionState { - private static final String NO_REQUEST_FIND_FOR_SEQUENCE_NUMBER = "No request find for sequence number "; - private static final Logger logger = LoggerFactory.getLogger(SMPPOutboundSessionBoundTX.class); - + public SessionState getSessionState() { return SessionState.BOUND_TX; } diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionClosed.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionClosed.java index 08dfffd..ad3035c 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionClosed.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionClosed.java @@ -20,8 +20,6 @@ import org.jsmpp.extra.SessionState; import org.jsmpp.session.BaseResponseHandler; import org.jsmpp.session.OutboundResponseHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * This class is closed state implementation of {@link SMPPOutboundSessionState}. This @@ -35,7 +33,6 @@ */ class SMPPOutboundSessionClosed implements SMPPOutboundSessionState { private static final String INVALID_PROCESS_FOR_CLOSED_SESSION = "Invalid process for closed session state"; - private static final Logger logger = LoggerFactory.getLogger(SMPPOutboundSessionClosed.class); public SessionState getSessionState() { return SessionState.CLOSED; diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionOpen.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionOpen.java index 208fd80..1b1e5c9 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionOpen.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionOpen.java @@ -27,8 +27,6 @@ import org.jsmpp.session.OutboundResponseHandler; import org.jsmpp.util.DefaultDecomposer; import org.jsmpp.util.PDUDecomposer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * This class is open state implementation of {@link SMPPOutboundSessionState}. When @@ -39,7 +37,6 @@ * @since 2.3 */ class SMPPOutboundSessionOpen implements SMPPOutboundSessionState { - private static final Logger logger = LoggerFactory.getLogger(SMPPOutboundSessionOpen.class); private static final String INVALID_PROCESS_FOR_OPEN_SESSION = "Invalid process for open session state"; private static final PDUDecomposer pduDecomposer = new DefaultDecomposer(); diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionUnbound.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionUnbound.java index 1639e82..0dc0fdc 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionUnbound.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionUnbound.java @@ -20,8 +20,6 @@ import org.jsmpp.extra.SessionState; import org.jsmpp.session.BaseResponseHandler; import org.jsmpp.session.OutboundResponseHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * This class is unbound state implementation of {@link SMPPOutboundSessionState}. All @@ -35,7 +33,6 @@ */ class SMPPOutboundSessionUnbound implements SMPPOutboundSessionState { private static final String INVALID_PROCESS_FOR_UNBOUND_SESSION = "Invalid process for unbound session state"; - private static final Logger logger = LoggerFactory.getLogger(SMPPOutboundSessionUnbound.class); public SessionState getSessionState() { return SessionState.UNBOUND; diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionBound.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionBound.java index 7d8c894..fb2a754 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionBound.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionBound.java @@ -27,8 +27,6 @@ abstract class SMPPServerSessionBound extends AbstractGenericSMPPSessionBound implements SMPPServerSessionState { - private static final String INVALID_PROCESS_FOR_BOUND_SESSION = "Invalid process for bound session state"; - public void processBind(Command pduHeader, byte[] pdu, ServerResponseHandler responseHandler) throws IOException { responseHandler.sendNegativeResponse(pduHeader.getCommandId(), diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionOpen.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionOpen.java index a32f5da..1455d20 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionOpen.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPServerSessionOpen.java @@ -25,15 +25,12 @@ import org.jsmpp.session.ServerResponseHandler; import org.jsmpp.util.DefaultDecomposer; import org.jsmpp.util.PDUDecomposer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * @author uudashr * */ class SMPPServerSessionOpen implements SMPPServerSessionState { - private static final Logger logger = LoggerFactory.getLogger(SMPPServerSessionOpen.class); private static final String INVALID_PROCESS_FOR_OPEN_SESSION = "Invalid process for open session state"; private static final PDUDecomposer pduDecomposer = new DefaultDecomposer(); diff --git a/jsmpp/src/test/java/org/jsmpp/bean/SimpleDataCodingTest.java b/jsmpp/src/test/java/org/jsmpp/bean/SimpleDataCodingTest.java index 4699908..23019cd 100644 --- a/jsmpp/src/test/java/org/jsmpp/bean/SimpleDataCodingTest.java +++ b/jsmpp/src/test/java/org/jsmpp/bean/SimpleDataCodingTest.java @@ -125,6 +125,6 @@ public void alpha8BitClass3() { @Test(expectedExceptions = IllegalArgumentException.class) public void testIllegalAlphabetUcs2() { - SimpleDataCoding dataCoding = new SimpleDataCoding(Alphabet.ALPHA_UCS2, MessageClass.CLASS1); + new SimpleDataCoding(Alphabet.ALPHA_UCS2, MessageClass.CLASS1); } } diff --git a/jsmpp/src/test/java/org/jsmpp/session/BindRequestReceiverTest.java b/jsmpp/src/test/java/org/jsmpp/session/BindRequestReceiverTest.java index de18aac..a5429a1 100644 --- a/jsmpp/src/test/java/org/jsmpp/session/BindRequestReceiverTest.java +++ b/jsmpp/src/test/java/org/jsmpp/session/BindRequestReceiverTest.java @@ -41,7 +41,7 @@ public void setUp() { public void testWaitTimeout() { try { - BindRequest request = requestReceiver.waitForRequest(1000); + requestReceiver.waitForRequest(1000); fail("Should fail since no request for 1000 millis"); } catch (IllegalStateException e) { e.printStackTrace(); @@ -55,7 +55,7 @@ public void testReceiveRequest() { try { requestReceiver.notifyAcceptBind(dummyBind()); - BindRequest request = requestReceiver.waitForRequest(1000); + requestReceiver.waitForRequest(1000); } catch (IllegalStateException e) { fail("Should not fail waitForRequest and success accepting request"); } catch (TimeoutException e) { @@ -97,7 +97,7 @@ public void testNoSingleAccept() { public void testNonSingleWait() { try { - BindRequest request = requestReceiver.waitForRequest(1000); + requestReceiver.waitForRequest(1000); fail("Should throw TimeoutException"); } catch (IllegalStateException e) { fail("Should throw TimeoutException"); diff --git a/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java b/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java index 939d6b1..23a365f 100644 --- a/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java +++ b/jsmpp/src/test/java/org/jsmpp/util/RelativeTimeFormatterTest.java @@ -96,7 +96,7 @@ public void formatRelativeDateWhenExceedsCentury() { GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("America/Denver")); date.add(Calendar.YEAR, 101); - String relativeTime = timeFormatter.format(date); + timeFormatter.format(date); fail("Expected IllegalArgumentException not thrown"); } From 7855ae78e919e71d9d87fc4cea832a3cb40622e2 Mon Sep 17 00:00:00 2001 From: Assen Sharlandjiev Date: Wed, 20 Dec 2017 14:46:15 +0200 Subject: [PATCH 205/212] #74 NPE in DeliveryReceipt constructor Fixed NPE in DeliveryReceipt constructor thrown when the delivery receipt does not have a submit date or done date. --- jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java b/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java index 900cdd7..c398bed 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java @@ -409,7 +409,9 @@ private static String getDeliveryReceiptValue(String attrName, String source) * format is less than 10. */ private static Date string2Date(String date) { - + if (date == null) { + return null; + } int year = Integer.parseInt(date.substring(0, 2)); int month = Integer.parseInt(date.substring(2, 4)); int day = Integer.parseInt(date.substring(4, 6)); From 8eac74c94219b2e8bb9fbdfe6e7082966a56cf84 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Fri, 22 Dec 2017 17:20:42 +0100 Subject: [PATCH 206/212] Add extra parenthesis, and add test case for nearly empty delivery report. --- .../main/java/org/jsmpp/bean/DeliveryReceipt.java | 9 +++++---- .../org/jsmpp/util/DeliveryReceiptParserTest.java | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java b/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java index c398bed..3300fcf 100644 --- a/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java +++ b/jsmpp/src/main/java/org/jsmpp/bean/DeliveryReceipt.java @@ -40,8 +40,7 @@ public class DeliveryReceipt implements DeliveryReceiptInterfacesubmit date and done date attribute */ - private final SimpleDateFormat dateFormat = new SimpleDateFormat( - "yyMMddHHmm"); + private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyMMddHHmm"); private String id; private Integer submitted; @@ -380,12 +379,14 @@ private static String getDeliveryReceiptValue(String attrName, String source) throws IndexOutOfBoundsException { String tmpAttr = attrName + ":"; int startIndex = source.indexOf(tmpAttr); - if (startIndex < 0) + if (startIndex < 0) { return null; + } startIndex = startIndex + tmpAttr.length(); int endIndex = source.indexOf(" ", startIndex); - if (endIndex > 0) + if (endIndex > 0) { return source.substring(startIndex, endIndex); + } return source.substring(startIndex); } diff --git a/jsmpp/src/test/java/org/jsmpp/util/DeliveryReceiptParserTest.java b/jsmpp/src/test/java/org/jsmpp/util/DeliveryReceiptParserTest.java index fe5f6aa..eee7e59 100644 --- a/jsmpp/src/test/java/org/jsmpp/util/DeliveryReceiptParserTest.java +++ b/jsmpp/src/test/java/org/jsmpp/util/DeliveryReceiptParserTest.java @@ -1,6 +1,7 @@ package org.jsmpp.util; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; import static org.testng.Assert.fail; import java.util.Calendar; @@ -112,6 +113,20 @@ public void parseWithoutSubAndDelivered() { fail("Failed parsing delivery receipt:" + e.getMessage()); } } + + @Test + public void parseWithOnlyStatus() throws Exception{ + DeliveryReceipt delReceipt = decomposer.deliveryReceipt("stat:DELIVRD"); + assertNull(delReceipt.getId()); + assertEquals(delReceipt.getFinalStatus(), DeliveryReceiptState.DELIVRD); + assertNull(delReceipt.getSubmitDate()); + assertNull(delReceipt.getDoneDate()); + + assertEquals(delReceipt.getSubmitted(), -1); + assertEquals(delReceipt.getDelivered(), -1); + assertNull(delReceipt.getError()); + assertNull(delReceipt.getText()); + } private static Date createDate(int year, int month, int day, int hour, int minute) { return createDate(year, month, day, hour, minute, 0); From e86b89be9620f7886b2529c98312d890b329a32f Mon Sep 17 00:00:00 2001 From: Pascal Schumacher Date: Fri, 19 Jan 2018 20:10:28 +0100 Subject: [PATCH 207/212] Add command status description to NegativeResponseException (closes #76) --- .../extra/NegativeResponseException.java | 36 +++++++++++++++++-- .../extra/NegativeResponseExceptionTest.java | 33 +++++++++++++++++ 2 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 jsmpp/src/test/java/org/jsmpp/extra/NegativeResponseExceptionTest.java diff --git a/jsmpp/src/main/java/org/jsmpp/extra/NegativeResponseException.java b/jsmpp/src/main/java/org/jsmpp/extra/NegativeResponseException.java index 76344f8..4fec431 100644 --- a/jsmpp/src/main/java/org/jsmpp/extra/NegativeResponseException.java +++ b/jsmpp/src/main/java/org/jsmpp/extra/NegativeResponseException.java @@ -1,5 +1,9 @@ package org.jsmpp.extra; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + import org.jsmpp.util.IntUtil; /** @@ -11,6 +15,25 @@ * */ public class NegativeResponseException extends Exception { + static { + HashMap mapping = new HashMap(); + mapping.put(1, "Message Length is invalid"); + mapping.put(2, "Command Length is invalid"); + mapping.put(3, "Invalid Command ID"); + mapping.put(4, "Incorrect BIND Status for given command"); + mapping.put(5, "ESME Already in Bound State"); + mapping.put(6, "Invalid Priority Flag"); + mapping.put(7, "Invalid Registered Delivery Flag"); + mapping.put(8, "System Error"); + mapping.put(10, "Invalid Source Address"); + mapping.put(11, "Invalid Destination Address"); + mapping.put(12, "Message ID is invalid"); + mapping.put(13, "Bind Failed"); + mapping.put(14, "Invalid Password"); + mapping.put(15, "Invalid System ID"); + commandStatusToDescription = Collections.unmodifiableMap(mapping); + } + private static final Map commandStatusToDescription; private static final long serialVersionUID = 7198456791204091251L; private final int commandStatus; @@ -20,11 +43,20 @@ public class NegativeResponseException extends Exception { * @param commandStatus is the command_status. */ public NegativeResponseException(int commandStatus) { - super("Negative response " + IntUtil.toHexString(commandStatus) - + " found"); + super(createMessageForCommandStatus(commandStatus)); this.commandStatus = commandStatus; } + private static String createMessageForCommandStatus(int commandStatus) { + String commandStatusHex = IntUtil.toHexString(commandStatus); + String description = commandStatusToDescription.get(commandStatus); + if (description != null) { + return String.format("Negative response %s (%s) found", commandStatusHex, description); + } else { + return String.format("Negative response %s found", commandStatusHex); + } + } + /** * Get the command_status. * diff --git a/jsmpp/src/test/java/org/jsmpp/extra/NegativeResponseExceptionTest.java b/jsmpp/src/test/java/org/jsmpp/extra/NegativeResponseExceptionTest.java new file mode 100644 index 0000000..172bafb --- /dev/null +++ b/jsmpp/src/test/java/org/jsmpp/extra/NegativeResponseExceptionTest.java @@ -0,0 +1,33 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.jsmpp.extra; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import org.testng.annotations.Test; + +public class NegativeResponseExceptionTest { + + @Test + public void testKnownCommandStatusValue() { + assertThat(new NegativeResponseException(11).getMessage(), is("Negative response 0000000b (Invalid Destination Address) found")); + } + + @Test + public void testUnknownCommandStatusValue() { + assertThat(new NegativeResponseException(400).getMessage(), is("Negative response 00000190 found")); + } +} From c55ce5bb7e54cd360b4f818c2b5e948c8a8e8359 Mon Sep 17 00:00:00 2001 From: Pascal Schumacher Date: Mon, 22 Jan 2018 22:18:29 +0100 Subject: [PATCH 208/212] Add missing command status description (according to SMMP 3.4) to NegativeResponseException (closes #76) --- .../extra/NegativeResponseException.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/jsmpp/src/main/java/org/jsmpp/extra/NegativeResponseException.java b/jsmpp/src/main/java/org/jsmpp/extra/NegativeResponseException.java index 4fec431..f40f3ce 100644 --- a/jsmpp/src/main/java/org/jsmpp/extra/NegativeResponseException.java +++ b/jsmpp/src/main/java/org/jsmpp/extra/NegativeResponseException.java @@ -25,12 +25,56 @@ public class NegativeResponseException extends Exception { mapping.put(6, "Invalid Priority Flag"); mapping.put(7, "Invalid Registered Delivery Flag"); mapping.put(8, "System Error"); + // 9 is reserved mapping.put(10, "Invalid Source Address"); mapping.put(11, "Invalid Destination Address"); mapping.put(12, "Message ID is invalid"); mapping.put(13, "Bind Failed"); mapping.put(14, "Invalid Password"); mapping.put(15, "Invalid System ID"); + // 16 is reserved + mapping.put(17, "Cancel SM Failed"); + // 18 is reserved + mapping.put(19, "Replace SM Failed"); + mapping.put(20, "Message Queue Full"); + mapping.put(21, "Invalid Service Type"); + // 22 - 50 are reserved + mapping.put(51, "Invalid number of destinations"); + mapping.put(52, "Invalid Distribution List name"); + // 53 - 63 are reserved + mapping.put(64, "Destination flag is invalid (submit_multi)"); + // 65 is reserved + mapping.put(66, "Invalid 'submit with replace' request"); + mapping.put(67, "Invalid esm_class field data"); + mapping.put(69, "submit_sm or submit_multi failed"); + // 70 - 71 are reserved + mapping.put(72, "Invalid Source address TON"); + mapping.put(73, "Invalid Source address NPI"); + mapping.put(80, "Invalid Destination address TON"); + mapping.put(81, "Invalid Destination address NPI"); + // 82 is reserved + mapping.put(83, "Invalid system_type field"); + mapping.put(84, "Invalid replace_if_present flag"); + mapping.put(85, "Invalid number of messages"); + // 86 - 87 are reserved + mapping.put(88, "Throttling error (ESME has exceeded allowed message limits)"); + // 89 - 96 are reserved + mapping.put(97, "Invalid Scheduled Delivery Time"); + mapping.put(98, "Invalid message validity period (Expiry time)"); + mapping.put(99, "Predefined Message Invalid or Not Found"); + mapping.put(100, "ESME Receiver Temporary App Error Code"); + mapping.put(101, "ESME Receiver Permanent App Error Code"); + mapping.put(102, "ESME Receiver Reject Message Error Code"); + mapping.put(103, "query_sm request failed"); + // 104 - 191 are reserved + mapping.put(192, "Error in the optional part of the PDU Body"); + mapping.put(193, "Optional Parameter not allowed"); + mapping.put(194, "Invalid Parameter Length"); + mapping.put(195, "Expected Optional Parameter missing"); + mapping.put(196, "Invalid Optional Parameter Value"); + // 197 - 253 are reserved + mapping.put(254, "Delivery Failure (used for data_sm_resp)"); + mapping.put(255, "Unknown Error"); commandStatusToDescription = Collections.unmodifiableMap(mapping); } private static final Map commandStatusToDescription; From 035a9d9c0dab3c8f3fd343f9278a2018a489459f Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Mon, 5 Feb 2018 12:50:50 +0100 Subject: [PATCH 209/212] Use the actual sequence number. --- .../java/org/jsmpp/session/state/SMPPOutboundSessionOpen.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionOpen.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionOpen.java index 1b1e5c9..f566f46 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionOpen.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPOutboundSessionOpen.java @@ -64,7 +64,7 @@ public void processDeliverSmResp(Command pduHeader, byte[] pdu, public void processEnquireLink(Command pduHeader, byte[] pdu, BaseResponseHandler responseHandler) throws IOException { PendingResponse pendingResp = responseHandler - .removeSentItem(1); + .removeSentItem(pduHeader.getSequenceNumber()); if (pendingResp != null) { pendingResp.doneWithInvalidResponse(new InvalidResponseException( "Receive unexpected enquire_link")); From 932a4d6244abc50211597969386a78863061be95 Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Mon, 5 Feb 2018 12:51:15 +0100 Subject: [PATCH 210/212] Prepare for 2.3.6 release --- CHANGES.txt | 7 +++++++ jsmpp-examples/pom.xml | 2 +- jsmpp/pom.xml | 2 +- pom.xml | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 166c176..25e8ae0 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,12 @@ Changes: +2.3.6 +- Add descriptions to negative response exceptions. +- Added custom delivery receipt examples +- Fix NPE in DeliveryReceipt constructor when date was blank +- Removed unused code +- Fix typo in composeSmeManualAcknowledgment method name + 2.3.5 - Rewrote the GSM 03.38 class - Don't check explicitly the sequence 1, but the session state diff --git a/jsmpp-examples/pom.xml b/jsmpp-examples/pom.xml index 44b8ff6..162ce50 100644 --- a/jsmpp-examples/pom.xml +++ b/jsmpp-examples/pom.xml @@ -3,7 +3,7 @@ jsmpp-pom org.jsmpp - 2.3.6-SNAPSHOT + 2.3.6 4.0.0 diff --git a/jsmpp/pom.xml b/jsmpp/pom.xml index c90b8e1..50f0583 100644 --- a/jsmpp/pom.xml +++ b/jsmpp/pom.xml @@ -3,7 +3,7 @@ org.jsmpp jsmpp-pom - 2.3.6-SNAPSHOT + 2.3.6 4.0.0 bundle diff --git a/pom.xml b/pom.xml index a8e131f..002003e 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.jsmpp jsmpp-pom - 2.3.6-SNAPSHOT + 2.3.6 pom jSMPP - Parent From ab2916b2209733d52272c18ed5eca3bfd9e09c9b Mon Sep 17 00:00:00 2001 From: Pim Moerenhout Date: Wed, 7 Feb 2018 14:39:33 +0100 Subject: [PATCH 211/212] Move to 2.3.7-SNAPSHOT release --- jsmpp-examples/pom.xml | 2 +- jsmpp/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/jsmpp-examples/pom.xml b/jsmpp-examples/pom.xml index 162ce50..e3f23ca 100644 --- a/jsmpp-examples/pom.xml +++ b/jsmpp-examples/pom.xml @@ -3,7 +3,7 @@ jsmpp-pom org.jsmpp - 2.3.6 + 2.3.7-SNAPSHOT 4.0.0 diff --git a/jsmpp/pom.xml b/jsmpp/pom.xml index 50f0583..8333777 100644 --- a/jsmpp/pom.xml +++ b/jsmpp/pom.xml @@ -3,7 +3,7 @@ org.jsmpp jsmpp-pom - 2.3.6 + 2.3.7-SNAPSHOT 4.0.0 bundle diff --git a/pom.xml b/pom.xml index 002003e..e36f826 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.jsmpp jsmpp-pom - 2.3.6 + 2.3.7-SNAPSHOT pom jSMPP - Parent From 6e2041a07732fdf4ddc3029bc774ae1880e2de77 Mon Sep 17 00:00:00 2001 From: vharseko Date: Fri, 8 Jun 2018 14:27:42 +0300 Subject: [PATCH 212/212] fix logs errors --- jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java | 2 +- .../main/java/org/jsmpp/session/state/SMPPSessionOpen.java | 4 ++-- jsmpp/src/main/java/org/jsmpp/util/StringParameter.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java index 2e8bd24..670f474 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java +++ b/jsmpp/src/main/java/org/jsmpp/session/AbstractSession.java @@ -289,7 +289,7 @@ protected Command executeSendCommand(SendCommandTask task, long timeout) try { pendingResp.waitDone(); - logger.debug("{} response with sequence {} received for session {}", task.getCommandName(), seqNum, sessionId); + logger.debug("{} response with sequence {} received for session {}", new Object[] {task.getCommandName(), seqNum, sessionId}); } catch (ResponseTimeoutException e) { pendingResponse.remove(seqNum); throw new ResponseTimeoutException("No response after waiting for " diff --git a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionOpen.java b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionOpen.java index e67e698..87633a8 100644 --- a/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionOpen.java +++ b/jsmpp/src/main/java/org/jsmpp/session/state/SMPPSessionOpen.java @@ -54,11 +54,11 @@ public void processBindResp(Command pduHeader, byte[] pdu, .removeSentItem(pduHeader.getSequenceNumber()); if (pendingResp != null) { try { - logger.debug("Bind Response header ({}, {}, {}, {})", + logger.debug("Bind Response header ({}, {}, {}, {})",new Object[] { pduHeader.getCommandLength(), pduHeader.getCommandIdAsHex(), IntUtil.toHexString(pduHeader.getCommandStatus()), - pduHeader.getSequenceNumber()); + pduHeader.getSequenceNumber()}); BindResp resp = pduDecomposer.bindResp(pdu); pendingResp.done(resp); } catch (PDUStringException e) { diff --git a/jsmpp/src/main/java/org/jsmpp/util/StringParameter.java b/jsmpp/src/main/java/org/jsmpp/util/StringParameter.java index a6457d3..17215d4 100644 --- a/jsmpp/src/main/java/org/jsmpp/util/StringParameter.java +++ b/jsmpp/src/main/java/org/jsmpp/util/StringParameter.java @@ -32,7 +32,7 @@ public enum StringParameter { * password string parameter. */ //SMPP providers may be use long passwords over SMPP 3.4 standard (like t-sms.ru) - PASSWORD(StringType.C_OCTEC_STRING, 0, 256, true, SMPPConstant.STAT_ESME_RINVPASWD), + PASSWORD(StringType.C_OCTET_STRING, 0, 256, true, SMPPConstant.STAT_ESME_RINVPASWD), /** * system_type string parameter.