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

View File

@@ -26,7 +26,7 @@ Vagrant.configure(2) do |config|
end end
config.vm.hostname = "devstack" 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.box_check_update = false
config.vm.network "private_network",ip:"192.168.10.6" config.vm.network "private_network",ip:"192.168.10.6"
config.vm.synced_folder "~/", "/vagrant_home" config.vm.synced_folder "~/", "/vagrant_home"

View File

@@ -477,9 +477,10 @@ function install_monasca_cassandra {
echo_summary "Install Monasca Cassandra" echo_summary "Install Monasca Cassandra"
if [[ "$OFFLINE" != "True" ]]; then 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 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}'` PUBLIC_KEY=`sudo apt_get update 2>&1 | awk '/NO_PUBKEY/ {print $NF}'`
if [ -n "${PUBLIC_KEY}" ]; then if [ -n "${PUBLIC_KEY}" ]; then
sudo apt-key adv --keyserver pool.sks-keyservers.net --recv-key ${PUBLIC_KEY} 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') sadd_s = sadd.alias('sadd')
aaa_aa = aa.alias('aaa_aa') aaa_aa = aa.alias('aaa_aa')
aaa = (select([aaa_aa.c.alarm_definition_id, aaa = (select(aaa_aa.c.alarm_definition_id,
models.group_concat([aaa_aa.c.action_id]).label('alarm_actions')]) models.group_concat([aaa_aa.c.action_id]).label('alarm_actions'))
.select_from(aaa_aa) .select_from(aaa_aa)
.where(aaa_aa.c.alarm_state == text("'ALARM'")) .where(aaa_aa.c.alarm_state == text("'ALARM'"))
.group_by(aaa_aa.c.alarm_definition_id) .group_by(aaa_aa.c.alarm_definition_id)
.alias('aaa')) .alias('aaa'))
aao_aa = aa.alias('aao_aa') aao_aa = aa.alias('aao_aa')
aao = (select([aao_aa.c.alarm_definition_id, aao = (select(aao_aa.c.alarm_definition_id,
models.group_concat([aao_aa.c.action_id]).label('ok_actions')]) models.group_concat([aao_aa.c.action_id]).label('ok_actions'))
.select_from(aao_aa) .select_from(aao_aa)
.where(aao_aa.c.alarm_state == text("'OK'")) .where(aao_aa.c.alarm_state == text("'OK'"))
.group_by(aao_aa.c.alarm_definition_id) .group_by(aao_aa.c.alarm_definition_id)
.alias('aao')) .alias('aao'))
aau_aa = aa.alias('aau_aa') aau_aa = aa.alias('aau_aa')
aau = (select([aau_aa.c.alarm_definition_id, aau = (select(aau_aa.c.alarm_definition_id,
models.group_concat([aau_aa.c.action_id]).label('undetermined_actions')]) models.group_concat([aau_aa.c.action_id]).label('undetermined_actions'))
.select_from(aau_aa) .select_from(aau_aa)
.where(aau_aa.c.alarm_state == text("'UNDETERMINED'")) .where(aau_aa.c.alarm_state == text("'UNDETERMINED'"))
.group_by(aau_aa.c.alarm_definition_id) .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(aao, aao.c.alarm_definition_id == ad_s.c.id)
.outerjoin(aau, aau.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, self.base_query = (select(ad_s.c.id,
ad_s.c.name, ad_s.c.name,
ad_s.c.description, ad_s.c.description,
ad_s.c.expression, ad_s.c.expression,
ad_s.c.match_by, ad_s.c.match_by,
ad_s.c.severity, ad_s.c.severity,
ad_s.c.actions_enabled, ad_s.c.actions_enabled,
aaa.c.alarm_actions, aaa.c.alarm_actions,
aao.c.ok_actions, aao.c.ok_actions,
aau.c.undetermined_actions])) aau.c.undetermined_actions))
self.get_sub_alarms_query = ( self.get_sub_alarms_query = (
select( select(sa_s.c.id.label('sub_alarm_id'),
[ sa_s.c.alarm_id,
sa_s.c.id.label('sub_alarm_id'), sa_s.c.expression) .select_from(
sa_s.c.alarm_id,
sa_s.c.expression]) .select_from(
sa_s.join( sa_s.join(
a_s, a_s,
a_s.c.id == sa_s.c.alarm_id) .join( 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.tenant_id == bindparam('b_tenant_id')) .where(
ad_s.c.id == bindparam('b_id')) .distinct()) ad_s.c.id == bindparam('b_id')) .distinct())
mdg = (select([md_s.c.dimension_set_id, mdg = (select(md_s.c.dimension_set_id,
models.group_concat( models.group_concat(
[md_s.c.name + text("'='") + md_s.c.value]).label('dimensions')]) [md_s.c.name + text("'='") + md_s.c.value]).label('dimensions'))
.select_from(md_s) .select_from(md_s)
.group_by(md_s.c.dimension_set_id) .group_by(md_s.c.dimension_set_id)
.alias('mdg')) .alias('mdg'))
self.get_alarm_metrics_query = ( self.get_alarm_metrics_query = (
select( select(
[a_s.c.id.label('alarm_id'), a_s.c.id.label('alarm_id'),
mde_s.c.name, mde_s.c.name,
mdg.c.dimensions]) .select_from( mdg.c.dimensions) .select_from(
a_s.join( a_s.join(
ad_s, ad_s,
ad_s.c.id == a_s.c.alarm_definition_id) .join( 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'))) .where(a.c.alarm_definition_id == bindparam('b_id')))
columns_gc = [sadd_s.c.dimension_name + text("'='") + sadd_s.c.value] columns_gc = [sadd_s.c.dimension_name + text("'='") + sadd_s.c.value]
saddg = (select([sadd_s.c.sub_alarm_definition_id, saddg = (select(sadd_s.c.sub_alarm_definition_id,
models.group_concat(columns_gc).label('dimensions')]) models.group_concat(columns_gc).label('dimensions'))
.select_from(sadd_s) .select_from(sadd_s)
.group_by(sadd_s.c.sub_alarm_definition_id) .group_by(sadd_s.c.sub_alarm_definition_id)
.alias('saddg')) .alias('saddg'))
self.get_sub_alarm_definitions_query = ( self.get_sub_alarm_definitions_query = (
select( select(sad_s,
[ saddg.c.dimensions) .select_from(
sad_s,
saddg.c.dimensions]) .select_from(
sad_s.outerjoin( sad_s.outerjoin(
saddg, saddg,
saddg.c.sub_alarm_definition_id == sad_s.c.id)) .where( 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_definition_id == bindparam('b_alarm_definition_id')) .where(
aa.c.alarm_state == bindparam('b_alarm_state'))) 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) .select_from(nm_s)
.where(nm_s.c.id == bindparam('b_id'))) .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.id == bindparam('b_id'))
.where(ad.c.deleted_at == null())) .where(ad.c.deleted_at == null()))
row = conn.execute(query, row = conn.execute(
b_tenant_id=tenant_id, query,
b_id=_id).fetchone() parameters={
'b_tenant_id': tenant_id,
'b_id': _id
}
).fetchone()
if row is not None: if row is not None:
return dict(row) return row._mapping
else: else:
raise exceptions.DoesNotExistException raise exceptions.DoesNotExistException
@@ -309,7 +309,7 @@ class AlarmDefinitionsRepository(sql_repository.SQLRepository,
for n, v in dimensions.items(): for n, v in dimensions.items():
bind_dimension_name = 'b_sadd_dimension_name_{}'.format(i) bind_dimension_name = 'b_sadd_dimension_name_{}'.format(i)
bind_value = 'b_sadd_value_{}'.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) .select_from(sadd)
.where(sadd.c.dimension_name == bindparam(bind_dimension_name)) .where(sadd.c.dimension_name == bindparam(bind_dimension_name))
.where(sadd.c.value == bindparam(bind_value)) .where(sadd.c.value == bindparam(bind_value))
@@ -356,22 +356,26 @@ class AlarmDefinitionsRepository(sql_repository.SQLRepository,
parms['b_limit'] = limit + 1 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 @sql_repository.sql_try_catch_block
def get_sub_alarms(self, tenant_id, alarm_definition_id): def get_sub_alarms(self, tenant_id, alarm_definition_id):
with self._db_engine.connect() as conn: with self._db_engine.connect() as conn:
return [dict(row) for row in conn.execute(self.get_sub_alarms_query, return [row._mapping for row in conn.execute(self.get_sub_alarms_query,
b_tenant_id=tenant_id, parameters={
b_id=alarm_definition_id).fetchall()] 'b_tenant_id': tenant_id,
'b_id': alarm_definition_id
}).fetchall()]
@sql_repository.sql_try_catch_block @sql_repository.sql_try_catch_block
def get_alarm_metrics(self, tenant_id, alarm_definition_id): def get_alarm_metrics(self, tenant_id, alarm_definition_id):
with self._db_engine.connect() as conn: with self._db_engine.connect() as conn:
return [dict(row) for row in conn.execute(self.get_alarm_metrics_query, return [row._mapping for row in conn.execute(self.get_alarm_metrics_query,
b_tenant_id=tenant_id, parameters={
b_id=alarm_definition_id).fetchall()] 'b_tenant_id': tenant_id,
'b_id': alarm_definition_id
}).fetchall()]
@sql_repository.sql_try_catch_block @sql_repository.sql_try_catch_block
def delete_alarm_definition(self, tenant_id, alarm_definition_id): 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: with self._db_engine.begin() as conn:
cursor = conn.execute(self.soft_delete_ad_query, cursor = conn.execute(
b_tenant_id=tenant_id, self.soft_delete_ad_query,
b_id=alarm_definition_id) parameters={
'b_tenant_id': tenant_id,
'b_id': alarm_definition_id
}
)
if cursor.rowcount < 1: if cursor.rowcount < 1:
return False return False
conn.execute(self.delete_a_query, conn.execute(
b_tenant_id=tenant_id, self.delete_a_query,
b_id=alarm_definition_id) parameters={
'b_tenant_id': tenant_id,
'b_id': alarm_definition_id
}
)
return True return True
@@ -408,9 +420,13 @@ class AlarmDefinitionsRepository(sql_repository.SQLRepository,
def _get_sub_alarm_definitions(self, conn, alarm_definition_id): def _get_sub_alarm_definitions(self, conn, alarm_definition_id):
return [ return [
dict(row) for row in conn.execute( row._mapping for row in conn.execute(
self.get_sub_alarm_definitions_query, 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 @sql_repository.sql_try_catch_block
def create_alarm_definition(self, tenant_id, name, expression, def create_alarm_definition(self, tenant_id, name, expression,
@@ -422,45 +438,57 @@ class AlarmDefinitionsRepository(sql_repository.SQLRepository,
now = datetime.datetime.utcnow() now = datetime.datetime.utcnow()
alarm_definition_id = uuidutils.generate_uuid() alarm_definition_id = uuidutils.generate_uuid()
conn.execute(self.create_alarm_definition_insert_ad_query, conn.execute(
b_id=alarm_definition_id, self.create_alarm_definition_insert_ad_query,
b_tenant_id=tenant_id, parameters={
b_name=name.encode('utf8'), 'b_id': alarm_definition_id,
b_description=description.encode('utf8'), 'b_tenant_id': tenant_id,
b_expression=expression.encode('utf8'), 'b_name': name.encode('utf8'),
b_severity=severity.upper().encode('utf8'), 'b_description': description.encode('utf8'),
b_match_by=",".join(match_by).encode('utf8'), 'b_expression': expression.encode('utf8'),
b_actions_enabled=True, 'b_severity': severity.upper().encode('utf8'),
b_created_at=now, 'b_match_by': ",".join(match_by).encode('utf8'),
b_updated_at=now) 'b_actions_enabled': True,
'b_created_at': now,
'b_updated_at': now
}
)
for sub_expr in sub_expr_list: for sub_expr in sub_expr_list:
sub_alarm_definition_id = uuidutils.generate_uuid() sub_alarm_definition_id = uuidutils.generate_uuid()
sub_expr.id = sub_alarm_definition_id sub_expr.id = sub_alarm_definition_id
metric_name = sub_expr.metric_name.encode("utf8") metric_name = sub_expr.metric_name.encode("utf8")
operator = sub_expr.normalized_operator.encode('utf8') operator = sub_expr.normalized_operator.encode('utf8')
conn.execute(self.create_alarm_definition_insert_sad_query, conn.execute(
b_id=sub_alarm_definition_id, self.create_alarm_definition_insert_sad_query,
b_alarm_definition_id=alarm_definition_id, parameters={
b_function=sub_expr.normalized_func.encode('utf8'), 'b_id': sub_alarm_definition_id,
b_metric_name=metric_name, 'b_alarm_definition_id': alarm_definition_id,
b_operator=operator, 'b_function': sub_expr.normalized_func.encode('utf8'),
b_threshold=sub_expr.threshold, 'b_metric_name': metric_name,
b_period=sub_expr.period, 'b_operator': operator,
b_periods=sub_expr.periods, 'b_threshold': sub_expr.threshold,
b_is_deterministic=sub_expr.deterministic, 'b_period': sub_expr.period,
b_created_at=now, 'b_periods': sub_expr.periods,
b_updated_at=now) 'b_is_deterministic': sub_expr.deterministic,
'b_created_at': now,
'b_updated_at': now
}
)
for dimension in sub_expr.dimensions_as_list: for dimension in sub_expr.dimensions_as_list:
parsed_dimension = dimension.split('=') parsed_dimension = dimension.split('=')
query = self.create_alarm_definition_insert_sadd_query query = self.create_alarm_definition_insert_sadd_query
sadi = sub_alarm_definition_id sadi = sub_alarm_definition_id
dimension_name = parsed_dimension[0].encode('utf8') dimension_name = parsed_dimension[0].encode('utf8')
conn.execute(query, conn.execute(
b_sub_alarm_definition_id=sadi, query,
b_dimension_name=dimension_name, parameters={
b_value=parsed_dimension[1].encode('utf8')) '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, self._insert_into_alarm_action(conn, alarm_definition_id,
alarm_actions, u"ALARM") alarm_actions, u"ALARM")
@@ -575,15 +603,17 @@ class AlarmDefinitionsRepository(sql_repository.SQLRepository,
actions_enabled=bindparam('b_actions_enabled'), actions_enabled=bindparam('b_actions_enabled'),
updated_at=bindparam('b_updated_at') updated_at=bindparam('b_updated_at')
), ),
b_name=new_name, parameters={
b_description=new_description, 'b_name': new_name,
b_expression=new_expression, 'b_description': new_description,
b_match_by=new_match_by, 'b_expression': new_expression,
b_severity=new_severity, 'b_match_by': new_match_by,
b_actions_enabled=bool(new_actions_enabled), 'b_severity': new_severity,
b_updated_at=now, 'b_actions_enabled': bool(new_actions_enabled),
b_tenant_id=tenant_id, 'b_updated_at': now,
b_id=alarm_definition_id) 'b_tenant_id': tenant_id,
'b_id': alarm_definition_id
})
parms = [] parms = []
for sub_alarm_definition_id, sub_alarm_def in ( for sub_alarm_definition_id, sub_alarm_def in (
changed_sub_alarm_defs_by_id.items()): changed_sub_alarm_defs_by_id.items()):
@@ -608,8 +638,12 @@ class AlarmDefinitionsRepository(sql_repository.SQLRepository,
self._delete_alarm_actions(conn, alarm_definition_id, self._delete_alarm_actions(conn, alarm_definition_id,
'UNDETERMINED') 'UNDETERMINED')
else: else:
conn.execute(self.delete_aa_query, conn.execute(
b_alarm_definition_id=alarm_definition_id) self.delete_aa_query,
parameters={
'b_alarm_definition_id': alarm_definition_id
}
)
# Insert new alarm actions # Insert new alarm actions
self._insert_into_alarm_action(conn, alarm_definition_id, 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.id == bindparam('b_id'))
.where(ad.c.deleted_at == null())) .where(ad.c.deleted_at == null()))
updated_row = conn.execute(query, updated_row = conn.execute(
b_id=alarm_definition_id, query,
b_tenant_id=tenant_id).fetchone() parameters={
'b_id': alarm_definition_id,
'b_tenant_id': tenant_id
}
).fetchone()
# TODO(thuvh) need return not found exception
if updated_row is None: if updated_row is None:
raise Exception("Failed to find current alarm definition") 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, sub_alarm_defs_dict = {'old': old_sub_alarm_defs_by_id,
'changed': changed_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) unchanged_sub_alarm_defs_by_id)
def _delete_alarm_actions(self, conn, _id, alarm_action_name): def _delete_alarm_actions(self, conn, _id, alarm_action_name):
conn.execute(self.delete_aa_state_query, conn.execute(
b_alarm_definition_id=_id, self.delete_aa_state_query,
b_alarm_state=alarm_action_name) parameters={
'b_alarm_definition_id': _id,
'b_alarm_state': alarm_action_name
}
)
def _insert_into_alarm_action(self, conn, alarm_definition_id, actions, def _insert_into_alarm_action(self, conn, alarm_definition_id, actions,
alarm_state): alarm_state):
@@ -737,15 +782,22 @@ class AlarmDefinitionsRepository(sql_repository.SQLRepository,
for action in actions: for action in actions:
b_id = action.encode('utf8') if six.PY2 else action b_id = action.encode('utf8') if six.PY2 else action
row = conn.execute(self.select_nm_query, row = conn.execute(
b_id=b_id).fetchone() self.select_nm_query,
parameters={
'b_id': b_id
}
).fetchone()
if row is None: if row is None:
raise exceptions.InvalidUpdateException( raise exceptions.InvalidUpdateException(
"Non-existent notification id {} submitted for {} " "Non-existent notification id {} submitted for {} "
"notification action".format(encodeutils.to_utf8(action), "notification action".format(encodeutils.to_utf8(action),
encodeutils.to_utf8(alarm_state))) encodeutils.to_utf8(alarm_state)))
conn.execute(self.insert_aa_query, conn.execute(
b_alarm_definition_id=alarm_definition_id, self.insert_aa_query,
b_alarm_state=alarm_state.encode('utf8') if six.PY2 else alarm_state, parameters={
b_action_id=action.encode('utf8') if six.PY2 else action '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] gc_columns = [md.c.name + text("'='") + md.c.value]
mdg = (select([md.c.dimension_set_id, mdg = (select(md.c.dimension_set_id,
models.group_concat(gc_columns).label('dimensions')]) models.group_concat(gc_columns).label('dimensions'))
.select_from(md) .select_from(md)
.group_by(md.c.dimension_set_id).alias('mdg')) .group_by(md.c.dimension_set_id).alias('mdg'))
@@ -74,31 +74,31 @@ class AlarmsRepository(sql_repository.SQLRepository,
mdg, mdg,
mdg.c.dimension_set_id == mdd.c.metric_dimension_set_id)) mdg.c.dimension_set_id == mdd.c.metric_dimension_set_id))
self.base_query = select([a_s.c.id.label('alarm_id'), self.base_query = select(a_s.c.id.label('alarm_id'),
a_s.c.state, a_s.c.state,
a_s.c.state_updated_at. a_s.c.state_updated_at.
label('state_updated_timestamp'), label('state_updated_timestamp'),
a_s.c.updated_at.label('updated_timestamp'), a_s.c.updated_at.label('updated_timestamp'),
a_s.c.created_at.label('created_timestamp'), a_s.c.created_at.label('created_timestamp'),
a_s.c.lifecycle_state, a_s.c.lifecycle_state,
a_s.c.link, a_s.c.link,
ad.c.id.label('alarm_definition_id'), ad.c.id.label('alarm_definition_id'),
ad.c.name.label('alarm_definition_name'), ad.c.name.label('alarm_definition_name'),
ad.c.severity, ad.c.severity,
mde.c.name.label('metric_name'), mde.c.name.label('metric_name'),
mdg.c.dimensions.label('metric_dimensions')]) 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))) .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)) .select_from(ad.join(a, ad.c.id == a.c.alarm_definition_id))
.where(ad.c.tenant_id == bindparam('b_tenant_id')) .where(ad.c.tenant_id == bindparam('b_tenant_id'))
.where(a.c.id == bindparam('b_id'))) .where(a.c.id == bindparam('b_id')))
self.get_am_query = (select([a_s.c.id.label('alarm_id'), self.get_am_query = (select(a_s.c.id.label('alarm_id'),
mde.c.name, mde.c.name,
mdg.c.dimensions]) mdg.c.dimensions)
.select_from(a_s.join(am, am.c.alarm_id == a_s.c.id) .select_from(a_s.join(am, am.c.alarm_id == a_s.c.id)
.join(mdd, .join(mdd,
mdd.c.id == mdd.c.id ==
@@ -111,10 +111,10 @@ class AlarmsRepository(sql_repository.SQLRepository,
.order_by(a_s.c.id) .order_by(a_s.c.id)
.distinct()) .distinct())
self.get_sa_query = (select([sa.c.id.label('sub_alarm_id'), self.get_sa_query = (select(sa.c.id.label('sub_alarm_id'),
sa.c.alarm_id, sa.c.alarm_id,
sa.c.expression, sa.c.expression,
ad.c.id.label('alarm_definition_id')]) ad.c.id.label('alarm_definition_id'))
.select_from(sa.join(a_s, .select_from(sa.join(a_s,
a_s.c.id == sa.c.alarm_id) a_s.c.id == sa.c.alarm_id)
.join(ad, .join(ad,
@@ -123,13 +123,13 @@ class AlarmsRepository(sql_repository.SQLRepository,
.where(a_s.c.id == bindparam('b_id')) .where(a_s.c.id == bindparam('b_id'))
.distinct()) .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, .select_from(a_s.join(ad,
ad.c.id == a_s.c.alarm_definition_id)) ad.c.id == a_s.c.alarm_definition_id))
.where(ad.c.tenant_id == bindparam('b_tenant_id')) .where(ad.c.tenant_id == bindparam('b_tenant_id'))
.where(a_s.c.id == bindparam('b_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, .select_from(a_s.join(ad,
ad.c.id == ad.c.id ==
a_s.c.alarm_definition_id)) a_s.c.alarm_definition_id))
@@ -137,7 +137,7 @@ class AlarmsRepository(sql_repository.SQLRepository,
.where(a_s.c.id == bindparam('b_id')) .where(a_s.c.id == bindparam('b_id'))
.alias('a_ad')) .alias('a_ad'))
select_tmp = (select([literal_column('id')]) select_tmp = (select(literal_column('id'))
.select_from(self.get_a_ad_query) .select_from(self.get_a_ad_query)
.distinct() .distinct()
.alias('temporarytable')) .alias('temporarytable'))
@@ -145,10 +145,10 @@ class AlarmsRepository(sql_repository.SQLRepository,
self.delete_alarm_query = (delete(a) self.delete_alarm_query = (delete(a)
.where(a.c.id.in_(select_tmp))) .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_')) .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, .select_from(a_s.join(am,
am.c.alarm_id == am.c.alarm_id ==
a_s.c.id) a_s.c.id)
@@ -162,12 +162,15 @@ class AlarmsRepository(sql_repository.SQLRepository,
@sql_repository.sql_try_catch_block @sql_repository.sql_try_catch_block
def get_alarm_definition(self, tenant_id, alarm_id): def get_alarm_definition(self, tenant_id, alarm_id):
with self._db_engine.connect() as conn: with self._db_engine.connect() as conn:
row = conn.execute(self.get_ad_query, row = conn.execute(
b_tenant_id=tenant_id, self.get_ad_query,
b_id=alarm_id).fetchone() parameters={
'b_tenant_id': tenant_id,
'b_id': alarm_id
}).fetchone()
if row is not None: if row is not None:
return dict(row) return row._mapping
else: else:
raise exceptions.DoesNotExistException raise exceptions.DoesNotExistException
@@ -175,17 +178,24 @@ class AlarmsRepository(sql_repository.SQLRepository,
def get_alarm_metrics(self, alarm_id): def get_alarm_metrics(self, alarm_id):
with self._db_engine.connect() as conn: with self._db_engine.connect() as conn:
rows = conn.execute(self.get_am_query, b_id=alarm_id).fetchall() rows = conn.execute(
return [dict(row) for row in rows] self.get_am_query,
parameters={'b_id': alarm_id}
).fetchall()
return [row._mapping for row in rows]
@sql_repository.sql_try_catch_block @sql_repository.sql_try_catch_block
def get_sub_alarms(self, tenant_id, alarm_id): def get_sub_alarms(self, tenant_id, alarm_id):
with self._db_engine.connect() as conn: with self._db_engine.connect() as conn:
rows = conn.execute(self.get_sa_query, rows = conn.execute(
b_tenant_id=tenant_id, self.get_sa_query,
b_id=alarm_id).fetchall() parameters={
return [dict(row) for row in rows] 'b_tenant_id': tenant_id,
'b_id': alarm_id
}
).fetchall()
return [row._mapping for row in rows]
@sql_repository.sql_try_catch_block @sql_repository.sql_try_catch_block
def update_alarm(self, tenant_id, _id, state, lifecycle_state, link): 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)) time_ms = int(round(time() * 1000.0))
with self._db_engine.connect() as conn: with self._db_engine.connect() as conn:
self.get_a_query.bind = self._db_engine self.get_a_query.bind = self._db_engine
prev_alarm = conn.execute(self.get_a_query, prev_alarm = conn.execute(
b_tenant_id=tenant_id, self.get_a_query,
b_id=_id).fetchone() parameters={
'b_tenant_id': tenant_id,
'b_id': _id
}
).fetchone()
if prev_alarm is None: if prev_alarm is None:
raise exceptions.DoesNotExistException raise exceptions.DoesNotExistException
else:
prev_alarm = prev_alarm._mapping
parms = {'b_lifecycle_state': lifecycle_state, parms = {'b_lifecycle_state': lifecycle_state,
'b_link': link} 'b_link': link}
@@ -206,8 +222,9 @@ class AlarmsRepository(sql_repository.SQLRepository,
bindparam('b_lifecycle_state'), bindparam('b_lifecycle_state'),
'link': bindparam('b_link'), 'link': bindparam('b_link'),
'updated_at': func.now()} 'updated_at': func.now()}
# TODO(thuvh) find better solution to get state from row
if state != prev_alarm['state']: prev_state = prev_alarm['state']
if state != prev_state:
parms['b_state'] = state parms['b_state'] = state
set_values['state'] = bindparam('b_state') set_values['state'] = bindparam('b_state')
set_values['state_updated_at'] = func.now() set_values['state_updated_at'] = func.now()
@@ -215,7 +232,7 @@ class AlarmsRepository(sql_repository.SQLRepository,
parms['b_tenant_id'] = tenant_id parms['b_tenant_id'] = tenant_id
parms['b_id'] = _id parms['b_id'] = _id
select_tmp = (select([literal_column('id')]) select_tmp = (select(literal_column('id'))
.select_from(self.get_a_ad_query) .select_from(self.get_a_ad_query)
.distinct() .distinct()
.alias('temporarytable')) .alias('temporarytable'))
@@ -227,15 +244,23 @@ class AlarmsRepository(sql_repository.SQLRepository,
conn.execute(update_query, parms) conn.execute(update_query, parms)
# TODO(thuvh) find a better solution
conn.commit()
return prev_alarm, time_ms return prev_alarm, time_ms
@sql_repository.sql_try_catch_block @sql_repository.sql_try_catch_block
def delete_alarm(self, tenant_id, _id): def delete_alarm(self, tenant_id, _id):
with self._db_engine.connect() as conn: with self._db_engine.connect() as conn:
cursor = conn.execute(self.delete_alarm_query, cursor = conn.execute(
b_tenant_id=tenant_id, self.delete_alarm_query,
b_id=_id) parameters={
'b_tenant_id': tenant_id,
'b_id': _id
})
# TODO(thuvh) find a better solution
conn.commit()
if cursor.rowcount < 1: if cursor.rowcount < 1:
raise exceptions.DoesNotExistException raise exceptions.DoesNotExistException
@@ -252,14 +277,18 @@ class AlarmsRepository(sql_repository.SQLRepository,
.where(a.c.id == bindparam('b_id')) .where(a.c.id == bindparam('b_id'))
.distinct()) .distinct())
rows = conn.execute(query, rows = conn.execute(
b_tenant_id=tenant_id, query,
b_id=_id).fetchall() parameters={
'b_tenant_id': tenant_id,
'b_id': _id
}
).fetchall()
if rows is None or len(rows) == 0: if rows is None or len(rows) == 0:
raise exceptions.DoesNotExistException raise exceptions.DoesNotExistException
return [dict(row) for row in rows] return [row._mapping for row in rows]
@sql_repository.sql_try_catch_block @sql_repository.sql_try_catch_block
def get_alarms(self, tenant_id, query_parms=None, offset=None, limit=None): 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 parms['b_state_updated_at'] = date_param
if 'metric_dimensions' in query_parms: 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) sub_query_from = (a.join(am, am.c.alarm_id == a.c.id)
.join(mdd, .join(mdd,
mdd.c.id == mdd.c.id ==
am.c.metric_definition_dimensions_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()): 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) 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): def _remap_columns(self, columns, columns_mapper):
received_cols = {} received_cols = {}
@@ -484,7 +513,7 @@ class AlarmsRepository(sql_repository.SQLRepository,
md, mdd.c.metric_dimension_set_id == md.c.dimension_set_id) .join( md, mdd.c.metric_dimension_set_id == md.c.dimension_set_id) .join(
am, am.c.metric_definition_dimensions_id == mdd.c.id)) 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) .select_from(sub_query_from)
.distinct() .distinct()
.alias('metrics')) .alias('metrics'))
@@ -494,7 +523,7 @@ class AlarmsRepository(sql_repository.SQLRepository,
query_columns = [func.count().label('count')] query_columns = [func.count().label('count')]
query_columns.extend([column(col) for col in group_by_columns]) query_columns.extend([column(col) for col in group_by_columns])
query = (select(query_columns) query = (select(*query_columns)
.select_from(query_from) .select_from(query_from)
.where(ad.c.tenant_id == bindparam('b_tenant_id'))) .where(ad.c.tenant_id == bindparam('b_tenant_id')))
@@ -539,13 +568,13 @@ class AlarmsRepository(sql_repository.SQLRepository,
query_parms['metric_name'].encode('utf8') query_parms['metric_name'].encode('utf8')
if 'metric_dimensions' in query_parms: 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) sub_query_from = (a.join(am, am.c.alarm_id == a.c.id)
.join(mdd, .join(mdd,
mdd.c.id == mdd.c.id ==
am.c.metric_definition_dimensions_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()): for i, metric_dimension in enumerate(query_parms['metric_dimensions'].items()):
dimension_value = metric_dimension[1] if six.PY3 else \ dimension_value = metric_dimension[1] if six.PY3 else \
@@ -599,4 +628,4 @@ class AlarmsRepository(sql_repository.SQLRepository,
parms['b_offset'] = offset parms['b_offset'] = offset
query = query.distinct() 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) self.nmt = models.create_nmt_model(metadata)
nmt = self.nmt nmt = self.nmt
self._nmt_query = select([nmt.c.name]) self._nmt_query = select(nmt.c.name)
@sql_repository.sql_try_catch_block @sql_repository.sql_try_catch_block
def list_notification_method_types(self): def list_notification_method_types(self):

View File

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

View File

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

View File

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

View File

@@ -272,18 +272,18 @@ class TestAlarmDefinitionRepoDB(base.BaseTestCase):
self.assertEqual(alarmA_id, alarmB['id']) self.assertEqual(alarmA_id, alarmB['id'])
query_sad = (select([self.sad.c.id]) query_sad = (select(self.sad.c.id)
.select_from(self.sad) .select_from(self.sad)
.where(self.sad.c.alarm_definition_id == alarmA_id)) .where(self.sad.c.alarm_definition_id == alarmA_id))
query_sadd = (select([func.count()]) query_sadd = (select(func.count())
.select_from(self.sadd) .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: with self.engine.connect() as conn:
count_sad = conn.execute(query_sad).fetchall() count_sad = conn.execute(query_sad).fetchall()
self.assertEqual(len(count_sad), 1) 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) self.assertEqual(count_sadd[0], 3)
def test_should_try_to_create_with_wrong_alarm_action(self): 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) sub_expr_list = (alarm_expr_parser.AlarmExprParser(expression).sub_expr_list)
else: else:
sub_expr_list = None sub_expr_list = None
# updated_row (dict), sub_alarm_defs_dict
updates = self.repo.update_or_patch_alarm_definition(TENANT_ID, '123', updates = self.repo.update_or_patch_alarm_definition(TENANT_ID, '123',
name, expression, name, expression,
sub_expr_list, actions_enabled, sub_expr_list, actions_enabled,
@@ -874,18 +876,35 @@ class TestAlarmDefinitionRepoDB(base.BaseTestCase):
match_by, severity, match_by, severity,
patch=True) patch=True)
alarm_def_row = \ self.assertEqual(updates[0]['id'], ALARM_DEF_123_FIELDS['id'])
(ALARM_DEF_123_FIELDS['id'], self.assertEqual(updates[0]['name'], name if name else ALARM_DEF_123_FIELDS['name'])
name if name else ALARM_DEF_123_FIELDS['name'], self.assertEqual(
description if description else ALARM_DEF_123_FIELDS['description'], updates[0]['expression'],
expression if expression else ALARM_DEF_123_FIELDS['expression'], 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'], self.assertEqual(updates[0]['match_by'], ALARM_DEF_123_FIELDS['match_by'])
actions_enabled if actions_enabled else ALARM_DEF_123_FIELDS['actions_enabled'], self.assertEqual(
u','.join(alarm_actions) if alarm_actions else ALARM_DEF_123_FIELDS['alarm_actions'], updates[0]['severity'],
u','.join(ok_actions) if ok_actions else ALARM_DEF_123_FIELDS['ok_actions'], severity if severity else ALARM_DEF_123_FIELDS['severity']
(u','.join(undetermined_actions) if undetermined_actions else )
ALARM_DEF_123_FIELDS['undetermined_actions'])) 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] sad = self.default_sads[0]
if expression and ALARM_DEF_123_FIELDS['expression'] != expression: if expression and ALARM_DEF_123_FIELDS['expression'] != expression:
@@ -921,4 +940,4 @@ class TestAlarmDefinitionRepoDB(base.BaseTestCase):
'periods': sad['periods']}) 'periods': sad['periods']})
expected_sub_alarm_maps = {'changed': {}, 'new': {}, expected_sub_alarm_maps = {'changed': {}, 'new': {},
'old': {}, 'unchanged': {u'111': sub_alarm_def}} '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) md = models.create_md_model(metadata)
gc_columns = [md.c.name + text("'='") + md.c.value] gc_columns = [md.c.name + text("'='") + md.c.value]
self.group_concat_md = ( self.group_concat_md = (
select([md.c.dimension_set_id, select(md.c.dimension_set_id,
models.group_concat(gc_columns).label('dimensions')]) models.group_concat(gc_columns).label('dimensions'))
.select_from(md) .select_from(md)
.group_by(md.c.dimension_set_id)) .group_by(md.c.dimension_set_id))
self.group_concat_md_order = ( self.group_concat_md_order = (
select([md.c.dimension_set_id, select(md.c.dimension_set_id,
models.group_concat(gc_columns, models.group_concat(gc_columns,
order_by=[md.c.name.asc()]).label('dimensions')]) order_by=[md.c.name.asc()]).label('dimensions'))
.select_from(md) .select_from(md)
.group_by(md.c.dimension_set_id)) .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'"]))))) asc(models.field_sort(md.c.dimension_set_id, map(text, ["'A'", "'B'", "'C'"])))))
def test_oracle(self): 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)) query = str(self.order_by_field.compile(dialect=dialect))
self.assertEqual(expected, query) self.assertEqual(expected, query)
def test_sybase(self): # def test_sybase(self):
from sqlalchemy.dialects import sybase as diale_ # from sqlalchemy.dialects import sybase as diale_
dialect = diale_.dialect() # dialect = diale_.dialect()
query = str(self.group_concat_md.compile(dialect=dialect)) # query = str(self.group_concat_md.compile(dialect=dialect))
expected = ( # expected = (
'''SELECT metric_dimension.dimension_set_id, LIST(metric_dimension.name || '=' ''' # '''SELECT metric_dimension.dimension_set_id, LIST(metric_dimension.name || '=' '''
'''|| metric_dimension.value, ',') AS dimensions ''' # '''|| metric_dimension.value, ',') AS dimensions '''
''' # '''
FROM metric_dimension GROUP BY metric_dimension.dimension_set_id''') # FROM metric_dimension GROUP BY metric_dimension.dimension_set_id''')
self.assertEqual(expected, query) # 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 = ( # expected = (
'''SELECT metric_dimension.dimension_set_id, LIST(metric_dimension.name || '=' ''' # '''SELECT metric_dimension.dimension_set_id, LIST(metric_dimension.name || '=' '''
'''|| metric_dimension.value, ',') AS dimensions ''' # '''|| metric_dimension.value, ',') AS dimensions '''
''' # '''
FROM metric_dimension GROUP BY metric_dimension.dimension_set_id''') # FROM metric_dimension GROUP BY metric_dimension.dimension_set_id''')
self.assertEqual(expected, query) # self.assertEqual(expected, query)
expected = ( # expected = (
"""SELECT metric_dimension.dimension_set_id \n""" # """SELECT metric_dimension.dimension_set_id \n"""
"""FROM metric_dimension ORDER BY CASE WHEN metric_dimension.dimension_set_id='A'""" # """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""" # """ THEN 0 WHEN metric_dimension.dimension_set_id='B' THEN 1 WHEN"""
""" metric_dimension.dimension_set_id='C' THEN 2 ELSE 3 END ASC""") # """ metric_dimension.dimension_set_id='C' THEN 2 ELSE 3 END ASC""")
query = str(self.order_by_field.compile(dialect=dialect)) # query = str(self.order_by_field.compile(dialect=dialect))
self.assertEqual(expected, query) # self.assertEqual(expected, query)
def test_mysql(self): def test_mysql(self):
from sqlalchemy.dialects import mysql as diale_ from sqlalchemy.dialects import mysql as diale_
@@ -138,8 +138,8 @@ FROM metric_dimension GROUP BY metric_dimension.dimension_set_id''')
expected = ( expected = (
'''SELECT metric_dimension.dimension_set_id, ''' '''SELECT metric_dimension.dimension_set_id, '''
'''GROUP_CONCAT(concat(concat(metric_dimension.name, ''' '''GROUP_CONCAT(concat(metric_dimension.name, '''
''''='), metric_dimension.value) SEPARATOR ',') AS dimensions ''' ''''=', metric_dimension.value) SEPARATOR ',') AS dimensions '''
''' '''
FROM metric_dimension GROUP BY metric_dimension.dimension_set_id''') FROM metric_dimension GROUP BY metric_dimension.dimension_set_id''')
self.assertEqual(expected, query) self.assertEqual(expected, query)
@@ -148,8 +148,8 @@ FROM metric_dimension GROUP BY metric_dimension.dimension_set_id''')
expected = ( expected = (
'''SELECT metric_dimension.dimension_set_id, ''' '''SELECT metric_dimension.dimension_set_id, '''
'''GROUP_CONCAT(concat(concat(metric_dimension.name, ''' '''GROUP_CONCAT(concat(metric_dimension.name, '''
''''='), metric_dimension.value) ORDER BY metric_dimension.name ASC ''' ''''=', metric_dimension.value) ORDER BY metric_dimension.name ASC '''
'''SEPARATOR ',') AS dimensions ''' '''SEPARATOR ',') AS dimensions '''
''' '''
FROM metric_dimension GROUP BY metric_dimension.dimension_set_id''') 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 cfg
from oslo_config import fixture as fixture_config from oslo_config import fixture as fixture_config
from oslo_db.sqlalchemy.engines import create_engine 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.common.repositories.sqla import models
from monasca_api.tests import base from monasca_api.tests import base
@@ -109,6 +109,8 @@ class TestNotificationMethodRepoDB(base.BaseTestCase):
with self.engine.connect() as conn: with self.engine.connect() as conn:
conn.execute(self._delete_nm_query) conn.execute(self._delete_nm_query)
conn.execute(self._insert_nm_query, self.default_nms) conn.execute(self._insert_nm_query, self.default_nms)
# TODO(thuvh) find better solution
conn.commit()
def test_fixture_and_setup(self): def test_fixture_and_setup(self):
class A(object): class A(object):
@@ -133,7 +135,8 @@ class TestNotificationMethodRepoDB(base.BaseTestCase):
'sub_alarm_definition_dimension'] 'sub_alarm_definition_dimension']
self.assertEqual(self.engine, a.engine) 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): def test_should_create(self):
from monasca_api.common.repositories import exceptions from monasca_api.common.repositories import exceptions
@@ -170,10 +173,17 @@ class TestNotificationMethodRepoDB(base.BaseTestCase):
def test_should_find_by_name(self): def test_should_find_by_name(self):
nms = self.repo.find_notification_by_name('444', 'MyEmail') nms = self.repo.find_notification_by_name('444', 'MyEmail')
expected = ('123', '444', 'MyEmail', 'EMAIL', 'a@b', 0, self.assertEqual(nms['id'], '123')
self.created_at, self.assertEqual(nms['tenant_id'], '444')
self.updated_at) self.assertEqual(nms['type'], 'EMAIL')
self.assertEqual(expected, nms) 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): def test_should_find(self):
nms = self.repo.list_notifications('444', None, None, 2) 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)) raise falcon.HTTPBadRequest('Bad Request', str(ex))
def _validate_name_not_conflicting(self, tenant_id, name, expected_id=None): 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 notification:
if not expected_id: if not expected_id: