def discoverHandlers(self): """ Force the discovery of URL, automatic call when we try to get handlers for the first time. You can disable the automatic call with autoDiscovery=False at initialization """ gLogger.debug("Trying to auto-discover the handlers for Tornado") # Look in config diracSystems = gConfig.getSections("/Systems") serviceList = [] if diracSystems["OK"]: for system in diracSystems["Value"]: try: instance = PathFinder.getSystemInstance(system) services = gConfig.getSections("/Systems/%s/%s/Services" % (system, instance)) if services["OK"]: for service in services["Value"]: newservice = "%s/%s" % (system, service) # We search in the CS all handlers which used HTTPS as protocol isHTTPS = gConfig.getValue( "/Systems/%s/%s/Services/%s/Protocol" % (system, instance, service) ) if isHTTPS and isHTTPS.lower() == "https": serviceList.append(newservice) # On systems sometime you have things not related to services... except RuntimeError: pass return self.loadHandlersByServiceName(serviceList)
def __init__(self, services=True, endpoints=False, port=None): """C'r :param list services: (default True) List of service handlers to load. If ``True``, loads all described in the CS If ``False``, do not load services :param list endpoints: (default False) List of endpoint handlers to load. If ``True``, loads all described in the CS If ``False``, do not load endpoints :param int port: Port to listen to. If ``None``, the port is resolved following the logic described in the class documentation """ self.__startTime = time.time() # Application metadata, routes and settings mapping on the ports self.__appsSettings = {} # Default port, if enother is not discover if port is None: port = gConfig.getValue( "/Systems/Tornado/%s/Port" % PathFinder.getSystemInstance("Tornado"), 8443) self.port = port # Handler manager initialization with default settings self.handlerManager = HandlerManager(services, endpoints) # temp value for computation, used by the monitoring self.__report = None # Last update time stamp self.__monitorLastStatsUpdate = None self.__monitoringLoopDelay = 60 # In secs self.activityMonitoring = False if "Monitoring" in Operations().getMonitoringBackends( monitoringType="ServiceMonitoring"): self.activityMonitoring = True # If services are defined, load only these ones (useful for debug purpose or specific services) retVal = self.handlerManager.loadServicesHandlers() if not retVal["OK"]: sLog.error(retVal["Message"]) raise ImportError( "Some services can't be loaded, check the service names and configuration." ) # Response time to load services self.__elapsedTime = time.time() - self.__startTime retVal = self.handlerManager.loadEndpointsHandlers() if not retVal["OK"]: sLog.error(retVal["Message"]) raise ImportError( "Some endpoints can't be loaded, check the endpoint names and configuration." )
def __init__(self, services=None, port=None): """ :param list services: (default None) List of service handlers to load. If ``None``, loads all :param int port: Port to listen to. If None, the port is resolved following the logic described in the class documentation """ if port is None: port = gConfig.getValue( "/Systems/Tornado/%s/Port" % PathFinder.getSystemInstance('Tornado'), 8443) if services and not isinstance(services, list): services = [services] # URLs for services. # Contains Tornado :py:class:`tornado.web.url` object self.urls = [] # Other infos self.port = port self.handlerManager = HandlerManager() # Monitoring attributes self._monitor = MonitoringClient() # temp value for computation, used by the monitoring self.__report = None # Last update time stamp self.__monitorLastStatsUpdate = None self.__monitoringLoopDelay = 60 # In secs # If services are defined, load only these ones (useful for debug purpose or specific services) if services: retVal = self.handlerManager.loadHandlersByServiceName(services) if not retVal['OK']: sLog.error(retVal['Message']) raise ImportError( "Some services can't be loaded, check the service names and configuration." ) # if no service list is given, load services from configuration handlerDict = self.handlerManager.getHandlersDict() for item in handlerDict.items(): # handlerDict[key].initializeService(key) self.urls.append(url(item[0], item[1])) # If there is no services loaded: if not self.urls: raise ImportError( "There is no services loaded, please check your configuration")
def main(): if os.environ.get("DIRAC_USE_TORNADO_IOLOOP", "false").lower() not in ("yes", "true"): raise RuntimeError( "DIRAC_USE_TORNADO_IOLOOP is not defined in the environment." + "\n" + "It is necessary to run with Tornado." + "\n" + "https://dirac.readthedocs.io/en/latest/DeveloperGuide/TornadoServices/index.html" ) from DIRAC import gConfig from DIRAC.ConfigurationSystem.Client import PathFinder from DIRAC.ConfigurationSystem.Client.ConfigurationData import gConfigurationData from DIRAC.Core.Tornado.Server.TornadoServer import TornadoServer from DIRAC.Core.Utilities.DErrno import includeExtensionErrors from DIRAC.FrameworkSystem.Client.Logger import gLogger localCfg = Script.localCfg localCfg.setConfigurationForServer("Tornado/Tornado") localCfg.addMandatoryEntry("/DIRAC/Setup") localCfg.addDefaultEntry("/DIRAC/Security/UseServerCertificate", "yes") localCfg.addDefaultEntry("LogLevel", "INFO") localCfg.addDefaultEntry("LogColor", True) resultDict = localCfg.loadUserData() if not resultDict["OK"]: gLogger.initialize("Tornado", "/") gLogger.error("There were errors when loading configuration", resultDict["Message"]) sys.exit(1) includeExtensionErrors() gLogger.initialize("Tornado", "/") # We check if there is no configuration server started as master # If you want to start a master CS you should use Configuration_Server.cfg and # use tornado-start-CS.py key = "/Systems/Configuration/%s/Services/Server/Protocol" % PathFinder.getSystemInstance( "Configuration") if gConfigurationData.isMaster() and gConfig.getValue( key, "dips").lower() == "https": gLogger.fatal("You can't run the CS and services in the same server!") sys.exit(0) serverToLaunch = TornadoServer(endpoints=True) serverToLaunch.startTornado()
def checkURLs(self): """Ensure that the running services have their URL in the Config.""" self.log.info("Checking URLs") # get services again, in case they were started/stop in controlComponents gConfig.forceRefresh(fromMaster=True) # get port used for https based services try: tornadoSystemInstance = PathFinder.getSystemInstance( system="Tornado", setup=self.setup, ) self._tornadoPort = gConfig.getValue( Path.cfgPath("/System/Tornado/", tornadoSystemInstance, "Port"), self._tornadoPort, ) except RuntimeError: pass self.log.debug("Using Tornado Port:", self._tornadoPort) res = self.getRunningInstances(instanceType="Services", runitStatus="All") if not res["OK"]: return S_ERROR("Failure to get running services") self.services = res["Value"] for service, options in sorted(self.services.items()): self.log.debug("Checking URL for %s with options %s" % (service, options)) # ignore SystemAdministrator, does not have URLs if "SystemAdministrator" in service: continue self._checkServiceURL(service, options) if self.csAPI.csModified and self.commitURLs: self.log.info("Commiting changes to the CS") result = self.csAPI.commit() if not result["OK"]: self.logError("Commit to CS failed", result["Message"]) return S_ERROR("Failed to commit to CS") return S_OK()
def main(): # Must be defined BEFORE any dirac import os.environ['DIRAC_USE_TORNADO_IOLOOP'] = "True" from DIRAC import gConfig from DIRAC.ConfigurationSystem.Client import PathFinder from DIRAC.ConfigurationSystem.Client.ConfigurationData import gConfigurationData from DIRAC.ConfigurationSystem.Client.LocalConfiguration import LocalConfiguration from DIRAC.Core.Tornado.Server.TornadoServer import TornadoServer from DIRAC.Core.Utilities.DErrno import includeExtensionErrors from DIRAC.FrameworkSystem.Client.Logger import gLogger # We check if there is no configuration server started as master # If you want to start a master CS you should use Configuration_Server.cfg and # use tornado-start-CS.py key = '/Systems/Configuration/%s/Services/Server/Protocol' % PathFinder.getSystemInstance('Configuration') if gConfigurationData.isMaster() and gConfig.getValue(key, 'dips').lower() == 'https': gLogger.fatal("You can't run the CS and services in the same server!") sys.exit(0) localCfg = LocalConfiguration() localCfg.setConfigurationForServer('Tornado/Tornado') localCfg.addMandatoryEntry("/DIRAC/Setup") localCfg.addDefaultEntry("/DIRAC/Security/UseServerCertificate", "yes") localCfg.addDefaultEntry("LogLevel", "INFO") localCfg.addDefaultEntry("LogColor", True) resultDict = localCfg.loadUserData() if not resultDict['OK']: gLogger.initialize("Tornado", "/") gLogger.error("There were errors when loading configuration", resultDict['Message']) sys.exit(1) includeExtensionErrors() gLogger.initialize('Tornado', "/") serverToLaunch = TornadoServer() serverToLaunch.startTornado()