Advertisement
Guest User

Untitled

a guest
Feb 23rd, 2017
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.08 KB | None | 0 0
  1. """This module is responsible to send notifications when conditions are satisfied."""
  2. #!/usr/bin/python
  3. # -*- coding:utf-8 -*-
  4. import os
  5. import json
  6. from service.service import Service
  7. """
  8. Reactioner is responsible to store data from requests such as:
  9. - type: create or delete
  10. - username
  11. - monitor: { type: value } monitor condition to be analyzed
  12. - cherries: a list of cherries to collect data and analyze
  13. - notify_id: api id for the created notify
  14.  
  15. with this data, reactioner monitors cherries and sends
  16. notification every time the monitor condition gets satified.
  17.  
  18. To use Reactioner, just run uplug-reactioner in the shell.
  19.  
  20. Reactioner reads some environment variables from config.json.
  21.  
  22. Some common tasks, such as reading from a config file and creating
  23. a mqtt client, is made by Service module.
  24. """
  25.  
  26. def __init__(self):
  27. self.root_path = os.path.dirname(os.path.realpath(__file__))
  28. super(Reactioner, self).__init__(app_path=self.root_path)
  29. command_topic = '$queue/user/+/{}'.format('status')
  30. self.subscribe(command_topic)
  31. self.client = MongoUtils(self.db_url, self.db_port, self.db_name)
  32.  
  33. def __create_notify(self, message):
  34. '''if everithing is ok, create the notify from database.'''
  35. self.client.insert(message)
  36.  
  37. def __delete_notify(self, message):
  38. '''if everithing is ok, delete the notify from database.'''
  39. self.client.remove(message)
  40.  
  41. def __valid_notify(self, message):
  42. '''Verify if received message can be found on database as a
  43. notification request, needed fields:
  44. - username
  45. - monitor: { type: value } monitor condition to be analyzed
  46. - cherries: a list of cherries to collect data and analyze
  47. - notify_id: notify id from api.'''
  48.  
  49. req_fields = ['username', 'monitor', 'cherries', 'notify_id']
  50. # must have all fields
  51. for item in req_fields:
  52. if item not in message:
  53. return False
  54.  
  55. # cherries list cannot be empty or null
  56. cherries = message.get('cherries')
  57. if not isinstance(cherries, list) or not len(cherries):
  58. return False
  59.  
  60. return True
  61.  
  62. def __handle_notify(self, message):
  63. '''Compare message with stored notification request.
  64. This method should compare message received from cherry
  65. with the requests stored on mongo and send notification
  66. when necessary. Conditions to verify:
  67. - username has requested notifies.
  68. - cherry is inside the list of cherries to monitor.
  69. - monitor condition has been satified.
  70.  
  71. if these three conditions are satisfied, the reactioner sends
  72. a notification to the user.'''
  73. notify_query = {
  74. 'username': message.get('username'),
  75. 'cherries': {'$in': [message.get('esp-id')]}
  76. }
  77. notifies = list(self.client.find(notify_query, {'monitor': 1, 'notify_id': 1}))
  78. print(notifies)
  79. if not notifies or not len(notifies):
  80. return
  81. for notify in notifies:
  82. data = {
  83. 'notify_id': notify.get('notify_id'),
  84. 'username': message.get('username'),
  85. 'cherry': message.get('esp-id')
  86. }
  87. for (monitor, value) in notify.get('monitor').items():
  88. if message.get(monitor) == value:
  89. if not data.get('monitor'): data['monitor'] = {}
  90. data['monitor'][monitor] = value
  91.  
  92. if data['monitor']:
  93. self.send_notify(data)
  94.  
  95. def status(self):
  96. '''Method that represents the topic of messages from cherry.
  97. the reactioner reads from the message, if the cherry is
  98. monitored, compares to the desired value and notifies.'''
  99. message = self.loads(self.message.payload)
  100. # compare with mongo notification comparator
  101. self.__handle_notify(message)
  102.  
  103. def notify(self):
  104. '''Should save/remove a user request for notifications.'''
  105. message = self.loads(self.message.payload)
  106. data = message.get('data')
  107. if message.get('type') == 'create' and self.__valid_notify(data):
  108. self.__create_notify(data)
  109. elif message.get('type') == 'delete':
  110. self.__delete_notify(data)
  111. else:
  112. self.logger.info('Not a valid message: %s', message)
  113.  
  114. def send_notify(self, data):
  115. '''Send notification to API.'''
  116. try:
  117. topic = 'user/{}/{}'.format(self.username, self.pub_topic)
  118. print(topic)
  119. self.publish('user/{}/{}'.format(self.username, self.pub_topic), json.dumps(data))
  120. except Exception:
  121. self.logger.error('data cant be parsed: %s', data)
  122.  
  123.  
  124. def main():
  125. """Main routine."""
  126. reactioner = Reactioner()
  127. reactioner.logger.info('Starting the reactioner from ' + reactioner.root_path)
  128. reactioner.loop_forever()
  129.  
  130. if __name__ == '__main__':
  131. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement