Detect missing metric_id before passing through bytearray()

It is possible for a row in Cassandra to have a missing metric_id
(shows as 'null' in cqlsh).  This causes an ugly NoneType error
to be passed up to the user on the command line for
'monaca metric-list'.

Fix is to detect the missing value, log an error, and return the
row with None for the metric_id.

Change-Id: Ie617932c6b12a6cfe441510e120bb77a3470b9cf
Story: 2005305
Task: 30194
This commit is contained in:
Joseph Davis 2019-03-26 14:17:18 -07:00
parent a936c123aa
commit d6852ee1b7
2 changed files with 54 additions and 0 deletions

View File

@ -277,6 +277,15 @@ class MetricsRepository(metrics_repository.AbstractMetricsRepository):
pair = d.split('\t')
dim_map[pair[0]] = pair[1]
if row.metric_id is None:
LOG.error(
'Metric is missing metric_id, using metric_id=None'
' name: {}, dimensions: {}'.format(
row.metric_name, row.dimensions))
return {'id': None,
'name': row.metric_name,
'dimensions': dim_map}
metric = {'id': binascii.hexlify(bytearray(row.metric_id)),
'name': row.metric_name,
'dimensions': dim_map}

View File

@ -335,6 +335,51 @@ class TestRepoMetricsCassandra(base.BaseTestCase):
u'hosttype': u'native'
}}], result)
# As Cassandra allows sparse data, it is possible to have a missing metric_id
@patch("monasca_api.common.repositories.cassandra."
"metrics_repository.Cluster.connect")
def test_list_metrics_empty_metric_id(self, cassandra_connect_mock):
cassandra_session_mock = cassandra_connect_mock.return_value
cassandra_future_mock = cassandra_session_mock.execute_async.return_value
Metric = namedtuple('Metric', 'metric_id metric_name dimensions')
cassandra_future_mock.result.return_value = [
Metric(
metric_id=None,
metric_name='disk.space_used_perc',
dimensions=[
'device\trootfs',
'hostname\thost0',
'hosttype\tnative',
'mount_point\t/']
)
]
repo = cassandra_repo.MetricsRepository()
result = repo.list_metrics(
"0b5e7d8c43f74430add94fba09ffd66e",
"region",
name="disk.space_user_perc",
dimensions={
"hostname": "host0",
"hosttype": "native",
"mount_point": "/",
"device": "rootfs"},
offset=None,
limit=1)
self.assertEqual([{
u'id': None,
u'name': u'disk.space_used_perc',
u'dimensions': {
u'device': u'rootfs',
u'hostname': u'host0',
u'mount_point': u'/',
u'hosttype': u'native'
}}], result)
@patch("monasca_api.common.repositories.cassandra."
"metrics_repository.Cluster.connect")
def test_list_metric_names(self, cassandra_connect_mock):