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
36 class SliceView (LoginRequiredAutoLogoutView):
38 def get (self,request, slicename=tmp_default_slice):
41 page.add_css_files ('css/slice-view.css')
42 page.add_js_files ( [ "js/common.functions.js" ] )
43 page.add_js_chunks ('$(function() { messages.debug("sliceview: jQuery version " + $.fn.jquery); });')
44 page.add_js_chunks ('$(function() { messages.debug("sliceview: users turned %s"); });'%("on" if do_query_users else "off"))
46 page.add_js_chunks ('$(function() { messages.debug("manifold URL %s"); });'%(config.manifold_url()))
47 page.expose_js_metadata()
49 metadata = page.get_metadata()
50 resource_md = metadata.details_by_object('resource')
51 resource_fields = [column['name'] for column in resource_md['column']]
53 user_md = metadata.details_by_object('user')
54 user_fields = ['user_hrn'] # [column['name'] for column in user_md['column']]
56 # TODO The query to run is embedded in the URL
57 main_query = Query.get('slice').filter_by('slice_hrn', '=', slicename)
60 'resource.hrn', 'resource.hostname', 'resource.type',
61 'resource.network_hrn',
64 #'application.measurement_point.counter'
67 query_resource_all = Query.get('resource').select(resource_fields)
69 query_user_all = Query.get('user').select(user_fields)
71 aq = AnalyzedQuery(main_query, metadata=metadata)
72 page.enqueue_query(main_query, analyzed_query=aq)
73 page.enqueue_query(query_resource_all)
75 page.enqueue_query(query_user_all)
77 # ... and for the relations
78 # XXX Let's hardcode resources for now
79 sq_resource = aq.subquery('resource')
80 sq_user = aq.subquery('user')
81 sq_lease = aq.subquery('lease')
82 sq_measurement = aq.subquery('measurement')
85 # Prepare the display according to all metadata
86 # (some parts will be pending, others can be triggered by users).
88 # For example slice measurements will not be requested by default...
90 # Create the base layout (Stack)...
93 title="Slice %s"%slicename,
97 # ... responsible for the slice properties...
104 html="<h2 class='well well-lg'> Slice %s</h2>"%slicename)
107 # --------------------------------------------------------------------------
108 # QueryUpdater (Pending Operations)
110 main_stack.insert(QueryUpdater(
112 title = 'Pending operations',
115 # start turned off, it will open up itself when stuff comes in
118 outline_complete = True,
121 # --------------------------------------------------------------------------
124 filter_query_editor = QueryEditor(
127 query_all = query_resource_all,
128 title = "Select Columns",
129 domid = 'select-columns',
131 filter_active_filters = ActiveFilters(
134 title = "Active Filters",
136 filters_area = Stack(
138 title = 'Filter Resources',
140 sons = [filter_query_editor, filter_active_filters],
142 toggled = 'persistent',
143 outline_complete = True,
145 main_stack.insert (filters_area)
147 # --------------------------------------------------------------------------
149 # the resources part is made of a Tabs (Geographic, List),
151 resources_as_gmap = GoogleMap(
153 title = 'Geographic view',
154 domid = 'resources-map',
155 # tab's sons preferably turn this off
158 query_all = query_resource_all,
159 googlemap_api_key = Config().googlemap_api_key(),
167 # because (senslab)map.css changes stuff for *all* canvas elements
168 # it destroys the googlemap behaviour
169 # turning this off for now until Anthony can fix that
170 # resources_as_3dmap = SensLabMap(
173 # domid = 'senslabmap',
174 # query = sq_resource,
175 # query_all = query_resource_all,
178 resources_as_list = QueryTable(
180 domid = 'resources-list',
182 # this is the query at the core of the slice list
184 query_all = query_resource_all,
186 datatables_options = {
187 'iDisplayLength': 25,
188 'bLengthChange' : True,
193 # with the new 'Filter' stuff on top, no need for anything but the querytable
194 resources_as_list_area = resources_as_list
196 resources_area = Tabs ( page=page,
200 outline_complete=True,
201 sons=[ resources_as_gmap,
203 # resources_as_3dmap,
204 resources_as_list_area, ],
205 active_domid = 'resources-map',
207 main_stack.insert (resources_area)
209 # --------------------------------------------------------------------------
216 outline_complete = True,
219 active_domid = 'users-list',
221 main_stack.insert(tab_users)
223 tab_users.insert(QueryTable(
225 title = 'Users List',
226 domid = 'users-list',
227 # tab's sons preferably turn this off
229 # this is the query at the core of the slice list
231 query_all = query_user_all,
233 datatables_options = {
234 'iDisplayLength' : 25,
235 'bLengthChange' : True,
241 # --------------------------------------------------------------------------
243 measurements_stats_cpu = SliceStat(
245 domid = 'resources-stats-cpu',
250 slicename = slicename,
254 measurements_stats_mem = SliceStat(
255 title = "Memory Usage",
256 domid = 'resources-stats-mem',
261 slicename = slicename,
265 measurements_stats_asb = SliceStat(
266 title = "Traffic Sent",
267 domid = 'resources-stats-asb',
272 slicename = slicename,
276 measurements_stats_arb = SliceStat(
277 title = "Traffic Received",
278 domid = 'resources-stats-arb',
283 slicename = slicename,
287 tab_measurements = Tabs ( page=page,
288 domid="measurements",
291 title="Measurements",
292 outline_complete=True,
293 sons=[ measurements_stats_cpu, measurements_stats_mem, measurements_stats_asb, measurements_stats_arb ],
294 active_domid = 'measurements_stats_cpu',
296 main_stack.insert (tab_measurements)
298 # tab_measurements = Tabs (
300 # active_domid = 'measurements-list',
301 # outline_complete = True,
303 # title = 'Measurements',
304 # domid = 'measurements',
306 # main_stack.insert(tab_measurements)
308 # tab_measurements.insert(QueryTable(
310 # title = 'Measurements',
311 # domid = 'measurements-list',
312 # # tab's sons preferably turn this off
314 # # this is the query at the core of the slice list
315 # query = sq_measurement,
316 # # do NOT set checkboxes to False
317 # # this table being otherwise empty, it just does not fly with dataTables
319 # datatables_options = {
320 # 'iDisplayLength' : 25,
321 # 'bLengthChange' : True,
322 # 'bAutoWidth' : True,
326 # # --------------------------------------------------------------------------
327 # # MESSAGES (we use transient=False for now)
329 main_stack.insert(Messages(
331 title = "Runtime messages for slice %s"%slicename,
334 # plain messages are probably less nice for production but more reliable for development for now
336 # these make sense only in non-transient mode..
338 toggled = 'persistent',
339 outline_complete = True,
343 # variables that will get passed to the view-unfold1.html template
346 # define 'unfold_main' to the template engine - the main contents
347 template_env [ 'unfold_main' ] = main_stack.render(request)
349 # more general variables expected in the template
350 template_env [ 'title' ] = '%(slicename)s'%locals()
351 # the menu items on the top
352 template_env [ 'topmenu_items' ] = topmenu_items('Slice', request)
353 # so we can sho who is logged
354 template_env [ 'username' ] = the_user (request)
356 # don't forget to run the requests
357 page.expose_queries ()
359 # xxx create another plugin with the same query and a different layout (with_datatables)
360 # show that it worls as expected, one single api call to backend and 2 refreshed views
362 # the prelude object in page contains a summary of the requirements() for all plugins
363 # define {js,css}_{files,chunks}
364 prelude_env = page.prelude_env()
365 template_env.update(prelude_env)
366 result=render_to_response ('view-unfold1.html',template_env,
367 context_instance=RequestContext(request))