//--- Class methods --- public static InstanceManager New(DekiWikiService dekiService, TaskTimerFactory timerFactory) { InstanceManager mgr; var srcString = dekiService.Config["wikis/@src"].AsText; if(!string.IsNullOrEmpty(srcString)) { XUri remoteDirUri; if(!XUri.TryParse(srcString, out remoteDirUri)) { //TODO: build a specialized exception out of this throw new ApplicationException(string.Format("Configuration is not valid. wikis/@src ({0})is not a valid url!", srcString)); } mgr = new RemoteInstanceManager(dekiService, timerFactory, remoteDirUri, dekiService.TempPath); } else { mgr = new LocalInstanceManager(dekiService, timerFactory); } mgr._maxInstances = dekiService.Config["wikis/@max"].AsInt ?? int.MaxValue; var timeoutSecs = dekiService.Config["wikis/@ttl"].AsDouble; if(timeoutSecs == null || timeoutSecs == 0) { mgr._inactiveInstanceTimeOut = TimeSpan.MaxValue; } else { mgr._inactiveInstanceTimeOut = TimeSpan.FromSeconds(timeoutSecs.Value); } var retryInterval = dekiService.Config["wikis/@retry-interval"].AsDouble ?? 10; mgr._abandonedInstanceRetryInterval = TimeSpan.FromSeconds(retryInterval); mgr._minInstanceIdletime = TimeSpan.FromSeconds(dekiService.Config["wikis/@idletime"].AsDouble ?? 60); return mgr; }
// --- Class methods --- public static InstanceManager New(DekiWikiService dekiService) { InstanceManager mgr = null; string srcString = dekiService.Config["wikis/@src"].AsText; if(!string.IsNullOrEmpty(srcString)) { XUri remoteDirUri = null; if(!XUri.TryParse(srcString, out remoteDirUri)) { //TODO: build a specialized exception out of this throw new ApplicationException(string.Format("Configuration is not valid. wikis/@src ({0})is not a valid url!", srcString)); } mgr = new RemoteInstanceManager(dekiService, remoteDirUri); } else { mgr = new LocalInstanceManager(dekiService); } mgr.maxInstances = dekiService.Config["wikis/@max"].AsUInt ?? 0; uint timeoutSecs = dekiService.Config["wikis/@ttl"].AsUInt ?? uint.MaxValue; if(timeoutSecs == 0 || timeoutSecs == uint.MaxValue) { mgr._inactiveInstanceTimeOut = TimeSpan.MaxValue; } else { mgr._inactiveInstanceTimeOut = TimeSpan.FromSeconds(timeoutSecs); } return mgr; }
// --- Constructors --- public RemoteInstanceManager(DekiWikiService dekiService, XUri directoryUri) : base(dekiService) { _directory = Plug.New(directoryUri); DreamMessage testMsg = _directory.GetAsync().Wait(); if (!testMsg.IsSuccessful) throw new DreamInternalErrorException(string.Format("Error validating remote deki portal service at '{0}'", directoryUri.ToString())); }
//--- Constructors --- public LocalInstanceManager(DekiWikiService dekiService, TaskTimerFactory timerFactory) : base(dekiService, timerFactory) { var dekiServiceConfig = dekiService.Config; if (dekiServiceConfig["wikis/config"].IsEmpty) { //Not in cluster mode (no other wikis defined): run all hosts under default wiki. AssociateHostnameWithWiki("*", DEFAULT_WIKI_ID); } else { foreach (XDoc wikiDoc in dekiServiceConfig["wikis/config"]) { var wikiId = wikiDoc["@id"].AsText; AssociateHostnameWithWiki(wikiDoc["host"].Select(hostDoc => hostDoc.Contents).ToArray(), wikiId); } } }
//--- Constructors --- public RemoteInstanceManager(DekiWikiService dekiService, TaskTimerFactory timerFactory, XUri directoryUri, string tempPath) : base(dekiService, timerFactory) { // validate temp folder _tempPath = tempPath; if(!Directory.Exists(_tempPath)) { throw new ArgumentException("temp folder does not exist", "tempPath"); } // check remote directory _directory = Plug.New(directoryUri); var testMsg = _directory.GetAsync().Wait(); if(!testMsg.IsSuccessful) { _log.WarnFormat("Error validating remote deki portal service at '{0}'", directoryUri); } }
//--- Constructors --- public RemoteInstanceManager(DekiWikiService dekiService, TaskTimerFactory timerFactory, XUri directoryUri, string tempPath) : base(dekiService, timerFactory) { // validate temp folder _tempPath = tempPath; if (!Directory.Exists(_tempPath)) { throw new ArgumentException("temp folder does not exist", "tempPath"); } // check remote directory _directory = Plug.New(directoryUri); var testMsg = _directory.GetAsync().Wait(); if (!testMsg.IsSuccessful) { _log.WarnFormat("Error validating remote deki portal service at '{0}'", directoryUri); } }
// --- Constructors --- public LocalInstanceManager(DekiWikiService dekiService) : base(dekiService) { XDoc dekiServiceConfig = dekiService.Config; Dictionary<string, string> wikiIds = new Dictionary<string, string>(); if (dekiServiceConfig["wikis/config"].IsEmpty) { //Not in cluster mode (no other wikis defined): run all hosts under default wiki. AssociateHostnameWithWiki("*", DEFAULT_WIKI_ID); } else { foreach (XDoc wikiDoc in dekiServiceConfig["wikis/config"]) { string wikiId = wikiDoc["@id"].AsText; List<string> hostNameList = new List<string>(); foreach (XDoc hostDoc in wikiDoc["host"]) { hostNameList.Add(hostDoc.Contents); } AssociateHostnameWithWiki(hostNameList.ToArray(), wikiId); } } }
//--- Class methods --- public static InstanceManager New(DekiWikiService dekiService, TaskTimerFactory timerFactory) { InstanceManager mgr; var srcString = dekiService.Config["wikis/@src"].AsText; if (!string.IsNullOrEmpty(srcString)) { XUri remoteDirUri; if (!XUri.TryParse(srcString, out remoteDirUri)) { //TODO: build a specialized exception out of this throw new ApplicationException(string.Format("Configuration is not valid. wikis/@src ({0})is not a valid url!", srcString)); } mgr = new RemoteInstanceManager(dekiService, timerFactory, remoteDirUri, dekiService.TempPath); } else { mgr = new LocalInstanceManager(dekiService, timerFactory); } mgr._maxInstances = dekiService.Config["wikis/@max"].AsInt ?? int.MaxValue; var timeoutSecs = dekiService.Config["wikis/@ttl"].AsDouble; if (timeoutSecs == null || timeoutSecs == 0) { mgr._inactiveInstanceTimeOut = TimeSpan.MaxValue; } else { mgr._inactiveInstanceTimeOut = TimeSpan.FromSeconds(timeoutSecs.Value); } var retryInterval = dekiService.Config["wikis/@retry-interval"].AsDouble ?? 10; mgr._abandonedInstanceRetryInterval = TimeSpan.FromSeconds(retryInterval); mgr._minInstanceIdletime = TimeSpan.FromSeconds(dekiService.Config["wikis/@idletime"].AsDouble ?? 60); return(mgr); }
//--- Constructors --- protected InstanceManager(DekiWikiService dekiService, TaskTimerFactory timerFactory) { _dekiService = dekiService; _timerFactory = timerFactory; }
//--- Class Methods --- public static void StartExtensionService(DekiContext context, ServiceBE service, ServiceRepository.IServiceInfo serviceInfo, bool forceRefresh) { // retrieve document describing the extension functions XUri uri = new XUri(service.Uri); XDoc manifest = null; DekiWikiService deki = context.Deki; var extension = serviceInfo.Extension; if (!service.ServiceLocal) { lock (deki.RemoteExtensionLibraries) { deki.RemoteExtensionLibraries.TryGetValue(uri, out manifest); } } if (manifest == null || forceRefresh) { manifest = Plug.New(uri).Get().ToDocument(); // normalize the extension XML manifest = manifest.TransformAsXml(_extensionConverterXslt); // check if document describes a valid extension: either the extension has no functions, or the functions have end-points if (manifest.HasName("extension") && ((manifest["function"].ListLength == 0) || (manifest["function/uri"].ListLength > 0))) { // add source uri for service manifest.Attr("uri", uri); // register service in extension list lock (deki.RemoteExtensionLibraries) { deki.RemoteExtensionLibraries[uri] = manifest; } } else { throw new ExtensionRemoveServiceInvalidOperationException(uri); } } extension.Manifest = manifest; // add function prefix if one is defined serviceInfo.Extension.SetPreference("namespace.custom", service.Preferences["namespace"]); string serviceNamespace = service.Preferences["namespace"] ?? manifest["namespace"].AsText; if (serviceNamespace != null) { serviceNamespace = serviceNamespace.Trim(); if (string.IsNullOrEmpty(serviceInfo.Namespace)) { // Note (arnec): Namespace from preferences is assigned at service creation. If we do not have one at this // point, it came from the extension manifest and needs to be registered as our default. Otherwise the // preference override persists as the namespace. context.Instance.RunningServices.RegisterNamespace(serviceInfo, serviceNamespace); } if (serviceNamespace.Length != 0) { if (!DekiScriptParser.IsIdentifier(serviceNamespace)) { throw new ExtensionNamespaceInvalidArgumentException(service.Preferences["namespace"] ?? manifest["namespace"].AsText); } } else { serviceNamespace = null; } } serviceNamespace = (serviceNamespace == null) ? string.Empty : (serviceNamespace + "."); // add custom library title extension.SetPreference("title.custom", service.Preferences["title"]); extension.SetPreference("label.custom", service.Preferences["label"]); extension.SetPreference("description.custom", service.Preferences["description"]); extension.SetPreference("uri.logo.custom", service.Preferences["uri.logo"]); extension.SetPreference("functions", service.Preferences["functions"]); extension.SetPreference("protected", service.Preferences["protected"]); // add each extension function bool.TryParse(service.Preferences["protected"], out extension.IsProtected); var functions = new List <ServiceRepository.ExtensionFunctionInfo>(); foreach (XDoc function in manifest["function"]) { XUri functionUri = function["uri"].AsUri; if (functionUri != null) { functions.Add(new ServiceRepository.ExtensionFunctionInfo(serviceNamespace + function["name"].Contents, functionUri)); } } extension.Functions = functions.ToArray(); }
// --- Constructors --- protected InstanceManager(DekiWikiService dekiService) { _dekiService = dekiService; }