Anusha Ramineni 47c68e2377 Change 'Datasources' page layout
This commit changes the datasources page layout, to avoid
loading all the data at once and showing the data in more
relevant page

Change-Id: Iaedc7be9d00060f3701b53c309738e5073450fdf
Partially-Implements: blueprint enhance-congress-dashboard
2017-05-24 03:53:00 +00:00

264 lines
11 KiB
Python

# Copyright 2014 VMware.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import copy
import logging
from django.core.urlresolvers import reverse
from django.template.defaultfilters import slugify
from django.utils.translation import ugettext_lazy as _
from horizon import exceptions
from horizon import messages
from horizon import tables
from congress_dashboard.api import congress
from congress_dashboard.datasources import tables as datasources_tables
logger = logging.getLogger(__name__)
class IndexView(tables.MultiTableView):
"""List service and policy defined data."""
table_classes = (datasources_tables.DataSourcesTable,
datasources_tables.DataSourceStatusesTable, )
template_name = 'admin/datasources/index.html'
def get_datasources_list_data(self):
try:
datasources = congress.datasources_list(self.request)
return datasources
except Exception as e:
msg = _('Unable to get data sources list: %s') % str(e)
messages.error(self.request, msg)
return []
def get_service_status_data(self):
ds = []
try:
ds = congress.datasource_statuses_list(self.request)
logger.debug("ds status : %s " % ds)
except Exception as e:
msg = _('Unable to get data source status list: %s') % str(e)
messages.error(self.request, msg)
return ds
class DatasourceView(tables.DataTableView):
template_name = 'admin/datasources/datasource_detail.html'
table_class = datasources_tables.DataSourcesTablesTable
def get_data(self):
ds_id = self.kwargs['datasource_id']
ds_temp = []
try:
ds_tables = congress.datasource_tables_list(self.request, ds_id)
for table in ds_tables:
table.set_value('datasource_id', ds_id)
table.set_id_as_name_if_empty()
# Object ids within a Horizon table must be unique. Otherwise,
# Horizon will cache the column values for the object by id and
# use the same column values for all rows with the same id.
table.set_value('table_id', table['id'])
table.set_value('id', '%s-%s' % (ds_id, table['table_id']))
ds_temp.append(table)
logger.debug("ds_temp %s" % ds_temp)
return ds_temp
except Exception as e:
msg_args = {'ds_id': ds_id, 'error': str(e)}
msg = _('Unable to get tables list for service "%(ds_id)s": '
'%(error)s') % msg_args
messages.error(self.request, msg)
return []
def get_context_data(self, **kwargs):
context = super(DatasourceView, self).get_context_data(**kwargs)
datasource_id = self.kwargs['datasource_id']
try:
datasource = congress.datasource_get(self.request, datasource_id)
status = congress.datasource_status_list(self.request,
datasource['name'])
context['last_updated'] = status['last_updated']
context['subscribers'] = status['subscribers']
context['subscriptions'] = status['subscriptions']
context['last_error'] = status['last_error']
context['number_of_updates'] = status['number_of_updates']
context['datasource_name'] = datasource['name']
context['status'] = ('Active' if status['initialized']
else 'Not Active')
return context
except Exception as e:
msg_args = {'ds_id': datasource_id, 'error': str(e)}
msg = _('Unable to get status for data source "%(ds_id)s": '
'%(error)s') % msg_args
messages.error(self.request, msg)
return []
class DetailView(tables.DataTableView):
"""List details about and rows from a data source (service or policy)."""
table_class = datasources_tables.DataSourceRowsTable
template_name = 'admin/datasources/detail.html'
def get_data(self):
datasource_id = self.kwargs['datasource_id']
table_name = self.kwargs.get('policy_table_name')
is_service = False
try:
if table_name:
# Policy data table.
rows = congress.policy_rows_list(self.request, datasource_id,
table_name)
if congress.TABLE_SEPARATOR in table_name:
table_name_parts = table_name.split(
congress.TABLE_SEPARATOR)
maybe_datasource_name = table_name_parts[0]
datasources = congress.datasources_list(self.request)
for datasource in datasources:
if datasource['name'] == maybe_datasource_name:
# Serivce-derived policy data table.
is_service = True
datasource_id = datasource['id']
table_name = table_name_parts[1]
break
else:
# Service data table.
is_service = True
datasource = congress.datasource_get_by_name(
self.request, datasource_id)
table_name = self.kwargs['service_table_name']
rows = congress.datasource_rows_list(
self.request, datasource_id, table_name)
except Exception as e:
msg_args = {
'table_name': table_name,
'ds_id': datasource_id,
'error': str(e)
}
msg = _('Unable to get rows in table "%(table_name)s", data '
'source "%(ds_id)s": %(error)s') % msg_args
messages.error(self.request, msg)
redirect = reverse('horizon:admin:datasources:index')
raise exceptions.Http302(redirect)
# Normally, in Horizon, the columns for a table are defined as
# attributes of the Table class. When the class is instantiated,
# the columns are processed during the metaclass initialization. To
# add columns dynamically, re-create the class from the metaclass
# with the added columns, re-create the Table from the new class,
# then reassign the Table stored in this View.
column_names = []
table_class_attrs = copy.deepcopy(dict(self.table_class.__dict__))
# Get schema from the server.
try:
if is_service:
schema = congress.datasource_table_schema_get(
self.request, datasource_id, table_name)
else:
schema = congress.policy_table_schema_get(
self.request, datasource_id, table_name)
except Exception as e:
msg_args = {
'table_name': table_name,
'ds_id': datasource_id,
'error': str(e)
}
msg = _('Unable to get schema for table "%(table_name)s", '
'data source "%(ds_id)s": %(error)s') % msg_args
messages.error(self.request, msg)
redirect = reverse('horizon:admin:datasources:index')
raise exceptions.Http302(redirect)
columns = schema['columns']
row_len = 0
if len(rows):
row_len = len(rows[0].get('data', []))
if not row_len or row_len == len(columns):
for col in columns:
col_name = col['name']
# Attribute name for column in the class must be a valid
# identifier. Slugify it.
col_slug = slugify(col_name)
column_names.append(col_slug)
table_class_attrs[col_slug] = tables.Column(
col_slug, verbose_name=col_name)
else:
# There could be another table with the same name and different
# arity. Divide the rows into unnamed columns. Number them for
# internal reference.
for i in xrange(0, row_len):
col_name = str(i)
column_names.append(col_name)
table_class_attrs[col_name] = tables.Column(
col_name, verbose_name='')
# Class and object re-creation, using a new class name, the same base
# classes, and the new class attributes, which now includes columns.
columnized_table_class_name = '%s%sRows' % (
slugify(datasource_id).title(), slugify(table_name).title())
columnized_table_class = tables.base.DataTableMetaclass(
str(columnized_table_class_name), self.table_class.__bases__,
table_class_attrs)
self.table_class = columnized_table_class
columnized_table = columnized_table_class(self.request, **self.kwargs)
self._tables[columnized_table_class._meta.name] = columnized_table
# Map columns names to row values.
num_cols = len(column_names)
for row in rows:
try:
row_data = row['data']
row.delete_by_key('data')
for i in xrange(0, num_cols):
row.set_value(column_names[i], row_data[i])
except Exception as e:
msg_args = {
'table_name': table_name,
'ds_id': datasource_id,
'error': str(e)
}
msg = _('Unable to get data for table "%(table_name)s", data '
'source "%(ds_id)s": %(error)s') % msg_args
messages.error(self.request, msg)
redirect = reverse('horizon:admin:datasources:index')
raise exceptions.Http302(redirect)
return rows
def get_context_data(self, **kwargs):
context = super(DetailView, self).get_context_data(**kwargs)
if 'policy_table_name' in kwargs:
table_name = kwargs.get('policy_table_name')
context['datasource_type'] = _('Policy')
datasource_name = kwargs['datasource_id']
else:
table_name = kwargs['service_table_name']
context['datasource_type'] = _('Service')
try:
datasource_id = kwargs['datasource_id']
datasource = congress.datasource_get(self.request,
datasource_id)
datasource_name = datasource['name']
except Exception as e:
datasource_name = datasource_id
logger.info('Failed to get data source "%s": %s' %
(datasource_id, str(e)))
context['datasource_name'] = datasource_name
context['table_name'] = table_name
return context