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

# Source Code for Module Products.ZenHub.services.ZenRender

      1  ###########################################################################
      2  #
      3  # This program is part of Zenoss Core, an open source monitoring platform.
      4  # Copyright (C) 2007, 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 as published by
      8  # the Free Software Foundation.
      9  #
     10  # For complete information please visit: http://www.zenoss.com/oss/
     11  #
     12  ###########################################################################
     13
     14  from Products.ZenHub.HubService import HubService
     15  from twisted.web import resource, server
     16  from twisted.internet import reactor
     17
     18  import xmlrpclib
     19
     20  import mimetypes
     21
     22  htmlResource = None
     23
     24  import logging
     25  log = logging.getLogger("zenrender")
     26
     27  __doc__ = "Provide a simple web server to forward render requests"
     28
     29 -class Render(resource.Resource):
     30
     31      isLeaf = True
     32
     33 -    def __init__(self):
     34          resource.Resource.__init__(self)
     35          self.renderers = {}
     36
     37
     38 -    def render_GET(self, request):
     39          "Deal with http requests"
     40          args = request.args.copy()
     41          for k, v in args.items():
     42              if len(v) == 1:
     43                  args[k] = v[0]
     44
     45          listener = request.postpath[-2]
     46          command = request.postpath[-1]
     47          args.setdefault('ftype', 'PNG')
     48          ftype = args['ftype']
     49          del args['ftype']
     50          mimetype = mimetypes.guess_type('.%s'%ftype)[0]
     51          if not mimetype: mimetype = 'image/%s'%ftype
     52          request.setHeader('Content-type', mimetype)
     53          def write(result):
     54              if result:
     55                  request.write(result)
     56              request.finish()
     57          def error(reason):
     58              log.error("Unable to fetch graph: %s", reason)
     59              request.finish()
     60          renderer = self.renderers.get(listener, False)
     61          if not renderer or not renderer.listeners:
     62              raise Exception("Renderer %s unavailable" % listener)
     63          d = renderer.listeners[0].callRemote(command, **args)
     64          d.addCallbacks(write, error)
     65          return server.NOT_DONE_YET
     66
     67 -    def render_POST(self, request):
     68          "Deal with XML-RPC requests"
     69          content = request.content.read()
     70          for instance, renderer in self.renderers.items():
     71              if instance != request.postpath[-1]: continue
     72              for listener in renderer.listeners:
     73                  try:
     74                      args, command = xmlrpclib.loads(content)
     75                      request.setHeader('Content-type', 'text/xml')
     76                      d = listener.callRemote(str(command), *args)
     77                      def write(result):
     78                          try:
     79                              response = xmlrpclib.dumps((result,),
     80                                                         methodresponse=True,
     81                                                         allow_none=True)
     82                              request.write(response)
     83                          except Exception, ex:
     84                              log.error("Unable to %s: %s", command, ex)
     85                          request.finish()
     86                      def error(reason):
     87                          log.error("Unable to %s: %s", command, reason)
     88                          request.finish()
     89                      d.addCallbacks(write, error)
     90                      return server.NOT_DONE_YET
     91                  except Exception, ex:
     92                      log.exception(ex)
     93                      log.warning("Skipping renderer %s" % instance)
     94          raise Exception("No renderer registered")
     95
     96 -    def getChild(self, unused, ignored):
     97          "Handle all paths"
     98          return self, ()
     99
    100
    101 -    def addRenderer(self, renderer):
    102          self.renderers[renderer.instance] = renderer
    103
    104 -class ZenRender(HubService):
    105
    106 -    def __init__(self, *args, **kw):
    107          HubService.__init__(self, *args, **kw)
    108          global htmlResource
    109          if not htmlResource:
    110              htmlResource = Render()
    111              reactor.listenTCP(8090, server.Site(htmlResource))
    112          htmlResource.addRenderer(self)
    113