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.scheduler import Scheduler
19 from plugins.querycode import QueryCode
20 from plugins.query_editor import QueryEditor
21 from plugins.active_filters import ActiveFilters
22 from plugins.quickfilter import QuickFilter
23 from plugins.messages import Messages
24 from plugins.slicestat import SliceStat
26 from myslice.config import Config
28 tmp_default_slice='ple.upmc.myslicedemo'
30 # temporary : turn off the users part to speed things up
40 class SliceView (LoginRequiredAutoLogoutView):
42 def get (self,request, slicename=tmp_default_slice):
45 page.add_css_files ('css/slice-view.css')
46 page.add_js_files ( [ "js/common.functions.js" ] )
47 page.add_js_chunks ('$(function() { messages.debug("sliceview: jQuery version " + $.fn.jquery); });')
48 page.add_js_chunks ('$(function() { messages.debug("sliceview: users turned %s"); });'%("on" if do_query_users else "off"))
49 page.add_js_chunks ('$(function() { messages.debug("sliceview: leases turned %s"); });'%("on" if do_query_leases else "off"))
51 page.add_js_chunks ('$(function() { messages.debug("manifold URL %s"); });'%(config.manifold_url()))
52 page.expose_js_metadata()
54 metadata = page.get_metadata()
55 resource_md = metadata.details_by_object('resource')
56 resource_fields = [column['name'] for column in resource_md['column']]
58 user_md = metadata.details_by_object('user')
59 user_fields = ['user_hrn'] # [column['name'] for column in user_md['column']]
61 # TODO The query to run is embedded in the URL
62 main_query = Query.get('slice').filter_by('slice_hrn', '=', slicename)
65 'resource.hrn', 'resource.hostname', 'resource.type',
66 'resource.network_hrn',
69 #'application.measurement_point.counter'
71 # for internal use in the querytable plugin;
72 # needs to be a unique column present for each returned record
73 main_query_key = 'hrn'
75 query_resource_all = Query.get('resource').select(resource_fields)
77 query_user_all = Query.get('user').select(user_fields)
79 aq = AnalyzedQuery(main_query, metadata=metadata)
80 page.enqueue_query(main_query, analyzed_query=aq)
81 page.enqueue_query(query_resource_all)
83 page.enqueue_query(query_user_all)
85 # ... and for the relations
86 # XXX Let's hardcode resources for now
87 sq_resource = aq.subquery('resource')
88 sq_user = aq.subquery('user')
89 sq_lease = aq.subquery('lease')
90 sq_measurement = aq.subquery('measurement')
93 # Prepare the display according to all metadata
94 # (some parts will be pending, others can be triggered by users).
96 # For example slice measurements will not be requested by default...
98 # Create the base layout (Stack)...
101 title="Slice %s"%slicename,
105 # ... responsible for the slice properties...
112 html="<h2 class='well well-lg'> Slice %s</h2>"%slicename)
115 # --------------------------------------------------------------------------
116 # QueryUpdater (Pending Operations)
118 main_stack.insert(QueryUpdater(
120 title = 'Pending operations',
123 # start turned off, it will open up itself when stuff comes in
126 outline_complete = True,
129 # --------------------------------------------------------------------------
132 filter_query_editor = QueryEditor(
135 query_all = query_resource_all,
136 title = "Select Columns",
137 domid = 'select-columns',
139 filter_active_filters = ActiveFilters(
142 title = "Active Filters",
144 filters_area = Stack(
146 title = 'Filter Resources',
148 sons = [filter_query_editor, filter_active_filters],
150 toggled = 'persistent',
151 outline_complete = True,
153 main_stack.insert (filters_area)
155 # --------------------------------------------------------------------------
157 # the resources part is made of a Tabs (Geographic, List),
159 resources_as_gmap = GoogleMap(
161 title = 'Geographic view',
162 domid = 'resources-map',
163 # tab's sons preferably turn this off
166 query_all = query_resource_all,
167 googlemap_api_key = Config().googlemap_api_key(),
175 resources_as_3dmap = SensLabMap(
178 domid = 'senslabmap',
180 query_all = query_resource_all,
183 resources_as_list = QueryTable(
185 domid = 'resources-list',
187 # this is the query at the core of the slice list
189 query_all = query_resource_all,
190 # safer to use 'hrn' as the internal unique key for this plugin
191 id_key = main_query_key,
193 datatables_options = {
194 'iDisplayLength': 25,
195 'bLengthChange' : True,
201 resources_as_scheduler = Scheduler(
206 query_all_resources = query_resource_all,
207 query_lease = sq_lease,
210 # with the new 'Filter' stuff on top, no need for anything but the querytable
211 resources_as_list_area = resources_as_list
216 resources_as_scheduler,
217 resources_as_list_area,
218 ] if do_query_leases else [
221 resources_as_list_area,
224 resources_area = Tabs ( page=page,
228 outline_complete=True,
229 sons= resources_sons,
230 active_domid = 'resources-map',
231 persistent_active=True,
233 main_stack.insert (resources_area)
235 # --------------------------------------------------------------------------
242 outline_complete = True,
245 active_domid = 'users-list',
247 main_stack.insert(tab_users)
249 tab_users.insert(QueryTable(
251 title = 'Users List',
252 domid = 'users-list',
253 # tab's sons preferably turn this off
255 # this is the query at the core of the slice list
257 query_all = query_user_all,
259 datatables_options = {
260 'iDisplayLength' : 25,
261 'bLengthChange' : True,
267 # --------------------------------------------------------------------------
269 measurements_stats_cpu = SliceStat(
271 domid = 'resources-stats-cpu',
276 slicename = slicename,
280 measurements_stats_mem = SliceStat(
281 title = "Memory Usage",
282 domid = 'resources-stats-mem',
287 slicename = slicename,
291 measurements_stats_asb = SliceStat(
292 title = "Traffic Sent",
293 domid = 'resources-stats-asb',
298 slicename = slicename,
302 measurements_stats_arb = SliceStat(
303 title = "Traffic Received",
304 domid = 'resources-stats-arb',
309 slicename = slicename,
313 tab_measurements = Tabs ( page=page,
314 domid="measurements",
317 title="Measurements",
318 outline_complete=True,
319 sons=[ measurements_stats_cpu, measurements_stats_mem, measurements_stats_asb, measurements_stats_arb ],
320 active_domid = 'measurements_stats_cpu',
322 main_stack.insert (tab_measurements)
324 # tab_measurements = Tabs (
326 # active_domid = 'measurements-list',
327 # outline_complete = True,
329 # title = 'Measurements',
330 # domid = 'measurements',
332 # main_stack.insert(tab_measurements)
334 # tab_measurements.insert(QueryTable(
336 # title = 'Measurements',
337 # domid = 'measurements-list',
338 # # tab's sons preferably turn this off
340 # # this is the query at the core of the slice list
341 # query = sq_measurement,
342 # # do NOT set checkboxes to False
343 # # this table being otherwise empty, it just does not fly with dataTables
345 # datatables_options = {
346 # 'iDisplayLength' : 25,
347 # 'bLengthChange' : True,
348 # 'bAutoWidth' : True,
352 # # --------------------------------------------------------------------------
353 # # MESSAGES (we use transient=False for now)
355 main_stack.insert(Messages(
357 title = "Runtime messages for slice %s"%slicename,
360 # plain messages are probably less nice for production but more reliable for development for now
362 # these make sense only in non-transient mode..
364 toggled = 'persistent',
365 outline_complete = True,
369 # variables that will get passed to the view-unfold1.html template
372 # define 'unfold_main' to the template engine - the main contents
373 template_env [ 'unfold_main' ] = main_stack.render(request)
375 # more general variables expected in the template
376 template_env [ 'title' ] = '%(slicename)s'%locals()
377 # the menu items on the top
378 template_env [ 'topmenu_items' ] = topmenu_items('Slice', request)
379 # so we can sho who is logged
380 template_env [ 'username' ] = the_user (request)
382 # don't forget to run the requests
383 page.expose_queries ()
385 # xxx create another plugin with the same query and a different layout (with_datatables)
386 # show that it worls as expected, one single api call to backend and 2 refreshed views
388 # the prelude object in page contains a summary of the requirements() for all plugins
389 # define {js,css}_{files,chunks}
390 prelude_env = page.prelude_env()
391 template_env.update(prelude_env)
392 result=render_to_response ('view-unfold1.html',template_env,
393 context_instance=RequestContext(request))