Notification Engine for Monasca
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

mysql_repo.py 5.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. # Copyright 2015-2017 FUJITSU LIMITED
  2. # (C) Copyright 2015,2016 Hewlett Packard Enterprise Development LP
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
  5. # in compliance with the License. You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software distributed under the License
  10. # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
  11. # or implied. See the License for the specific language governing permissions and limitations under
  12. # the License.
  13. from oslo_log import log as logging
  14. import pymysql
  15. from monasca_notification.common.repositories.base import base_repo
  16. from monasca_notification.common.repositories import exceptions as exc
  17. log = logging.getLogger(__name__)
  18. class MysqlRepo(base_repo.BaseRepo):
  19. def __init__(self, config):
  20. super(MysqlRepo, self).__init__(config)
  21. self._mysql_ssl = config['mysql']['ssl'] or None
  22. self._mysql_host = config['mysql']['host']
  23. self._mysql_port = config['mysql']['port']
  24. self._mysql_user = config['mysql']['user']
  25. self._mysql_passwd = config['mysql']['passwd']
  26. self._mysql_dbname = config['mysql']['db']
  27. self._mysql = None
  28. def _connect_to_mysql(self):
  29. self._mysql = None
  30. try:
  31. self._mysql = pymysql.connect(host=self._mysql_host,
  32. port=self._mysql_port,
  33. user=self._mysql_user,
  34. passwd=self._mysql_passwd,
  35. db=self._mysql_dbname,
  36. ssl=self._mysql_ssl,
  37. use_unicode=True,
  38. charset="utf8")
  39. self._mysql.autocommit(True)
  40. except pymysql.Error as e:
  41. log.exception('MySQL connect failed %s', e)
  42. raise
  43. def fetch_notifications(self, alarm):
  44. try:
  45. if self._mysql is None:
  46. self._connect_to_mysql()
  47. cur = self._mysql.cursor()
  48. cur.execute(self._find_alarm_action_sql, (alarm['alarmDefinitionId'], alarm['newState']))
  49. for row in cur:
  50. yield (row[0], row[1].lower(), row[2], row[3], row[4])
  51. except pymysql.Error as e:
  52. self._mysql = None
  53. log.exception("Couldn't fetch alarms actions %s", e)
  54. raise exc.DatabaseException(e)
  55. def get_alarm_current_state(self, alarm_id):
  56. try:
  57. if self._mysql is None:
  58. self._connect_to_mysql()
  59. cur = self._mysql.cursor()
  60. cur.execute(self._find_alarm_state_sql, alarm_id)
  61. row = cur.fetchone()
  62. state = row[0] if row is not None else None
  63. return state
  64. except pymysql.Error as e:
  65. self._mysql = None
  66. log.exception("Couldn't fetch the current alarm state %s", e)
  67. raise exc.DatabaseException(e)
  68. def fetch_notification_method_types(self):
  69. try:
  70. if self._mysql is None:
  71. self._connect_to_mysql()
  72. cur = self._mysql.cursor()
  73. cur.execute(self._find_all_notification_types_sql)
  74. for row in cur:
  75. yield (row[0])
  76. except pymysql.Error as e:
  77. self._mysql = None
  78. log.exception("Couldn't fetch notification types %s", e)
  79. raise exc.DatabaseException(e)
  80. def insert_notification_method_types(self, notification_types):
  81. try:
  82. if self._mysql is None:
  83. self._connect_to_mysql()
  84. cur = self._mysql.cursor()
  85. cur.executemany(self._insert_notification_types_sql, notification_types)
  86. except pymysql.IntegrityError as ignoredException:
  87. # If multiple instances of the notification engine tries to write the
  88. # same content at the same time, only one of them will succeed and others will
  89. # get duplicate primary key, integrity error. We can safely ignore this error.
  90. # This may happen only during the first start when the tables are empty.
  91. code, mesg = ignoredException.args
  92. if code == pymysql.constants.ER.DUP_ENTRY:
  93. log.debug("Notification type exists in DB. Ignoring the exception {}".format(mesg))
  94. else:
  95. raise exc.DatabaseException(ignoredException)
  96. except pymysql.Error as e:
  97. self._mysql = None
  98. log.exception("Couldn't insert notification types %s", e)
  99. raise exc.DatabaseException(e)
  100. def get_notification(self, notification_id):
  101. try:
  102. if self._mysql is None:
  103. self._connect_to_mysql()
  104. cur = self._mysql.cursor()
  105. cur.execute(self._get_notification_sql, notification_id)
  106. row = cur.fetchone()
  107. if row is None:
  108. return None
  109. else:
  110. return [row[0], row[1].lower(), row[2], row[3]]
  111. except pymysql.Error as e:
  112. self._mysql = None
  113. log.exception("Couldn't fetch the notification method %s", e)
  114. raise exc.DatabaseException(e)