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

Source Code for Module Products.ZenHub.services.RenderConfig

  1  ############################################################################## 
  2  #  
  3  # Copyright (C) Zenoss, Inc. 2009, 2011, all rights reserved. 
  4  #  
  5  # This content is made available according to terms specified in 
  6  # License.zenoss under the directory where your Zenoss product is installed. 
  7  #  
  8  ############################################################################## 
  9   
 10   
 11  """RenderConfig 
 12   
 13  zenhub service to start looking for requests to render performance graphs. 
 14  """ 
 15   
 16  from Products.ZenUtils.Utils import ipv6_available 
 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 socket 
 29  import xmlrpclib, mimetypes 
 30   
 31  # Global variable 
 32  htmlResource = None 
 33   
 34   
35 -class Render(resource.Resource):
36 37 isLeaf = True 38
39 - def __init__(self):
40 resource.Resource.__init__(self) 41 self.renderers = {}
42
43 - def render_GET(self, request):
44 "Deal with http requests" 45 args = request.args.copy() 46 for k, v in args.items(): 47 if len(v) == 1: 48 args[k] = v[0] 49 50 command = request.postpath[-1] 51 if command in ('favicon.ico',): 52 log.debug("Received a bad request: %s", command) 53 return '' 54 from Products.ZenHub import ZENHUB_ZENRENDER 55 if len(request.postpath) > 1: 56 listener = request.postpath[-2] 57 else: 58 listener = ZENHUB_ZENRENDER 59 args.setdefault('ftype', 'PNG') 60 ftype = args['ftype'] 61 del args['ftype'] 62 mimetype = mimetypes.guess_type('x.%s' % ftype)[0] 63 if mimetype is None: 64 mimetype = 'image/%s' % ftype.lower() 65 request.setHeader('Content-type', mimetype) 66 def write(result): 67 if result: 68 request.write(result) 69 request.finish()
70 def error(reason): 71 log.error("Unable to fetch graph: %s", reason) 72 request.finish()
73 renderer = self.renderers.get(listener, False) 74 if renderer and listener == ZENHUB_ZENRENDER: 75 try: 76 rs = RenderServer(listener) 77 renderFn = getattr(rs,command) 78 result = renderFn(**args) 79 reactor.callLater(0,write, result) 80 except Exception as e: 81 log.exception("Exception getting graph") 82 reactor.callLater(0,error, e.msg) 83 else: 84 if not renderer or not renderer.listeners: 85 raise Exception("Renderer %s unavailable" % listener) 86 d = renderer.listeners[0].callRemote(command, **args) 87 d.addCallbacks(write, error) 88 return server.NOT_DONE_YET 89
90 - def render_POST(self, request):
91 "Deal with XML-RPC requests" 92 content = request.content.read() 93 for instance, renderer in self.renderers.items(): 94 if instance != request.postpath[-1]: continue 95 for listener in renderer.listeners: 96 try: 97 args, command = xmlrpclib.loads(content) 98 request.setHeader('Content-type', 'text/xml') 99 d = listener.callRemote(str(command), *args) 100 def write(result): 101 try: 102 response = xmlrpclib.dumps((result,), 103 methodresponse=True, 104 allow_none=True) 105 request.write(response) 106 except Exception, ex: 107 log.error("Unable to %s: %s", command, ex) 108 request.finish()
109 def error(reason): 110 log.error("Unable to %s: %s", command, reason) 111 request.finish() 112 d.addCallbacks(write, error) 113 return server.NOT_DONE_YET 114 except Exception, ex: 115 log.exception(ex) 116 log.warning("Skipping renderer %s" % instance) 117 raise Exception("No renderer registered") 118
119 - def getChild(self, unused, ignored):
120 "Handle all paths" 121 return self, ()
122
123 - def addRenderer(self, renderer):
124 self.renderers[renderer.instance] = renderer
125 126
127 -class RenderConfig(NullConfigService):
128 - def __init__(self, dmd, instance):
129 from Products.ZenHub import ZENHUB_ZENRENDER 130 if instance == ZENHUB_ZENRENDER: 131 self.dmd = dmd 132 self.instance = instance 133 else: 134 NullConfigService.__init__(self, dmd, instance) 135 136 global htmlResource 137 try: 138 if not htmlResource: 139 htmlResource = Render() 140 log.info("Starting graph retrieval listener on port 8090") 141 interface = '::' if ipv6_available() else '' 142 reactor.listenTCP(8090, server.Site(htmlResource), interface=interface) 143 htmlResource.addRenderer(self) 144 except CannotListenError, e: 145 # Probably in a hub worker; no big deal 146 log.debug("Not starting render listener because the port is " 147 "already in use.")
148