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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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(
  49. self._find_alarm_action_sql,
  50. (alarm['alarmDefinitionId'],
  51. alarm['newState']))
  52. for row in cur:
  53. yield (row[0], row[1].lower(), row[2], row[3], row[4])
  54. except pymysql.Error as e:
  55. self._mysql = None
  56. log.exception("Couldn't fetch alarms actions %s", e)
  57. raise exc.DatabaseException(e)
  58. def get_alarm_current_state(self, alarm_id):
  59. try:
  60. if self._mysql is None:
  61. self._connect_to_mysql()
  62. cur = self._mysql.cursor()
  63. cur.execute(self._find_alarm_state_sql, alarm_id)
  64. row = cur.fetchone()
  65. state = row[0] if row is not None else None
  66. return state
  67. except pymysql.Error as e:
  68. self._mysql = None
  69. log.exception("Couldn't fetch the current alarm state %s", e)
  70. raise exc.DatabaseException(e)
  71. def fetch_notification_method_types(self):
  72. try:
  73. if self._mysql is None:
  74. self._connect_to_mysql()
  75. cur = self._mysql.cursor()
  76. cur.execute(self._find_all_notification_types_sql)
  77. for row in cur:
  78. yield (row[0])
  79. except pymysql.Error as e:
  80. self._mysql = None
  81. log.exception("Couldn't fetch notification types %s", e)
  82. raise exc.DatabaseException(e)
  83. def insert_notification_method_types(self, notification_types):
  84. try:
  85. if self._mysql is None:
  86. self._connect_to_mysql()
  87. cur = self._mysql.cursor()
  88. cur.executemany(self._insert_notification_types_sql, notification_types)
  89. except pymysql.IntegrityError as ignoredException:
  90. # If multiple instances of the notification engine tries to write the
  91. # same content at the same time, only one of them will succeed and others will
  92. # get duplicate primary key, integrity error. We can safely ignore this error.
  93. # This may happen only during the first start when the tables are empty.
  94. code, mesg = ignoredException.args
  95. if code == pymysql.constants.ER.DUP_ENTRY:
  96. log.debug("Notification type exists in DB. Ignoring the exception {}".format(mesg))
  97. else:
  98. raise exc.DatabaseException(ignoredException)
  99. except pymysql.Error as e:
  100. self._mysql = None
  101. log.exception("Couldn't insert notification types %s", e)
  102. raise exc.DatabaseException(e)
  103. def get_notification(self, notification_id):
  104. try:
  105. if self._mysql is None:
  106. self._connect_to_mysql()
  107. cur = self._mysql.cursor()
  108. cur.execute(self._get_notification_sql, notification_id)
  109. row = cur.fetchone()
  110. if row is None:
  111. return None
  112. else:
  113. return [row[0], row[1].lower(), row[2], row[3]]
  114. except pymysql.Error as e:
  115. self._mysql = None
  116. log.exception("Couldn't fetch the notification method %s", e)
  117. raise exc.DatabaseException(e)