public override DekiAuthenticationService.User GetUser(string user) { User result = null; XDoc doc = XDocFactory.LoadFrom(_path, MimeType.XML); XDoc userNode = doc[string.Format("users/user[@name=\"{0}\"]", user)]; if (!userNode.IsEmpty) { List <Group> groups = GetGroups(doc, string.Format("groups/group[user/@name=\"{0}\"]", user)); if (groups.Count == 0) { groups.Add(new Group(string.Empty)); } result = new User( userNode["@name"].IsEmpty ? string.Empty : userNode["@name"].AsText, userNode["email"].IsEmpty ? string.Empty : userNode["email"].AsText, groups.ToArray() ); result.Custom["fullname"] = userNode["fullname"].IsEmpty ? string.Empty : userNode["fullname"].AsText; result.Custom["status"] = userNode["status"].IsEmpty ? "enabled" : userNode["status"].AsText; } return(result); }
//--- Methods --- protected override void OnStart(string[] args) { TimeSpan time; _sysEventLog.WriteEntry("host service starting", EventLogEntryType.Information); // TODO (steveb): make settings file name & location configurable (use app settings) string baseFolder = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedName); string startupFile = Path.Combine(baseFolder, "mindtouch.dream.startup.xml"); XDoc settings = XDoc.Empty; settings = XDocFactory.LoadFrom(startupFile, MimeType.XML); if (settings == null) { throw new Exception("invalid settings file"); } // create environment time = DebugUtil.Stopwatch(delegate() { _host = new DreamHost(settings); }); _sysEventLog.WriteEntry(string.Format("ApiKey: {0}", _host.Self.Uri.GetParam("apikey")), EventLogEntryType.Information); _sysEventLog.WriteEntry(string.Format("initialized {0} secs", time.TotalSeconds), EventLogEntryType.Information); // execute all scripts time = DebugUtil.Stopwatch(delegate() { _host.RunScripts(settings, null); }); _sysEventLog.WriteEntry(string.Format("ready {0} secs", time.TotalSeconds), EventLogEntryType.Information); }
private void LoadRecordsFromFileSystem() { string storagePath = Config["filestorage-path"].AsText; if (string.IsNullOrEmpty(storagePath)) { return; } if (!System.IO.Directory.Exists(storagePath)) { return; } string[] files = System.IO.Directory.GetFiles(storagePath, "*.xml", System.IO.SearchOption.TopDirectoryOnly); if (files != null) { foreach (string file in files) { try { DirectoryRecord record = new DirectoryRecord(); record.Name = System.IO.Path.GetFileNameWithoutExtension(file); record.Value = XDocFactory.LoadFrom(file, MimeType.XML); _directory[record.Name] = record; } catch (Exception) { System.IO.File.Delete(file); } } } }
private void MigrateLegacyStateFile() { // check if state file exists, and convert state to meta files var statefile = Path.Combine(_path, STATE_FILENAME); if (!File.Exists(statefile)) { return; } var state = XDocFactory.LoadFrom(statefile, MimeType.XML); // restore file expiration list foreach (var entry in state["file"]) { var filepath = Path.Combine(_path, entry["path"].Contents); var when = entry["date.expire"].AsDate; var ttl = TimeSpan.FromSeconds(entry["date.ttl"].AsDouble ?? 0); if (!File.Exists(filepath) || !when.HasValue) { continue; } _log.DebugFormat("migrating file meta data. Scheduled for deletion at {0}", when); WriteMeta(filepath, ttl, when); } File.Delete(statefile); }
private ExpiringHashSet <string> .Entry SyncMeta(string filePath) { lock (_expirationEntries) { DateTime?expire = null; var ttl = TimeSpan.Zero; var metaPath = GetMetaPath(filePath); if (File.Exists(metaPath)) { var meta = XDocFactory.LoadFrom(metaPath, MimeType.XML); expire = meta["expire.date"].AsDate; ttl = TimeSpan.FromSeconds(meta["expire.ttl"].AsDouble ?? 0); } if (expire.HasValue) { // set up expiration _expirationEntries.SetOrUpdate(filePath, expire.Value, ttl); } else { // no expiration anymore, so expiration needs to be removed _expirationEntries.Delete(filePath); } return(_expirationEntries[filePath]); } }
public void GlobalSetup() { _log.Debug("setup"); var assemblyPath = @"MindTouch.Deki.Util.Tests.dll"; _inspector = new TypeInspector(); _inspector.InspectAssembly(assemblyPath); _xmlDocumentation = XDocFactory.LoadFrom(@"MindTouch.Deki.Util.Tests.xml", MimeType.TEXT_XML); }
//--- Class Methods --- public static XDekiScript LoadFrom(string filename) { XDoc doc = XDocFactory.LoadFrom(filename, MimeType.XML); if (doc == null) { return(null); } return(new XDekiScript(doc)); }
public static XDoc GenerateLicense(string[] licenseArgs) { Init(); Tuplet <int, Stream, Stream> exitValues = CallLicenseGenerator(licenseArgs); Assert.AreEqual(0, exitValues.Item1, "Unexpected return code\n" + GetErrorMsg(exitValues.Item2) + GetErrorMsg(exitValues.Item3)); // Retrieve generated license return(!File.Exists(_genLicensePath) ? null : XDocFactory.LoadFrom(_genLicensePath, MimeType.XML)); }
public FilePackageReader(string packageDirectory) { _packageDirectory = packageDirectory; string path = Path.Combine(_packageDirectory, "package.xml"); if (!File.Exists(path)) { throw new FileNotFoundException("Unable to locate manifest", path); } _package = XDocFactory.LoadFrom(path, MimeType.TEXT_XML); }
private XDoc LoadExportDocumentFromFile(string exportDocumentPath) { if (!File.Exists(exportDocumentPath)) { throw new ConfigurationException("No such export document: {0}", exportDocumentPath); } try { return(XDocFactory.LoadFrom(exportDocumentPath, MimeType.TEXT_XML)); } catch (Exception e) { throw new ConfigurationException("Unable to load '{0}': {1}", exportDocumentPath, e.Message); } }
// --- Methods --- private void LoadDefaults() { // load default parameter values from the xml data file _defaultValues = new NameValueCollection(); try { XDoc defaultDoc = XDocFactory.LoadFrom("DefaultData.xml", MimeType.XML); foreach (XDoc defaultValue in defaultDoc["/params/param"]) { _defaultValues.Add(defaultValue["name"].Contents.Trim(), defaultValue["default"].Contents.Trim()); } } catch { } }
public void AddNewGroup() { //Assumptions: // user joe:supersecret exists //Actions: // create new group in xml file // try to create group from xml // try to receive new group from server //Expected result: // new group created in deki Plug p = Utils.BuildPlugForAdmin(); string serviceid = GetServiceIDBySID(p, SID); DreamMessage msg = p.At("site", "services", serviceid).Get(); Assert.AreEqual(DreamStatus.Ok, msg.Status); string filename = msg.ToDocument()["config/value[@key='xmlauth-path']"].AsText; string groupname = Utils.GenerateUniqueName(); XDoc xdoc = XDocFactory.LoadFrom(filename, MimeType.XML); xdoc["groups"] .Start("group").Attr("name", groupname).End(); xdoc.Save(filename); XDoc groupDoc = new XDoc("group") .Elem("name", groupname) .Start("service.authentication").Attr("id", serviceid).End() .Start("permissions.group") .Elem("role", "Contributor") .End() .Start("users") .End(); msg = p.At("groups").WithQuery("authusername=joe").WithQuery("authpassword=supersecret").Post(groupDoc); Assert.AreEqual(DreamStatus.Ok, msg.Status); string groupid = msg.ToDocument()["@id"].AsText; Assert.IsFalse(string.IsNullOrEmpty(groupid)); msg = p.At("groups").WithQuery("authprovider=" + serviceid).Get(); Assert.AreEqual(DreamStatus.Ok, msg.Status); Assert.IsFalse(msg.ToDocument()[string.Format("group[groupname=\"{0}\"]", groupname)].IsEmpty); msg = p.At("groups", groupid).Delete(); Assert.AreEqual(DreamStatus.Ok, msg.Status); }
public override Group GetGroup(string group) { XDoc doc = XDocFactory.LoadFrom(_path, MimeType.XML); XDoc groupNode = doc[string.Format("groups/group[@name=\"{0}\"]", group)]; if (!groupNode.IsEmpty) { return(new Group(groupNode["@name"].IsEmpty ? string.Empty : groupNode["@name"].AsText)); } return(null); }
private XDoc RetrieveFromFileSystem(string key) { string fullPath = BuildSavePath(key); if (fullPath != null && System.IO.File.Exists(fullPath)) { return(XDocFactory.LoadFrom(fullPath, MimeType.XML)); } else { return(null); } }
private void AddNewGroupToXml(Plug p, string serviceid, string groupname) { DreamMessage msg = p.At("site", "services", serviceid).Get(); Assert.AreEqual(DreamStatus.Ok, msg.Status); string filename = msg.ToDocument()["config/value[@key='xmlauth-path']"].AsText; XDoc xdoc = XDocFactory.LoadFrom(filename, MimeType.XML); xdoc["groups"].Start("group").Attr("name", groupname).End(); xdoc.Save(filename); }
public void GetSettingsIncludingLicenseInfo() { Plug p = Utils.BuildPlugForAdmin(); var msg = p.At("site", "settings").With("apikey", Utils.Settings.ApiKey).With("include", "license").Get(); Assert.AreEqual(DreamStatus.Ok, msg.Status); var settingsDoc = msg.ToDocument(); // Assert the license information is included in the settings. Assert.IsFalse(settingsDoc["license"].IsEmpty, "No license information was returned as part of the site's settings."); var license = XDocFactory.LoadFrom(Utils.Settings.LicensePath, MimeType.TEXT_XML); Assert.IsFalse(settingsDoc["license/type"].IsEmpty, "The license's type was not included and it must be included."); Assert.AreEqual(license["@type"].Contents, settingsDoc["license/type"].Contents, "The license type from GET:site/settings does not match the value from the license file"); }
public Dictionary <string, string> ReadUrlsFromAllManifests() { Dictionary <string, string> confToMtUrls = new Dictionary <string, string>(StringComparer.InvariantCultureIgnoreCase); if (Directory.Exists("data")) { string[] manifestFiles = Directory.GetFiles("data", "*.manifest.xml", SearchOption.TopDirectoryOnly); foreach (string filename in manifestFiles) { XDoc spaceManifest = XDocFactory.LoadFrom(filename, MimeType.XML); confToMtUrls = ReadUrlsFromManifest(confToMtUrls, spaceManifest); } } return(confToMtUrls); }
private List <string> ConfigureFromXml(string configFile) { if (!File.Exists(configFile)) { throw new ConfigurationException("No such config file: {0}", configFile); } XDoc config = null; try { config = XDocFactory.LoadFrom(configFile, MimeType.TEXT_XML); } catch (Exception e) { throw new ConfigurationException("Unable to load '{0}': {1}", configFile, e.Message); } List <string> extraOpts = new List <string>(); foreach (string flagPath in new string[] { "export", "copy", "archive", "recursive" }) { XDoc flag = config["@" + flagPath]; if (!flag.IsEmpty && (flag.AsBool ?? false)) { extraOpts.Add("-" + flagPath); } } foreach (string argPath in new string[] { "host", "uri", "importreltopath", "importrelto", "exportreltopath", "exportrelto", "exportdoc", "exportpath", "exportlist", "authtoken", "user", "password" }) { string opt = config["@" + argPath].AsText; if (string.IsNullOrEmpty(opt)) { continue; } extraOpts.Add("-" + argPath); extraOpts.Add(opt); } XDoc export = config["export"]; if (!export.IsEmpty) { ExportDocument = export; } XDoc target = config["target"]; if (!target.IsEmpty) { FilePath = target.AsText; } return(extraOpts); }
public XDoc GetManifestFromDisk(string space) { XDoc ret = null; if (string.IsNullOrEmpty(space)) { space = "_global"; } string filename = string.Format(@"data\{0}.manifest.xml", space.ToLowerInvariant()); if (File.Exists(filename)) { ret = XDocFactory.LoadFrom(filename, MimeType.XML); } return(ret); }
// CLEANUP (CL-442): pull this out into its own interface, but for that RemoteInstanceManager must be autofac controlled private DreamMessage CachedRequest(Plug plug, string filename) { var fullpath = Path.Combine(_tempPath, filename); // attempt to fecth a response from the portal var response = plug.WithTimeout(TIMEOUT).GetAsync().Wait(); // check if we got a positive response if (response.IsSuccessful) { // cache response on disk try { response.ToDocument().Save(fullpath); } catch (Exception e) { _log.Warn(string.Format("Unable to write file '{0}'.", fullpath), e); // just in case, let's remove the file try { File.Delete(fullpath); } catch { } } return(response); } // check if we got a negative response if (response.Status == DreamStatus.Gone) { // cache response on disk try { File.Delete(fullpath); } catch { } return(response); } // no response, let's check if we have a cached response on disk try { var xml = XDocFactory.LoadFrom(fullpath, MimeType.XML); _log.WarnFormat("Portal did not respond. Using previously cached response instead from {0}", filename); return(DreamMessage.Ok(xml)); } catch { } return(response); }
//--- Class Methods --- private static void Main(string[] args) { Plug host = null; try { // create the dream environment XDoc dreamConfigDoc = new XDoc("config"); dreamConfigDoc.Elem("server-name", MKS_PATH); dreamConfigDoc.Elem("service-dir", Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)); dreamConfigDoc.Elem("apikey", API_KEY); host = (new DreamHost(dreamConfigDoc)).Self.With("apikey", API_KEY); host.At("load").With("name", "mindtouch.deki.mwconverter").Post(); host.At("load").With("name", "mindtouch.deki").Post(); host.At("load").With("name", "mindtouch.indexservice").Post(); host.At("load").With("name", "mindtouch.deki.services").Post(); } catch (Exception e) { Console.WriteLine("An unexpected error occurred while creating the dream host."); Console.WriteLine(e); Environment.Exit(1); } try { // load the configuration information XDoc converterConfigDoc = XDocFactory.LoadFrom(CONFIG_FILE, MimeType.XML); XDoc dekiConfigDoc = XDocFactory.LoadFrom(converterConfigDoc["//deki/startup-xml"].Contents, MimeType.XML)["//config"]; dekiConfigDoc["path"].ReplaceValue("converter"); dekiConfigDoc["sid"].ReplaceValue("http://services.mindtouch.com/deki/internal/2007/12/mediawiki-converter"); dekiConfigDoc.Add(converterConfigDoc["//mediawiki"]); host.At("services").Post(dekiConfigDoc); } catch (Exception e) { Console.WriteLine("An unexpected error occurred while loading the converter configuration settings."); Console.WriteLine(e); Environment.Exit(1); } Plug service = Plug.New(host.Uri.AtAbsolutePath("converter"), TimeSpan.MaxValue); service.PostAsync(); Console.ReadLine(); }
public override bool CheckUserPassword(string user, string password) { XDoc doc = XDocFactory.LoadFrom(_path, MimeType.XML); XDoc userNode = doc[string.Format("users/user[@name=\"{0}\"]", user)]; if (!userNode.IsEmpty && (userNode["status"].IsEmpty || userNode["status"].AsText.ToUpper() == "ENABLED")) { if (userNode["password"].IsEmpty) { throw new DreamInternalErrorException("Password not found."); } if (userNode["password/@type"].IsEmpty) { throw new DreamInternalErrorException("Password type not found."); } switch (userNode["password/@type"].AsText.ToUpper()) { case "MD5": { MD5 md5 = new MD5CryptoServiceProvider(); byte[] hash = md5.ComputeHash(Encoding.Default.GetBytes(password)); StringBuilder builder = new StringBuilder(hash.Length); for (int i = 0; i < hash.Length; i++) { builder.Append(hash[i].ToString("x2")); } return(StringComparer.OrdinalIgnoreCase.Compare(userNode["password"].AsText, builder.ToString()) == 0); } case "PLAIN": return(userNode["password"].AsText == password); default: throw new DreamInternalErrorException("Unsupported password type."); } } return(false); }
private void AddNewUserToXml(Plug p, string serviceid, string username, string password) { DreamMessage msg = p.At("site", "services", serviceid).Get(); Assert.AreEqual(DreamStatus.Ok, msg.Status); string filename = msg.ToDocument()["config/value[@key='xmlauth-path']"].AsText; XDoc xdoc = XDocFactory.LoadFrom(filename, MimeType.XML); xdoc["users"] .Start("user").Attr("name", username) .Start("password").Attr("type", "plain").Value(password).End() .Elem("email", username + "@somewhere.com") .Elem("fullname", username) .Elem("status", "enabled") .End(); xdoc.Save(filename); }
public void GetSettings() { // GET:site/settings // http://developer.mindtouch.com/Deki/API_Reference/GET%3asite%2f%2fsettings Plug p = Utils.BuildPlugForAdmin(); DreamMessage msg = p.At("site", "settings").Get(); Assert.AreEqual(DreamStatus.Ok, msg.Status); var settingsDoc = msg.ToDocument(); Assert.AreEqual(true, settingsDoc[ConfigBL.ANONYMOUS_USER].IsEmpty, "The anonymous user information was included but must not be included."); Assert.AreEqual(false, settingsDoc[ConfigBL.LICENSE].IsEmpty, "The license wasn't included but must be included."); var license = XDocFactory.LoadFrom(Utils.Settings.LicensePath, MimeType.TEXT_XML); Assert.IsFalse(settingsDoc[ConfigBL.LICENSE_PRODUCTKEY].IsEmpty, "Failed to include the productkey"); Assert.IsFalse(settingsDoc[ConfigBL.LICENSE_STATE].IsEmpty, "Failed to include the license's state"); Assert.AreEqual(true, settingsDoc[String.Format("{0}/{1}", ConfigBL.LICENSE, "type")].IsEmpty, "Private information was revealed when it must not had been revealed"); Assert.AreEqual(true, settingsDoc["license/state"]["@readonly"].AsBool, "The license's state is not marked as readonly and has to be."); Assert.AreEqual(true, settingsDoc["license/productkey/@readonly"].AsBool, "The license's productkey is not markedas readonly and has to be."); }
public void RunScript(XDoc script, string path) { // check if a filename was provided string filename = script["@src"].AsText; if (filename != null) { // check if filename is relative if (!Path.IsPathRooted(filename) && (path != null)) { filename = Path.Combine(path, filename); } // attempt to load script file if (!File.Exists(filename)) { throw new FileNotFoundException(string.Format("script not found: {0}", filename)); } script = XDocFactory.LoadFrom(filename, MimeType.XML); } // execute script if (script == null) { throw new Exception(string.Format("invalid script: {0}", script.AsText)); } // convert <config> element into a <script> element if (script.HasName("config")) { XDoc doc = new XDoc("script"); doc.Start("action").Attr("verb", "POST").Attr("path", "/host/services"); doc.Add(script); doc.End(); script = doc; } // execute script _host.At("execute").Post(script); }
private TestSettings() { var branchAttr = typeof(DekiWikiService).Assembly.GetAttribute <SvnBranchAttribute>(); var branch = "trunk"; if (branchAttr != null) { branch = branchAttr.Branch; } _basePath = @"C:\mindtouch\public\dekiwiki\" + branch + @"\"; MockPlug.DeregisterAll(); string configfile = "mindtouch.deki.tests.xml"; if (File.Exists(configfile)) { _xdoc = XDocFactory.LoadFrom(configfile, MimeType.XML); } else { _xdoc = new XDoc("config"); } }
//--- Methods --- private void CallbackHandler(Plug plug, string verb, XUri uri, DreamMessage request, Result <DreamMessage> response) { if (uri.Segments.Length == 0) { response.Return(DreamMessage.Ok()); return; } var segments = uri.Segments; var wikiId = segments[0]; if (wikiId.StartsWith("=")) { var id = (HostLookupOverride == null) ? DefaultWikiId : HostLookupOverride(wikiId.Substring(1)); response.Return(DreamMessage.Ok(new XDoc("wiki").Attr("id", id))); return; } if (segments.Length == 2 && segments[1] == "license") { XDoc license; if (LicenseOverride == null) { _log.Debug("returning license from disk"); license = XDocFactory.LoadFrom(Utils.Settings.LicensePath, MimeType.TEXT_XML); } else { _log.Debug("returning license from override callback"); license = LicenseOverride(wikiId); } response.Return(DreamMessage.Ok(license)); return; } var config = (ConfigOverride == null) ? DefaultConfig : ConfigOverride(wikiId); response.Return(DreamMessage.Ok(config)); }
static void Main(string[] args) { using (System.IO.StreamWriter logStream = new System.IO.StreamWriter("mindtouch.deki.acconverter.log")) { logStream.AutoFlush = true; try { string assemblyName = System.IO.Path.GetFileName(System.Reflection.Assembly.GetExecutingAssembly().Location); string configFileName = assemblyName + ".xml"; if (!System.IO.File.Exists(configFileName)) { string mess = "File: \"" + configFileName + "\" not found"; logStream.WriteLine(mess); Console.WriteLine(mess); Console.ReadLine(); return; } XDoc settings = XDocFactory.LoadFrom(configFileName, MimeType.XML); if (settings.IsEmpty) { string mess = "Invalid settings file"; logStream.WriteLine(mess); Console.WriteLine(mess); Console.ReadLine(); return; } string confluenceAPIUrl = settings["ConfluenceAPIUrl"].AsText; string ConfluenceXMLRPCUrl = settings["ConfluenceXMLRPCUrl"].AsText; string confluenceUserName = settings["ConfluenceUserName"].AsText; string confluenceUserPassword = settings["ConfluenceUserPassword"].AsText; string dreamAPIUrl = settings["DreamAPIUrl"].AsText; string dekiUserName = settings["DekiUserName"].AsText; string dekiUserPassword = settings["DekiUserPassword"].AsText; bool? compatibleConvertUserPermissions = settings["CompatibleConvertUserPermissions"].AsBool; bool processNewsPages = settings["ProcessNewsPages"].AsBool ?? true; bool processPersonalSpaces = settings["ProcessPersonalSpaces"].AsBool ?? true; string fallbackSpacePrefix = settings["FallbackSpacePrefix"].AsText; if ((confluenceAPIUrl == null) || (confluenceUserName == null) || (confluenceUserPassword == null) || (dreamAPIUrl == null) || (dekiUserName == null) || (dekiUserPassword == null) || (!compatibleConvertUserPermissions.HasValue)) { string mess = "Invalid settings file"; logStream.WriteLine(mess); Console.WriteLine(mess); Console.ReadLine(); return; } List <string> spacesToConvert = new List <string>(); if (!settings["SpacesToImport"].IsEmpty) { foreach (XDoc spaceDoc in settings["SpacesToImport"].Elements) { string spaceTitle = spaceDoc.AsText.ToLower(); spacesToConvert.Add(spaceTitle); } } bool success = ACConverter.Convert(ConfluenceXMLRPCUrl, confluenceAPIUrl, confluenceUserName, confluenceUserPassword, dreamAPIUrl, dekiUserName, dekiUserPassword, compatibleConvertUserPermissions.Value, spacesToConvert, processNewsPages, processPersonalSpaces, fallbackSpacePrefix); if (success) { string mess = "Conversion successfully completed!"; logStream.WriteLine(mess); Console.WriteLine(mess); } } catch (DreamResponseException e) { string mess = DateTime.Now.ToString("HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture.DateTimeFormat) + " An unexpected error has occurred:"; logStream.WriteLine(mess); logStream.WriteLine(e.Response.ToString()); logStream.WriteLine(e); Console.WriteLine(mess); Console.WriteLine(e); } catch (System.Web.Services.Protocols.SoapException e) { string mess = DateTime.Now.ToString("HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture.DateTimeFormat) + " An unexpected error has occurred:"; logStream.WriteLine(mess); if ((e.Detail != null) && (e.Detail.OuterXml != null)) { logStream.WriteLine(e.Detail.OuterXml); } logStream.WriteLine(e); Console.WriteLine(mess); Console.WriteLine(e); } catch (Exception e) { string mess = DateTime.Now.ToString("HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture.DateTimeFormat) + " An unexpected error has occurred:"; logStream.WriteLine(mess); logStream.WriteLine(e); Console.WriteLine(mess); Console.WriteLine(e); } Console.ReadLine(); } }
//--- Class Methods --- private static int Main(string[] args) { bool useTty = true; TimeSpan time; // process command line arguments XDoc config = new XDoc("config"); for (int i = 0; i < args.Length; i += 2) { string key = args[i].ToLowerInvariant(); string value = ((i + 1) < args.Length) ? args[i + 1] : string.Empty; switch (key) { case "help": PrintUsage(); return(0); case "notty": --i; useTty = false; break; case "capture-stack-trace": --i; DebugUtil.CaptureStackTrace = true; break; case "nolog": --i; // NOTE (steveb): this option used to disable logging, but was removed in favor of using the automatic re-reading of app.config by log4net break; case "settings": case "config": if (!File.Exists(value)) { WriteError(key, "config file not found"); return(1); } config = XDocFactory.LoadFrom(value, MimeType.XML); break; case "script": config.Start("script").Attr("src", value).End(); break; case "ip": case "host": config.Elem("host", value); break; case "http-port": case "path-prefix": case "server-path": case "server-name": case "storage-dir": case "connect-limit": case "apikey": case "guid": config.Elem(key, value); break; case "public-uri": case "root-uri": config.Elem("uri.public", value); break; case "service-dir": config.Elem("storage-dir", value); break; case "collect-interval": int interval; if (!int.TryParse(value, out interval)) { WriteError(key, "invalid collection interval (must be an integer representing seconds)"); return(1); } if (interval > 0) { DebugUtil.SetCollectionInterval(TimeSpan.FromSeconds(interval)); } break; case "auth": config.Elem("authentication-shemes", value); break; default: WriteError(key, "unknown setting"); return(1); } } try { // initialize environment if (config["apikey"].IsEmpty) { string apikey = StringUtil.CreateAlphaNumericKey(32); config.Elem("apikey", apikey); Console.WriteLine("Dream Host APIKEY: {0}", apikey); } Console.WriteLine("-------------------- initializing"); time = DebugUtil.Stopwatch(() => { _host = new DreamHost(config); }); Console.WriteLine("-------------------- initialized {0} secs", time.TotalSeconds); // execute scripts time = DebugUtil.Stopwatch(() => { _host.RunScripts(config, null); }); Console.WriteLine("-------------------- ready {0} secs", time.TotalSeconds); // for UNIX systems, let's also listen to SIGTERM if (SysUtil.IsUnix) { new Thread(SigTermHandler) { IsBackground = true }.Start(); } // check if we can use the console if (useTty) { int debuglevel = 0; // wait for user input then exit while (_host.IsRunning) { Thread.Sleep(250); #region Interactive Key Handler if (Console.KeyAvailable) { ConsoleKeyInfo key = Console.ReadKey(true); switch (key.Key) { case ConsoleKey.Q: case ConsoleKey.Escape: case ConsoleKey.Spacebar: Console.WriteLine("Shutting down"); return(0); case ConsoleKey.G: Console.WriteLine("Full garbage collection pass"); System.GC.Collect(); break; case ConsoleKey.C: Console.Clear(); break; case ConsoleKey.D: switch (++debuglevel) { default: debuglevel = 0; Threading.RendezVousEvent.CaptureTaskState = false; DebugUtil.CaptureStackTrace = false; Console.WriteLine("Debug capture: none"); break; case 1: Threading.RendezVousEvent.CaptureTaskState = true; DebugUtil.CaptureStackTrace = false; Console.WriteLine("Debug capture: task-state only"); break; case 2: Threading.RendezVousEvent.CaptureTaskState = true; DebugUtil.CaptureStackTrace = true; Console.WriteLine("Debug capture: task-state and stack-trace"); break; } break; case ConsoleKey.I: { Console.WriteLine("--- System Information ---"); // show memory Console.WriteLine("Allocated memory: {0}", GC.GetTotalMemory(false)); // show threads int workerThreads; int completionThreads; int dispatcherThreads; int backgroundThreads; AsyncUtil.GetAvailableThreads(out workerThreads, out completionThreads, out dispatcherThreads, out backgroundThreads); int maxWorkerThreads; int maxCompletionThreads; int maxDispatcherThreads; int maxBackgroundThreads; AsyncUtil.GetMaxThreads(out maxWorkerThreads, out maxCompletionThreads, out maxDispatcherThreads, out maxBackgroundThreads); Console.WriteLine("Thread-pool worker threads available: {0} (max: {1})", workerThreads, maxWorkerThreads); Console.WriteLine("Thread-pool completion threads available: {0} (max: {1})", completionThreads, maxCompletionThreads); Console.WriteLine("Dispatcher threads available: {0} (max: {1})", dispatcherThreads, maxDispatcherThreads); Console.WriteLine("Thread-pool background worker threads available: {0} (max: {1})", backgroundThreads, maxBackgroundThreads); // show pending/waiting timers var taskTimerStats = Tasking.TaskTimerFactory.GetStatistics(); Console.WriteLine("Pending timer objects: {0}", taskTimerStats.PendingTimers); Console.WriteLine("Queued timer objects: {0}", taskTimerStats.QueuedTimers); Console.WriteLine("Timer retries: {0}", taskTimerStats.Retries); // show activities var activities = _host.ActivityMessages; Console.WriteLine("Host activities: {0}", activities.Length); foreach (var activity in activities) { Console.WriteLine("* {0}: {1}", activity.Created.ToString(XDoc.RFC_DATETIME_FORMAT), activity.Description); } // show pending tasks Console.WriteLine("Pending rendez-vous events: {0}", Threading.RendezVousEvent.PendingCounter); Console.WriteLine("Pending results: {0}", AResult.PendingCounter); lock (Threading.RendezVousEvent.Pending) { int count = 0; foreach (var entry in Threading.RendezVousEvent.Pending.Values) { ++count; if (entry.Key != null) { var context = entry.Key.GetState <DreamContext>(); if (context != null) { Console.WriteLine("--- DreamContext for pending rendez-vous event #{0} ---", count); Console.WriteLine(context.Uri.ToString(false)); } } Console.WriteLine(); if (entry.Value != null) { Console.WriteLine("--- Stack trace for pending rendez-vous event #{0} ---", count); Console.WriteLine(entry.Value.ToString()); } } } Console.WriteLine("--------------------------"); } break; case ConsoleKey.H: Console.WriteLine("Help:"); Console.WriteLine(" Q - quit application"); Console.WriteLine(" ESC - quit application"); Console.WriteLine(" SPACE - quit application"); Console.WriteLine(" G - full garbage collection"); Console.WriteLine(" C - clear screen"); Console.WriteLine(" D - set debug capture level"); Console.WriteLine(" I - show system information (memory, threads, pending tasks)"); Console.WriteLine(" H - this help text"); break; } } #endregion } } else { _host.WaitUntilShutdown(); } } finally { Console.WriteLine("-------------------- shutting down"); TaskTimerFactory.ShutdownAll(); if (_host != null) { _host.Dispose(); } } return(0); }
private DekiScriptInvocationTargetDescriptor ConvertFunction(XDoc function) { string functionName = function["name"].AsText; if (string.IsNullOrEmpty(functionName)) { _log.WarnFormat("function without name in script {0}; skipping function definition", _manifestUri); return(null); } // determine function access level DreamAccess access; switch (function["access"].AsText ?? "public") { case "private": access = DreamAccess.Private; break; case "internal": access = DreamAccess.Internal; break; case "public": access = DreamAccess.Public; break; default: _log.WarnFormat("unrecognized access level '{0}' for function {1} in script {2}; defaulting to public", function["access"].AsText, functionName, _manifestUri); access = DreamAccess.Public; break; } // convert parameters List <DekiScriptParameter> parameters = new List <DekiScriptParameter>(); foreach (XDoc param in function["param"]) { string paramName = param["@name"].AsText; // determine if parameter has a default value string paramDefault = param["@default"].AsText; DekiScriptLiteral paramDefaultExpression = DekiScriptNil.Value; bool paramOptional = false; if (paramDefault != null) { paramOptional = true; try { paramDefaultExpression = ScriptRuntime.Evaluate(DekiScriptParser.Parse(Location.Start, paramDefault), DekiScriptEvalMode.Evaluate, ScriptRuntime.CreateEnv()); } catch (Exception e) { _log.ErrorExceptionFormat(e, "invalid default value for parameter {0} in function {1} in script {2}; skipping function definition", paramName, functionName, _manifestUri); return(null); } } else { paramOptional = (param["@optional"].AsText == "true"); } // determine parameter type string paramType = param["@type"].AsText ?? "any"; DekiScriptType paramScriptType; if (!SysUtil.TryParseEnum(paramType, out paramScriptType)) { _log.WarnFormat("unrecognized param type '{0}' for parameter {1} in function {2} in script {3}; defaulting to any", paramType, paramName, functionName, _manifestUri); paramScriptType = DekiScriptType.ANY; } // add parameter parameters.Add(new DekiScriptParameter(paramName, paramScriptType, paramOptional, param.Contents, typeof(object), paramDefaultExpression)); } var parameterArray = parameters.ToArray(); // determine function body XDoc ret = function["return"]; string src = ret["@src"].AsText; string type = ret["@type"].AsText; DekiScriptExpression expression; if (!string.IsNullOrEmpty(src)) { // 'src' attribute is set, load the script from it XDoc script; if (_manifestUri != null) { // check if uri is relative XUri scriptUri = XUri.TryParse(src) ?? _manifestUri.AtPath(src); script = Plug.New(scriptUri).Get().ToDocument(); } else { // check if filename is relative if (!Path.IsPathRooted(src)) { src = Path.Combine(_resourcesPath, src); } script = XDocFactory.LoadFrom(src, MimeType.XML); } expression = DekiScriptParser.Parse(script); type = type ?? "xml"; } else if (!ret["html"].IsEmpty) { // <return> element contains a <html> node; parse it as a script expression = DekiScriptParser.Parse(ret["html"]); type = type ?? "xml"; } else if (!ret.IsEmpty) { // <return> element contains something else; use the text contents as deki-script expression var location = new Location(string.Format("/function[name={0}]/return", functionName)); expression = DekiScriptParser.Parse(location, function["return"].AsText ?? string.Empty); expression = DekiScriptExpression.ReturnScope(location, expression); type = type ?? "any"; } else { _log.WarnFormat("function {0} has no body in script {1}; skipping function definition", functionName, _manifestUri); return(null); } // determine return type DekiScriptType returnScriptType; if (!SysUtil.TryParseEnum(type, out returnScriptType)) { _log.WarnFormat("unrecognized return type '{0}' for function {1} in script {2}; defaulting to any", type, functionName, _manifestUri); returnScriptType = DekiScriptType.ANY; } // create function descriptor var target = new DekiScriptScriptFunctionInvocationTarget(access, parameterArray, expression, _commonEnv, returnScriptType); string description = function["description"].AsText; string transform = function["@transform"].AsText; return(new DekiScriptInvocationTargetDescriptor(access, false, false, functionName, parameterArray, returnScriptType, description, transform, target)); }