コード例 #1
0
        private DekiScriptLiteral InvokeHelper(DekiScriptRuntime runtime, DekiScriptList args)
        {
            // convert passed in arguments
            object[] arguments = new object[Parameters.Length];
            int      i         = 0;

            try {
                for (; i < Parameters.Length; ++i)
                {
                    var value = args[i].NativeValue;

                    // check if we need to convert the value
                    if ((value != null) && (Parameters[i].NativeType != typeof(object)))
                    {
                        // check for the special case where we cast from XML to STR
                        if ((value is XDoc) && (Parameters[i].NativeType == typeof(string)))
                        {
                            XDoc xml = (XDoc)value;
                            if (xml.HasName("html"))
                            {
                                value = xml["body[not(@target)]"].Contents;
                            }
                            else
                            {
                                value = xml.ToString();
                            }
                        }
                        else
                        {
                            // rely on the default type conversion rules
                            value = SysUtil.ChangeType(value, Parameters[i].NativeType);
                        }
                    }
                    arguments[i] = value;
                }
            } catch {
                throw new ArgumentException(string.Format("could not convert parameter '{0}' (index {1}) from {2} to {3}", Parameters[i].Name, i, args[i].ScriptTypeName, DekiScriptLiteral.AsScriptTypeName(Parameters[i].ScriptType)));
            }

            // invoke method
            var result = _invoke(runtime, arguments);

            // check if result is a URI
            if (result is XUri)
            {
                // normalize URI if possible
                DreamContext context = DreamContext.CurrentOrNull;
                if (context != null)
                {
                    result = context.AsPublicUri((XUri)result);
                }
            }
            var literal = DekiScriptLiteral.FromNativeValue(result);

            try {
                return(literal.Convert(ReturnType));
            } catch (DekiScriptInvalidCastException) {
                throw new DekiScriptInvalidReturnCastException(Location.None, literal.ScriptType, ReturnType);
            }
        }
コード例 #2
0
        internal static string AsPublicUiUri(Title title, bool forceUseIndexPhp)
        {
            DreamContext context = DreamContext.Current;
            string       baseUri = context.GetParam("baseuri", null);

            if (baseUri != null)
            {
                return(baseUri + title.AsUiUriPath(true).Substring(Title.INDEX_PHP_TITLE.Length));
            }
            else
            {
                DekiContext deki   = DekiContext.Current;
                XUri        global = context.AsPublicUri(deki.UiUri.Uri.WithoutPathQueryFragment().WithoutCredentials());
                return(global.SchemeHostPort + "/" + title.AsUiUriPath(forceUseIndexPhp));
            }
        }
コード例 #3
0
ファイル: servicebase.cs プロジェクト: danice/DReAM
        public virtual Yield GetServiceInfo(DreamContext context, DreamMessage request, Result<DreamMessage> response)
        {
            XDoc blueprint = Blueprint;
            string title = blueprint["name"].AsText ?? "Service Blueprint";
            XDoc result = new XDoc("html").Attr("xmlns", "http://www.w3.org/1999/xhtml")
                .Start("head")
                    .Elem("title", title)
                    .Start("meta").Attr("http-equiv", "content-type").Attr("content", "text/html;charset=utf-8").End()
                    .Start("meta").Attr("http-equiv", "Content-Style-Type").Attr("content", "text/css").End()
                .End();
            if(blueprint.IsEmpty) {
                result.Elem("body", "Missing service blueprint");
            } else {
                result.Start("body")
                        .Elem("h1", title)
                        .Start("p")
                            .Value(blueprint["copyright"].Contents)
                            .Value(" ")
                            .Start("a").Attr("href", blueprint["info"].Contents).Value("(more)").End()
                            .Value(" ")
                            .Start("a").Attr("href", Self.Uri.At("@blueprint").Path).Value("(blueprint)").End()
                        .End();

                // show configuration information
                XDoc config = blueprint["configuration"];
                if(!config.IsEmpty) {
                    result.Elem("h2", "Configuration");
                    result.Start("ul");
                    foreach(XDoc entry in config["entry"]) {
                        result.Start("li");
                        if(entry["valuetype"].Contents != string.Empty) {
                            result.Value(string.Format("{0} = {1} : {2}", entry["name"].Contents, entry["valuetype"].Contents, entry["description"].Contents));
                        } else {
                            result.Value(string.Format("{0} : {1}", entry["name"].Contents, entry["description"].Contents));
                        }
                        result.End();
                    }
                    result.End();
                }

                // sort features by signature then verb
                blueprint["features"].Sort(delegate(XDoc first, XDoc second) {
                    string[] firstPattern = first["pattern"].Contents.Split(new[] { ':' }, 2);
                    string[] secondPattern = second["pattern"].Contents.Split(new[] { ':' }, 2);
                    int cmp = firstPattern[1].CompareInvariantIgnoreCase(secondPattern[1]);
                    if(cmp != 0) {
                        return cmp;
                    }
                    return firstPattern[0].CompareInvariant(secondPattern[0]);
                });

                // display features
                XDoc features = blueprint["features/feature"];
                if(!features.IsEmpty) {
                    result.Elem("h2", "Features");
                    List<string> modifiers = new List<string>();
                    foreach(XDoc feature in features) {
                        modifiers.Clear();

                        // add modifiers
                        string modifier = feature["access"].AsText;
                        if(modifier != null) {
                            modifiers.Add(modifier);
                        }
                        modifier = feature["obsolete"].AsText;
                        if(modifier != null) {
                            modifiers.Add("OBSOLETE => " + modifier);
                        }
                        if(modifiers.Count > 0) {
                            modifier = " (" + string.Join(", ", modifiers.ToArray()) + ")";
                        } else {
                            modifier = string.Empty;
                        }

                        // check if feature has GET verb and no path parameters
                        string pattern = feature["pattern"].Contents;
                        if(pattern.StartsWithInvariantIgnoreCase(Verb.GET + ":") && (pattern.IndexOfAny(new[] { '{', '*', '?' }) == -1)) {
                            string[] parts = pattern.Split(new[] { ':' }, 2);
                            result.Start("h3")
                                .Start("a").Attr("href", context.AsPublicUri(Self.Uri.AtPath(parts[1])))
                                    .Value(feature["pattern"].Contents)
                                .End()
                                .Value(modifier)
                            .End();
                        } else {
                            result.Elem("h3", feature["pattern"].Contents + modifier);
                        }
                        result.Start("p")
                                .Value(feature["description"].Contents)
                                .Value(" ")
                                .Start("a").Attr("href", feature["info"].Contents).Value("(more)").End();
                        XDoc paramlist = feature["param"];
                        if(!paramlist.IsEmpty) {
                            result.Start("ul");
                            foreach(XDoc param in paramlist) {
                                result.Start("li");
                                if(param["valuetype"].Contents != string.Empty) {
                                    result.Value(string.Format("{0} = {1} : {2}", param["name"].Contents, param["valuetype"].Contents, param["description"].Contents));
                                } else {
                                    result.Value(string.Format("{0} : {1}", param["name"].Contents, param["description"].Contents));
                                }
                                result.End();
                            }
                            result.End();
                        }
                        result.End();
                    }
                }
            }
            response.Return(DreamMessage.Ok(MimeType.HTML, result.ToString()));
            yield break;
        }
コード例 #4
0
ファイル: DreamHostService.cs プロジェクト: maximmass/DReAM
 internal Yield GetServices(DreamContext context, DreamMessage request, Result<DreamMessage> response)
 {
     XDoc result = new XDoc("services");
     result.WithXslTransform(context.AsPublicUri(context.Env.Self).At("resources", "services.xslt").Path);
     lock(_services) {
         result.Attr("count", _services.Count);
         foreach(KeyValuePair<string, ServiceEntry> entry in _services) {
             result.Start("service");
             result.Elem("path", entry.Key);
             result.Elem("uri", entry.Value.Uri);
             if(entry.Value.Owner != null) {
                 result.Elem("uri.owner", entry.Value.Owner);
             }
             if(entry.Value.SID != null) {
                 result.Elem("sid", entry.Value.SID);
             }
             result.Elem("type", entry.Value.Service.GetType().FullName);
             result.End();
         }
     }
     response.Return(DreamMessage.Ok(result));
     yield break;
 }
コード例 #5
0
ファイル: DreamHostService.cs プロジェクト: maximmass/DReAM
        private Yield GetStatus(DreamContext context, DreamMessage request, Result<DreamMessage> response)
        {
            DateTime now = DateTime.UtcNow;
            XDoc result = new XDoc("status");
            result.WithXslTransform(context.AsPublicUri(context.Env.Self).At("resources", "status.xslt").Path);
            XUri self = Self.Uri.With("apikey", context.GetParam("apikey", null));

            // host information
            double age = Math.Max((now - _created).TotalSeconds, 1);
            result.Start("host").Attr("created", _created).Attr("age", age).Attr("requests", _requestCounter).Attr("rate", _requestCounter / age);
            result.Elem("uri.local", _localMachineUri.ToString());
            result.Elem("uri.public", _publicUri);

            // host/aliases
            result.Start("aliases").Attr("count", _aliases.Count).Attr("href", self.At("status", "aliases")).End();

            // connections
            result.Start("connections").Attr("count", _connectionCounter).Attr("limit", _connectionLimit).End();

            // activities
            lock(_activities) {
                result.Start("activities").Attr("count", _activities.Count).Attr("href", self.At("status", "activities"));
                foreach(Tuplet<DateTime, string> description in _activities.Values) {
                    result.Start("description").Attr("created", description.Item1).Attr("age", (now - description.Item1).TotalSeconds).Value(description.Item2).End();
                }
                result.End();
            }

            // infos
            lock(_infos) {
                result.Start("infos").Attr("count", _infos.Count);
                foreach(KeyValuePair<string, Tuplet<int, string>> entry in _infos) {
                    result.Start("info").Attr("source", entry.Key).Attr("hits", entry.Value.Item1).Attr("rate", entry.Value.Item1 / age).Value(entry.Value.Item2).End();
                }
                result.End();
            }

            // host/services information
            result.Start("services").Attr("count", _services.Count).Attr("href", self.At("services")).End();

            // host/features
            result.Start("features").Attr("href", self.At("status", "features")).End();

            // host/cache
            long size = 0;
            int count = 0;
            lock(_responseCache) {
                foreach(Dictionary<object, DreamMessage> cache in _responseCache.Values) {
                    count += cache.Count;
                    foreach(DreamMessage message in cache.Values) {
                        size += message.ToBytes().LongLength;
                    }
                }
            }
            result.Start("cache").Attr("count", count).Attr("size", size).Attr("hits", _responseCacheHits).Attr("misses", _responseCacheMisses).End();

            // end host information
            result.End();

            // system information
            result.Start("system");

            // system/memory information
            result.Elem("memory.used", GC.GetTotalMemory(false));

            // system/thread information
            int workerThreads;
            int completionThreads;
            int dispatcherThreads;
            Async.GetAvailableThreads(out workerThreads, out completionThreads, out dispatcherThreads);
            int maxWorkerThreads;
            int maxCompletionThreads;
            int maxDispatcherThreads;
            Async.GetMaxThreads(out maxWorkerThreads, out maxCompletionThreads, out maxDispatcherThreads);
            result.Elem("workerthreads.max", maxWorkerThreads);
            result.Elem("workerthreads.used", maxWorkerThreads - workerThreads);
            result.Elem("completionthreads.max", maxCompletionThreads);
            result.Elem("completionthreads.used", maxCompletionThreads - completionThreads);
            result.Elem("dispatcherthreads.max", maxDispatcherThreads);
            result.Elem("dispatcherthreads.used", maxDispatcherThreads - dispatcherThreads);

            // timer information
            var taskTimerStats = TaskTimerFactory.GetStatistics();
            result.Start("timers.queued").Attr("href", self.At("status", "timers")).Value(taskTimerStats.QueuedTimers).End();
            result.Start("timers.pending").Attr("href", self.At("status", "timers")).Value(taskTimerStats.PendingTimers).End();
            result.Elem("timers.counter", taskTimerStats.Counter);
            result.Elem("timers.last", taskTimerStats.Last);

            // rendez-vous events
            result.Start("async").Attr("count", RendezVousEvent.PendingCounter + AResult.PendingCounter);
            lock(RendezVousEvent.Pending) {
                foreach(var entry in RendezVousEvent.Pending.Values) {
                    result.Start("details");
                    if(entry.Key != null) {
                        var dc = entry.Key.GetState<DreamContext>();
                        if(dc != null) {
                            result.Elem("verb", dc.Verb);
                            result.Elem("uri", dc.Uri);
                        }
                    }
                    if(entry.Value != null) {
                        result.Start("stacktrace");
                        XException.AddStackTrace(result, entry.Value.ToString());
                        result.End();
                    }
                    result.End();
                }
            }
            result.End();

            // xml name table stats
            LockFreeXmlNameTable table = SysUtil.NameTable as LockFreeXmlNameTable;
            if(table != null) {
                int capacity;
                int entries;
                long bytes;
                int[] distribution;
                double expected;
                table.GetStats(out capacity, out entries, out bytes, out distribution, out expected);
                result.Start("xmlnametable").Attr("href", self.At("status", "xmlnametable"));
                result.Elem("capacity", capacity.ToString("#,##0"));
                result.Elem("bytes", bytes.ToString("#,##0"));
                result.Elem("entries", entries.ToString("#,##0"));
                result.Elem("expected-comparisons", expected);
                result.Elem("distribution", "[" + string.Join("; ", Array.ConvertAll(distribution, i => i.ToString("#,##0"))) + "]");
                result.End();
            }

            // replicate app settings
            result.Start("app-settings");
            foreach(var key in System.Configuration.ConfigurationManager.AppSettings.AllKeys) {
                result.Start("entry").Attr("key", key).Attr("value", System.Configuration.ConfigurationManager.AppSettings[key]).End();
            }
            result.End();

            // end of </system>
            result.End();

            response.Return(DreamMessage.Ok(result));
            yield break;
        }
コード例 #6
0
        private void LoadScript()
        {
            _manifestPath  = null;
            _resourcesPath = null;
            _manifestUri   = null;
            _resourcesUri  = null;
            _manifest      = null;

            // read manifest
            _manifestPath = Config["manifest"].AsText;
            if (string.IsNullOrEmpty(_manifestPath))
            {
                throw new ArgumentNullException("manifest");
            }
            _manifestUri = XUri.TryParse(_manifestPath);
            if (_manifestUri != null)
            {
                _manifestPath = null;
                _manifest     = Plug.New(_manifestUri).Get().ToDocument();
                _resourcesUri = Config["resources"].AsUri ?? _manifestUri.WithoutLastSegment();
            }
            else
            {
                _manifest      = XDocFactory.LoadFrom(_manifestPath, MimeType.XML);
                _resourcesPath = Config["resources"].AsText ?? Path.GetDirectoryName(_manifestPath);
            }
            if (!_manifest.HasName("extension"))
            {
                throw new ArgumentException("invalid extension manifest");
            }

            // initilize runtime
            _runtime = new DekiScriptRuntime();

            // read manifest settings
            _title       = _manifest["title"].AsText;
            _label       = _manifest["label"].AsText;
            _copyright   = _manifest["copyright"].AsText;
            _description = _manifest["description"].AsText;
            _help        = _manifest["uri.help"].AsText;
            _logo        = _manifest["uri.logo"].AsText;
            _namespace   = _manifest["namespace"].AsText;

            // initialize evaluation environment
            _commonEnv = _runtime.CreateEnv();

            // read functions
            _functions = new Dictionary <XUri, DekiScriptInvocationTargetDescriptor>();
            foreach (var function in _manifest["function"])
            {
                var descriptor = ConvertFunction(function);
                if (descriptor != null)
                {
                    var uri = Self.At(descriptor.SystemName);
                    DekiScriptInvocationTargetDescriptor old;
                    if (_functions.TryGetValue(uri, out old))
                    {
                        _log.WarnFormat("duplicate function name {0} in script {1}", descriptor.Name, _manifestUri);
                    }
                    _functions[uri] = descriptor;
                }
            }
            _runtime.RegisterExtensionFunctions(_functions);

            // add extension functions to env
            foreach (var function in _functions)
            {
                _commonEnv.Vars.AddNativeValueAt(function.Value.Name.ToLowerInvariant(), function.Key);
            }

            // add configuration settings
            DreamContext  context      = DreamContext.Current;
            DekiScriptMap scriptConfig = new DekiScriptMap();

            foreach (KeyValuePair <string, string> entry in Config.ToKeyValuePairs())
            {
                XUri local;
                if (XUri.TryParse(entry.Value, out local))
                {
                    local = context.AsPublicUri(local);
                    scriptConfig.AddAt(entry.Key.Split('/'), DekiScriptExpression.Constant(local.ToString()));
                }
                else
                {
                    scriptConfig.AddAt(entry.Key.Split('/'), DekiScriptExpression.Constant(entry.Value));
                }
            }
            _commonEnv.Vars.Add("config", scriptConfig);
        }