Skip to content

Commit

Permalink
Merge pull request #150 from zoufou/v0.6-beta
Browse files Browse the repository at this point in the history
v0.6b13
  • Loading branch information
farirat committed May 14, 2015
2 parents 2da1632 + c4c141e commit cdf5fd1
Show file tree
Hide file tree
Showing 12 changed files with 93 additions and 52 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ python:
# Command to install dependencies
install:
- python setup.py sdist
- sudo pip install dist/jasmin-0.6b12.tar.gz
- sudo pip install dist/jasmin-0.6b13.tar.gz
# Commands to run tests:
script:
# Add jasmind to system autostartup:
Expand Down
2 changes: 1 addition & 1 deletion jasmin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

MAJOR = 0
MINOR = 6
PATCH = 12
PATCH = 13
META = 'b'

def get_version():
Expand Down
1 change: 1 addition & 0 deletions jasmin/managers/clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,7 @@ def perspective_submit_sm(self, cid, SubmitSmPDU, priority = 1, validity_period
hashValues = {'system_id': source_connector.system_id,
'source_addr': SubmitSmPDU.params['source_addr'],
'destination_addr': SubmitSmPDU.params['destination_addr'],
'sub_date': datetime.datetime.now(),
'registered_delivery': SubmitSmPDU.params['registered_delivery'],
'expiry': source_connector.factory.config.dlr_expiry}
self.redisClient.setex(hashKey,
Expand Down
5 changes: 3 additions & 2 deletions jasmin/managers/content.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class DLRContentForSmpps(Content):
"""A DLR Content holding information about the origin SubmitSm sent from smpps and
receipt acknowledgment details"""

def __init__(self, message_status, msgid, system_id, source_addr, destination_addr):
def __init__(self, message_status, msgid, system_id, source_addr, destination_addr, sub_date):
properties = {}

# ESME_* statuses are returned from SubmitSmResp
Expand All @@ -81,7 +81,8 @@ def __init__(self, message_status, msgid, system_id, source_addr, destination_ad
'message_status': message_status,
'system_id': system_id,
'source_addr': source_addr,
'destination_addr': destination_addr}
'destination_addr': destination_addr,
'sub_date': str(sub_date)}

Content.__init__(self, msgid, properties = properties)

Expand Down
8 changes: 6 additions & 2 deletions jasmin/managers/listeners.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ def submit_sm_resp_event(self, r, amqpMessage):
system_id = smpps_map['system_id']
source_addr = smpps_map['source_addr']
destination_addr = smpps_map['destination_addr']
sub_date = smpps_map['sub_date']
registered_delivery = smpps_map['registered_delivery']
smpps_map_expiry = smpps_map['expiry']

Expand All @@ -356,7 +357,8 @@ def submit_sm_resp_event(self, r, amqpMessage):
msgid,
system_id,
source_addr,
destination_addr)
destination_addr,
sub_date)

routing_key = 'dlr_thrower.smpps'
self.log.debug("Publishing DLRContentForSmpps[%s] with routing_key[%s]" % (msgid, routing_key))
Expand Down Expand Up @@ -604,6 +606,7 @@ def deliver_sm_event(self, smpp, pdu, concatenated = False):
system_id = smpps_map['system_id']
source_addr = smpps_map['source_addr']
destination_addr = smpps_map['destination_addr']
sub_date = smpps_map['sub_date']
registered_delivery = smpps_map['registered_delivery']
smpps_map_expiry = smpps_map['expiry']

Expand All @@ -623,7 +626,8 @@ def deliver_sm_event(self, smpp, pdu, concatenated = False):
submit_sm_queue_id,
system_id,
source_addr,
destination_addr)
destination_addr,
sub_date)

routing_key = 'dlr_thrower.smpps'
self.log.debug("Publishing DLRContentForSmpps[%s] with routing_key[%s]" % (submit_sm_queue_id, routing_key))
Expand Down
11 changes: 7 additions & 4 deletions jasmin/managers/test/test_contents.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,32 +170,35 @@ def test_normal(self):
system_id = 'username'
source_addr = '999'
destination_addr = '111'
sub_date = datetime.now()

c = DLRContentForSmpps(message_status, msgid, system_id, source_addr, destination_addr)
c = DLRContentForSmpps(message_status, msgid, system_id, source_addr, destination_addr, sub_date)

self.assertEquals(c.body, msgid)
self.assertEquals(len(c['headers']), 5)
self.assertEquals(len(c['headers']), 6)
self.assertEquals(c['headers']['try-count'], 0)
self.assertEquals(c['headers']['message_status'], message_status)
self.assertEquals(c['headers']['system_id'], system_id)
self.assertEquals(c['headers']['source_addr'], source_addr)
self.assertEquals(c['headers']['destination_addr'], destination_addr)
self.assertEquals(c['headers']['sub_date'], str(sub_date))

def test_message_status(self):
msgid = 'msgid'
system_id = 'username'
source_addr = '999'
destination_addr = '111'
sub_date = datetime.now()

validStatuses = ['ESME_ROK', 'DELIVRD', 'EXPIRED', 'DELETED',
'UNDELIV', 'ACCEPTD', 'UNKNOWN', 'REJECTD', 'ESME_ANYTHING']

for status in validStatuses:
c = DLRContentForSmpps(status, msgid, system_id, source_addr, destination_addr)
c = DLRContentForSmpps(status, msgid, system_id, source_addr, destination_addr, sub_date)

self.assertEquals(c['headers']['message_status'], status)

self.assertRaises(InvalidParameterError, DLRContentForSmpps, 'anystatus', msgid, system_id, source_addr, destination_addr)
self.assertRaises(InvalidParameterError, DLRContentForSmpps, 'anystatus', msgid, system_id, source_addr, destination_addr, sub_date)

class DeliverSmContentTestCase(ContentTestCase):
def test_normal_nopickling(self):
Expand Down
81 changes: 47 additions & 34 deletions jasmin/protocols/smpp/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import struct
import math
import re
import datetime
import dateutil
from jasmin.vendor.smpp.pdu.operations import SubmitSM, DataSM, DeliverSM
from jasmin.protocols.smpp.configs import SMPPClientConfig
from jasmin.vendor.smpp.pdu.pdu_types import (EsmClass,
Expand Down Expand Up @@ -151,18 +153,59 @@ def SubmitSM(self, short_message, data_coding = 0, **kwargs):

return pdu

def getReceipt(self, dlr_pdu, msgid, source_addr, destination_addr, message_status):
def getReceipt(self, dlr_pdu, msgid, source_addr, destination_addr, message_status, sub_date):
"Will build a DataSm or a DeliverSm (depending on dlr_pdu) containing a receipt data"

# Prepare message_state
if message_status[:5] == 'ESME_':
if message_status == 'ESME_ROK':
message_state = MessageState.ACCEPTED
err = 0
else:
message_state = MessageState.UNDELIVERABLE
err = 10
elif message_status == 'UNDELIV':
message_state = MessageState.UNDELIVERABLE
err = 10
elif message_status == 'REJECTD':
message_state = MessageState.REJECTED
err = 20
elif message_status == 'DELIVRD':
err = 0
message_state = MessageState.DELIVERED
elif message_status == 'EXPIRED':
err = 30
message_state = MessageState.EXPIRED
elif message_status == 'DELETED':
err = 40
message_state = MessageState.DELETED
elif message_status == 'ACCEPTD':
err = 0
message_state = MessageState.ACCEPTED
elif message_status == 'UNKNOWN':
err = 50
message_state = MessageState.UNKNOWN
else:
raise UnknownMessageStatusError('Unknow message_status: %s' % message_status)

# Build pdu
if dlr_pdu == 'deliver_sm':
short_message = r"id:%s submit date:%s done date:%s stat:%s err:%03d" % (
msgid,
dateutil.parser.parse(sub_date).strftime("%Y%m%d%H%M"),
datetime.datetime.now().strftime("%Y%m%d%H%M"),
message_state,
err,
)

# Build DeliverSM pdu
# Note:
# message_payload is not set in pdu since it seems there's a bug in smpp.pdu
pdu = DeliverSM(
source_addr = destination_addr,
destination_addr = source_addr,
esm_class = EsmClass(EsmClassMode.DEFAULT, EsmClassType.SMSC_DELIVERY_RECEIPT),
receipted_message_id = msgid,
short_message = short_message,
message_state = message_state,
)
else:
# Build DataSM pdu
Expand All @@ -171,37 +214,7 @@ def getReceipt(self, dlr_pdu, msgid, source_addr, destination_addr, message_stat
destination_addr = source_addr,
esm_class = EsmClass(EsmClassMode.DEFAULT, EsmClassType.SMSC_DELIVERY_RECEIPT),
receipted_message_id = msgid,
message_state = message_state,
)

# Set pdu.message_state
if message_status[:5] == 'ESME_':
# It is a receipt catched from a submit_sm_resp
if message_status == 'ESME_ROK':
pdu.params['message_state'] = MessageState.ACCEPTED
else:
pdu.params['message_state'] = MessageState.UNDELIVERABLE
elif message_status == 'UNDELIV':
# It is a receipt catched from a deliver_sm
pdu.params['message_state'] = MessageState.UNDELIVERABLE
elif message_status == 'REJECTD':
# It is a receipt catched from a deliver_sm
pdu.params['message_state'] = MessageState.REJECTED
elif message_status == 'DELIVRD':
# It is a receipt catched from a deliver_sm
pdu.params['message_state'] = MessageState.DELIVERED
elif message_status == 'EXPIRED':
# It is a receipt catched from a deliver_sm
pdu.params['message_state'] = MessageState.EXPIRED
elif message_status == 'DELETED':
# It is a receipt catched from a deliver_sm
pdu.params['message_state'] = MessageState.DELETED
elif message_status == 'ACCEPTD':
# It is a receipt catched from a deliver_sm
pdu.params['message_state'] = MessageState.ACCEPTED
elif message_status == 'UNKNOWN':
# It is a receipt catched from a deliver_sm
pdu.params['message_state'] = MessageState.UNKNOWN
else:
raise UnknownMessageStatusError('Unknow message_status: %s' % message_status)

return pdu
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ def test_any_network_type(self):
self.assertEquals('GSM', str(pdu.params['source_network_type']))
self.assertEquals('GSM', str(pdu.params['dest_network_type']))

def test_deliver_sm_with_message_payload(self):
pduHex = '0000009200000005000000000001693c00000032313635333532303730330000003737383800040000000001000000000424004f69643a30303030343336393439207375626d697420646174653a3135303432313135303820646f6e6520646174653a3135303432313135303820737461743a44454c49565244206572723a30303000001e00063661616435000427000102'
pdu = self.getPDU(pduHex)
SMStringEncoder().decodeSM(pdu)

# Asserts
self.assertEquals('id:0000436949 submit date:1504211508 done date:1504211508 stat:DELIVRD err:000\x00', str(pdu.params['message_payload']))
self.assertEquals('6aad5', str(pdu.params['receipted_message_id']))

def test_invalid_command_length(self):
"Related to #124"

Expand Down
2 changes: 0 additions & 2 deletions jasmin/protocols/smpp/test/test_pdu_encoding.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,6 @@ def do_bind_conversion_test(self, pduBindKlass, reqCommandIdHex, respCommandIdHe
respPdu = reqPdu.requireAck(1, CommandStatus.ESME_ROK, system_id='TSI7588', sc_interface_version=0x34)
self.do_conversion_test(PDUEncoder(), respPdu, '0000001d%s000000000000000154534937353838000210000134' % respCommandIdHex)



def test_BindTransmitter_conversion(self):
self.do_bind_conversion_test(BindTransmitter, '00000002', '80000002')

Expand Down
15 changes: 12 additions & 3 deletions jasmin/routing/test/test_throwers_dlr.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import mock
import datetime
from twisted.internet import reactor, defer
from twisted.trial import unittest
from jasmin.queues.factory import AmqpFactory
Expand Down Expand Up @@ -207,8 +208,11 @@ def setUp(self):
self.DLRThrower.config.max_retries = 2

@defer.inlineCallbacks
def publishDLRContentForSmppapi(self, message_status, msgid, system_id, source_addr, destination_addr):
content = DLRContentForSmpps(message_status, msgid, system_id, source_addr, destination_addr)
def publishDLRContentForSmppapi(self, message_status, msgid, system_id, source_addr, destination_addr, sub_date = None):
if sub_date is None:
sub_date = datetime.datetime.now()

content = DLRContentForSmpps(message_status, msgid, system_id, source_addr, destination_addr, sub_date)
yield self.amqpBroker.publish(exchange='messaging', routing_key='dlr_thrower.smpps', content=content)

@defer.inlineCallbacks
Expand Down Expand Up @@ -259,7 +263,8 @@ def test_throwing_smpps_to_bound_connection_as_deliver_sm(self):
# Install mocks
self.smppc_factory.lastProto.PDUDataRequestReceived = mock.Mock(wraps=self.smppc_factory.lastProto.PDUDataRequestReceived)

yield self.publishDLRContentForSmppapi('ESME_ROK', 'MSGID', 'username', '999', '000')
sub_date = datetime.datetime.now()
yield self.publishDLRContentForSmppapi('ESME_ROK', 'MSGID', 'username', '999', '000', sub_date)

yield waitFor(1)

Expand All @@ -272,6 +277,10 @@ def test_throwing_smpps_to_bound_connection_as_deliver_sm(self):
self.assertEqual(received_pdu_1.params['destination_addr'], '999')
self.assertEqual(received_pdu_1.params['receipted_message_id'], 'MSGID')
self.assertEqual(str(received_pdu_1.params['message_state']), 'ACCEPTED')
self.assertEqual(received_pdu_1.params['short_message'], 'id:MSGID submit date:%s done date:%s stat:ACCEPTED err:000' % (
sub_date.strftime("%Y%m%d%H%M"),
sub_date.strftime("%Y%m%d%H%M"),
))

# Unbind & Disconnect
yield self.smppc_factory.smpp.unbindAndDisconnect()
Expand Down
4 changes: 2 additions & 2 deletions jasmin/routing/throwers.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,6 @@ def http_dlr_callback(self, message):
url = message.content.properties['headers']['url']
method = message.content.properties['headers']['method']
level = message.content.properties['headers']['level']
DLRContentForHttpapi = message.content.body
self.log.debug('Got one message (msgid:%s) to throw' % (msgid))

# If any, clear requeuing timer
Expand Down Expand Up @@ -394,7 +393,7 @@ def smpp_dlr_callback(self, message):
message_status = message.content.properties['headers']['message_status']
source_addr = message.content.properties['headers']['source_addr']
destination_addr = message.content.properties['headers']['destination_addr']
DLRContentForSmpps = message.content.body
sub_date = message.content.properties['headers']['sub_date']
self.log.debug('Got one message (msgid:%s) to throw' % (msgid))

# If any, clear requeuing timer
Expand All @@ -417,6 +416,7 @@ def smpp_dlr_callback(self, message):
source_addr = source_addr,
destination_addr = destination_addr,
message_status = message_status,
sub_date = sub_date,
)

# Deliver (or throw) the receipt through the deliverer
Expand Down
5 changes: 4 additions & 1 deletion jasmin/vendor/smpp/pdu/pdu_encoding.py
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,9 @@ def decode(self, file):
smLength = self.smLengthEncoder.decode(file)
return OctetStringEncoder(smLength).decode(file)

class MessagePayloadEncoder(OctetStringEncoder):
pass

class OptionEncoder(IEncoder):

def __init__(self):
Expand Down Expand Up @@ -784,7 +787,7 @@ def __init__(self):
T.ms_availability_status: MsAvailabilityStatusEncoder(),
# Jasmin update:
T.network_error_code: NetworkErrorCodeEncoder(self.getLength),
T.message_payload: OctetStringEncoder(self.getLength),
T.message_payload: MessagePayloadEncoder(self.getLength),
T.delivery_failure_reason: DeliveryFailureReasonEncoder(),
T.more_messages_to_send: MoreMessagesToSendEncoder(),
T.message_state: MessageStateEncoder(),
Expand Down

0 comments on commit cdf5fd1

Please sign in to comment.