Browse Source

Restore fixes.

pull/361/head
Sebastian 7 years ago
parent
commit
ec02459cc4
  1. 2
      extensions/Squidex.Extensions/Actions/Algolia/AlgoliaAction.cs
  2. 2
      extensions/Squidex.Extensions/Actions/ElasticSearch/ElasticSearchAction.cs
  3. 4
      src/Squidex.Domain.Apps.Entities/Apps/BackupApps.cs
  4. 54
      src/Squidex.Domain.Apps.Entities/Backup/BackupGrain.cs
  5. 2
      src/Squidex.Domain.Apps.Entities/Backup/BackupHandler.cs
  6. 4
      src/Squidex.Domain.Apps.Entities/Backup/Helpers/Downloader.cs
  7. 14
      src/Squidex.Domain.Apps.Entities/Backup/Helpers/Safe.cs
  8. 5
      src/Squidex.Domain.Apps.Entities/Backup/IBackupArchiveLocation.cs
  9. 46
      src/Squidex.Domain.Apps.Entities/Backup/RestoreGrain.cs
  10. 7
      src/Squidex.Domain.Apps.Entities/Backup/TempFolderBackupArchiveLocation.cs
  11. 2
      src/Squidex/app/features/settings/pages/backups/backups-page.component.html
  12. 6
      src/Squidex/appsettings.json
  13. 10
      src/Squidex/package-lock.json
  14. 2
      tools/Migrate_00/Program.cs
  15. 2
      tools/Migrate_01/RebuildOptions.cs
  16. 11
      tools/Migrate_01/RebuildRunner.cs

2
extensions/Squidex.Extensions/Actions/Algolia/AlgoliaAction.cs

@ -15,7 +15,7 @@ namespace Squidex.Extensions.Actions.Algolia
IconImage = "<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><path d='M16 .842C7.633.842.842 7.625.842 16S7.625 31.158 16 31.158c8.374 0 15.158-6.791 15.158-15.166S24.375.842 16 .842zm0 25.83c-5.898 0-10.68-4.781-10.68-10.68S10.101 5.313 16 5.313s10.68 4.781 10.68 10.679-4.781 10.68-10.68 10.68zm0-19.156v7.956c0 .233.249.388.458.279l7.055-3.663a.312.312 0 0 0 .124-.434 8.807 8.807 0 0 0-7.319-4.447z'/></svg>",
IconColor = "#0d9bf9",
Display = "Populate Algolia index",
Description = "Populate and synchronize indices in Algolia for full text search.",
Description = "Populate and synchronize indexes in Algolia for full text search.",
ReadMore = "https://www.algolia.com/")]
public sealed class AlgoliaAction : RuleAction
{

2
extensions/Squidex.Extensions/Actions/ElasticSearch/ElasticSearchAction.cs

@ -17,7 +17,7 @@ namespace Squidex.Extensions.Actions.ElasticSearch
IconImage = "<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 29 28'><path d='M13.427 17.436H4.163C3.827 16.354 3.636 15.2 3.636 14s.182-2.355.527-3.436h15.245c1.891 0 3.418 1.545 3.418 3.445a3.421 3.421 0 0 1-3.418 3.427h-5.982zm-.436 1.146H4.6a11.508 11.508 0 0 0 4.2 4.982 11.443 11.443 0 0 0 15.827-3.209 5.793 5.793 0 0 0-4.173-1.773H12.99zm7.464-9.164a5.794 5.794 0 0 0 4.173-1.773 11.45 11.45 0 0 0-9.536-5.1c-2.327 0-4.491.7-6.3 1.891a11.554 11.554 0 0 0-4.2 4.982h15.864z'/></svg>",
IconColor = "#1e5470",
Display = "Populate ElasticSearch index",
Description = "Populate and synchronize indices in ElasticSearch for full text search.",
Description = "Populate and synchronize indexes in ElasticSearch for full text search.",
ReadMore = "https://www.elastic.co/")]
public sealed class ElasticSearchAction : RuleAction
{

4
src/Squidex.Domain.Apps.Entities/Apps/BackupApps.cs

@ -127,11 +127,11 @@ namespace Squidex.Domain.Apps.Entities.Apps
{
if (!(isReserved = await appsByNameIndex.ReserveAppAsync(appId, appName)))
{
throw new BackupRestoreException("vThe app id or name is not available.");
throw new BackupRestoreException("The app id or name is not available.");
}
}
public override async Task CleanupRestoreAsync(Guid appId)
public override async Task CleanupRestoreErrorAsync(Guid appId)
{
if (isReserved)
{

54
src/Squidex.Domain.Apps.Entities/Backup/BackupGrain.cs

@ -10,6 +10,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using NodaTime;
using Orleans.Concurrency;
using Squidex.Domain.Apps.Entities.Backup.Helpers;
@ -34,8 +35,8 @@ namespace Squidex.Domain.Apps.Entities.Backup
private readonly IAssetStore assetStore;
private readonly IBackupArchiveLocation backupArchiveLocation;
private readonly IClock clock;
private readonly IEnumerable<BackupHandler> handlers;
private readonly IJsonSerializer serializer;
private readonly IServiceProvider serviceProvider;
private readonly IEventDataFormatter eventDataFormatter;
private readonly IEventStore eventStore;
private readonly ISemanticLog log;
@ -48,8 +49,8 @@ namespace Squidex.Domain.Apps.Entities.Backup
IClock clock,
IEventStore eventStore,
IEventDataFormatter eventDataFormatter,
IEnumerable<BackupHandler> handlers,
IJsonSerializer serializer,
IServiceProvider serviceProvider,
ISemanticLog log,
IStore<Guid> store)
: base(store)
@ -59,7 +60,7 @@ namespace Squidex.Domain.Apps.Entities.Backup
Guard.NotNull(clock, nameof(clock));
Guard.NotNull(eventStore, nameof(eventStore));
Guard.NotNull(eventDataFormatter, nameof(eventDataFormatter));
Guard.NotNull(handlers, nameof(handlers));
Guard.NotNull(serviceProvider, nameof(serviceProvider));
Guard.NotNull(serializer, nameof(serializer));
Guard.NotNull(log, nameof(log));
@ -68,8 +69,8 @@ namespace Squidex.Domain.Apps.Entities.Backup
this.clock = clock;
this.eventStore = eventStore;
this.eventDataFormatter = eventDataFormatter;
this.handlers = handlers;
this.serializer = serializer;
this.serviceProvider = serviceProvider;
this.log = log;
}
@ -86,10 +87,12 @@ namespace Squidex.Domain.Apps.Entities.Backup
{
if (!job.Stopped.HasValue)
{
var jobId = job.Id.ToString();
job.Stopped = clock.GetCurrentInstant();
await Safe.DeleteAsync(backupArchiveLocation, job.Id, log);
await Safe.DeleteAsync(assetStore, job.Id, log);
await Safe.DeleteAsync(backupArchiveLocation, jobId, log);
await Safe.DeleteAsync(assetStore, jobId, log);
job.Status = JobStatus.Failed;
@ -120,15 +123,29 @@ namespace Squidex.Domain.Apps.Entities.Backup
currentTask = new CancellationTokenSource();
currentJob = job;
var lastTimestamp = job.Started;
State.Jobs.Insert(0, job);
await WriteStateAsync();
Process(job, currentTask.Token);
}
private void Process(BackupStateJob job, CancellationToken ct)
{
ProcessAsync(job, ct).Forget();
}
private async Task ProcessAsync(BackupStateJob job, CancellationToken ct)
{
var jobId = job.Id.ToString();
var handlers = CreateHandlers();
var lastTimestamp = job.Started;
try
{
using (var stream = await backupArchiveLocation.OpenStreamAsync(job.Id))
using (var stream = await backupArchiveLocation.OpenStreamAsync(jobId))
{
using (var writer = new BackupWriter(serializer, stream, true))
{
@ -162,16 +179,16 @@ namespace Squidex.Domain.Apps.Entities.Backup
stream.Position = 0;
currentTask.Token.ThrowIfCancellationRequested();
ct.ThrowIfCancellationRequested();
await assetStore.UploadAsync(job.Id.ToString(), 0, null, stream, false, currentTask.Token);
await assetStore.UploadAsync(jobId, 0, null, stream, false, currentTask.Token);
}
job.Status = JobStatus.Completed;
}
catch (Exception ex)
{
log.LogError(ex, job.Id.ToString(), (ctx, w) => w
log.LogError(ex, jobId, (ctx, w) => w
.WriteProperty("action", "makeBackup")
.WriteProperty("status", "failed")
.WriteProperty("backupId", ctx));
@ -180,7 +197,7 @@ namespace Squidex.Domain.Apps.Entities.Backup
}
finally
{
await Safe.DeleteAsync(backupArchiveLocation, job.Id, log);
await Safe.DeleteAsync(backupArchiveLocation, jobId, log);
job.Stopped = clock.GetCurrentInstant();
@ -220,8 +237,10 @@ namespace Squidex.Domain.Apps.Entities.Backup
}
else
{
await Safe.DeleteAsync(backupArchiveLocation, job.Id, log);
await Safe.DeleteAsync(assetStore, job.Id, log);
var jobId = job.Id.ToString();
await Safe.DeleteAsync(backupArchiveLocation, jobId, log);
await Safe.DeleteAsync(assetStore, jobId, log);
State.Jobs.Remove(job);
@ -229,6 +248,11 @@ namespace Squidex.Domain.Apps.Entities.Backup
}
}
private IEnumerable<BackupHandler> CreateHandlers()
{
return serviceProvider.GetRequiredService<IEnumerable<BackupHandler>>();
}
public Task<J<List<IBackupJob>>> GetStateAsync()
{
return J.AsTask(State.Jobs.OfType<IBackupJob>().ToList());

2
src/Squidex.Domain.Apps.Entities/Backup/BackupHandler.cs

@ -37,7 +37,7 @@ namespace Squidex.Domain.Apps.Entities.Backup
return TaskHelper.Done;
}
public virtual Task CleanupRestoreAsync(Guid appId)
public virtual Task CleanupRestoreErrorAsync(Guid appId)
{
return TaskHelper.Done;
}

4
src/Squidex.Domain.Apps.Entities/Backup/Helpers/Downloader.cs

@ -15,7 +15,7 @@ namespace Squidex.Domain.Apps.Entities.Backup.Helpers
{
public static class Downloader
{
public static async Task DownloadAsync(this IBackupArchiveLocation backupArchiveLocation, Uri url, Guid id)
public static async Task DownloadAsync(this IBackupArchiveLocation backupArchiveLocation, Uri url, string id)
{
if (string.Equals(url.Scheme, "file"))
{
@ -60,7 +60,7 @@ namespace Squidex.Domain.Apps.Entities.Backup.Helpers
}
}
public static async Task<BackupReader> OpenArchiveAsync(this IBackupArchiveLocation backupArchiveLocation, Guid id, IJsonSerializer serializer)
public static async Task<BackupReader> OpenArchiveAsync(this IBackupArchiveLocation backupArchiveLocation, string id, IJsonSerializer serializer)
{
Stream stream = null;

14
src/Squidex.Domain.Apps.Entities/Backup/Helpers/Safe.cs

@ -14,7 +14,7 @@ namespace Squidex.Domain.Apps.Entities.Backup.Helpers
{
public static class Safe
{
public static async Task DeleteAsync(IBackupArchiveLocation backupArchiveLocation, Guid id, ISemanticLog log)
public static async Task DeleteAsync(IBackupArchiveLocation backupArchiveLocation, string id, ISemanticLog log)
{
try
{
@ -22,33 +22,33 @@ namespace Squidex.Domain.Apps.Entities.Backup.Helpers
}
catch (Exception ex)
{
log.LogError(ex, id.ToString(), (logOperationId, w) => w
log.LogError(ex, id, (logOperationId, w) => w
.WriteProperty("action", "deleteArchive")
.WriteProperty("status", "failed")
.WriteProperty("operationId", logOperationId));
}
}
public static async Task DeleteAsync(IAssetStore assetStore, Guid id, ISemanticLog log)
public static async Task DeleteAsync(IAssetStore assetStore, string id, ISemanticLog log)
{
try
{
await assetStore.DeleteAsync(id.ToString(), 0, null);
await assetStore.DeleteAsync(id, 0, null);
}
catch (Exception ex)
{
log.LogError(ex, id.ToString(), (logOperationId, w) => w
log.LogError(ex, id, (logOperationId, w) => w
.WriteProperty("action", "deleteBackup")
.WriteProperty("status", "failed")
.WriteProperty("operationId", logOperationId));
}
}
public static async Task CleanupRestoreAsync(BackupHandler handler, Guid appId, Guid id, ISemanticLog log)
public static async Task CleanupRestoreErrorAsync(BackupHandler handler, Guid appId, Guid id, ISemanticLog log)
{
try
{
await handler.CleanupRestoreAsync(appId);
await handler.CleanupRestoreErrorAsync(appId);
}
catch (Exception ex)
{

5
src/Squidex.Domain.Apps.Entities/Backup/IBackupArchiveLocation.cs

@ -5,7 +5,6 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.IO;
using System.Threading.Tasks;
@ -13,8 +12,8 @@ namespace Squidex.Domain.Apps.Entities.Backup
{
public interface IBackupArchiveLocation
{
Task<Stream> OpenStreamAsync(Guid backupId);
Task<Stream> OpenStreamAsync(string backupId);
Task DeleteArchiveAsync(Guid backupId);
Task DeleteArchiveAsync(string backupId);
}
}

46
src/Squidex.Domain.Apps.Entities/Backup/RestoreGrain.cs

@ -8,6 +8,7 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using NodaTime;
using Squidex.Domain.Apps.Core.Apps;
using Squidex.Domain.Apps.Entities.Apps.Commands;
@ -31,11 +32,11 @@ namespace Squidex.Domain.Apps.Entities.Backup
private readonly IBackupArchiveLocation backupArchiveLocation;
private readonly IClock clock;
private readonly ICommandBus commandBus;
private readonly IEnumerable<BackupHandler> handlers;
private readonly IJsonSerializer serializer;
private readonly IEventStore eventStore;
private readonly IEventDataFormatter eventDataFormatter;
private readonly ISemanticLog log;
private readonly IServiceProvider serviceProvider;
private readonly IStreamNameResolver streamNameResolver;
private RestoreStateJob CurrentJob
@ -48,9 +49,9 @@ namespace Squidex.Domain.Apps.Entities.Backup
ICommandBus commandBus,
IEventStore eventStore,
IEventDataFormatter eventDataFormatter,
IEnumerable<BackupHandler> handlers,
IJsonSerializer serializer,
ISemanticLog log,
IServiceProvider serviceProvider,
IStreamNameResolver streamNameResolver,
IStore<string> store)
: base(store)
@ -60,8 +61,8 @@ namespace Squidex.Domain.Apps.Entities.Backup
Guard.NotNull(commandBus, nameof(commandBus));
Guard.NotNull(eventStore, nameof(eventStore));
Guard.NotNull(eventDataFormatter, nameof(eventDataFormatter));
Guard.NotNull(handlers, nameof(handlers));
Guard.NotNull(serializer, nameof(serializer));
Guard.NotNull(serviceProvider, nameof(serviceProvider));
Guard.NotNull(store, nameof(store));
Guard.NotNull(streamNameResolver, nameof(streamNameResolver));
Guard.NotNull(log, nameof(log));
@ -71,8 +72,8 @@ namespace Squidex.Domain.Apps.Entities.Backup
this.commandBus = commandBus;
this.eventStore = eventStore;
this.eventDataFormatter = eventDataFormatter;
this.handlers = handlers;
this.serializer = serializer;
this.serviceProvider = serviceProvider;
this.streamNameResolver = streamNameResolver;
this.log = log;
}
@ -88,16 +89,18 @@ namespace Squidex.Domain.Apps.Entities.Backup
{
if (CurrentJob?.Status == JobStatus.Started)
{
var handlers = CreateHandlers();
Log("Failed due application restart");
CurrentJob.Status = JobStatus.Failed;
await CleanupAsync();
await CleanupAsync(handlers);
await WriteStateAsync();
}
}
public Task RestoreAsync(Uri url, RefToken actor, string newAppName)
public async Task RestoreAsync(Uri url, RefToken actor, string newAppName)
{
Guard.NotNull(url, nameof(url));
Guard.NotNull(actor, nameof(actor));
@ -122,9 +125,9 @@ namespace Squidex.Domain.Apps.Entities.Backup
Url = url
};
Process();
await WriteStateAsync();
return TaskHelper.Done;
Process();
}
private void Process()
@ -134,6 +137,8 @@ namespace Squidex.Domain.Apps.Entities.Backup
private async Task ProcessAsync()
{
var handlers = CreateHandlers();
var logContext = (jobId: CurrentJob.Id.ToString(), jobUrl: CurrentJob.Url.ToString());
using (Profiler.StartSession())
@ -157,11 +162,11 @@ namespace Squidex.Domain.Apps.Entities.Backup
await DownloadAsync();
}
using (var reader = await backupArchiveLocation.OpenArchiveAsync(CurrentJob.Id, serializer))
using (var reader = await backupArchiveLocation.OpenArchiveAsync(CurrentJob.Id.ToString(), serializer))
{
using (Profiler.Trace("ReadEvents"))
{
await ReadEventsAsync(reader);
await ReadEventsAsync(reader, handlers);
}
foreach (var handler in handlers)
@ -212,7 +217,7 @@ namespace Squidex.Domain.Apps.Entities.Backup
Log("Failed with internal error");
}
await CleanupAsync();
await CleanupAsync(handlers);
CurrentJob.Status = JobStatus.Failed;
@ -258,15 +263,15 @@ namespace Squidex.Domain.Apps.Entities.Backup
}
}
private async Task CleanupAsync()
private async Task CleanupAsync(IEnumerable<BackupHandler> handlers)
{
await Safe.DeleteAsync(backupArchiveLocation, CurrentJob.Id, log);
await Safe.DeleteAsync(backupArchiveLocation, CurrentJob.Id.ToString(), log);
if (CurrentJob.AppId != Guid.Empty)
{
foreach (var handler in handlers)
{
await Safe.CleanupRestoreAsync(handler, CurrentJob.AppId, CurrentJob.Id, log);
await Safe.CleanupRestoreErrorAsync(handler, CurrentJob.AppId, CurrentJob.Id, log);
}
}
}
@ -275,22 +280,22 @@ namespace Squidex.Domain.Apps.Entities.Backup
{
Log("Downloading Backup");
await backupArchiveLocation.DownloadAsync(CurrentJob.Url, CurrentJob.Id);
await backupArchiveLocation.DownloadAsync(CurrentJob.Url, CurrentJob.Id.ToString());
Log("Downloaded Backup");
}
private async Task ReadEventsAsync(BackupReader reader)
private async Task ReadEventsAsync(BackupReader reader, IEnumerable<BackupHandler> handlers)
{
await reader.ReadEventsAsync(streamNameResolver, eventDataFormatter, async storedEvent =>
{
await HandleEventAsync(reader, storedEvent.Stream, storedEvent.Event);
await HandleEventAsync(reader, handlers, storedEvent.Stream, storedEvent.Event);
});
Log($"Reading {reader.ReadEvents} events and {reader.ReadAttachments} attachments completed.", true);
}
private async Task HandleEventAsync(BackupReader reader, string stream, Envelope<IEvent> @event)
private async Task HandleEventAsync(BackupReader reader, IEnumerable<BackupHandler> handlers, string stream, Envelope<IEvent> @event)
{
if (@event.Payload is SquidexEvent squidexEvent)
{
@ -340,6 +345,11 @@ namespace Squidex.Domain.Apps.Entities.Backup
}
}
private IEnumerable<BackupHandler> CreateHandlers()
{
return serviceProvider.GetRequiredService<IEnumerable<BackupHandler>>();
}
public Task<J<IRestoreJob>> GetJobAsync()
{
return Task.FromResult<J<IRestoreJob>>(CurrentJob);

7
src/Squidex.Domain.Apps.Entities/Backup/TempFolderBackupArchiveLocation.cs

@ -5,7 +5,6 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.IO;
using System.Threading.Tasks;
using Squidex.Infrastructure.Tasks;
@ -14,14 +13,14 @@ namespace Squidex.Domain.Apps.Entities.Backup
{
public sealed class TempFolderBackupArchiveLocation : IBackupArchiveLocation
{
public Task<Stream> OpenStreamAsync(Guid backupId)
public Task<Stream> OpenStreamAsync(string backupId)
{
var tempFile = GetTempFile(backupId);
return Task.FromResult<Stream>(new FileStream(tempFile, FileMode.OpenOrCreate, FileAccess.ReadWrite));
}
public Task DeleteArchiveAsync(Guid backupId)
public Task DeleteArchiveAsync(string backupId)
{
var tempFile = GetTempFile(backupId);
@ -36,7 +35,7 @@ namespace Squidex.Domain.Apps.Entities.Backup
return TaskHelper.Done;
}
private static string GetTempFile(Guid backupId)
private static string GetTempFile(string backupId)
{
return Path.Combine(Path.GetTempPath(), backupId + ".zip");
}

2
src/Squidex/app/features/settings/pages/backups/backups-page.component.html

@ -40,7 +40,7 @@
<div *ngSwitchCase="'Completed'" class="backup-status backup-status-success">
<i class="icon-checkmark"></i>
</div>
<div *NgSwitchDefault class="backup-status backup-status-pending spin">
<div *ngSwitchDefault class="backup-status backup-status-pending spin">
<i class="icon-hour-glass"></i>
</div>
</div>

6
src/Squidex/appsettings.json

@ -430,6 +430,10 @@
/*
* Set to true to rebuild schemas.
*/
"schemas": false
"schemas": false,
/*
* Set to true to rebuild indexes.
*/
"indexes": false
}
}

10
src/Squidex/package-lock.json

@ -2037,7 +2037,7 @@
"dependencies": {
"jsesc": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
"resolved": "http://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
"integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=",
"dev": true
},
@ -9249,7 +9249,7 @@
},
"node-fetch": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz",
"resolved": "http://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz",
"integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U="
},
"node-forge": {
@ -9639,7 +9639,7 @@
},
"onetime": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
"resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
"integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=",
"dev": true
},
@ -13298,7 +13298,7 @@
"dependencies": {
"json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"resolved": "http://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"dev": true,
"requires": {
@ -15408,7 +15408,7 @@
},
"whatwg-fetch": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz",
"resolved": "http://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz",
"integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng=="
},
"which": {

2
tools/Migrate_00/Program.cs

@ -22,7 +22,7 @@ namespace Migrate_00
var collection = mongoDatabase.GetCollection<BsonDocument>("Events");
Console.Write("Migrate Indices.....");
Console.Write("Migrate indexes.....");
collection.Indexes.DropAll();

2
tools/Migrate_01/RebuildOptions.cs

@ -15,6 +15,8 @@ namespace Migrate_01
public bool Contents { get; set; }
public bool Indexes { get; set; }
public bool Rules { get; set; }
public bool Schemas { get; set; }

11
tools/Migrate_01/RebuildRunner.cs

@ -8,6 +8,7 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using Migrate_01.Migrations;
using Squidex.Infrastructure;
namespace Migrate_01
@ -15,15 +16,18 @@ namespace Migrate_01
public sealed class RebuildRunner
{
private readonly Rebuilder rebuilder;
private readonly PopulateGrainIndexes populateGrainIndexes;
private readonly RebuildOptions rebuildOptions;
public RebuildRunner(Rebuilder rebuilder, IOptions<RebuildOptions> rebuildOptions)
public RebuildRunner(Rebuilder rebuilder, IOptions<RebuildOptions> rebuildOptions, PopulateGrainIndexes populateGrainIndexes)
{
Guard.NotNull(rebuilder, nameof(rebuilder));
Guard.NotNull(rebuildOptions, nameof(rebuildOptions));
Guard.NotNull(populateGrainIndexes, nameof(populateGrainIndexes));
this.rebuilder = rebuilder;
this.rebuildOptions = rebuildOptions.Value;
this.populateGrainIndexes = populateGrainIndexes;
}
public async Task RunAsync(CancellationToken ct)
@ -52,6 +56,11 @@ namespace Migrate_01
{
await rebuilder.RebuildContentAsync(ct);
}
if (rebuildOptions.Indexes)
{
await populateGrainIndexes.UpdateAsync();
}
}
}
}

Loading…
Cancel
Save