From e052364595fdbfefd35a0745982cc28bf05c5939 Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Sun, 19 Aug 2018 14:51:30 +0200 Subject: [PATCH] Bugfixes for restore --- src/Squidex.Domain.Apps.Entities/Apps/BackupApps.cs | 3 +++ .../Backup/BackupGrain.cs | 2 +- .../States/DefaultStreamNameResolver.cs | 2 +- .../pages/restore/restore-page.component.html | 3 +++ .../pages/restore/restore-page.component.ts | 2 +- .../app/shared/services/backups.service.spec.ts | 5 +++-- src/Squidex/app/shared/services/backups.service.ts | 12 ++++++++++-- src/Squidex/app/shared/state/backups.forms.ts | 8 +++++++- 8 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/Squidex.Domain.Apps.Entities/Apps/BackupApps.cs b/src/Squidex.Domain.Apps.Entities/Apps/BackupApps.cs index c54ae17a5..eed1cdf70 100644 --- a/src/Squidex.Domain.Apps.Entities/Apps/BackupApps.cs +++ b/src/Squidex.Domain.Apps.Entities/Apps/BackupApps.cs @@ -11,6 +11,7 @@ using System.Threading.Tasks; using Newtonsoft.Json.Linq; using Orleans; using Squidex.Domain.Apps.Entities.Apps.Indexes; +using Squidex.Domain.Apps.Entities.Apps.State; using Squidex.Domain.Apps.Entities.Backup; using Squidex.Domain.Apps.Events; using Squidex.Domain.Apps.Events.Apps; @@ -166,6 +167,8 @@ namespace Squidex.Domain.Apps.Entities.Apps public override async Task CompleteRestoreAsync(Guid appId, BackupReader reader) { + await RebuildAsync(appId, (e, s) => s.Apply(e)); + await grainFactory.GetGrain(SingleGrain.Id).AddAppAsync(appCreated.AppId.Id, appCreated.AppId.Name); foreach (var user in activeUsers) diff --git a/src/Squidex.Domain.Apps.Entities/Backup/BackupGrain.cs b/src/Squidex.Domain.Apps.Entities/Backup/BackupGrain.cs index b1f87e841..21067ce66 100644 --- a/src/Squidex.Domain.Apps.Entities/Backup/BackupGrain.cs +++ b/src/Squidex.Domain.Apps.Entities/Backup/BackupGrain.cs @@ -139,7 +139,7 @@ namespace Squidex.Domain.Apps.Entities.Backup { using (var stream = await backupArchiveLocation.OpenStreamAsync(job.Id)) { - using (var writer = new BackupWriter(stream)) + using (var writer = new BackupWriter(stream, true)) { await eventStore.QueryAsync(async storedEvent => { diff --git a/src/Squidex.Infrastructure/States/DefaultStreamNameResolver.cs b/src/Squidex.Infrastructure/States/DefaultStreamNameResolver.cs index 2351cd68d..582011a20 100644 --- a/src/Squidex.Infrastructure/States/DefaultStreamNameResolver.cs +++ b/src/Squidex.Infrastructure/States/DefaultStreamNameResolver.cs @@ -38,7 +38,7 @@ namespace Squidex.Infrastructure.States Guard.NotNullOrEmpty(streamName, nameof(streamName)); Guard.NotNull(idGenerator, nameof(idGenerator)); - var positionOfDash = streamName.LastIndexOf('-'); + var positionOfDash = streamName.IndexOf('-'); if (positionOfDash >= 0) { diff --git a/src/Squidex/app/features/administration/pages/restore/restore-page.component.html b/src/Squidex/app/features/administration/pages/restore/restore-page.component.html index 82dbb493b..9ddcbc968 100644 --- a/src/Squidex/app/features/administration/pages/restore/restore-page.component.html +++ b/src/Squidex/app/features/administration/pages/restore/restore-page.component.html @@ -55,6 +55,9 @@
+
+ +
diff --git a/src/Squidex/app/features/administration/pages/restore/restore-page.component.ts b/src/Squidex/app/features/administration/pages/restore/restore-page.component.ts index bc3883734..fa8977ccf 100644 --- a/src/Squidex/app/features/administration/pages/restore/restore-page.component.ts +++ b/src/Squidex/app/features/administration/pages/restore/restore-page.component.ts @@ -57,7 +57,7 @@ export class RestorePageComponent implements OnDestroy, OnInit { if (value) { this.restoreForm.submitCompleted({}); - this.backupsService.postRestore(value.url) + this.backupsService.postRestore(value) .subscribe(() => { this.dialogs.notifyInfo('Restore started, it can take several minutes to complete.'); }, error => { diff --git a/src/Squidex/app/shared/services/backups.service.spec.ts b/src/Squidex/app/shared/services/backups.service.spec.ts index 22a51cb2d..c88b0f161 100644 --- a/src/Squidex/app/shared/services/backups.service.spec.ts +++ b/src/Squidex/app/shared/services/backups.service.spec.ts @@ -14,7 +14,8 @@ import { BackupDto, BackupsService, DateTime, - RestoreDto + RestoreDto, + StartRestoreDto } from './../'; describe('BackupsService', () => { @@ -169,7 +170,7 @@ describe('BackupsService', () => { it('should make post request to start restore', inject([BackupsService, HttpTestingController], (backupsService: BackupsService, httpMock: HttpTestingController) => { - backupsService.postRestore('http://url').subscribe(); + backupsService.postRestore(new StartRestoreDto('http://url')).subscribe(); const req = httpMock.expectOne('http://service/p/api/apps/restore'); diff --git a/src/Squidex/app/shared/services/backups.service.ts b/src/Squidex/app/shared/services/backups.service.ts index 676e968a9..68b8298a3 100644 --- a/src/Squidex/app/shared/services/backups.service.ts +++ b/src/Squidex/app/shared/services/backups.service.ts @@ -43,6 +43,14 @@ export class RestoreDto { } } +export class StartRestoreDto { + constructor( + public readonly url: string, + public readonly newAppName?: string + ) { + } +} + @Injectable() export class BackupsService { constructor( @@ -106,10 +114,10 @@ export class BackupsService { pretifyError('Failed to start backup.')); } - public postRestore(downloadUrl: string): Observable { + public postRestore(dto: StartRestoreDto): Observable { const url = this.apiUrl.buildUrl(`api/apps/restore`); - return this.http.post(url, { url: downloadUrl }).pipe( + return this.http.post(url, dto).pipe( tap(() => { this.analytics.trackEvent('Restore', 'Started'); }), diff --git a/src/Squidex/app/shared/state/backups.forms.ts b/src/Squidex/app/shared/state/backups.forms.ts index cbdb82d5b..475050a6c 100644 --- a/src/Squidex/app/shared/state/backups.forms.ts +++ b/src/Squidex/app/shared/state/backups.forms.ts @@ -8,7 +8,7 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { map, startWith } from 'rxjs/operators'; -import { Form } from '@app/framework'; +import { Form, ValidatorsEx } from '@app/framework'; export class RestoreForm extends Form { public hasNoUrl = @@ -16,6 +16,12 @@ export class RestoreForm extends Form { constructor(formBuilder: FormBuilder) { super(formBuilder.group({ + name: [null, + [ + Validators.maxLength(40), + ValidatorsEx.pattern('[a-z0-9]+(\-[a-z0-9]+)*', 'Name can contain lower case letters (a-z), numbers and dashes (not at the end).') + ] + ], url: [null, [ Validators.required