Package Products :: Package ZenHub :: Package services :: Module RenderConfig
[hide private]
[frames] | no frames]

Source Code for Module Products.ZenHub.services.RenderConfig

  1  ########################################################################### 
  2  # 
  3  # This program is part of Zenoss Core, an open source monitoring platform. 
  4  # Copyright (C) 2009, 2011 Zenoss Inc. 
  5  # 
  6  # This program is free software; you can redistribute it and/or modify it 
  7  # under the terms of the GNU General Public License version 2 or (at your 
  8  # option) any later version as published by the Free Software Foundation. 
  9  # 
 10  # For complete information please visit: http://www.zenoss.com/oss/ 
 11  # 
 12  ########################################################################### 
 13   
 14  __doc__ = """RenderConfig 
 15  zenhub service to start looking for requests to render performance graphs 
 16  """ 
 17   
 18  import logging 
 19  log = logging.getLogger('zen.HubService.RenderConfig') 
 20   
 21  import Globals 
 22  from Products.ZenCollector.services.config import NullConfigService 
 23  from Products.ZenRRD.zenrender import RenderServer 
 24   
 25  from twisted.web import resource, server 
 26  from twisted.internet import reactor 
 27  from twisted.internet.error import CannotListenError 
 28  import xmlrpclib, mimetypes 
 29   
 30  # Global variable 
 31  htmlResource = None 
 32   
 33   
34 -class Render(resource.Resource):
35 36 isLeaf = True 37
38 - def __init__(self):
39 resource.Resource.__init__(self) 40 self.renderers = {}
41
42 - def render_GET(self, request):
43 "Deal with http requests" 44 args = request.args.copy() 45 for k, v in args.items(): 46 if len(v) == 1: 47 args[k] = v[0] 48 49 command = request.postpath[-1] 50 if command in ('favicon.ico',): 51 log.debug("Received a bad request: %s", command) 52 return '' 53 listener = request.postpath[-2] 54 args.setdefault('ftype', 'PNG') 55 ftype = args['ftype'] 56 del args['ftype'] 57 mimetype = mimetypes.guess_type('x.%s' % ftype)[0] 58 if mimetype is None: 59 mimetype = 'image/%s' % ftype.lower() 60 request.setHeader('Content-type', mimetype) 61 def write(result): 62 if result: 63 request.write(result) 64 request.finish()
65 def error(reason): 66 log.error("Unable to fetch graph: %s", reason) 67 request.finish()
68 from Products.ZenHub.zenhub import ZENHUB_ZENRENDER 69 renderer = self.renderers.get(listener, False) 70 if renderer and listener == ZENHUB_ZENRENDER: 71 try: 72 rs = RenderServer(listener) 73 renderFn = getattr(rs,command) 74 result = renderFn(**args) 75 reactor.callLater(0,write, result) 76 except Exception as e: 77 log.exception("Exception getting graph") 78 reactor.callLater(0,error, e.msg) 79 else: 80 if not renderer or not renderer.listeners: 81 raise Exception("Renderer %s unavailable" % listener) 82 d = renderer.listeners[0].callRemote(command, **args) 83 d.addCallbacks(write, error) 84 return server.NOT_DONE_YET 85
86 - def render_POST(self, request):
87 "Deal with XML-RPC requests" 88 content = request.content.read() 89 for instance, renderer in self.renderers.items(): 90 if instance != request.postpath[-1]: continue 91 for listener in renderer.listeners: 92 try: 93 args, command = xmlrpclib.loads(content) 94 request.setHeader('Content-type', 'text/xml') 95 d = listener.callRemote(str(command), *args) 96 def write(result): 97 try: 98 response = xmlrpclib.dumps((result,), 99 methodresponse=True, 100 allow_none=True) 101 request.write(response) 102 except Exception, ex: 103 log.error("Unable to %s: %s", command, ex) 104 request.finish()
105 def error(reason): 106 log.error("Unable to %s: %s", command, reason) 107 request.finish() 108 d.addCallbacks(write, error) 109 return server.NOT_DONE_YET 110 except Exception, ex: 111 log.exception(ex) 112 log.warning("Skipping renderer %s" % instance) 113 raise Exception("No renderer registered") 114
115 - def getChild(self, unused, ignored):
116 "Handle all paths" 117 return self, ()
118
119 - def addRenderer(self, renderer):
120 self.renderers[renderer.instance] = renderer
121 122
123 -class RenderConfig(NullConfigService):
124 - def __init__(self, dmd, instance):
125 from Products.ZenHub.zenhub import ZENHUB_ZENRENDER 126 if instance == ZENHUB_ZENRENDER: 127 self.dmd = dmd 128 self.instance = instance 129 else: 130 NullConfigService.__init__(self, dmd, instance) 131 132 global htmlResource 133 try: 134 if not htmlResource: 135 htmlResource = Render() 136 log.info("Starting graph retrieval listener on port 8090") 137 reactor.listenTCP(8090, server.Site(htmlResource)) 138 htmlResource.addRenderer(self) 139 except CannotListenError, e: 140 # Probably in a hub worker; no big deal 141 log.debug("Not starting render listener because the port is " 142 "already in use.")
143