Represents a running Repository. There is always one instance in any appdomain. Repository will be stopped when the instance is disposing.
Inheritance: IDisposable
Exemplo n.º 1
0
 internal static RepositoryInstance Start(RepositoryStartSettings settings)
 {
     if (!_started)
     {
         lock (_startStopSync)
         {
             if (!_started)
             {
                 var instance = new RepositoryInstance();
                 instance._settings = new RepositoryStartSettings.ImmutableRepositoryStartSettings(settings);
                 _instance          = instance;
                 try
                 {
                     instance.DoStart();
                 }
                 catch (Exception)
                 {
                     _instance = null;
                     throw;
                 }
                 _started = true;
             }
         }
     }
     return(_instance);
 }
Exemplo n.º 2
0
        internal static void Shutdown()
        {
            if (_instance == null)
            {
                _started = false;

                SnLog.WriteWarning("Repository shutdown has already completed.");
                return;
            }

            lock (_startStopSync)
            {
                if (_instance == null)
                {
                    _started = false;

                    SnLog.WriteWarning("Repository shutdown has already completed.");
                    return;
                }

                SnTrace.Repository.Write("Sending a goodbye message.");

                _instance.ConsoleWriteLine();

                _instance.ConsoleWriteLine("Sending a goodbye message...");
                DistributedApplication.ClusterChannel.ClusterMemberInfo.NeedToRecover = false;
                var pingMessage = new PingMessage();
                pingMessage.SendAsync(CancellationToken.None).GetAwaiter().GetResult();

                foreach (var svc in _instance.serviceInstances)
                {
                    SnTrace.Repository.Write("Shutting down {0}", svc.GetType().Name);
                    svc.Shutdown();
                }

                SnTrace.Repository.Write("Shutting down {0}", DistributedApplication.ClusterChannel.GetType().Name);
                DistributedApplication.ClusterChannel.ShutDownAsync(CancellationToken.None).GetAwaiter().GetResult();

                SnTrace.Repository.Write("Shutting down Security.");
                SecurityHandler.ShutDownSecurity();

                SnTrace.Repository.Write("Shutting down IndexingEngine.");
                IndexManager.ShutDown();

                ContextHandler.Reset();

                var t   = DateTime.UtcNow - _instance._startupInfo.Starting;
                var msg = $"Repository has stopped. Running time: {t.Days}.{t.Hours:d2}:{t.Minutes:d2}:{t.Seconds:d2}";

                SnTrace.Repository.Write(msg);
                SnTrace.Flush();

                _instance.ConsoleWriteLine(msg);
                _instance.ConsoleWriteLine();
                SnLog.WriteInformation(msg);

                _instance = null;
                _started  = false;
            }
        }
Exemplo n.º 3
0
        internal static void Shutdown()
        {
            _instance.ConsoleWriteLine();

            DistributedApplication.ClusterChannel.ShutDown();

            if (Instance.StartSettings.BackupIndexAtTheEnd)
            {
                if (LuceneManagerIsRunning)
                {
                    _instance.ConsoleWriteLine("Backing up the index...");
                    SenseNet.Search.Indexing.BackupTools.SynchronousBackupIndex();
                    _instance.ConsoleWriteLine("The backup of index is finished.");
                }
                else
                {
                    _instance.ConsoleWriteLine("Backing up index is skipped because Lucene was not started.");
                }
            }

            if (LuceneManagerIsRunning)
            {
                SenseNet.Search.Indexing.LuceneManager.ShutDown();
            }

            WaitForWriterLockFileIsReleased(WaitForLockFileType.OnEnd);

            var t   = DateTime.Now - _instance._startupInfo.Starting;
            var msg = String.Format("Repository has stopped. Running time: {0}.{1:d2}:{2:d2}:{3:d2}", t.Days, t.Hours, t.Minutes, t.Seconds);

            _instance.ConsoleWriteLine(msg);
            _instance.ConsoleWriteLine();
            Logger.WriteInformation(msg);
            _instance = null;
        }
Exemplo n.º 4
0
        /// <summary>
        /// Executes the boot sequence of the Repository by the passed <see cref="RepositoryStartSettings"/>.
        /// </summary>
        /// <example>
        /// Use the following code in your tool or other outer application:
        /// <code>
        /// var startSettings = new RepositoryStartSettings
        /// {
        ///     PluginsPath = pluginsPath, // Local directory path of plugins if it is different from your tool's path.
        ///     Console = Console.Out      // Startup sequence will be traced to given writer.
        /// };
        /// using (SenseNet.ContentRepository.Repository.Start(startSettings))
        /// {
        ///     // your code
        /// }
        /// </code>
        /// </example>
        /// <remarks>
        /// Repository will be stopped if the returned <see cref="RepositoryStartSettings"/> instance is disposed.
        /// </remarks>
        /// <returns>A new IDisposable <see cref="RepositoryInstance"/> instance.</returns>
        /// <returns></returns>
        public static RepositoryInstance Start(RepositoryStartSettings settings)
        {
            var instance = RepositoryInstance.Start(settings);

            SystemAccount.Execute(() => Root);
            return(instance);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Executes the boot sequence of the Repository by the passed <see cref="RepositoryStartSettings"/>.
        /// </summary>
        /// <example>
        /// Use the following code in your tool or other outer application:
        /// <code>
        /// var startSettings = new RepositoryStartSettings
        /// {
        ///     PluginsPath = pluginsPath, // Local directory path of plugins if it is different from your tool's path.
        ///     Console = Console.Out      // Startup sequence will be traced to given writer.
        /// };
        /// using (SenseNet.ContentRepository.Repository.Start(startSettings))
        /// {
        ///     // your code
        /// }
        /// </code>
        /// </example>
        /// <remarks>
        /// Repository will be stopped if the returned <see cref="RepositoryStartSettings"/> instance is disposed.
        /// </remarks>
        /// <returns>A new IDisposable <see cref="RepositoryInstance"/> instance.</returns>
        /// <returns></returns>
        public static RepositoryInstance Start(RepositoryStartSettings settings)
        {
            var instance = RepositoryInstance.Start(settings);

            AccessProvider.ChangeToSystemAccount();
            Root = (PortalRoot)Node.LoadNode(RootPath);
            AccessProvider.RestoreOriginalUser();
            return(instance);
        }
Exemplo n.º 6
0
        public static RepositoryInstance Start(RepositoryBuilder builder)
        {
            // Required early configuration
            BlobStorageComponents.DataProvider     = Providers.Instance.BlobMetaDataProvider;
            BlobStorageComponents.ProviderSelector = Providers.Instance.BlobProviderSelector;

            var initialData = builder.InitialData;

            if (initialData != null)
            {
                DataStore.InstallInitialDataAsync(initialData, CancellationToken.None)
                .GetAwaiter().GetResult();
            }

            RepositoryInstance repositoryInstance = null;
            var exclusiveLockOptions = builder.Services?.GetService <IOptions <ExclusiveLockOptions> >()?.Value;

            ExclusiveBlock.RunAsync("SenseNet.PatchManager", Guid.NewGuid().ToString(),
                                    ExclusiveBlockType.WaitAndAcquire, exclusiveLockOptions, CancellationToken.None, () =>
            {
                var logger       = Providers.Instance.GetProvider <ILogger <SnILogger> >();
                var patchManager = new PatchManager(builder, logRecord => { logRecord.WriteTo(logger); });
                patchManager.ExecutePatchesOnBeforeStart();

                repositoryInstance = Start((RepositoryStartSettings)builder);

                var permissions = initialData?.Permissions;
                if (permissions != null && permissions.Count > 0)
                {
                    SecurityHandler.SecurityInstaller.InstallDefaultSecurityStructure(initialData);
                }

                var indexingEngine = Providers.Instance.SearchEngine.IndexingEngine;
                if (indexingEngine.Running && initialData?.IndexDocuments != null)
                {
                    indexingEngine.ClearIndexAsync(CancellationToken.None)
                    .ConfigureAwait(false).GetAwaiter().GetResult();
                    indexingEngine.WriteIndexAsync(null, null,
                                                   initialData.IndexDocuments, CancellationToken.None)
                    .ConfigureAwait(false).GetAwaiter().GetResult();
                }

                patchManager.ExecutePatchesOnAfterStart();
                RepositoryVersionInfo.Reset();

                return(System.Threading.Tasks.Task.CompletedTask);
            }).GetAwaiter().GetResult();

            return(repositoryInstance);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Executes the boot sequence of the Repository by the passed <see cref="RepositoryStartSettings"/>.
        /// </summary>
        /// <example>
        /// Use the following code in your tool or other outer application:
        /// <code>
        /// var startSettings = new RepositoryStartSettings
        /// {
        ///     PluginsPath = pluginsPath, // Local directory path of plugins if it is different from your tool's path.
        ///     Console = Console.Out      // Startup sequence will be traced to given writer.
        /// };
        /// using (SenseNet.ContentRepository.Repository.Start(startSettings))
        /// {
        ///     // your code
        /// }
        /// </code>
        /// </example>
        /// <remarks>
        /// Repository will be stopped if the returned <see cref="RepositoryStartSettings"/> instance is disposed.
        /// </remarks>
        /// <returns>A new IDisposable <see cref="RepositoryInstance"/> instance.</returns>
        /// <returns></returns>
        public static RepositoryInstance Start(RepositoryStartSettings settings)
        {
            if (!settings.ExecutingPatches)
            {
                // Switch ON this flag so that inner repository start operations
                // do not try to execute patches again recursively.
                settings.ExecutingPatches = true;

                //TODO: [auto-patch] this feature is not released yet
                //PackageManager.ExecuteAssemblyPatches(settings);
            }

            var instance = RepositoryInstance.Start(settings);
            SystemAccount.Execute(() => Root);
            return instance;
        }
Exemplo n.º 8
0
        /// <summary>
        /// Waits for write.lock to disappear for a configured time interval. Timeout: configured with IndexLockFileWaitForRemovedTimeout key.
        /// If timeout is exceeded an error is logged and execution continues. For errors at OnStart an email is also sent to a configured address.
        /// </summary>
        /// <param name="waitType">A parameter that influences the logged error message and email template only.</param>
        public static void WaitForWriterLockFileIsReleased(WaitForLockFileType waitType)
        {
            // check if writer.lock is still there -> if yes, wait for other appdomain to quit or lock to disappear - until a given timeout.
            // after timeout is passed, Repository.Start will deliberately attempt to remove lock file on following startup

            if (!WaitForWriterLockFileIsReleased())
            {
                // lock file was not removed by other or current appdomain for the given time interval (onstart: other appdomain might use it, onend: current appdomain did not release it yet)
                // onstart -> notify operator and start repository anyway
                // onend -> log error, and continue
                var template = waitType == WaitForLockFileType.OnEnd ? WRITELOCKREMOVEERRORONENDTEMPLATESTR : WRITELOCKREMOVEERRORTEMPLATESTR;
                SnLog.WriteError(string.Format(template, Indexing.IndexLockFileWaitForRemovedTimeout,
                                               AppDomain.CurrentDomain.FriendlyName, AppDomain.CurrentDomain.BaseDirectory));

                if (waitType == WaitForLockFileType.OnStart)
                {
                    RepositoryInstance.SendWaitForLockErrorMail();
                }
            }
        }
Exemplo n.º 9
0
 internal static RepositoryInstance Start(RepositoryStartSettings settings)
 {
     if (!_started)
     {
         lock (_startupSync)
         {
             if (!_started)
             {
                 var instance = new RepositoryInstance();
                 instance._settings = new RepositoryStartSettings.ImmutableRepositoryStartSettings(settings);
                 _instance          = instance;
                 try
                 {
                     instance.DoStart();
                 }
                 catch (SqlException) //Workaround for VPN connectivity problem in LR office
                 {
                     Thread.Sleep(5000);
                     try
                     {
                         instance.DoStart();
                     }
                     catch (Exception)
                     {
                         _instance = null;
                         throw;
                     }
                 }
                 catch (Exception)
                 {
                     _instance = null;
                     throw;
                 }
                 _started = true;
             }
         }
     }
     return(_instance);
 }
Exemplo n.º 10
0
 internal static RepositoryInstance Start(RepositoryStartSettings settings)
 {
     if (!_started)
     {
         lock (_startupSync)
         {
             if (!_started)
             {
                 var instance = new RepositoryInstance();
                 instance._settings = new RepositoryStartSettings.ImmutableRepositoryStartSettings(settings);
                 _instance = instance;
                 try
                 {
                     instance.DoStart();
                 }
                 catch (SqlException) //Workaround for VPN connectivity problem in LR office
                 {
                     Thread.Sleep(5000);
                     try
                     {
                         instance.DoStart();
                     }
                     catch (Exception)
                     {
                         _instance = null;
                         throw;
                     }
                 }
                 catch (Exception)
                 {
                     _instance = null;
                     throw;
                 }
                 _started = true;
             }
         }
     }
     return _instance;
 }
Exemplo n.º 11
0
        internal static void Shutdown()
        {
            _instance.ConsoleWriteLine();

            DistributedApplication.ClusterChannel.ShutDown();

            if (Instance.StartSettings.BackupIndexAtTheEnd)
            {
                if (LuceneManagerIsRunning)
                {
                    _instance.ConsoleWriteLine("Backing up the index...");
                    SenseNet.Search.Indexing.BackupTools.SynchronousBackupIndex();
                    _instance.ConsoleWriteLine("The backup of index is finished.");
                }
                else
                {
                    _instance.ConsoleWriteLine("Backing up index is skipped because Lucene was not started.");
                }
            }

            if (LuceneManagerIsRunning)
                SenseNet.Search.Indexing.LuceneManager.ShutDown();

            WaitForWriterLockFileIsReleased(WaitForLockFileType.OnEnd);

            var t = DateTime.Now - _instance._startupInfo.Starting;
            var msg = String.Format("Repository has stopped. Running time: {0}.{1:d2}:{2:d2}:{3:d2}", t.Days, t.Hours, t.Minutes, t.Seconds);

            _instance.ConsoleWriteLine(msg);
            _instance.ConsoleWriteLine();
            Logger.WriteInformation(msg);
            _instance = null;
        }
Exemplo n.º 12
0
 /// <summary>
 /// Stops all internal services of the Repository.
 /// </summary>
 public static void Shutdown()
 {
     RepositoryInstance.Shutdown();
 }
Exemplo n.º 13
0
 /// <summary>
 /// Returns the running state of the Repository.
 /// </summary>
 /// <returns>True if the Repository has started yet otherwise false.</returns>
 public static bool Started()
 {
     return(RepositoryInstance.Started());
 }
Exemplo n.º 14
0
        internal static void Shutdown()
        {
            if (_instance == null)
            {
                SnLog.WriteWarning("Repository shutdown has already completed.");
                return;
            }

            lock (_shutDownSync)
            {
                if (_instance == null)
                {
                    SnLog.WriteWarning("Repository shutdown has already completed.");
                    return;
                }

                SnTrace.Repository.Write("Sending a goodbye message.");

                _instance.ConsoleWriteLine();

                _instance.ConsoleWriteLine("Sending a goodbye message...");
                DistributedApplication.ClusterChannel.ClusterMemberInfo.NeedToRecover = false;
                var pingMessage = new PingMessage();
                pingMessage.Send();

                foreach (var svc in _instance.serviceInstances)
                {
                    SnTrace.Repository.Write("Shutting down {0}", svc.GetType().Name);
                    svc.Shutdown();
                }

                SnTrace.Repository.Write("Shutting down {0}", DistributedApplication.ClusterChannel.GetType().Name);
                DistributedApplication.ClusterChannel.ShutDown();

                if (Instance.StartSettings.BackupIndexAtTheEnd)
                {
                    SnTrace.Repository.Write("Backing up the index.");
                    if (LuceneManagerIsRunning)
                    {
                        _instance.ConsoleWriteLine("Backing up the index...");
                        SenseNet.Search.Indexing.BackupTools.SynchronousBackupIndex();
                        _instance.ConsoleWriteLine("The backup of index is finished.");
                    }
                    else
                    {
                        _instance.ConsoleWriteLine("Backing up index is skipped because Lucene was not started.");
                    }
                }

                if (LuceneManagerIsRunning)
                {
                    SnTrace.Repository.Write("Shutting down LuceneManager.");
                    SenseNet.Search.Indexing.LuceneManager.ShutDown();
                }

                SnTrace.Repository.Write("Waiting for writer lock file is released.");
                WaitForWriterLockFileIsReleased(WaitForLockFileType.OnEnd);

                var t   = DateTime.UtcNow - _instance._startupInfo.Starting;
                var msg = String.Format("Repository has stopped. Running time: {0}.{1:d2}:{2:d2}:{3:d2}", t.Days,
                                        t.Hours, t.Minutes, t.Seconds);

                SnTrace.Repository.Write(msg);
                SnTrace.Flush();

                _instance.ConsoleWriteLine(msg);
                _instance.ConsoleWriteLine();
                SnLog.WriteInformation(msg);
                _instance = null;
            }
        }
Exemplo n.º 15
0
        public static RepositoryInstance Start(RepositoryBuilder builder)
        {
            var connectionStrings = builder.Services?.GetRequiredService <IOptions <ConnectionStringOptions> >();

            Providers.Instance.InitializeBlobProviders(connectionStrings?.Value ?? new ConnectionStringOptions());

            EnsureDatabase(builder);

            var initialData = builder.InitialData;

            if (initialData != null)
            {
                Providers.Instance.DataStore.InstallInitialDataAsync(initialData, CancellationToken.None)
                .GetAwaiter().GetResult();
            }

            RepositoryInstance repositoryInstance = null;
            var exclusiveLockOptions = builder.Services?.GetService <IOptions <ExclusiveLockOptions> >()?.Value;

            ExclusiveBlock.RunAsync("SenseNet.PatchManager", Guid.NewGuid().ToString(),
                                    ExclusiveBlockType.WaitAndAcquire, exclusiveLockOptions, CancellationToken.None, () =>
            {
                var logger       = Providers.Instance.GetProvider <ILogger <SnILogger> >();
                var patchManager = new PatchManager(builder, logRecord => { logRecord.WriteTo(logger); });
                patchManager.ExecutePatchesOnBeforeStart();

                repositoryInstance = Start((RepositoryStartSettings)builder);

                var permissions = initialData?.Permissions;
                if (permissions != null && permissions.Count > 0)
                {
                    new SecurityInstaller(Providers.Instance.SecurityHandler, Providers.Instance.StorageSchema,
                                          Providers.Instance.DataStore).InstallDefaultSecurityStructure(initialData);
                }

                var indexingEngine = Providers.Instance.SearchEngine.IndexingEngine;
                if (indexingEngine.Running)
                {
                    if (initialData?.IndexDocuments != null)
                    {
                        // Build the index from an in-memory structure. This is a developer use case.
                        indexingEngine.ClearIndexAsync(CancellationToken.None)
                        .ConfigureAwait(false).GetAwaiter().GetResult();
                        indexingEngine.WriteIndexAsync(null, null,
                                                       initialData.IndexDocuments, CancellationToken.None)
                        .ConfigureAwait(false).GetAwaiter().GetResult();
                    }
                    else
                    {
                        // make sure the index exists and contains documents
                        EnsureIndex(builder);
                    }
                }

                patchManager.ExecutePatchesOnAfterStart();
                RepositoryVersionInfo.Reset();

                return(System.Threading.Tasks.Task.CompletedTask);
            }).GetAwaiter().GetResult();

            return(repositoryInstance);
        }