internal ILicenseManager CreateCurrentLicenseManager()
        {
            LicenseStateTransitionCallback callback = (previousLicense, newLicense) => {
                var init = false;
                _sessionFactory.Initialize(Config ?? _deki.Config, newLicense.LicenseDoc, new DekiInstanceSettings());
                if (previousLicense.LicenseState == LicenseStateType.INACTIVE && (newLicense.LicenseState == LicenseStateType.COMMUNITY || newLicense.LicenseState == LicenseStateType.COMMERCIAL || newLicense.LicenseState == LicenseStateType.TRIAL))
                {
                    // this is used to import packages that should only be imported into a fresh instance, being activated for the first time
                    init = true;
                }
                _log.DebugFormat("[{0}] executing license transition from '{1}' to '{2}' with init={3}", Id, previousLicense.LicenseState, newLicense.LicenseState, init);
                ServiceBL.RestartServices();
                EventSink.LicenseUpdated(previousLicense.LicenseState, newLicense.LicenseState, DekiContext.Current.Now);
                _deki.PackageUpdater.At("update").Post(
                    new XDoc("update")
                    .Attr("wikiid", Id)
                    .Attr("init", init)
                    .Elem("uri", _deki.Self),
                    new Result <DreamMessage>());
            };
            var container = DreamContext.Current.Container;
            var licenseBL = container.Resolve <ILicenseBL>();
            var seatingBL = container.Resolve <ISeatingBL>();
            var userBL    = container.Resolve <IUserBL>();
            var settings  = container.Resolve <IInstanceSettings>();

            return(new LicenseManager(_licenseController, userBL, _licenseData, licenseBL, settings, seatingBL, callback));
        }
Beispiel #2
0
 //--- Methods ---
 public void Initialize(XDoc config, XDoc license, IInstanceSettings instanceSettings)
 {
     //Initialize the child session factory
     _nextFactory.Initialize(config, license, instanceSettings);
 }
        /// <summary>
        /// Calls methods to perform initial init of a wiki instance including db updates, etc
        /// </summary>
        public void Startup(DekiContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            if (_status != DekiInstanceStatus.CREATED)
            {
                throw new InvalidOperationException("bad state");
            }
            _status = DekiInstanceStatus.INITIALIZING;

            // run startup code
            try {
                // have to initialize the event sink first since because license checking might trigger a license transition event
                _eventSink = new DekiChangeSink(Id, DekiContext.Current.ApiUri, DekiContext.Current.Deki.PubSub.At("publish").WithCookieJar(DekiContext.Current.Deki.Cookies));

                // create the IDekiDataSessionFactory for this instance
                Type typeMySql   = Type.GetType("MindTouch.Deki.Data.MySql.MySqlDekiDataSessionFactory, mindtouch.deki.data.mysql", true);
                Type typeCaching = null;
                try {
                    typeCaching = Type.GetType("MindTouch.Deki.Data.Caching.CachingDekiDataSessionFactory, mindtouch.data.caching", false);
                } catch (Exception x) {
                    Log.Warn("The caching library was found but could not be loaded. Check that its version matches the version of your MindTouch API", x);
                }

                // FUN FACT: DekiInstanceSettings is a proxy for the static calls in ConfigBL, which expects to access DbUtils.CurrentSession,
                // which has to be initialized by the session factory.. Yes, the very session factory that takes DekiInstanceSettings as part
                // of its initialization call. I call it the M.C.Escher Design Pattern.
                var sessionFactory = (IDekiDataSessionFactory)typeMySql.GetConstructor(Type.EmptyTypes).Invoke(null);
                sessionFactory = new LoggingDekiDataSessionFactory(sessionFactory);
                sessionFactory = new DekiDataSessionProfilerFactory(sessionFactory);
                if (typeCaching != null)
                {
                    sessionFactory = (IDekiDataSessionFactory)typeCaching.GetConstructor(new[] { typeof(IDekiDataSessionFactory) }).Invoke(new object[] { sessionFactory });
                }
                _sessionFactory = sessionFactory;
                _sessionFactory.Initialize(Config ?? _deki.Config, _licenseController.LicenseDoc, new DekiInstanceSettings());
                var state = context.LicenseManager.LicenseState;
                if (state == LicenseStateType.UNDEFINED)
                {
                    throw new MindTouchInvalidLicenseStateException();
                }

                // set deki license token
                _token = context.LicenseManager.LicenseDocument["licensee/deki"].AsText;
                if (string.IsNullOrEmpty(_token))
                {
                    // compute deki license token
                    var    tokenKey = _apiKey ?? _deki.MasterApiKey;
                    ulong  folded_productkey_md5 = 0;
                    byte[] md5_bytes             = StringUtil.ComputeHash(tokenKey, Encoding.UTF8);
                    for (int i = 0; i < md5_bytes.Length; ++i)
                    {
                        folded_productkey_md5 ^= (ulong)md5_bytes[i] << (i & 7) * 8;
                    }
                    _token = folded_productkey_md5.ToString("X");
                }

                // check if a storage config section was provided (default storage is filesystem provider)
                XDoc storageConfig;
                switch (ConfigBL.GetInstanceSettingsValue("storage/@type", ConfigBL.GetInstanceSettingsValue("storage/type", "default")))
                {
                case "default":
                    string defaultAttachPath = Path.Combine(_deki.DekiPath, "attachments");
                    storageConfig = new XDoc("config")
                                    .Elem("path", defaultAttachPath)
                                    .Elem("cache-path", Path.Combine(defaultAttachPath, ".cache"));
                    _storage = new FSStorage(storageConfig);
                    break;

                case "fs":
                    string fsPath = ConfigBL.GetInstanceSettingsValue("storage/fs/path", null);

                    //Replace a $1 with the wiki name
                    fsPath        = string.Format(PhpUtil.ConvertToFormatString(fsPath ?? string.Empty), Id);
                    storageConfig = new XDoc("config")
                                    .Elem("path", fsPath)
                                    .Elem("cache-path", ConfigBL.GetInstanceSettingsValue("storage/fs/cache-path", null));
                    _storage = new FSStorage(storageConfig);
                    break;

                case "s3":
                    storageConfig = new XDoc("config")
                                    .Elem("publickey", ConfigBL.GetInstanceSettingsValue("storage/s3/publickey", null))
                                    .Elem("privatekey", ConfigBL.GetInstanceSettingsValue("storage/s3/privatekey", null))
                                    .Elem("bucket", ConfigBL.GetInstanceSettingsValue("storage/s3/bucket", null))
                                    .Elem("prefix", string.Format(PhpUtil.ConvertToFormatString(ConfigBL.GetInstanceSettingsValue("storage/s3/prefix", string.Empty)), DekiContext.Current.Instance.Id))
                                    .Elem("timeout", ConfigBL.GetInstanceSettingsValue("storage/s3/timeout", null))
                                    .Elem("allowredirects", ConfigBL.GetInstanceSettingsValue("storage/s3/allowredirects", null))
                                    .Elem("redirecttimeout", ConfigBL.GetInstanceSettingsValue("storage/s3/redirecttimeout", null));
                    _storage = new S3Storage(storageConfig, _loggerRepository.Get <S3Storage>());
                    break;

                default:
                    throw new ArgumentException("Storage provider unknown or not defined (key: storage/type)", "storage/type");
                }

                HomePageId = DbUtils.CurrentSession.Pages_HomePageId;
                _eventSink.InstanceStarting(DekiContext.Current.Now);
            } catch {
                // we failed to initialize
                _status = DekiInstanceStatus.ABANDONED;
                throw;
            }

            // set state to initializing
            _status = DekiInstanceStatus.INITIALIZING;
        }
Beispiel #4
0
        /// <summary>
        /// Calls methods to perform initial init of a wiki instance including db updates, etc
        /// </summary>
        public void Startup(DekiContext context) {
            if(context == null) {
                throw new ArgumentNullException("context");
            }
            if(_status != DekiInstanceStatus.CREATED) {
                throw new InvalidOperationException("bad state");
            }
            _status = DekiInstanceStatus.INITIALIZING;

            // run startup code
            try {

                // have to initialize the event sink first since because license checking might trigger a license transition event
                _eventSink = new DekiChangeSink(Id, DekiContext.Current.ApiUri, DekiContext.Current.Deki.PubSub.At("publish").WithCookieJar(DekiContext.Current.Deki.Cookies));

                // create the IDekiDataSessionFactory for this instance
                Type typeMySql = Type.GetType("MindTouch.Deki.Data.MySql.MySqlDekiDataSessionFactory, mindtouch.deki.data.mysql", true);
                Type typeCaching = null;
                try {
                    typeCaching = Type.GetType("MindTouch.Deki.Data.Caching.CachingDekiDataSessionFactory, mindtouch.data.caching", false);
                } catch(Exception x) {
                    Log.Warn("The caching library was found but could not be loaded. Check that its version matches the version of your MindTouch API", x);
                }

                // FUN FACT: DekiInstanceSettings is a proxy for the static calls in ConfigBL, which expects to access DbUtils.CurrentSession,
                // which has to be initialized by the session factory.. Yes, the very session factory that takes DekiInstanceSettings as part
                // of its initialization call. I call it the M.C.Escher Design Pattern.
                var sessionFactory = (IDekiDataSessionFactory)typeMySql.GetConstructor(Type.EmptyTypes).Invoke(null);
                sessionFactory = new LoggingDekiDataSessionFactory(sessionFactory);
                sessionFactory = new DekiDataSessionProfilerFactory(sessionFactory);
                if(typeCaching != null) {
                    sessionFactory = (IDekiDataSessionFactory)typeCaching.GetConstructor(new[] { typeof(IDekiDataSessionFactory) }).Invoke(new object[] { sessionFactory });
                }
                _sessionFactory = sessionFactory;
                _sessionFactory.Initialize(Config ?? _deki.Config, _licenseController.LicenseDoc, new DekiInstanceSettings());
                var state = context.LicenseManager.LicenseState;
                if(state == LicenseStateType.UNDEFINED) {
                    throw new MindTouchInvalidLicenseStateException();
                }

                // set deki license token
                _token = context.LicenseManager.LicenseDocument["licensee/deki"].AsText;
                if(string.IsNullOrEmpty(_token)) {

                    // compute deki license token
                    var tokenKey = _apiKey ?? _deki.MasterApiKey;
                    ulong folded_productkey_md5 = 0;
                    byte[] md5_bytes = StringUtil.ComputeHash(tokenKey, Encoding.UTF8);
                    for(int i = 0; i < md5_bytes.Length; ++i) {
                        folded_productkey_md5 ^= (ulong)md5_bytes[i] << (i & 7) * 8;
                    }
                    _token = folded_productkey_md5.ToString("X");
                }

                // check if a storage config section was provided (default storage is filesystem provider)
                XDoc storageConfig;
                switch(ConfigBL.GetInstanceSettingsValue("storage/@type", ConfigBL.GetInstanceSettingsValue("storage/type", "default"))) {
                case "default":
                    string defaultAttachPath = Path.Combine(_deki.DekiPath, "attachments");
                    storageConfig = new XDoc("config")
                        .Elem("path", defaultAttachPath)
                        .Elem("cache-path", Path.Combine(defaultAttachPath, ".cache"));
                    _storage = new FSStorage(storageConfig);
                    break;
                case "fs":
                    string fsPath = ConfigBL.GetInstanceSettingsValue("storage/fs/path", null);

                    //Replace a $1 with the wiki name                
                    fsPath = string.Format(PhpUtil.ConvertToFormatString(fsPath ?? string.Empty), Id);
                    storageConfig = new XDoc("config")
                        .Elem("path", fsPath)
                        .Elem("cache-path", ConfigBL.GetInstanceSettingsValue("storage/fs/cache-path", null));
                    _storage = new FSStorage(storageConfig);
                    break;
                case "s3":
                    storageConfig = new XDoc("config")
                        .Elem("publickey", ConfigBL.GetInstanceSettingsValue("storage/s3/publickey", null))
                        .Elem("privatekey", ConfigBL.GetInstanceSettingsValue("storage/s3/privatekey", null))
                        .Elem("bucket", ConfigBL.GetInstanceSettingsValue("storage/s3/bucket", null))
                        .Elem("prefix", string.Format(PhpUtil.ConvertToFormatString(ConfigBL.GetInstanceSettingsValue("storage/s3/prefix", string.Empty)), DekiContext.Current.Instance.Id))
                        .Elem("timeout", ConfigBL.GetInstanceSettingsValue("storage/s3/timeout", null))
                        .Elem("allowredirects", ConfigBL.GetInstanceSettingsValue("storage/s3/allowredirects", null))
                        .Elem("redirecttimeout", ConfigBL.GetInstanceSettingsValue("storage/s3/redirecttimeout", null));
                    _storage = new S3Storage(storageConfig, _loggerRepository.Get<S3Storage>());
                    break;
                default:
                    throw new ArgumentException("Storage provider unknown or not defined (key: storage/type)", "storage/type");
                }

                HomePageId = DbUtils.CurrentSession.Pages_HomePageId;
                _eventSink.InstanceStarting(DekiContext.Current.Now);
            } catch {

                // we failed to initialize
                _status = DekiInstanceStatus.ABANDONED;
                throw;
            }

            // set state to initializing
            _status = DekiInstanceStatus.INITIALIZING;
        }