change cassandra repo and fix sqlalchemy 2

- change list colum to single colum of select command
- optimize concat test case
- change row mapping to dict method
- remove sysbase testcase because of removing from sqlalchemy
- use jammy in vagrant for dev env
- remove retired project in zuul
- add not found test for notification with find by name

Change-Id: Ie77ccf6b15593520ae4f486843cdc46d7e25c628
This commit is contained in:
Hoai-Thu Vuong
2024-05-18 02:27:47 +07:00
parent a24fd834d0
commit 908815723b
13 changed files with 431 additions and 273 deletions

View File

@@ -5,7 +5,6 @@
Base job for running tempest tests with monasca-api devstack plugin.
timeout: 7800
required-projects:
- openstack/devstack-gate
- openstack/monasca-agent
- openstack/monasca-api
- openstack/monasca-common
@@ -70,7 +69,6 @@
Base job for running tempest tests with monasca-log-api devstack plugin.
timeout: 7800
required-projects:
- openstack/devstack-gate
- openstack/monasca-api
- openstack/monasca-common
- openstack/python-monascaclient

View File

@@ -26,7 +26,7 @@ Vagrant.configure(2) do |config|
end
config.vm.hostname = "devstack"
config.vm.box = "bento/ubuntu-20.04"
config.vm.box = "bento/ubuntu-22.04"
config.vm.box_check_update = false
config.vm.network "private_network",ip:"192.168.10.6"
config.vm.synced_folder "~/", "/vagrant_home"

View File

@@ -477,9 +477,10 @@ function install_monasca_cassandra {
echo_summary "Install Monasca Cassandra"
if [[ "$OFFLINE" != "True" ]]; then
sudo sh -c "echo 'deb http://www.apache.org/dist/cassandra/debian ${CASSANDRA_VERSION} main' > /etc/apt/sources.list.d/cassandra.sources.list"
sudo sh -c "echo 'deb [signed-by=/etc/apt/keyrings/apache-cassandra.asc] https://debian.cassandra.apache.org ${CASSANDRA_VERSION} main' > /etc/apt/sources.list.d/cassandra.sources.list"
REPOS_UPDATED=False
curl https://www.apache.org/dist/cassandra/KEYS | sudo apt-key add -
mkdir -p /etc/apt/keyrings
curl -o /etc/apt/keyrings/apache-cassandra.asc https://downloads.apache.org/cassandra/KEYS
PUBLIC_KEY=`sudo apt_get update 2>&1 | awk '/NO_PUBKEY/ {print $NF}'`
if [ -n "${PUBLIC_KEY}" ]; then
sudo apt-key adv --keyserver pool.sks-keyservers.net --recv-key ${PUBLIC_KEY}

View File

@@ -72,24 +72,24 @@ class AlarmDefinitionsRepository(sql_repository.SQLRepository,
sadd_s = sadd.alias('sadd')
aaa_aa = aa.alias('aaa_aa')
aaa = (select([aaa_aa.c.alarm_definition_id,
models.group_concat([aaa_aa.c.action_id]).label('alarm_actions')])
aaa = (select(aaa_aa.c.alarm_definition_id,
models.group_concat([aaa_aa.c.action_id]).label('alarm_actions'))
.select_from(aaa_aa)
.where(aaa_aa.c.alarm_state == text("'ALARM'"))
.group_by(aaa_aa.c.alarm_definition_id)
.alias('aaa'))
aao_aa = aa.alias('aao_aa')
aao = (select([aao_aa.c.alarm_definition_id,
models.group_concat([aao_aa.c.action_id]).label('ok_actions')])
aao = (select(aao_aa.c.alarm_definition_id,
models.group_concat([aao_aa.c.action_id]).label('ok_actions'))
.select_from(aao_aa)
.where(aao_aa.c.alarm_state == text("'OK'"))
.group_by(aao_aa.c.alarm_definition_id)
.alias('aao'))
aau_aa = aa.alias('aau_aa')
aau = (select([aau_aa.c.alarm_definition_id,
models.group_concat([aau_aa.c.action_id]).label('undetermined_actions')])
aau = (select(aau_aa.c.alarm_definition_id,
models.group_concat([aau_aa.c.action_id]).label('undetermined_actions'))
.select_from(aau_aa)
.where(aau_aa.c.alarm_state == text("'UNDETERMINED'"))
.group_by(aau_aa.c.alarm_definition_id)
@@ -99,23 +99,21 @@ class AlarmDefinitionsRepository(sql_repository.SQLRepository,
.outerjoin(aao, aao.c.alarm_definition_id == ad_s.c.id)
.outerjoin(aau, aau.c.alarm_definition_id == ad_s.c.id))
self.base_query = (select([ad_s.c.id,
ad_s.c.name,
ad_s.c.description,
ad_s.c.expression,
ad_s.c.match_by,
ad_s.c.severity,
ad_s.c.actions_enabled,
aaa.c.alarm_actions,
aao.c.ok_actions,
aau.c.undetermined_actions]))
self.base_query = (select(ad_s.c.id,
ad_s.c.name,
ad_s.c.description,
ad_s.c.expression,
ad_s.c.match_by,
ad_s.c.severity,
ad_s.c.actions_enabled,
aaa.c.alarm_actions,
aao.c.ok_actions,
aau.c.undetermined_actions))
self.get_sub_alarms_query = (
select(
[
sa_s.c.id.label('sub_alarm_id'),
sa_s.c.alarm_id,
sa_s.c.expression]) .select_from(
select(sa_s.c.id.label('sub_alarm_id'),
sa_s.c.alarm_id,
sa_s.c.expression) .select_from(
sa_s.join(
a_s,
a_s.c.id == sa_s.c.alarm_id) .join(
@@ -124,18 +122,18 @@ class AlarmDefinitionsRepository(sql_repository.SQLRepository,
ad_s.c.tenant_id == bindparam('b_tenant_id')) .where(
ad_s.c.id == bindparam('b_id')) .distinct())
mdg = (select([md_s.c.dimension_set_id,
models.group_concat(
[md_s.c.name + text("'='") + md_s.c.value]).label('dimensions')])
mdg = (select(md_s.c.dimension_set_id,
models.group_concat(
[md_s.c.name + text("'='") + md_s.c.value]).label('dimensions'))
.select_from(md_s)
.group_by(md_s.c.dimension_set_id)
.alias('mdg'))
self.get_alarm_metrics_query = (
select(
[a_s.c.id.label('alarm_id'),
mde_s.c.name,
mdg.c.dimensions]) .select_from(
a_s.c.id.label('alarm_id'),
mde_s.c.name,
mdg.c.dimensions) .select_from(
a_s.join(
ad_s,
ad_s.c.id == a_s.c.alarm_definition_id) .join(
@@ -161,17 +159,15 @@ class AlarmDefinitionsRepository(sql_repository.SQLRepository,
.where(a.c.alarm_definition_id == bindparam('b_id')))
columns_gc = [sadd_s.c.dimension_name + text("'='") + sadd_s.c.value]
saddg = (select([sadd_s.c.sub_alarm_definition_id,
models.group_concat(columns_gc).label('dimensions')])
saddg = (select(sadd_s.c.sub_alarm_definition_id,
models.group_concat(columns_gc).label('dimensions'))
.select_from(sadd_s)
.group_by(sadd_s.c.sub_alarm_definition_id)
.alias('saddg'))
self.get_sub_alarm_definitions_query = (
select(
[
sad_s,
saddg.c.dimensions]) .select_from(
select(sad_s,
saddg.c.dimensions) .select_from(
sad_s.outerjoin(
saddg,
saddg.c.sub_alarm_definition_id == sad_s.c.id)) .where(
@@ -257,7 +253,7 @@ class AlarmDefinitionsRepository(sql_repository.SQLRepository,
aa.c.alarm_definition_id == bindparam('b_alarm_definition_id')) .where(
aa.c.alarm_state == bindparam('b_alarm_state')))
self.select_nm_query = (select([nm_s.c.id])
self.select_nm_query = (select(nm_s.c.id)
.select_from(nm_s)
.where(nm_s.c.id == bindparam('b_id')))
@@ -280,12 +276,16 @@ class AlarmDefinitionsRepository(sql_repository.SQLRepository,
.where(ad.c.id == bindparam('b_id'))
.where(ad.c.deleted_at == null()))
row = conn.execute(query,
b_tenant_id=tenant_id,
b_id=_id).fetchone()
row = conn.execute(
query,
parameters={
'b_tenant_id': tenant_id,
'b_id': _id
}
).fetchone()
if row is not None:
return dict(row)
return row._mapping
else:
raise exceptions.DoesNotExistException
@@ -309,7 +309,7 @@ class AlarmDefinitionsRepository(sql_repository.SQLRepository,
for n, v in dimensions.items():
bind_dimension_name = 'b_sadd_dimension_name_{}'.format(i)
bind_value = 'b_sadd_value_{}'.format(i)
sadd_ = (select([sadd.c.sub_alarm_definition_id])
sadd_ = (select(sadd.c.sub_alarm_definition_id)
.select_from(sadd)
.where(sadd.c.dimension_name == bindparam(bind_dimension_name))
.where(sadd.c.value == bindparam(bind_value))
@@ -356,22 +356,26 @@ class AlarmDefinitionsRepository(sql_repository.SQLRepository,
parms['b_limit'] = limit + 1
return [dict(row) for row in conn.execute(query, parms).fetchall()]
return [row._mapping for row in conn.execute(query, parms).fetchall()]
@sql_repository.sql_try_catch_block
def get_sub_alarms(self, tenant_id, alarm_definition_id):
with self._db_engine.connect() as conn:
return [dict(row) for row in conn.execute(self.get_sub_alarms_query,
b_tenant_id=tenant_id,
b_id=alarm_definition_id).fetchall()]
return [row._mapping for row in conn.execute(self.get_sub_alarms_query,
parameters={
'b_tenant_id': tenant_id,
'b_id': alarm_definition_id
}).fetchall()]
@sql_repository.sql_try_catch_block
def get_alarm_metrics(self, tenant_id, alarm_definition_id):
with self._db_engine.connect() as conn:
return [dict(row) for row in conn.execute(self.get_alarm_metrics_query,
b_tenant_id=tenant_id,
b_id=alarm_definition_id).fetchall()]
return [row._mapping for row in conn.execute(self.get_alarm_metrics_query,
parameters={
'b_tenant_id': tenant_id,
'b_id': alarm_definition_id
}).fetchall()]
@sql_repository.sql_try_catch_block
def delete_alarm_definition(self, tenant_id, alarm_definition_id):
@@ -388,16 +392,24 @@ class AlarmDefinitionsRepository(sql_repository.SQLRepository,
"""
with self._db_engine.begin() as conn:
cursor = conn.execute(self.soft_delete_ad_query,
b_tenant_id=tenant_id,
b_id=alarm_definition_id)
cursor = conn.execute(
self.soft_delete_ad_query,
parameters={
'b_tenant_id': tenant_id,
'b_id': alarm_definition_id
}
)
if cursor.rowcount < 1:
return False
conn.execute(self.delete_a_query,
b_tenant_id=tenant_id,
b_id=alarm_definition_id)
conn.execute(
self.delete_a_query,
parameters={
'b_tenant_id': tenant_id,
'b_id': alarm_definition_id
}
)
return True
@@ -408,9 +420,13 @@ class AlarmDefinitionsRepository(sql_repository.SQLRepository,
def _get_sub_alarm_definitions(self, conn, alarm_definition_id):
return [
dict(row) for row in conn.execute(
row._mapping for row in conn.execute(
self.get_sub_alarm_definitions_query,
b_alarm_definition_id=alarm_definition_id).fetchall()]
parameters={
'b_alarm_definition_id': alarm_definition_id
}
).fetchall()
]
@sql_repository.sql_try_catch_block
def create_alarm_definition(self, tenant_id, name, expression,
@@ -422,45 +438,57 @@ class AlarmDefinitionsRepository(sql_repository.SQLRepository,
now = datetime.datetime.utcnow()
alarm_definition_id = uuidutils.generate_uuid()
conn.execute(self.create_alarm_definition_insert_ad_query,
b_id=alarm_definition_id,
b_tenant_id=tenant_id,
b_name=name.encode('utf8'),
b_description=description.encode('utf8'),
b_expression=expression.encode('utf8'),
b_severity=severity.upper().encode('utf8'),
b_match_by=",".join(match_by).encode('utf8'),
b_actions_enabled=True,
b_created_at=now,
b_updated_at=now)
conn.execute(
self.create_alarm_definition_insert_ad_query,
parameters={
'b_id': alarm_definition_id,
'b_tenant_id': tenant_id,
'b_name': name.encode('utf8'),
'b_description': description.encode('utf8'),
'b_expression': expression.encode('utf8'),
'b_severity': severity.upper().encode('utf8'),
'b_match_by': ",".join(match_by).encode('utf8'),
'b_actions_enabled': True,
'b_created_at': now,
'b_updated_at': now
}
)
for sub_expr in sub_expr_list:
sub_alarm_definition_id = uuidutils.generate_uuid()
sub_expr.id = sub_alarm_definition_id
metric_name = sub_expr.metric_name.encode("utf8")
operator = sub_expr.normalized_operator.encode('utf8')
conn.execute(self.create_alarm_definition_insert_sad_query,
b_id=sub_alarm_definition_id,
b_alarm_definition_id=alarm_definition_id,
b_function=sub_expr.normalized_func.encode('utf8'),
b_metric_name=metric_name,
b_operator=operator,
b_threshold=sub_expr.threshold,
b_period=sub_expr.period,
b_periods=sub_expr.periods,
b_is_deterministic=sub_expr.deterministic,
b_created_at=now,
b_updated_at=now)
conn.execute(
self.create_alarm_definition_insert_sad_query,
parameters={
'b_id': sub_alarm_definition_id,
'b_alarm_definition_id': alarm_definition_id,
'b_function': sub_expr.normalized_func.encode('utf8'),
'b_metric_name': metric_name,
'b_operator': operator,
'b_threshold': sub_expr.threshold,
'b_period': sub_expr.period,
'b_periods': sub_expr.periods,
'b_is_deterministic': sub_expr.deterministic,
'b_created_at': now,
'b_updated_at': now
}
)
for dimension in sub_expr.dimensions_as_list:
parsed_dimension = dimension.split('=')
query = self.create_alarm_definition_insert_sadd_query
sadi = sub_alarm_definition_id
dimension_name = parsed_dimension[0].encode('utf8')
conn.execute(query,
b_sub_alarm_definition_id=sadi,
b_dimension_name=dimension_name,
b_value=parsed_dimension[1].encode('utf8'))
conn.execute(
query,
parameters={
'b_sub_alarm_definition_id': sadi,
'b_dimension_name': dimension_name,
'b_value': parsed_dimension[1].encode('utf8')
}
)
self._insert_into_alarm_action(conn, alarm_definition_id,
alarm_actions, u"ALARM")
@@ -575,15 +603,17 @@ class AlarmDefinitionsRepository(sql_repository.SQLRepository,
actions_enabled=bindparam('b_actions_enabled'),
updated_at=bindparam('b_updated_at')
),
b_name=new_name,
b_description=new_description,
b_expression=new_expression,
b_match_by=new_match_by,
b_severity=new_severity,
b_actions_enabled=bool(new_actions_enabled),
b_updated_at=now,
b_tenant_id=tenant_id,
b_id=alarm_definition_id)
parameters={
'b_name': new_name,
'b_description': new_description,
'b_expression': new_expression,
'b_match_by': new_match_by,
'b_severity': new_severity,
'b_actions_enabled': bool(new_actions_enabled),
'b_updated_at': now,
'b_tenant_id': tenant_id,
'b_id': alarm_definition_id
})
parms = []
for sub_alarm_definition_id, sub_alarm_def in (
changed_sub_alarm_defs_by_id.items()):
@@ -608,8 +638,12 @@ class AlarmDefinitionsRepository(sql_repository.SQLRepository,
self._delete_alarm_actions(conn, alarm_definition_id,
'UNDETERMINED')
else:
conn.execute(self.delete_aa_query,
b_alarm_definition_id=alarm_definition_id)
conn.execute(
self.delete_aa_query,
parameters={
'b_alarm_definition_id': alarm_definition_id
}
)
# Insert new alarm actions
self._insert_into_alarm_action(conn, alarm_definition_id,
@@ -631,12 +665,19 @@ class AlarmDefinitionsRepository(sql_repository.SQLRepository,
.where(ad.c.id == bindparam('b_id'))
.where(ad.c.deleted_at == null()))
updated_row = conn.execute(query,
b_id=alarm_definition_id,
b_tenant_id=tenant_id).fetchone()
updated_row = conn.execute(
query,
parameters={
'b_id': alarm_definition_id,
'b_tenant_id': tenant_id
}
).fetchone()
# TODO(thuvh) need return not found exception
if updated_row is None:
raise Exception("Failed to find current alarm definition")
else:
updated_row = updated_row._mapping
sub_alarm_defs_dict = {'old': old_sub_alarm_defs_by_id,
'changed': changed_sub_alarm_defs_by_id,
@@ -725,9 +766,13 @@ class AlarmDefinitionsRepository(sql_repository.SQLRepository,
unchanged_sub_alarm_defs_by_id)
def _delete_alarm_actions(self, conn, _id, alarm_action_name):
conn.execute(self.delete_aa_state_query,
b_alarm_definition_id=_id,
b_alarm_state=alarm_action_name)
conn.execute(
self.delete_aa_state_query,
parameters={
'b_alarm_definition_id': _id,
'b_alarm_state': alarm_action_name
}
)
def _insert_into_alarm_action(self, conn, alarm_definition_id, actions,
alarm_state):
@@ -737,15 +782,22 @@ class AlarmDefinitionsRepository(sql_repository.SQLRepository,
for action in actions:
b_id = action.encode('utf8') if six.PY2 else action
row = conn.execute(self.select_nm_query,
b_id=b_id).fetchone()
row = conn.execute(
self.select_nm_query,
parameters={
'b_id': b_id
}
).fetchone()
if row is None:
raise exceptions.InvalidUpdateException(
"Non-existent notification id {} submitted for {} "
"notification action".format(encodeutils.to_utf8(action),
encodeutils.to_utf8(alarm_state)))
conn.execute(self.insert_aa_query,
b_alarm_definition_id=alarm_definition_id,
b_alarm_state=alarm_state.encode('utf8') if six.PY2 else alarm_state,
b_action_id=action.encode('utf8') if six.PY2 else action
)
conn.execute(
self.insert_aa_query,
parameters={
'b_alarm_definition_id': alarm_definition_id,
'b_alarm_state': alarm_state.encode('utf8') if six.PY2 else alarm_state,
'b_action_id': action.encode('utf8') if six.PY2 else action
}
)

View File

@@ -56,8 +56,8 @@ class AlarmsRepository(sql_repository.SQLRepository,
gc_columns = [md.c.name + text("'='") + md.c.value]
mdg = (select([md.c.dimension_set_id,
models.group_concat(gc_columns).label('dimensions')])
mdg = (select(md.c.dimension_set_id,
models.group_concat(gc_columns).label('dimensions'))
.select_from(md)
.group_by(md.c.dimension_set_id).alias('mdg'))
@@ -74,31 +74,31 @@ class AlarmsRepository(sql_repository.SQLRepository,
mdg,
mdg.c.dimension_set_id == mdd.c.metric_dimension_set_id))
self.base_query = select([a_s.c.id.label('alarm_id'),
a_s.c.state,
a_s.c.state_updated_at.
label('state_updated_timestamp'),
a_s.c.updated_at.label('updated_timestamp'),
a_s.c.created_at.label('created_timestamp'),
a_s.c.lifecycle_state,
a_s.c.link,
ad.c.id.label('alarm_definition_id'),
ad.c.name.label('alarm_definition_name'),
ad.c.severity,
mde.c.name.label('metric_name'),
mdg.c.dimensions.label('metric_dimensions')])
self.base_query = select(a_s.c.id.label('alarm_id'),
a_s.c.state,
a_s.c.state_updated_at.
label('state_updated_timestamp'),
a_s.c.updated_at.label('updated_timestamp'),
a_s.c.created_at.label('created_timestamp'),
a_s.c.lifecycle_state,
a_s.c.link,
ad.c.id.label('alarm_definition_id'),
ad.c.name.label('alarm_definition_name'),
ad.c.severity,
mde.c.name.label('metric_name'),
mdg.c.dimensions.label('metric_dimensions'))
self.base_subquery_list = (select([a_s.c.id])
self.base_subquery_list = (select(a_s.c.id)
.select_from(a_s.join(ad, a_s.c.alarm_definition_id == ad.c.id)))
self.get_ad_query = (select([ad])
self.get_ad_query = (select(ad)
.select_from(ad.join(a, ad.c.id == a.c.alarm_definition_id))
.where(ad.c.tenant_id == bindparam('b_tenant_id'))
.where(a.c.id == bindparam('b_id')))
self.get_am_query = (select([a_s.c.id.label('alarm_id'),
mde.c.name,
mdg.c.dimensions])
self.get_am_query = (select(a_s.c.id.label('alarm_id'),
mde.c.name,
mdg.c.dimensions)
.select_from(a_s.join(am, am.c.alarm_id == a_s.c.id)
.join(mdd,
mdd.c.id ==
@@ -111,10 +111,10 @@ class AlarmsRepository(sql_repository.SQLRepository,
.order_by(a_s.c.id)
.distinct())
self.get_sa_query = (select([sa.c.id.label('sub_alarm_id'),
sa.c.alarm_id,
sa.c.expression,
ad.c.id.label('alarm_definition_id')])
self.get_sa_query = (select(sa.c.id.label('sub_alarm_id'),
sa.c.alarm_id,
sa.c.expression,
ad.c.id.label('alarm_definition_id'))
.select_from(sa.join(a_s,
a_s.c.id == sa.c.alarm_id)
.join(ad,
@@ -123,13 +123,13 @@ class AlarmsRepository(sql_repository.SQLRepository,
.where(a_s.c.id == bindparam('b_id'))
.distinct())
self.get_a_query = (select([a_s.c.state, a_s.c.link, a_s.c.lifecycle_state])
self.get_a_query = (select(a_s.c.state, a_s.c.link, a_s.c.lifecycle_state)
.select_from(a_s.join(ad,
ad.c.id == a_s.c.alarm_definition_id))
.where(ad.c.tenant_id == bindparam('b_tenant_id'))
.where(a_s.c.id == bindparam('b_id')))
self.get_a_ad_query = (select([a_s.c.id])
self.get_a_ad_query = (select(a_s.c.id)
.select_from(a_s.join(ad,
ad.c.id ==
a_s.c.alarm_definition_id))
@@ -137,7 +137,7 @@ class AlarmsRepository(sql_repository.SQLRepository,
.where(a_s.c.id == bindparam('b_id'))
.alias('a_ad'))
select_tmp = (select([literal_column('id')])
select_tmp = (select(literal_column('id'))
.select_from(self.get_a_ad_query)
.distinct()
.alias('temporarytable'))
@@ -145,10 +145,10 @@ class AlarmsRepository(sql_repository.SQLRepository,
self.delete_alarm_query = (delete(a)
.where(a.c.id.in_(select_tmp)))
md_ = (select([mde.c.id])
md_ = (select(mde.c.id)
.where(mde.c.name == bindparam('b_md_name')).alias('md_'))
self.get_a_am_query = (select([a_s.c.id])
self.get_a_am_query = (select(a_s.c.id)
.select_from(a_s.join(am,
am.c.alarm_id ==
a_s.c.id)
@@ -162,12 +162,15 @@ class AlarmsRepository(sql_repository.SQLRepository,
@sql_repository.sql_try_catch_block
def get_alarm_definition(self, tenant_id, alarm_id):
with self._db_engine.connect() as conn:
row = conn.execute(self.get_ad_query,
b_tenant_id=tenant_id,
b_id=alarm_id).fetchone()
row = conn.execute(
self.get_ad_query,
parameters={
'b_tenant_id': tenant_id,
'b_id': alarm_id
}).fetchone()
if row is not None:
return dict(row)
return row._mapping
else:
raise exceptions.DoesNotExistException
@@ -175,17 +178,24 @@ class AlarmsRepository(sql_repository.SQLRepository,
def get_alarm_metrics(self, alarm_id):
with self._db_engine.connect() as conn:
rows = conn.execute(self.get_am_query, b_id=alarm_id).fetchall()
return [dict(row) for row in rows]
rows = conn.execute(
self.get_am_query,
parameters={'b_id': alarm_id}
).fetchall()
return [row._mapping for row in rows]
@sql_repository.sql_try_catch_block
def get_sub_alarms(self, tenant_id, alarm_id):
with self._db_engine.connect() as conn:
rows = conn.execute(self.get_sa_query,
b_tenant_id=tenant_id,
b_id=alarm_id).fetchall()
return [dict(row) for row in rows]
rows = conn.execute(
self.get_sa_query,
parameters={
'b_tenant_id': tenant_id,
'b_id': alarm_id
}
).fetchall()
return [row._mapping for row in rows]
@sql_repository.sql_try_catch_block
def update_alarm(self, tenant_id, _id, state, lifecycle_state, link):
@@ -193,12 +203,18 @@ class AlarmsRepository(sql_repository.SQLRepository,
time_ms = int(round(time() * 1000.0))
with self._db_engine.connect() as conn:
self.get_a_query.bind = self._db_engine
prev_alarm = conn.execute(self.get_a_query,
b_tenant_id=tenant_id,
b_id=_id).fetchone()
prev_alarm = conn.execute(
self.get_a_query,
parameters={
'b_tenant_id': tenant_id,
'b_id': _id
}
).fetchone()
if prev_alarm is None:
raise exceptions.DoesNotExistException
else:
prev_alarm = prev_alarm._mapping
parms = {'b_lifecycle_state': lifecycle_state,
'b_link': link}
@@ -206,8 +222,9 @@ class AlarmsRepository(sql_repository.SQLRepository,
bindparam('b_lifecycle_state'),
'link': bindparam('b_link'),
'updated_at': func.now()}
if state != prev_alarm['state']:
# TODO(thuvh) find better solution to get state from row
prev_state = prev_alarm['state']
if state != prev_state:
parms['b_state'] = state
set_values['state'] = bindparam('b_state')
set_values['state_updated_at'] = func.now()
@@ -215,7 +232,7 @@ class AlarmsRepository(sql_repository.SQLRepository,
parms['b_tenant_id'] = tenant_id
parms['b_id'] = _id
select_tmp = (select([literal_column('id')])
select_tmp = (select(literal_column('id'))
.select_from(self.get_a_ad_query)
.distinct()
.alias('temporarytable'))
@@ -227,15 +244,23 @@ class AlarmsRepository(sql_repository.SQLRepository,
conn.execute(update_query, parms)
# TODO(thuvh) find a better solution
conn.commit()
return prev_alarm, time_ms
@sql_repository.sql_try_catch_block
def delete_alarm(self, tenant_id, _id):
with self._db_engine.connect() as conn:
cursor = conn.execute(self.delete_alarm_query,
b_tenant_id=tenant_id,
b_id=_id)
cursor = conn.execute(
self.delete_alarm_query,
parameters={
'b_tenant_id': tenant_id,
'b_id': _id
})
# TODO(thuvh) find a better solution
conn.commit()
if cursor.rowcount < 1:
raise exceptions.DoesNotExistException
@@ -252,14 +277,18 @@ class AlarmsRepository(sql_repository.SQLRepository,
.where(a.c.id == bindparam('b_id'))
.distinct())
rows = conn.execute(query,
b_tenant_id=tenant_id,
b_id=_id).fetchall()
rows = conn.execute(
query,
parameters={
'b_tenant_id': tenant_id,
'b_id': _id
}
).fetchall()
if rows is None or len(rows) == 0:
raise exceptions.DoesNotExistException
return [dict(row) for row in rows]
return [row._mapping for row in rows]
@sql_repository.sql_try_catch_block
def get_alarms(self, tenant_id, query_parms=None, offset=None, limit=None):
@@ -324,13 +353,13 @@ class AlarmsRepository(sql_repository.SQLRepository,
parms['b_state_updated_at'] = date_param
if 'metric_dimensions' in query_parms:
sub_query = select([a.c.id])
sub_query = select(a.c.id)
sub_query_from = (a.join(am, am.c.alarm_id == a.c.id)
.join(mdd,
mdd.c.id ==
am.c.metric_definition_dimensions_id))
sub_query_md_base = select([md.c.dimension_set_id]).select_from(md)
sub_query_md_base = select(md.c.dimension_set_id).select_from(md)
for i, metric_dimension in enumerate(query_parms['metric_dimensions'].items()):
@@ -422,7 +451,7 @@ class AlarmsRepository(sql_repository.SQLRepository,
main_query = main_query.order_by(*order_columns)
return [dict(row) for row in conn.execute(main_query, parms).fetchall()]
return [row._mapping for row in conn.execute(main_query, parms).fetchall()]
def _remap_columns(self, columns, columns_mapper):
received_cols = {}
@@ -484,7 +513,7 @@ class AlarmsRepository(sql_repository.SQLRepository,
md, mdd.c.metric_dimension_set_id == md.c.dimension_set_id) .join(
am, am.c.metric_definition_dimensions_id == mdd.c.id))
sub_query = (select(sub_query_columns)
sub_query = (select(*sub_query_columns)
.select_from(sub_query_from)
.distinct()
.alias('metrics'))
@@ -494,7 +523,7 @@ class AlarmsRepository(sql_repository.SQLRepository,
query_columns = [func.count().label('count')]
query_columns.extend([column(col) for col in group_by_columns])
query = (select(query_columns)
query = (select(*query_columns)
.select_from(query_from)
.where(ad.c.tenant_id == bindparam('b_tenant_id')))
@@ -539,13 +568,13 @@ class AlarmsRepository(sql_repository.SQLRepository,
query_parms['metric_name'].encode('utf8')
if 'metric_dimensions' in query_parms:
sub_query = select([a.c.id])
sub_query = select(a.c.id)
sub_query_from = (a.join(am, am.c.alarm_id == a.c.id)
.join(mdd,
mdd.c.id ==
am.c.metric_definition_dimensions_id))
sub_query_md_base = select([md.c.dimension_set_id]).select_from(md)
sub_query_md_base = select(md.c.dimension_set_id).select_from(md)
for i, metric_dimension in enumerate(query_parms['metric_dimensions'].items()):
dimension_value = metric_dimension[1] if six.PY3 else \
@@ -599,4 +628,4 @@ class AlarmsRepository(sql_repository.SQLRepository,
parms['b_offset'] = offset
query = query.distinct()
return [dict(row) for row in conn.execute(query, parms).fetchall()]
return [row._mapping for row in conn.execute(query, parms).fetchall()]

View File

@@ -30,7 +30,7 @@ class NotificationMethodTypeRepository(sql_repository.SQLRepository,
self.nmt = models.create_nmt_model(metadata)
nmt = self.nmt
self._nmt_query = select([nmt.c.name])
self._nmt_query = select(nmt.c.name)
@sql_repository.sql_try_catch_block
def list_notification_method_types(self):

View File

@@ -37,13 +37,13 @@ class NotificationsRepository(sql_repository.SQLRepository,
nm = self.nm
self._select_nm_count_name_query = (select([func.count()])
self._select_nm_count_name_query = (select(func.count())
.select_from(nm)
.where(
and_(nm.c.tenant_id == bindparam('b_tenant_id'),
nm.c.name == bindparam('b_name'))))
self._select_nm_count_id_query = (select([func.count()])
self._select_nm_count_id_query = (select(func.count())
.select_from(nm)
.where(
and_(nm.c.tenant_id == bindparam('b_tenant_id'),
@@ -74,12 +74,12 @@ class NotificationsRepository(sql_repository.SQLRepository,
period=bindparam('b_period'),
updated_at=bindparam('b_updated_at')))
self._select_nm_id_query = (select([nm])
self._select_nm_id_query = (select(nm)
.where(
and_(nm.c.tenant_id == bindparam('b_tenant_id'),
nm.c.id == bindparam('b_id'))))
self._select_nm_name_query = (select([nm])
self._select_nm_name_query = (select(nm)
.where(
and_(nm.c.tenant_id == bindparam('b_tenant_id'),
nm.c.name == bindparam('b_name'))))
@@ -88,9 +88,13 @@ class NotificationsRepository(sql_repository.SQLRepository,
notification_type, address, period):
with self._db_engine.connect() as conn:
row = conn.execute(self._select_nm_count_name_query,
b_tenant_id=tenant_id,
b_name=name.encode('utf8')).fetchone()
row = conn.execute(
self._select_nm_count_name_query,
parameters={
'b_tenant_id': tenant_id,
'b_name': name.encode('utf8')
}
).fetchone()
if int(row[0]) > 0:
raise exceptions.AlreadyExistsException('Notification already '
@@ -99,15 +103,22 @@ class NotificationsRepository(sql_repository.SQLRepository,
now = datetime.datetime.utcnow()
notification_id = uuidutils.generate_uuid()
conn.execute(self._insert_nm_query,
b_id=notification_id,
b_tenant_id=tenant_id,
b_name=name.encode('utf8'),
b_type=notification_type.encode('utf8'),
b_address=address.encode('utf8'),
b_period=period,
b_created_at=now,
b_updated_at=now)
conn.execute(
self._insert_nm_query,
parameters={
'b_id': notification_id,
'b_tenant_id': tenant_id,
'b_name': name.encode('utf8'),
'b_type': notification_type.encode('utf8'),
'b_address': address.encode('utf8'),
'b_period': period,
'b_created_at': now,
'b_updated_at': now
}
)
# TODO(thuvh) need check better solution
conn.commit()
return notification_id
@@ -119,7 +130,7 @@ class NotificationsRepository(sql_repository.SQLRepository,
with self._db_engine.connect() as conn:
nm = self.nm
select_nm_query = (select([nm])
select_nm_query = (select(nm)
.where(nm.c.tenant_id == bindparam('b_tenant_id')))
parms = {'b_tenant_id': tenant_id}
@@ -145,35 +156,50 @@ class NotificationsRepository(sql_repository.SQLRepository,
rows = conn.execute(select_nm_query, parms).fetchall()
return [dict(row) for row in rows]
return [row._mapping for row in rows]
@sql_repository.sql_try_catch_block
def delete_notification(self, tenant_id, _id):
with self._db_engine.connect() as conn:
row = conn.execute(self._select_nm_count_id_query,
b_tenant_id=tenant_id,
b_id=_id).fetchone()
row = conn.execute(
self._select_nm_count_id_query,
parameters={
'b_tenant_id': tenant_id,
'b_id': _id
}
).fetchone()
if int(row[0]) < 1:
raise exceptions.DoesNotExistException
conn.execute(self._delete_nm_query,
b_tenant_id=tenant_id,
b_id=_id)
conn.execute(
self._delete_nm_query,
parameters={
'b_tenant_id': tenant_id,
'b_id': _id
}
)
# TODO(thuvh) need check better solution
conn.commit()
@sql_repository.sql_try_catch_block
def list_notification(self, tenant_id, notification_id):
with self._db_engine.connect() as conn:
row = conn.execute(self._select_nm_id_query,
b_tenant_id=tenant_id,
b_id=notification_id).fetchone()
row = conn.execute(
self._select_nm_id_query,
parameters={
'b_tenant_id': tenant_id,
'b_id': notification_id
}
).fetchone()
if row is not None:
return dict(row)
return row._mapping
else:
raise exceptions.DoesNotExistException
@@ -181,9 +207,18 @@ class NotificationsRepository(sql_repository.SQLRepository,
def find_notification_by_name(self, tenant_id, name):
name = name if six.PY3 else name.encode('utf8')
with self._db_engine.connect() as conn:
return conn.execute(self._select_nm_name_query,
b_tenant_id=tenant_id,
b_name=name).fetchone()
row = conn.execute(
self._select_nm_name_query,
parameters={
'b_tenant_id': tenant_id,
'b_name': name
}
).fetchone()
if row is not None:
return row._mapping
else:
raise exceptions.DoesNotExistException('Not Found')
@sql_repository.sql_try_catch_block
def update_notification(
@@ -197,14 +232,21 @@ class NotificationsRepository(sql_repository.SQLRepository,
with self._db_engine.connect() as conn:
now = datetime.datetime.utcnow()
cursor = conn.execute(self._update_nm_query,
b_id=notification_id,
b_tenant_id=tenant_id,
b_name=name.encode('utf8'),
b_type=notification_type.encode('utf8'),
b_address=address.encode('utf8'),
b_period=period,
b_updated_at=now)
cursor = conn.execute(
self._update_nm_query,
parameters={
'b_id': notification_id,
'b_tenant_id': tenant_id,
'b_name': name.encode('utf8'),
'b_type': notification_type.encode('utf8'),
'b_address': address.encode('utf8'),
'b_period': period,
'b_updated_at': now
}
)
# TODO(thuvh) need check better solution
conn.commit()
if cursor.rowcount < 1:
raise exceptions.DoesNotExistException('Not Found')

View File

@@ -48,7 +48,10 @@ class Fingerprint(object):
@staticmethod
def _get_metadata(engine):
return MetaData(bind=engine)
metadata_obj = MetaData()
metadata_obj.create_all(engine)
metadata_obj.reflect(engine)
return metadata_obj
@staticmethod
def _get_schema_raw(metadata):

View File

@@ -1081,8 +1081,9 @@ class TestAlarmRepoDB(base.BaseTestCase):
self.assertNotEqual(original_state_updated_date,
new_state_updated_date,
'state_updated_at did not change')
alarm_tmp = tuple(alarm[k] for k in ('state', 'link', 'lifecycle_state'))
self.assertEqual(alarm_tmp, prev_state)
for k in ('state', 'link', 'lifecycle_state'):
self.assertEqual(alarm[k], prev_state[k])
alarm['state_updated_timestamp'] = alarm_new['state_updated_timestamp']
alarm['updated_timestamp'] = alarm_new['updated_timestamp']
alarm['state'] = alarm_new['state']
@@ -1103,8 +1104,8 @@ class TestAlarmRepoDB(base.BaseTestCase):
self.assertEqual(unchanged_state_updated_date,
new_state_updated_date,
'state_updated_at did change')
alarm_new_tmp = tuple(alarm_new[k] for k in ('state', 'link', 'lifecycle_state'))
self.assertEqual(alarm_new_tmp, prev_state)
for k in ('state', 'link', 'lifecycle_state'):
self.assertEqual(alarm_new[k], prev_state[k])
def test_should_throw_exception_on_update(self):
tenant_id = 'bob'

View File

@@ -272,18 +272,18 @@ class TestAlarmDefinitionRepoDB(base.BaseTestCase):
self.assertEqual(alarmA_id, alarmB['id'])
query_sad = (select([self.sad.c.id])
query_sad = (select(self.sad.c.id)
.select_from(self.sad)
.where(self.sad.c.alarm_definition_id == alarmA_id))
query_sadd = (select([func.count()])
query_sadd = (select(func.count())
.select_from(self.sadd)
.where(self.sadd.c.sub_alarm_definition_id == bindparam('id')))
.where(self.sadd.c.sub_alarm_definition_id == bindparam('b_id')))
with self.engine.connect() as conn:
count_sad = conn.execute(query_sad).fetchall()
self.assertEqual(len(count_sad), 1)
count_sadd = conn.execute(query_sadd, id=count_sad[0][0]).fetchone()
count_sadd = conn.execute(query_sadd, parameters={'b_id': count_sad[0][0]}).fetchone()
self.assertEqual(count_sadd[0], 3)
def test_should_try_to_create_with_wrong_alarm_action(self):
@@ -866,6 +866,8 @@ class TestAlarmDefinitionRepoDB(base.BaseTestCase):
sub_expr_list = (alarm_expr_parser.AlarmExprParser(expression).sub_expr_list)
else:
sub_expr_list = None
# updated_row (dict), sub_alarm_defs_dict
updates = self.repo.update_or_patch_alarm_definition(TENANT_ID, '123',
name, expression,
sub_expr_list, actions_enabled,
@@ -874,18 +876,35 @@ class TestAlarmDefinitionRepoDB(base.BaseTestCase):
match_by, severity,
patch=True)
alarm_def_row = \
(ALARM_DEF_123_FIELDS['id'],
name if name else ALARM_DEF_123_FIELDS['name'],
description if description else ALARM_DEF_123_FIELDS['description'],
expression if expression else ALARM_DEF_123_FIELDS['expression'],
ALARM_DEF_123_FIELDS['match_by'], # match-by can't change
severity if severity else ALARM_DEF_123_FIELDS['severity'],
actions_enabled if actions_enabled else ALARM_DEF_123_FIELDS['actions_enabled'],
u','.join(alarm_actions) if alarm_actions else ALARM_DEF_123_FIELDS['alarm_actions'],
u','.join(ok_actions) if ok_actions else ALARM_DEF_123_FIELDS['ok_actions'],
(u','.join(undetermined_actions) if undetermined_actions else
ALARM_DEF_123_FIELDS['undetermined_actions']))
self.assertEqual(updates[0]['id'], ALARM_DEF_123_FIELDS['id'])
self.assertEqual(updates[0]['name'], name if name else ALARM_DEF_123_FIELDS['name'])
self.assertEqual(
updates[0]['expression'],
expression if expression else ALARM_DEF_123_FIELDS['expression']
)
self.assertEqual(updates[0]['match_by'], ALARM_DEF_123_FIELDS['match_by'])
self.assertEqual(
updates[0]['severity'],
severity if severity else ALARM_DEF_123_FIELDS['severity']
)
self.assertEqual(
updates[0]['actions_enabled'],
actions_enabled if actions_enabled else ALARM_DEF_123_FIELDS['actions_enabled']
)
self.assertEqual(
updates[0]['alarm_actions'],
u','.join(alarm_actions) if alarm_actions else ALARM_DEF_123_FIELDS['alarm_actions']
)
self.assertEqual(
updates[0]['ok_actions'],
u','.join(ok_actions) if ok_actions else ALARM_DEF_123_FIELDS['ok_actions']
)
self.assertEqual(
updates[0]['undetermined_actions'],
(u','.join(undetermined_actions)
if undetermined_actions
else ALARM_DEF_123_FIELDS['undetermined_actions'])
)
sad = self.default_sads[0]
if expression and ALARM_DEF_123_FIELDS['expression'] != expression:
@@ -921,4 +940,4 @@ class TestAlarmDefinitionRepoDB(base.BaseTestCase):
'periods': sad['periods']})
expected_sub_alarm_maps = {'changed': {}, 'new': {},
'old': {}, 'unchanged': {u'111': sub_alarm_def}}
self.assertEqual((alarm_def_row, expected_sub_alarm_maps), updates)
self.assertEqual(expected_sub_alarm_maps, updates[1])

View File

@@ -28,19 +28,19 @@ class TestModelsDB(base.BaseTestCase):
md = models.create_md_model(metadata)
gc_columns = [md.c.name + text("'='") + md.c.value]
self.group_concat_md = (
select([md.c.dimension_set_id,
models.group_concat(gc_columns).label('dimensions')])
select(md.c.dimension_set_id,
models.group_concat(gc_columns).label('dimensions'))
.select_from(md)
.group_by(md.c.dimension_set_id))
self.group_concat_md_order = (
select([md.c.dimension_set_id,
models.group_concat(gc_columns,
order_by=[md.c.name.asc()]).label('dimensions')])
select(md.c.dimension_set_id,
models.group_concat(gc_columns,
order_by=[md.c.name.asc()]).label('dimensions'))
.select_from(md)
.group_by(md.c.dimension_set_id))
self.order_by_field = (select([md.c.dimension_set_id]) .select_from(md) .order_by(
self.order_by_field = (select(md.c.dimension_set_id) .select_from(md) .order_by(
asc(models.field_sort(md.c.dimension_set_id, map(text, ["'A'", "'B'", "'C'"])))))
def test_oracle(self):
@@ -102,34 +102,34 @@ FROM metric_dimension GROUP BY metric_dimension.dimension_set_id''')
query = str(self.order_by_field.compile(dialect=dialect))
self.assertEqual(expected, query)
def test_sybase(self):
from sqlalchemy.dialects import sybase as diale_
dialect = diale_.dialect()
query = str(self.group_concat_md.compile(dialect=dialect))
# def test_sybase(self):
# from sqlalchemy.dialects import sybase as diale_
# dialect = diale_.dialect()
# query = str(self.group_concat_md.compile(dialect=dialect))
expected = (
'''SELECT metric_dimension.dimension_set_id, LIST(metric_dimension.name || '=' '''
'''|| metric_dimension.value, ',') AS dimensions '''
'''
FROM metric_dimension GROUP BY metric_dimension.dimension_set_id''')
self.assertEqual(expected, query)
# expected = (
# '''SELECT metric_dimension.dimension_set_id, LIST(metric_dimension.name || '=' '''
# '''|| metric_dimension.value, ',') AS dimensions '''
# '''
# FROM metric_dimension GROUP BY metric_dimension.dimension_set_id''')
# self.assertEqual(expected, query)
query = str(self.group_concat_md_order.compile(dialect=dialect))
# query = str(self.group_concat_md_order.compile(dialect=dialect))
expected = (
'''SELECT metric_dimension.dimension_set_id, LIST(metric_dimension.name || '=' '''
'''|| metric_dimension.value, ',') AS dimensions '''
'''
FROM metric_dimension GROUP BY metric_dimension.dimension_set_id''')
self.assertEqual(expected, query)
# expected = (
# '''SELECT metric_dimension.dimension_set_id, LIST(metric_dimension.name || '=' '''
# '''|| metric_dimension.value, ',') AS dimensions '''
# '''
# FROM metric_dimension GROUP BY metric_dimension.dimension_set_id''')
# self.assertEqual(expected, query)
expected = (
"""SELECT metric_dimension.dimension_set_id \n"""
"""FROM metric_dimension ORDER BY CASE WHEN metric_dimension.dimension_set_id='A'"""
""" THEN 0 WHEN metric_dimension.dimension_set_id='B' THEN 1 WHEN"""
""" metric_dimension.dimension_set_id='C' THEN 2 ELSE 3 END ASC""")
query = str(self.order_by_field.compile(dialect=dialect))
self.assertEqual(expected, query)
# expected = (
# """SELECT metric_dimension.dimension_set_id \n"""
# """FROM metric_dimension ORDER BY CASE WHEN metric_dimension.dimension_set_id='A'"""
# """ THEN 0 WHEN metric_dimension.dimension_set_id='B' THEN 1 WHEN"""
# """ metric_dimension.dimension_set_id='C' THEN 2 ELSE 3 END ASC""")
# query = str(self.order_by_field.compile(dialect=dialect))
# self.assertEqual(expected, query)
def test_mysql(self):
from sqlalchemy.dialects import mysql as diale_
@@ -138,8 +138,8 @@ FROM metric_dimension GROUP BY metric_dimension.dimension_set_id''')
expected = (
'''SELECT metric_dimension.dimension_set_id, '''
'''GROUP_CONCAT(concat(concat(metric_dimension.name, '''
''''='), metric_dimension.value) SEPARATOR ',') AS dimensions '''
'''GROUP_CONCAT(concat(metric_dimension.name, '''
''''=', metric_dimension.value) SEPARATOR ',') AS dimensions '''
'''
FROM metric_dimension GROUP BY metric_dimension.dimension_set_id''')
self.assertEqual(expected, query)
@@ -148,8 +148,8 @@ FROM metric_dimension GROUP BY metric_dimension.dimension_set_id''')
expected = (
'''SELECT metric_dimension.dimension_set_id, '''
'''GROUP_CONCAT(concat(concat(metric_dimension.name, '''
''''='), metric_dimension.value) ORDER BY metric_dimension.name ASC '''
'''GROUP_CONCAT(concat(metric_dimension.name, '''
''''=', metric_dimension.value) ORDER BY metric_dimension.name ASC '''
'''SEPARATOR ',') AS dimensions '''
'''
FROM metric_dimension GROUP BY metric_dimension.dimension_set_id''')

View File

@@ -20,7 +20,7 @@ import fixtures
from oslo_config import cfg
from oslo_config import fixture as fixture_config
from oslo_db.sqlalchemy.engines import create_engine
from sqlalchemy import delete, MetaData, insert, bindparam
from sqlalchemy import delete, MetaData, insert, inspect, bindparam
from monasca_api.common.repositories.sqla import models
from monasca_api.tests import base
@@ -109,6 +109,8 @@ class TestNotificationMethodRepoDB(base.BaseTestCase):
with self.engine.connect() as conn:
conn.execute(self._delete_nm_query)
conn.execute(self._insert_nm_query, self.default_nms)
# TODO(thuvh) find better solution
conn.commit()
def test_fixture_and_setup(self):
class A(object):
@@ -133,7 +135,8 @@ class TestNotificationMethodRepoDB(base.BaseTestCase):
'sub_alarm_definition_dimension']
self.assertEqual(self.engine, a.engine)
self.assertEqual(self.engine.table_names(), expected_list_tables)
inspection = inspect(self.engine)
self.assertEqual(inspection.get_table_names(), expected_list_tables)
def test_should_create(self):
from monasca_api.common.repositories import exceptions
@@ -170,10 +173,17 @@ class TestNotificationMethodRepoDB(base.BaseTestCase):
def test_should_find_by_name(self):
nms = self.repo.find_notification_by_name('444', 'MyEmail')
expected = ('123', '444', 'MyEmail', 'EMAIL', 'a@b', 0,
self.created_at,
self.updated_at)
self.assertEqual(expected, nms)
self.assertEqual(nms['id'], '123')
self.assertEqual(nms['tenant_id'], '444')
self.assertEqual(nms['type'], 'EMAIL')
self.assertEqual(nms['address'], 'a@b')
self.assertEqual(nms['period'], 0)
self.assertEqual(nms['created_at'], self.created_at)
self.assertEqual(nms['updated_at'], self.updated_at)
from monasca_api.common.repositories import exceptions
self.assertRaises(exceptions.DoesNotExistException,
self.repo.find_notification_by_name, '444', '222222MyEmail22222')
def test_should_find(self):
nms = self.repo.list_notifications('444', None, None, 2)

View File

@@ -58,7 +58,10 @@ class Notifications(notifications_api_v2.NotificationsV2API):
raise falcon.HTTPBadRequest('Bad Request', str(ex))
def _validate_name_not_conflicting(self, tenant_id, name, expected_id=None):
notification = self._notifications_repo.find_notification_by_name(tenant_id, name)
try:
notification = self._notifications_repo.find_notification_by_name(tenant_id, name)
except exceptions.DoesNotExistException:
notification = None
if notification:
if not expected_id: