Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

fix volatile params, fix redirect and add params to redirect

  • Loading branch information...
commit bff4c736fbdca2ca8c160c29922f3300cf101a6d 1 parent 903b332
@tamiel tamiel authored
View
12 src/plivo/rest/freeswitch/grammar.py
@@ -132,8 +132,8 @@ def prepare_text(self, element):
else:
self.text = text.strip()
- def fetch_rest_xml(self, url, method='POST'):
- raise RESTRedirectException(url, method)
+ def fetch_rest_xml(self, url, params={}, method='POST'):
+ raise RESTRedirectException(url, params, method)
class Conference(Grammar):
@@ -332,7 +332,7 @@ def run(self, outbound_socket):
outbound_socket.bgapi("sched_del %s" % sched_hangup_id)
# Call url action
if self.action and is_valid_url(self.action):
- self.fetch_rest_xml(self.action, self.method)
+ self.fetch_rest_xml(self.action, method=self.method)
class GetDigits(Grammar):
@@ -468,8 +468,8 @@ def run(self, outbound_socket):
digits = outbound_socket.get_var('pagd_input')
if digits is not None and self.action:
# Call Parent Class Function
- outbound_socket.params.update({'Digits': digits})
- self.fetch_rest_xml(self.action, self.method)
+ params = {'Digits': digits}
+ self.fetch_rest_xml(self.action, params, self.method)
class Hangup(Grammar):
@@ -790,7 +790,7 @@ def parse_grammar(self, element, uri=None):
self.url = url
def run(self, outbound_socket):
- self.fetch_rest_xml(self.url, self.method)
+ self.fetch_rest_xml(self.url, method=self.method)
class Reject(Grammar):
View
2  src/plivo/rest/freeswitch/helpers.py
@@ -154,7 +154,7 @@ def _prepare_http_request(self, uri, params, method='POST'):
request.add_header("HTTP_X_PLIVO_SIGNATURE", "%s" % signature)
return request
- def fetch_response(self, uri, params, method='POST'):
+ def fetch_response(self, uri, params={}, method='POST'):
if not method in ('GET', 'POST'):
raise NotImplementedError('HTTP %s method not implemented' \
% method)
View
24 src/plivo/rest/freeswitch/inbound_socket.py
@@ -18,10 +18,15 @@ class RESTInboundSocket(InboundEventSocket):
...
...
"""
- def __init__(self, host, port, password, filter="ALL", log=None):
+ def __init__(self, host, port, password,
+ outbound_address='',
+ auth_id='', auth_token='',
+ filter="ALL", log=None):
InboundEventSocket.__init__(self, host, port, password, filter)
- self.fs_outbound_address = ""
+ self.fs_outbound_address = outbound_address
self.log = log
+ self.auth_id = auth_id
+ self.auth_token = auth_token
# Mapping of Key: job-uuid - Value: request_id
self.bk_jobs = {}
# Transfer jobs: call_uuid - Value: where to transfer
@@ -142,22 +147,17 @@ def hangup_complete(self, request_uuid, call_uuid, reason, ev, hangup_url):
'reason': reason}
self.post_to_url(hangup_url, params)
- def post_to_url(self, url=None, params={}):
- # TODO Need a retry mechanism or a fallback url to try
- # Need to build a pool and retry later the failing post_url
- # URL can be temporary unavailable
- # In last resort,log the errors in a different log file
- # error-api.log
+ def post_to_url(self, url=None, params={}, method='POST'):
if not url:
return None
- http_obj = HTTPRequest()
+ http_obj = HTTPRequest(self.auth_id, self.auth_token)
try:
- data = http_obj.fetch_response(url, params, method='POST')
- self.log.info("Posted to %s with %s --Result: %s"
+ data = http_obj.fetch_response(url, params, method)
+ self.log.info("Posted to %s with %s -- Result: %s"
% (url, params, data))
return data
except Exception, e:
- self.log.error("Post to %s with %s --Error: %s"
+ self.log.error("Post to %s with %s -- Error: %s"
% (url, params, e))
return None
View
61 src/plivo/rest/freeswitch/outbound_socket.py
@@ -74,10 +74,10 @@ def __init__(self, socket, address, log,
self.xml_response = ""
self.parsed_grammar = []
self.lexed_xml_response = []
- self.answer_url = ""
+ self.target_url = ""
self.hangup_url = ""
self.direction = ""
- self.params = None
+ self.session_params = None
self._action_queue = gevent.queue.Queue()
self.default_answer_url = default_answer_url
self.default_hangup_url = default_hangup_url
@@ -137,7 +137,7 @@ def on_channel_hangup(self, event):
elif self.default_hangup_url:
hangup_url = self.default_hangup_url
if hangup_url:
- self.params.update({'hangupCause': self._hangup_cause})
+ self.session_params['hangup_cause'] = self._hangup_cause
self.log.info("Posting hangup to %s" % hangup_url)
self.post_to_url(hangup_url, params)
@@ -183,21 +183,21 @@ def run(self):
# Look for variables in channel headers
aleg_uuid = channel.get_header('Caller-Unique-ID')
aleg_request_uuid = channel.get_header('variable_request_uuid')
- self.answer_url = channel.get_header('variable_answer_url')
+ self.target_url = channel.get_header('variable_answer_url')
sched_hangup_id = channel.get_header('variable_sched_hangup_id')
# Don't post hangup in outbound direction
self.default_hangup_url = None
self.hangup_url = None
else:
- # Look for an answer url in order below :
+ # Look for target url in order below :
# get transfer_url from channel variable
# get answer_url from channel variable
# get default answer_url
- self.answer_url = self.get_var('transfer_url')
- if not self.answer_url:
- self.answer_url = self.get_var('answer_url')
- if not self.answer_url:
- self.answer_url = self.default_answer_url
+ self.target_url = self.get_var('transfer_url')
+ if not self.target_url:
+ self.target_url = self.get_var('answer_url')
+ if not self.target_url:
+ self.target_url = self.default_answer_url
# Look for a sched_hangup_id
sched_hangup_id = self.get_var('sched_hangup_id')
# Look for hangup_url
@@ -207,7 +207,7 @@ def run(self):
sched_hangup_id = ""
# Post to ANSWER URL and get XML Response
- self.params = {
+ self.session_params = {
'call_uuid': self.call_uuid,
'called_no': called_no,
'from_no': from_no,
@@ -230,12 +230,13 @@ def process_call(self):
Parse the XML and Execute it
"""
fetch_method = 'POST'
+ params = {}
for x in range(MAX_REDIRECT):
try:
if self.has_hangup():
self.log.warn("Channel has hung up, breaking Processing Call")
return
- self.fetch_xml(method=fetch_method)
+ self.fetch_xml(params=params, method=fetch_method)
if not self.xml_response:
self.log.warn("No XML Response")
return
@@ -245,9 +246,12 @@ def process_call(self):
self.log.info("End of RESTXML")
return
except RESTRedirectException, redirect:
- # Set Answer URL to Redirect URL
- self.answer_url = redirect.get_url()
+ # Set target URL to Redirect URL
+ # Set method to Redirect method
+ # Set additional params to Redirect params
+ self.target_url = redirect.get_url()
fetch_method = redirect.get_method()
+ params = redirect.get_params()
if not fetch_method:
fetch_method = 'POST'
# Reset all the previous response and grammar
@@ -255,7 +259,7 @@ def process_call(self):
self.parsed_grammar = []
self.lexed_xml_response = []
self.log.info("Redirecting to %s to fetch RESTXML" \
- % self.answer_url)
+ % self.target_url)
gevent.sleep(0.010)
continue
except Exception, e:
@@ -268,34 +272,37 @@ def process_call(self):
return
self.log.warn("Max Redirect Reached !")
- def fetch_xml(self, method='POST'):
+ def fetch_xml(self, params={}, method='POST'):
"""
This method will retrieve the xml from the answer_url
The url result expected is an XML content which will be stored in
xml_response
"""
+ # auto add session parameters
+ params.update(self.session_params)
self.log.info("Fetching %s RESTXML from %s with %s" \
- % (method, self.answer_url, self.params))
+ % (method, self.target_url, params))
http_obj = HTTPRequest(self.auth_id, self.auth_token)
- self.xml_response = http_obj.fetch_response(self.answer_url,
- self.params, method)
+ self.xml_response = http_obj.fetch_response(self.target_url,
+ params, method)
self.log.info("Requested RESTXML to %s with %s" \
- % (self.answer_url, self.params))
+ % (self.target_url, params))
- def post_to_url(self, url=None, params={}):
+ def post_to_url(self, url=None, params={}, method='POST'):
"""
- This method will do an http POST request to the Url
+ This method will do an http POST or GET request to the Url
"""
if not url:
return None
+ params = params.update(self.session_params)
http_obj = HTTPRequest(self.auth_id, self.auth_token)
try:
- data = http_obj.fetch_response(url, params, method='POST')
- self.log.info("Posted to %s with %s --Result: %s"
+ data = http_obj.fetch_response(url, params, method)
+ self.log.info("Posted to %s with %s -- Result: %s"
% (url, params, data))
return data
except Exception, e:
- self.log.error("Post to %s with %s --Error: %s"
+ self.log.error("Post to %s with %s -- Error: %s"
% (url, params, e))
return None
@@ -309,7 +316,7 @@ def lex_xml(self):
#convert the string into an Element instance
doc = etree.fromstring(xml_str)
except Exception, e:
- raise RESTSyntaxException("Invalid RESTXML Response Syntax: %s"
+ raise RESTSyntaxException("Invalid RESTXML Response Syntax: %s" \
% str(e))
# Make sure the document has a <Response> root
@@ -335,7 +342,7 @@ def parse_xml(self):
for element in self.lexed_xml_response:
grammar_element = getattr(grammar, str(element.tag), None)
grammar_instance = grammar_element()
- grammar_instance.parse_grammar(element, self.answer_url)
+ grammar_instance.parse_grammar(element, self.target_url)
self.parsed_grammar.append(grammar_instance)
# Validate, Parse & Store the nested children
# inside the main grammar element
View
7 src/plivo/rest/freeswitch/rest_exceptions.py
@@ -23,12 +23,17 @@ class RESTDownloadException(Exception):
class RESTRedirectException(Exception):
- def __init__(self, url=None, method=None):
+ def __init__(self, url=None, params={}, method=None):
self.url = url
self.method = method
+ self.params = params
def get_url(self):
return self.url
def get_method(self):
return self.method
+
+ def get_params(self):
+ return self.params
+
View
26 src/plivo/rest/freeswitch/rest_server.py
@@ -63,16 +63,26 @@ def __init__(self, configfile, daemon=False,
fs_port = int(fs_port)
fs_password = helpers.get_conf_value(self._config,
'freeswitch', 'FS_PASSWORD')
- self._rest_inbound_socket = RESTInboundSocket(fs_host, fs_port,
- fs_password, filter='ALL',
- log=self.log)
+ # get auth id and auth token
+ self.auth_id = helpers.get_conf_value(self._config,
+ 'rest_server', 'AUTH_ID')
+ self.auth_token = helpers.get_conf_value(self._config,
+ 'rest_server', 'AUTH_TOKEN')
+ # get outbound socket host/port
fs_out_address = helpers.get_conf_value(self._config,
'freeswitch', 'FS_OUTBOUND_ADDRESS')
fs_out_host, fs_out_port = fs_out_address.split(':', 1)
# if outbound host is 0.0.0.0, send to 127.0.0.1
if fs_out_host == '0.0.0.0':
fs_out_address = '127.0.0.1:%s' % fs_out_port
- self._rest_inbound_socket.fs_outbound_address = fs_out_address
+ # create inbound socket instance
+ self._rest_inbound_socket = RESTInboundSocket(fs_host, fs_port,
+ fs_password,
+ outbound_address=fs_out_address,
+ auth_id=self.auth_id,
+ auth_token=self.auth_token,
+ filter='ALL',
+ log=self.log)
# expose api functions to flask app
for path, func_desc in urls.URLS.iteritems():
func, methods = func_desc
@@ -152,7 +162,8 @@ def do_daemon(self):
group = grp.getgrgid(gid)[0]
# daemonize now
plivo.utils.daemonize.daemon(user, group, path='/',
- pidfile=self._pidfile, other_groups=())
+ pidfile=self._pidfile,
+ other_groups=())
def sig_term(self, *args):
"""if we receive a term signal, we will shutdown properly
@@ -192,12 +203,13 @@ def start(self):
try:
while self._run:
try:
- self.log.info("Trying to connect to FreeSWITCH at: %s"
- % self.fs_inbound_address)
+ self.log.info("Trying to connect to FreeSWITCH at: %s" \
+ % self.fs_inbound_address)
self._rest_inbound_socket.connect()
# reset retries when connection is a success
retries = 1
self.log.info("Connected to FreeSWITCH")
+ # serve forever
self._rest_inbound_socket.serve_forever()
except ConnectError, e:
if self._run is False:

0 comments on commit bff4c73

Please sign in to comment.
Something went wrong with that request. Please try again.