Example #1
0
        protected override Yield Start(XDoc config, IContainer container, Result result)
        {
            yield return(Coroutine.Invoke(base.Start, config, new Result()));

            // ensure imagemagick is setup correctly.
            if (string.IsNullOrEmpty(ImageMagickConvertPath))
            {
                throw new NotImplementedException("Please set 'imagemagick-convert-path' in config to path of ImageMagick's 'convert'");
            }
            if (!File.Exists(ImageMagickIdentifyPath))
            {
                throw new FileNotFoundException("Cannot find ImagicMagick 'identify' binary: ", ImageMagickIdentifyPath);
            }
            if (string.IsNullOrEmpty(ImageMagickIdentifyPath))
            {
                throw new NotImplementedException("Please set 'imagemagick-identify-path' in config to path of ImageMagick's 'identify'");
            }
            if (!File.Exists(ImageMagickConvertPath))
            {
                throw new FileNotFoundException("Cannot find ImagicMagick 'convert' binary: ", ImageMagickConvertPath);
            }

            // check for 'apikey'
            _apikey = Config["api-key"].AsText ?? Config["apikey"].AsText;
            if (string.IsNullOrEmpty(_apikey))
            {
                throw new ArgumentNullException("apikey", "The global apikey is not defined. Please ensure that you have a global <apikey> defined in the MindTouch Core service settings xml file.");
            }
            InitializeContainer(container);

            // intialize instance manager
            _instanceManager = InstanceManager.New(this, this.TimerFactory);

            // setup resource manager
            lock (SyncRoot) {
                if (ResourceManager == null)
                {
                    ResourceManager = new PlainTextResourceManager(ResourcesPath);
                    ScreenFont      = new DekiFont(Plug.New("resource://mindtouch.deki/MindTouch.Deki.Resources.Arial.mtdf").Get().AsBytes());
                }
            }

            // initialize scripting engine
            XDoc scripting = Config["scripting"];

            DekiScriptLibrary.InsertTextLimit = scripting["max-web-response-length"].AsLong ?? DekiScriptLibrary.InsertTextLimit;
            DekiScriptLibrary.MinCacheTtl     = scripting["min-web-cache-ttl"].AsDouble ?? DekiScriptLibrary.MinCacheTtl;

            // set up deki pub sub (by default we override uri.publish with our own service, unless @must-use=true is specified)
            if (!(Config["uri.publish/@must-use"].AsBool ?? false))
            {
                Result <Plug> pubsubResult;
                XDoc          pubsubConfig = new XDoc("config")
                                             .Elem("uri.deki", Self.Uri.With("apikey", MasterApiKey))
                                             .Start("downstream")
                                             .Elem("uri", PubSub.At("publish").Uri.WithoutLastSegment().At("subscribers"))
                                             .End()
                                             .Start("components")
                                             .Start("component")
                                             .Attr("type", typeof(IPubSubDispatcher).AssemblyQualifiedName)
                                             .Attr("implementation", typeof(DekiDispatcher).AssemblyQualifiedName)
                                             .End()
                                             .End()
                                             .Elem("authtoken", MasterApiKey);
                foreach (var cookie in Cookies.Fetch(PubSub.Uri))
                {
                    pubsubConfig.Add(cookie.AsSetCookieDocument);
                }
                var messageQueuePath = config["publish/queue-path"].AsText;
                if (!string.IsNullOrEmpty(messageQueuePath))
                {
                    pubsubConfig.Elem("queue-path", messageQueuePath);
                }
                yield return(pubsubResult = CreateService(
                                 "pubsub",
                                 "sid://mindtouch.com/dream/2008/10/pubsub",
                                 pubsubConfig,
                                 new Result <Plug>()));

                PubSub = pubsubResult.Value;
            }

            // set up package updater service (unless it was passed in)
            XUri packageUpdater;

            if (config["packageupdater/@uri"].IsEmpty)
            {
                var packageConfig = config["packageupdater"];
                packageConfig = packageConfig.IsEmpty ? new XDoc("config") : packageConfig.Clone();
                if (packageConfig["package-path"].IsEmpty)
                {
                    packageConfig.Elem("package-path", Path.Combine(Path.Combine(config["deki-path"].AsText, "packages"), "default"));
                }
                yield return(CreateService(
                                 "packageupdater",
                                 "sid://mindtouch.com/2010/04/packageupdater",
                                 new XDoc("config")
                                 .Elem("apikey", MasterApiKey)
                                 .AddNodes(packageConfig),
                                 new Result <Plug>()
                                 ));

                packageUpdater = Self.Uri.At("packageupdater");
            }
            else
            {
                packageUpdater = config["packageupdater/@uri"].AsUri;
            }
            _packageUpdater = Plug.New(packageUpdater);

            // set up emailer service (unless it was passed in)
            XUri mailerUri;

            if (config["uri.mailer"].IsEmpty)
            {
                yield return(CreateService(
                                 "mailer",
                                 "sid://mindtouch.com/2009/01/dream/email",
                                 new XDoc("config")
                                 .Elem("apikey", MasterApiKey)
                                 .AddAll(Config["smtp/*"]),
                                 new Result <Plug>()
                                 ));

                mailerUri = Self.Uri.At("mailer");
            }
            else
            {
                mailerUri = config["uri.mailer"].AsUri;
            }
            _mailer = Plug.New(mailerUri);

            // set up the email subscription service (unless it was passed in)
            XUri pageSubscription;

            if (config["uri.page-subscription"].IsEmpty)
            {
                XDoc pagesubserviceConfig = new XDoc("config")
                                            .Elem("uri.deki", Self.Uri)
                                            .Elem("uri.emailer", mailerUri.At("message"))
                                            .Elem("resources-path", ResourcesPath)
                                            .Elem("apikey", MasterApiKey)
                                            .Start("components")
                                            .Start("component")
                                            .Attr("scope", "factory")
                                            .Attr("type", typeof(IPageSubscriptionDataSessionFactory).AssemblyQualifiedName)
                                            .Attr("implementation", "MindTouch.Deki.Data.MySql.UserSubscription.MySqlPageSubscriptionSessionFactory, mindtouch.deki.data.mysql")
                                            .End()
                                            .End()
                                            .AddAll(Config["page-subscription/*"]);
                foreach (var cookie in Cookies.Fetch(mailerUri))
                {
                    pagesubserviceConfig.Add(cookie.AsSetCookieDocument);
                }
                yield return(CreateService(
                                 "pagesubservice",
                                 "sid://mindtouch.com/deki/2008/11/changesubscription",
                                 pagesubserviceConfig,
                                 new Result <Plug>()
                                 ));

                pageSubscription = Self.Uri.At("pagesubservice");
                config.Elem("uri.page-subscription", pageSubscription);
            }
            else
            {
                pageSubscription = config["uri.page-subscription"].AsUri;
            }
            _pageSubscription = Plug.New(pageSubscription);

            // set up package importer, if not provided
            if (Config["uri.package"].IsEmpty)
            {
                yield return(CreateService(
                                 "package",
                                 "sid://mindtouch.com/2009/07/package",
                                 new XDoc("config").Elem("uri.deki", Self.Uri),
                                 new Result <Plug>()));

                Config.Elem("uri.package", Self.Uri.At("package"));
            }

            // set up lucene
            _luceneIndex = Plug.New(Config["indexer/@src"].AsUri);
            if (_luceneIndex == null)
            {
                // create the indexer service
                XDoc luceneIndexConfig = new XDoc("config")
                                         .AddNodes(Config["indexer"])
                                         .Start("apikey").Attr("hidden", true).Value(MasterApiKey).End();
                if (luceneIndexConfig["path.store"].IsEmpty)
                {
                    luceneIndexConfig.Elem("path.store", Path.Combine(Path.Combine(config["deki-path"].AsText, "luceneindex"), "$1"));
                }
                yield return(CreateService("luceneindex", SID_FOR_LUCENE_INDEX, luceneIndexConfig, new Result <Plug>()).Set(v => _luceneIndex = v));

                _isLocalLuceneService = true;
            }
            else
            {
                // push our host's pubsub service to lucene, to keep it up to date on our changes
                var pubsub = new XDoc("pubsub").Attr("href", PubSub);
                foreach (var cookie in PubSub.CookieJar.Fetch(PubSub.Uri))
                {
                    pubsub.Add(cookie.AsSetCookieDocument);
                }
                yield return(_luceneIndex.At("subscriptions").PostAsync(pubsub));
            }

            // configure indexing whitelist
            _indexNamespaceWhitelist = new[] { NS.MAIN, NS.PROJECT, NS.USER, NS.TEMPLATE, NS.HELP, NS.MAIN_TALK, NS.PROJECT_TALK, NS.USER_TALK, NS.TEMPLATE_TALK, NS.HELP_TALK, NS.SPECIAL, NS.SPECIAL_TALK };
            if (!string.IsNullOrEmpty(Config["indexer/namespace-whitelist"].AsText))
            {
                List <NS> customWhitelist = new List <NS>();
                foreach (string item in Config["indexer/namespace-whitelist"].AsText.Split(','))
                {
                    NS ns;
                    if (SysUtil.TryParseEnum(item, out ns))
                    {
                        customWhitelist.Add(ns);
                    }
                }
                _indexNamespaceWhitelist = customWhitelist.ToArray();
            }

            if (!Config["wikis/globalconfig/cache/varnish"].IsEmpty)
            {
                // create the varnish service

                // TODO (petee): getting the varnish config from wikis/globalconfig/cache is a hack
                // The frontend needs to get the max-age to send out the cache headers but we currently have no way
                // of getting the DekiWikiService config so we'll hack it so it comes back in GET:site/settings.
                XDoc varnishConfig = new XDoc("config")
                                     .Elem("uri.deki", Self.Uri.With("apikey", MasterApiKey))
                                     .Elem("uri.varnish", Config["wikis/globalconfig/cache/varnish"].AsUri)
                                     .Elem("varnish-purge-delay", Config["wikis/globalconfig/cache/varnish-purge-delay"].AsInt ?? 10)
                                     .Elem("varnish-max-age", Config["wikis/globalconfig/cache/varnish-max-age"].AsInt ?? 300)
                                     .Start("apikey").Attr("hidden", true).Value(MasterApiKey).End();
                yield return(CreateService("varnish", SID_FOR_VARNISH_SERVICE, varnishConfig, new Result <Plug>()));
            }
            _isInitialized = true;
            result.Return();
        }