Source code for cheshire3.server

from __future__ import with_statement

import os

from lxml import etree
from lxml.builder import ElementMaker

from cheshire3.baseObjects import Server
from cheshire3.bootstrap import BSLxmlParser, BootstrapDocument
from cheshire3.configParser import C3Object
from cheshire3.exceptions import (ConfigFileException,
                                  ObjectDoesNotExistException,
                                  XMLSyntaxError,
                                  FileSystemException)
from cheshire3.internal import cheshire3Root, CONFIG_NS


class SimpleServer(Server):
[docs] databases = {} # here because it's global to the install _possiblePaths = {'sortPath': {"docs": "Path to the 'sort' utility"}} def __init__(self, session, configFile="serverConfig.xml"): # self.defaultFunctionLog = "__api__" self.defaultFunctionLog = "" self.databaseConfigs = {} self.databases = {} self.id = "DefaultServer" session.server = self # Bootstrappage dom = self._getDomFromFile(session, configFile) try: topNode = dom.childNodes[0] except: topNode = dom C3Object.__init__(self, session, topNode, None) # Add default logger to session log = self.get_path(session, 'defaultLogger', None) if log: session.logger = log def _cacheDatabases(self, session): # Read in all Database configurations, build and cache Database objects for dbid in self.databaseConfigs.keys(): db = self.get_object(session, dbid) self.databases[dbid] = db def register_databaseConfigFile(self, session, file_path): """Register a Cheshire3 Database config file. Register a configuration file for a Cheshire3 Database with the server. This process simply tells the server that it should include the configuration(s) in your file (it does not ingest your file) so you don't need to re-register when you make changes to the file. """ # Read in proposed config file with open(file_path, 'r') as fh: confdoc = BootstrapDocument(fh) # Check it's parsable try: confrec = BSLxmlParser.process_document(session, confdoc) except XMLSyntaxError as e: msg = ("Config file {0} is not well-formed and valid XML: " "{1}".format(file_path, e.message)) self.log_critical(session, msg) raise ConfigFileException(msg) # Extract the database identifier confdom = confrec.get_dom(session) dbid = confdom.attrib.get('id', None) if dbid is None: msg = ("Config file {0} must have an 'id' attribute at the " "top-level".format(file_path)) self.log_critical(session, msg) raise ConfigFileException(msg) # Check that the identifier is not already in use by existing database try: self.get_object(session, dbid) except ObjectDoesNotExistException: # Doesn't exists, so OK to register it pass else: msg = ("Database with id '{0}' is already registered. " "Please specify a different id in your configurations " "file.".format(dbid)) self.log_critical(session, msg) raise ConfigFileException(msg) # Generate plugin XML plugin = E.config( E.subConfigs( E.path({'type': "database", 'id': dbid}, file_path ) ) ) # Try to do this by writing config plugin file if possible serverDefaultPath = self.get_path(session, 'defaultPath', cheshire3Root) userSpecificPath = os.path.join(os.path.expanduser('~'), '.cheshire3-server') pluginPath = os.path.join('configs', 'databases', '{0}.xml'.format(dbid)) try: pluginfh = open(os.path.join(serverDefaultPath, pluginPath), 'w') except IOError: try: pluginfh = open(os.path.join(userSpecificPath, pluginPath), 'w') except IOError: msg = ("Database plugin directory {0} unavailable for writing" "".format(os.path.join(userSpecificPath, pluginPath))) self.log_critical(session, msg) raise FileSystemException(msg) pluginfh.write(etree.tostring(plugin, pretty_print=True, encoding="utf-8")) pluginfh.close() self.log_info(session, "Database configured in {0} registered with Cheshire3 " "Server {1}".format(file_path, self.id)) # Set up ElementMaker for Cheshire3 config namespace E = ElementMaker(namespace=CONFIG_NS, nsmap={None: CONFIG_NS})