1 from django.template import RequestContext
2 from django.shortcuts import render_to_response
4 from unfold.loginrequired import LoginRequiredAutoLogoutView
6 from unfold.page import Page
7 from manifold.core.query import Query, AnalyzedQuery
9 from ui.topmenu import topmenu_items, the_user
11 from plugins.raw import Raw
12 from plugins.stack import Stack
13 from plugins.tabs import Tabs
14 from plugins.querytable import QueryTable
15 from plugins.queryupdater import QueryUpdater
16 from plugins.googlemap import GoogleMap
17 from plugins.senslabmap import SensLabMap
18 from plugins.querycode import QueryCode
19 from plugins.query_editor import QueryEditor
20 from plugins.active_filters import ActiveFilters
21 from plugins.quickfilter import QuickFilter
22 from plugins.messages import Messages
23 from plugins.slicestat import SliceStat
25 from myslice.config import Config
27 tmp_default_slice='ple.upmc.myslicedemo'
29 # temporary : turn off the users part to speed things up
33 class SliceView (LoginRequiredAutoLogoutView):
35 def get (self,request, slicename=tmp_default_slice):
38 page.add_css_files ('css/slice-view.css')
39 page.add_js_files ( [ "js/common.functions.js" ] )
40 page.add_js_chunks ('$(function() { messages.debug("sliceview: jQuery version " + $.fn.jquery); });')
41 page.add_js_chunks ('$(function() { messages.debug("sliceview: users turned %s"); });'%("on" if do_query_users else "off"))
43 page.add_js_chunks ('$(function() { messages.debug("manifold URL %s"); });'%(config.manifold_url()))
44 page.expose_js_metadata()
46 metadata = page.get_metadata()
47 resource_md = metadata.details_by_object('resource')
48 resource_fields = [column['name'] for column in resource_md['column']]
50 user_md = metadata.details_by_object('user')
51 user_fields = ['user_hrn'] # [column['name'] for column in user_md['column']]
53 # TODO The query to run is embedded in the URL
54 main_query = Query.get('slice').filter_by('slice_hrn', '=', slicename)
57 'resource.hrn', 'resource.hostname', 'resource.type',
58 'resource.network_hrn',
61 #'application.measurement_point.counter'
64 query_resource_all = Query.get('resource').select(resource_fields)
66 query_user_all = Query.get('user').select(user_fields)
68 aq = AnalyzedQuery(main_query, metadata=metadata)
69 page.enqueue_query(main_query, analyzed_query=aq)
70 page.enqueue_query(query_resource_all)
72 page.enqueue_query(query_user_all)
74 # ... and for the relations
75 # XXX Let's hardcode resources for now
76 sq_resource = aq.subquery('resource')
77 sq_user = aq.subquery('user')
78 sq_lease = aq.subquery('lease')
79 sq_measurement = aq.subquery('measurement')
82 # Prepare the display according to all metadata
83 # (some parts will be pending, others can be triggered by users).
85 # For example slice measurements will not be requested by default...
87 # Create the base layout (Stack)...
90 title="Slice %s"%slicename,
94 # ... responsible for the slice properties...
101 html="<h2 class='well well-lg'> Slice %s</h2>"%slicename)
104 # --------------------------------------------------------------------------
105 # QueryUpdater (Pending Operations)
107 main_stack.insert(QueryUpdater(
109 title = 'Pending operations',
112 # start turned off, it will open up itself when stuff comes in
115 outline_complete = True,
118 # --------------------------------------------------------------------------
121 filter_query_editor = QueryEditor(
124 query_all = query_resource_all,
125 title = "Select Columns",
126 domid = 'select-columns',
128 filter_active_filters = ActiveFilters(
131 title = "Active Filters",
133 filters_area = Stack(
135 title = 'Filter Resources',
137 sons = [filter_query_editor, filter_active_filters],
139 toggled = 'persistent',
140 outline_complete = True,
142 main_stack.insert (filters_area)
144 # --------------------------------------------------------------------------
146 # the resources part is made of a Tabs (Geographic, List),
148 resources_as_gmap = GoogleMap(
150 title = 'Geographic view',
151 domid = 'resources-map',
152 # tab's sons preferably turn this off
155 query_all = query_resource_all,
163 resources_as_3dmap = SensLabMap(
166 domid = 'senslabmap',
168 query_all = query_resource_all,
171 resources_as_list = QueryTable(
173 domid = 'resources-list',
175 # this is the query at the core of the slice list
177 query_all = query_resource_all,
179 datatables_options = {
180 'iDisplayLength': 25,
181 'bLengthChange' : True,
186 # with the new 'Filter' stuff on top, no need for anything but the querytable
187 resources_as_list_area = resources_as_list
189 resources_area = Tabs ( page=page,
193 outline_complete=True,
194 sons=[ resources_as_gmap,
196 resources_as_list_area, ],
197 active_domid = 'resources-map',
199 main_stack.insert (resources_area)
201 # --------------------------------------------------------------------------
208 outline_complete = True,
211 active_domid = 'users-list',
213 main_stack.insert(tab_users)
215 tab_users.insert(QueryTable(
217 title = 'Users List',
218 domid = 'users-list',
219 # tab's sons preferably turn this off
221 # this is the query at the core of the slice list
223 query_all = query_user_all,
225 datatables_options = {
226 'iDisplayLength' : 25,
227 'bLengthChange' : True,
233 # --------------------------------------------------------------------------
235 measurements_stats_cpu = SliceStat(
237 domid = 'resources-stats-cpu',
242 slicename = slicename,
246 measurements_stats_mem = SliceStat(
247 title = "Memory Usage",
248 domid = 'resources-stats-mem',
253 slicename = slicename,
257 measurements_stats_asb = SliceStat(
258 title = "Traffic Sent",
259 domid = 'resources-stats-asb',
264 slicename = slicename,
268 measurements_stats_arb = SliceStat(
269 title = "Traffic Received",
270 domid = 'resources-stats-arb',
275 slicename = slicename,
279 tab_measurements = Tabs ( page=page,
280 domid="measurements",
283 title="Measurements",
284 outline_complete=True,
285 sons=[ measurements_stats_cpu, measurements_stats_mem, measurements_stats_asb, measurements_stats_arb ],
286 active_domid = 'measurements_stats_cpu',
288 main_stack.insert (tab_measurements)
290 # tab_measurements = Tabs (
292 # active_domid = 'measurements-list',
293 # outline_complete = True,
295 # title = 'Measurements',
296 # domid = 'measurements',
298 # main_stack.insert(tab_measurements)
300 # tab_measurements.insert(QueryTable(
302 # title = 'Measurements',
303 # domid = 'measurements-list',
304 # # tab's sons preferably turn this off
306 # # this is the query at the core of the slice list
307 # query = sq_measurement,
308 # # do NOT set checkboxes to False
309 # # this table being otherwise empty, it just does not fly with dataTables
311 # datatables_options = {
312 # 'iDisplayLength' : 25,
313 # 'bLengthChange' : True,
314 # 'bAutoWidth' : True,
318 # # --------------------------------------------------------------------------
319 # # MESSAGES (we use transient=False for now)
320 # main_stack.insert(Messages(
322 # title = "Runtime messages for slice %s"%slicename,
323 # domid = "msgs-pre",
325 # # plain messages are probably less nice for production but more reliable for development for now
327 # # these make sense only in non-transient mode..
329 # toggled = 'persistent',
330 # outline_complete = True,
334 # variables that will get passed to the view-unfold1.html template
337 # define 'unfold_main' to the template engine - the main contents
338 template_env [ 'unfold_main' ] = main_stack.render(request)
340 # more general variables expected in the template
341 template_env [ 'title' ] = '%(slicename)s'%locals()
342 # the menu items on the top
343 template_env [ 'topmenu_items' ] = topmenu_items('Slice', request)
344 # so we can sho who is logged
345 template_env [ 'username' ] = the_user (request)
347 # don't forget to run the requests
348 page.expose_queries ()
350 # xxx create another plugin with the same query and a different layout (with_datatables)
351 # show that it worls as expected, one single api call to backend and 2 refreshed views
353 # the prelude object in page contains a summary of the requirements() for all plugins
354 # define {js,css}_{files,chunks}
355 prelude_env = page.prelude_env()
356 template_env.update(prelude_env)
357 result=render_to_response ('view-unfold1.html',template_env,
358 context_instance=RequestContext(request))