Migrate policy API calls to generated service (#17782)

Signed-off-by: AllForNothing <sshijun@vmware.com>

Signed-off-by: AllForNothing <sshijun@vmware.com>
This commit is contained in:
Shijun Sun 2022-11-15 17:26:20 +08:00 committed by GitHub
parent f2212eef25
commit e86e9aa529
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 417 additions and 656 deletions

View File

@ -8,6 +8,7 @@ import { clone } from '../../../../shared/units/utils';
import { InlineAlertComponent } from '../../../../shared/components/inline-alert/inline-alert.component'; import { InlineAlertComponent } from '../../../../shared/components/inline-alert/inline-alert.component';
import { SharedTestingModule } from '../../../../shared/shared.module'; import { SharedTestingModule } from '../../../../shared/shared.module';
import { AddImmutableRuleComponent } from './add-rule/add-immutable-rule.component'; import { AddImmutableRuleComponent } from './add-rule/add-immutable-rule.component';
import { ImmutableService } from '../../../../../../ng-swagger-gen/services/immutable.service';
describe('ImmutableTagComponent', () => { describe('ImmutableTagComponent', () => {
let component: ImmutableTagComponent; let component: ImmutableTagComponent;
@ -110,16 +111,13 @@ describe('ImmutableTagComponent', () => {
}, },
}, },
]; ];
const fakedImmutableTagService = { const mockedImmutableService = {
getI18nKey() { getRentenitionMetadata() {
return 'test';
},
getRetentionMetadata() {
return throwError(() => { return throwError(() => {
return { error: { message: 'error' } }; return { error: { message: 'error' } };
}); });
}, },
getRules(projectId) { ListImmuRules(projectId) {
if (projectId) { if (projectId) {
return of(mockRules); return of(mockRules);
} }
@ -127,13 +125,13 @@ describe('ImmutableTagComponent', () => {
return 'error'; return 'error';
}); });
}, },
updateRule() { UpdateImmuRule() {
return of(null); return of(null);
}, },
deleteRule() { DeleteImmuRule() {
return of(null); return of(null);
}, },
createRule(projectId, cloneRuleNoId) { CreateImmuRule(projectId, cloneRuleNoId) {
if (projectId) { if (projectId) {
return of(mockRules); return of(mockRules);
} }
@ -145,6 +143,11 @@ describe('ImmutableTagComponent', () => {
return of(null); return of(null);
}, },
}; };
const fakedImmutableTagService = {
getI18nKey() {
return 'test';
},
};
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
declarations: [ declarations: [
@ -159,6 +162,10 @@ describe('ImmutableTagComponent', () => {
provide: ImmutableTagService, provide: ImmutableTagService,
useValue: fakedImmutableTagService, useValue: fakedImmutableTagService,
}, },
{
provide: ImmutableService,
useValue: mockedImmutableService,
},
{ {
provide: ActivatedRoute, provide: ActivatedRoute,
useValue: { useValue: {

View File

@ -1,11 +1,17 @@
import { Component, OnInit, ViewChild } from '@angular/core'; import { Component, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { ImmutableTagService } from './immutable-tag.service'; import { ImmutableTagService } from './immutable-tag.service';
import { ImmutableRetentionRule } from '../tag-retention/retention'; import {
ImmutableRetentionRule,
RuleMetadate,
} from '../tag-retention/retention';
import { finalize } from 'rxjs/operators'; import { finalize } from 'rxjs/operators';
import { ErrorHandler } from '../../../../shared/units/error-handler'; import { ErrorHandler } from '../../../../shared/units/error-handler';
import { clone } from '../../../../shared/units/utils'; import { clone } from '../../../../shared/units/utils';
import { AddImmutableRuleComponent } from './add-rule/add-immutable-rule.component'; import { AddImmutableRuleComponent } from './add-rule/add-immutable-rule.component';
import { ImmutableService } from '../../../../../../ng-swagger-gen/services/immutable.service';
import { RetentionService } from '../../../../../../ng-swagger-gen/services/retention.service';
import { ProjectService } from '../../../../../../ng-swagger-gen/services/project.service';
@Component({ @Component({
selector: 'app-immutable-tag', selector: 'app-immutable-tag',
@ -25,7 +31,10 @@ export class ImmutableTagComponent implements OnInit {
constructor( constructor(
private route: ActivatedRoute, private route: ActivatedRoute,
private immutableTagService: ImmutableTagService, private immutableTagService: ImmutableTagService,
public errorHandler: ErrorHandler private immutableService: ImmutableService,
private retentionService: RetentionService,
public errorHandler: ErrorHandler,
private projectService: ProjectService
) {} ) {}
ngOnInit() { ngOnInit() {
@ -35,27 +44,31 @@ export class ImmutableTagComponent implements OnInit {
} }
getMetadata() { getMetadata() {
this.immutableTagService.getRetentionMetadata().subscribe( this.retentionService.getRentenitionMetadata().subscribe({
response => { next: res => {
this.addRuleComponent.metadata = response; this.addRuleComponent.metadata = res as RuleMetadate;
}, },
error => { error: err => {
this.errorHandler.error(error); this.errorHandler.error(err);
} },
); });
} }
getRules() { getRules() {
this.immutableTagService.getRules(this.projectId).subscribe( this.immutableService
response => { .ListImmuRules({
this.rules = response as ImmutableRetentionRule[]; projectNameOrId: this.projectId.toString(),
this.loadingRule = false; })
}, .subscribe({
error => { next: res => {
this.errorHandler.error(error); this.rules = res as ImmutableRetentionRule[];
this.loadingRule = false; this.loadingRule = false;
} },
); error: err => {
this.errorHandler.error(err);
this.loadingRule = false;
},
});
} }
editRuleByIndex(index) { editRuleByIndex(index) {
@ -71,31 +84,40 @@ export class ImmutableTagComponent implements OnInit {
cloneRule.disabled = isActionDisable; cloneRule.disabled = isActionDisable;
this.ruleIndex = -1; this.ruleIndex = -1;
this.loadingRule = true; this.loadingRule = true;
this.immutableTagService this.immutableService
.updateRule(this.projectId, cloneRule) .UpdateImmuRule({
.subscribe( immutableRuleId: cloneRule.id,
response => { projectNameOrId: this.projectId.toString(),
ImmutableRule: cloneRule,
})
.subscribe({
next: res => {
this.getRules(); this.getRules();
}, },
error => { error: err => {
this.loadingRule = false; this.loadingRule = false;
this.errorHandler.error(error); this.errorHandler.error(err);
} },
); });
} }
deleteRule(ruleId) { deleteRule(ruleId) {
// // if rules is empty, clear schedule. // // if rules is empty, clear schedule.
this.ruleIndex = -1; this.ruleIndex = -1;
this.loadingRule = true; this.loadingRule = true;
this.immutableTagService.deleteRule(this.projectId, ruleId).subscribe( this.immutableService
response => { .DeleteImmuRule({
this.getRules(); projectNameOrId: this.projectId.toString(),
}, immutableRuleId: ruleId,
error => { })
this.loadingRule = false; .subscribe({
this.errorHandler.error(error); next: res => {
} this.getRules();
); },
error: err => {
this.loadingRule = false;
this.errorHandler.error(err);
},
});
} }
openAddRule() { openAddRule() {
@ -113,15 +135,19 @@ export class ImmutableTagComponent implements OnInit {
} }
refreshAfterCreatRetention() { refreshAfterCreatRetention() {
this.immutableTagService.getProjectInfo(this.projectId).subscribe( this.projectService
response => { .getProject({
this.getRules(); projectNameOrId: this.projectId.toString(),
}, })
error => { .subscribe({
this.loadingRule = false; next: res => {
this.errorHandler.error(error); this.getRules();
} },
); error: err => {
this.loadingRule = false;
this.errorHandler.error(err);
},
});
} }
clickAdd(rule) { clickAdd(rule) {
@ -129,76 +155,64 @@ export class ImmutableTagComponent implements OnInit {
this.addRuleComponent.onGoing = true; this.addRuleComponent.onGoing = true;
if (this.addRuleComponent.isAdd) { if (this.addRuleComponent.isAdd) {
if (!rule.id) { if (!rule.id) {
this.immutableTagService this.immutableService
.createRule(this.projectId, rule) .CreateImmuRule({
projectNameOrId: this.projectId.toString(),
ImmutableRule: rule,
})
.pipe( .pipe(
finalize(() => (this.addRuleComponent.onGoing = false)) finalize(() => (this.addRuleComponent.onGoing = false))
) )
.subscribe( .subscribe({
response => { next: res => {
this.refreshAfterCreatRetention(); this.refreshAfterCreatRetention();
this.addRuleComponent.close(); this.addRuleComponent.close();
}, },
error => { error: err => {
if (error && error.error && error.error.message) { if (err && err.error && err.error.message) {
error = this.immutableTagService.getI18nKey( err = this.immutableTagService.getI18nKey(
error.error.message err.error.message
); );
} }
this.addRuleComponent.inlineAlert.showInlineError( this.addRuleComponent.inlineAlert.showInlineError(
error err
); );
this.loadingRule = false; this.loadingRule = false;
}
);
} else {
this.immutableTagService
.updateRule(this.projectId, rule)
.pipe(
finalize(() => (this.addRuleComponent.onGoing = false))
)
.subscribe(
response => {
this.getRules();
this.addRuleComponent.close();
}, },
error => { });
this.loadingRule = false; } else {
if (error && error.error && error.error.message) { this.updateRule(rule);
error = this.immutableTagService.getI18nKey(
error.error.message
);
}
this.addRuleComponent.inlineAlert.showInlineError(
error
);
}
);
} }
} else { } else {
this.immutableTagService this.updateRule(rule);
.updateRule(this.projectId, rule)
.pipe(finalize(() => (this.addRuleComponent.onGoing = false)))
.subscribe(
response => {
this.getRules();
this.addRuleComponent.close();
},
error => {
if (error && error.error && error.error.message) {
error = this.immutableTagService.getI18nKey(
error.error.message
);
}
this.addRuleComponent.inlineAlert.showInlineError(
error
);
this.loadingRule = false;
}
);
} }
} }
updateRule(rule: any) {
this.immutableService
.UpdateImmuRule({
projectNameOrId: this.projectId.toString(),
immutableRuleId: rule.id,
ImmutableRule: rule,
})
.pipe(finalize(() => (this.addRuleComponent.onGoing = false)))
.subscribe({
next: res => {
this.getRules();
this.addRuleComponent.close();
},
error: err => {
this.loadingRule = false;
if (err && err.error && err.error.message) {
err = this.immutableTagService.getI18nKey(
err.error.message
);
}
this.addRuleComponent.inlineAlert.showInlineError(err);
},
});
}
formatPattern(pattern: string): string { formatPattern(pattern: string): string {
let str: string = pattern; let str: string = pattern;
if (/^{\S+}$/.test(str)) { if (/^{\S+}$/.test(str)) {

View File

@ -1,15 +1,10 @@
import { ImmutableTagService } from './immutable-tag.service'; import { ImmutableTagService } from './immutable-tag.service';
import { TestBed, inject } from '@angular/core/testing'; import { TestBed, inject } from '@angular/core/testing';
import {
HttpClientTestingModule,
HttpTestingController,
} from '@angular/common/http/testing';
describe('ImmutableTagService', () => { describe('ImmutableTagService', () => {
beforeEach(() => beforeEach(() =>
TestBed.configureTestingModule({ TestBed.configureTestingModule({
providers: [ImmutableTagService], providers: [ImmutableTagService],
imports: [HttpClientTestingModule],
}) })
); );
@ -17,114 +12,7 @@ describe('ImmutableTagService', () => {
const service: ImmutableTagService = TestBed.get(ImmutableTagService); const service: ImmutableTagService = TestBed.get(ImmutableTagService);
expect(service).toBeTruthy(); expect(service).toBeTruthy();
}); });
it('should get rules', inject( it('should get rules', inject([ImmutableTagService], service => {
[HttpTestingController, ImmutableTagService], expect(service).toBeTruthy();
( }));
httpMock: HttpTestingController,
immutableTagService: ImmutableTagService
) => {
const mockRules = [
{
id: 1,
project_id: 1,
disabled: false,
priority: 0,
action: 'immutable',
template: 'immutable_template',
tag_selectors: [
{
kind: 'doublestar',
decoration: 'matches',
pattern: '**',
},
],
scope_selectors: {
repository: [
{
kind: 'doublestar',
decoration: 'repoMatches',
pattern: '**',
},
],
},
},
{
id: 2,
project_id: 1,
disabled: false,
priority: 0,
action: 'immutable',
template: 'immutable_template',
tag_selectors: [
{
kind: 'doublestar',
decoration: 'matches',
pattern: '44',
},
],
scope_selectors: {
repository: [
{
kind: 'doublestar',
decoration: 'repoMatches',
pattern: '**',
},
],
},
},
{
id: 3,
project_id: 1,
disabled: false,
priority: 0,
action: 'immutable',
template: 'immutable_template',
tag_selectors: [
{
kind: 'doublestar',
decoration: 'matches',
pattern: '555',
},
],
scope_selectors: {
repository: [
{
kind: 'doublestar',
decoration: 'repoMatches',
pattern: '**',
},
],
},
},
{
id: 4,
project_id: 1,
disabled: false,
priority: 0,
action: 'immutable',
template: 'immutable_template',
tag_selectors: [
{
kind: 'doublestar',
decoration: 'matches',
pattern: 'fff**',
},
],
scope_selectors: {
repository: [
{
kind: 'doublestar',
decoration: 'repoMatches',
pattern: '**ggg',
},
],
},
},
];
immutableTagService.getRules(1).subscribe(res => {
expect(res).toEqual(mockRules);
});
}
));
}); });

View File

@ -1,16 +1,4 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import {
ImmutableRetentionRule,
RuleMetadate,
} from '../tag-retention/retention';
import { Observable, throwError as observableThrowError } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { Project } from '../../project';
import {
CURRENT_BASE_HREF,
HTTP_JSON_OPTIONS,
} from '../../../../shared/units/utils';
@Injectable() @Injectable()
export class ImmutableTagService { export class ImmutableTagService {
@ -25,59 +13,10 @@ export class ImmutableTagService {
nothing: 'NONE', nothing: 'NONE',
}; };
constructor(private http: HttpClient) {}
getI18nKey(str: string): string { getI18nKey(str: string): string {
if (this.I18nMap[str.trim()]) { if (this.I18nMap[str.trim()]) {
return 'IMMUTABLE_TAG.' + this.I18nMap[str.trim()]; return 'IMMUTABLE_TAG.' + this.I18nMap[str.trim()];
} }
return str; return str;
} }
getRetentionMetadata(): Observable<RuleMetadate> {
return this.http
.get(`${CURRENT_BASE_HREF}/retentions/metadatas`)
.pipe(map(response => response as RuleMetadate))
.pipe(catchError(error => observableThrowError(error)));
}
getRules(projectId): Observable<ImmutableRetentionRule[]> {
return this.http
.get(`${CURRENT_BASE_HREF}/projects/${projectId}/immutabletagrules`)
.pipe(map(response => response as ImmutableRetentionRule[]))
.pipe(catchError(error => observableThrowError(error)));
}
createRule(projectId: number, retention: ImmutableRetentionRule) {
return this.http
.post(
`${CURRENT_BASE_HREF}/projects/${projectId}/immutabletagrules`,
retention
)
.pipe(catchError(error => observableThrowError(error)));
}
updateRule(projectId, immutabletagrule: ImmutableRetentionRule) {
return this.http
.put(
`${CURRENT_BASE_HREF}/projects/${projectId}/immutabletagrules/${immutabletagrule.id}`,
immutabletagrule
)
.pipe(catchError(error => observableThrowError(error)));
}
deleteRule(projectId, ruleId) {
return this.http
.delete(
`${CURRENT_BASE_HREF}/projects/${projectId}/immutabletagrules/${ruleId}`,
HTTP_JSON_OPTIONS
)
.pipe(catchError(error => observableThrowError(error)));
}
getProjectInfo(projectId) {
return this.http
.get(`${CURRENT_BASE_HREF}/projects/${projectId}`)
.pipe(map(response => response as Project))
.pipe(catchError(error => observableThrowError(error)));
}
} }

View File

@ -157,3 +157,7 @@ export class RuleMetadate {
export const RUNNING: string = 'Running'; export const RUNNING: string = 'Running';
export const PENDING: string = 'Pending'; export const PENDING: string = 'Pending';
export const TIMEOUT: number = 5000; export const TIMEOUT: number = 5000;
export enum RetentionAction {
STOP = 'stop',
}

View File

@ -12,6 +12,7 @@ import { Registry } from '../../../../../../../../ng-swagger-gen/models/registry
import { of } from 'rxjs'; import { of } from 'rxjs';
import { delay } from 'rxjs/operators'; import { delay } from 'rxjs/operators';
import { TIMEOUT } from '../../retention'; import { TIMEOUT } from '../../retention';
import { RetentionService } from '../../../../../../../../ng-swagger-gen/services/retention.service';
describe('TagRetentionTasksComponent', () => { describe('TagRetentionTasksComponent', () => {
let component: TagRetentionTasksComponent; let component: TagRetentionTasksComponent;
@ -44,10 +45,13 @@ describe('TagRetentionTasksComponent', () => {
total: 1, total: 1,
}, },
]; ];
const mockedTagRetentionService = {
seeLog() {},
};
const mockTagRetentionService = { const mockRetentionService = {
count: 0, count: 0,
getExecutionHistory() { listRetentionTasksResponse() {
if (this.count === 0) { if (this.count === 0) {
this.count += 1; this.count += 1;
const response: HttpResponse<Array<Registry>> = const response: HttpResponse<Array<Registry>> =
@ -80,7 +84,11 @@ describe('TagRetentionTasksComponent', () => {
providers: [ providers: [
{ {
provide: TagRetentionService, provide: TagRetentionService,
useValue: mockTagRetentionService, useValue: mockedTagRetentionService,
},
{
provide: RetentionService,
useValue: mockRetentionService,
}, },
], ],
}).compileComponents(); }).compileComponents();

View File

@ -1,9 +1,10 @@
import { Component, Input, OnDestroy } from '@angular/core'; import { Component, Input, OnDestroy } from '@angular/core';
import { finalize } from 'rxjs/operators'; import { finalize } from 'rxjs/operators';
import { TagRetentionComponent } from '../../tag-retention.component'; import { TagRetentionComponent } from '../../tag-retention.component';
import { TagRetentionService } from '../../tag-retention.service';
import { ErrorHandler } from '../../../../../../shared/units/error-handler'; import { ErrorHandler } from '../../../../../../shared/units/error-handler';
import { PENDING, RUNNING, TIMEOUT } from '../../retention'; import { PENDING, RUNNING, TIMEOUT } from '../../retention';
import { RetentionService } from '../../../../../../../../ng-swagger-gen/services/retention.service';
import { TagRetentionService } from '../../tag-retention.service';
@Component({ @Component({
selector: 'app-tag-retention-tasks', selector: 'app-tag-retention-tasks',
@ -23,6 +24,7 @@ export class TagRetentionTasksComponent implements OnDestroy {
tasksTimeout; tasksTimeout;
constructor( constructor(
private tagRetentionService: TagRetentionService, private tagRetentionService: TagRetentionService,
private retentionService: RetentionService,
private errorHandler: ErrorHandler private errorHandler: ErrorHandler
) {} ) {}
ngOnDestroy() { ngOnDestroy() {
@ -33,32 +35,22 @@ export class TagRetentionTasksComponent implements OnDestroy {
} }
loadLog() { loadLog() {
this.loading = true; this.loading = true;
this.tagRetentionService this.retentionService
.getExecutionHistory( .listRetentionTasksResponse({
this.retentionId, id: this.retentionId,
this.executionId, eid: this.executionId,
this.page, page: this.page,
this.pageSize pageSize: this.pageSize,
) })
.pipe(finalize(() => (this.loading = false))) .pipe(finalize(() => (this.loading = false)))
.subscribe( .subscribe({
(response: any) => { next: res => {
// Get total count this.handleResponse(res);
if (response.headers) {
let xHeader: string =
response.headers.get('x-total-count');
if (xHeader) {
this.total = parseInt(xHeader, 0);
}
}
this.tasks = response.body as Array<any>;
TagRetentionComponent.calculateDuration(this.tasks);
this.loopGettingTasks();
}, },
error => { error: err => {
this.errorHandler.error(error); this.errorHandler.error(err);
} },
); });
} }
seeLog(executionId, taskId) { seeLog(executionId, taskId) {
this.tagRetentionService.seeLog(this.retentionId, executionId, taskId); this.tagRetentionService.seeLog(this.retentionId, executionId, taskId);
@ -72,28 +64,31 @@ export class TagRetentionTasksComponent implements OnDestroy {
}) })
) { ) {
this.tasksTimeout = setTimeout(() => { this.tasksTimeout = setTimeout(() => {
this.tagRetentionService this.retentionService
.getExecutionHistory( .listRetentionTasksResponse({
this.retentionId, id: this.retentionId,
this.executionId, eid: this.executionId,
this.page, page: this.page,
this.pageSize pageSize: this.pageSize,
) })
.pipe(finalize(() => (this.loading = false))) .pipe(finalize(() => (this.loading = false)))
.subscribe(res => { .subscribe(res => {
// Get total count this.handleResponse(res);
if (res.headers) {
let xHeader: string =
res.headers.get('x-total-count');
if (xHeader) {
this.total = parseInt(xHeader, 0);
}
}
this.tasks = res.body as Array<any>;
TagRetentionComponent.calculateDuration(this.tasks);
this.loopGettingTasks();
}); });
}, TIMEOUT); }, TIMEOUT);
} }
} }
handleResponse(res: any) {
// Get total count
if (res.headers) {
let xHeader: string = res.headers.get('x-total-count');
if (xHeader) {
this.total = parseInt(xHeader, 0);
}
}
this.tasks = res.body as Array<any>;
TagRetentionComponent.calculateDuration(this.tasks);
this.loopGettingTasks();
}
} }

View File

@ -15,6 +15,7 @@ import { delay } from 'rxjs/operators';
import { SharedTestingModule } from '../../../../shared/shared.module'; import { SharedTestingModule } from '../../../../shared/shared.module';
import { HttpHeaders, HttpResponse } from '@angular/common/http'; import { HttpHeaders, HttpResponse } from '@angular/common/http';
import { Registry } from '../../../../../../ng-swagger-gen/models/registry'; import { Registry } from '../../../../../../ng-swagger-gen/models/registry';
import { RetentionService } from 'ng-swagger-gen/services/retention.service';
describe('TagRetentionComponent', () => { describe('TagRetentionComponent', () => {
const mockedRunningExecutions = [ const mockedRunningExecutions = [
@ -42,18 +43,12 @@ describe('TagRetentionComponent', () => {
let component: TagRetentionComponent; let component: TagRetentionComponent;
let fixture: ComponentFixture<TagRetentionComponent>; let fixture: ComponentFixture<TagRetentionComponent>;
const mockTagRetentionService = { const mockTagRetentionService = {
seeLog: () => of(null).pipe(delay(0)),
};
const mockRetentionService = {
createRetention: () => of(null).pipe(delay(0)), createRetention: () => of(null).pipe(delay(0)),
updateRetention: () => of(null).pipe(delay(0)), updateRetention: () => of(null).pipe(delay(0)),
runNowTrigger: () => of(null).pipe(delay(0)), listRetentionExecutionsResponse() {
whatIfRunTrigger: () => of(null).pipe(delay(0)),
AbortRun: () => of(null).pipe(delay(0)),
seeLog: () => of(null).pipe(delay(0)),
getExecutionHistory: () =>
of({
body: [],
}).pipe(delay(0)),
count: 0,
getRunNowList() {
if (this.count === 0) { if (this.count === 0) {
this.count += 1; this.count += 1;
const response: HttpResponse<Array<Registry>> = const response: HttpResponse<Array<Registry>> =
@ -78,13 +73,7 @@ describe('TagRetentionComponent', () => {
return of(response).pipe(delay(0)); return of(response).pipe(delay(0));
} }
}, },
getProjectInfo: () => getRentenitionMetadata: () => of(new RuleMetadate()).pipe(delay(0)),
of({
metadata: {
retention_id: 1,
},
}).pipe(delay(0)),
getRetentionMetadata: () => of(new RuleMetadate()).pipe(delay(0)),
getRetention: () => of(new Retention()).pipe(delay(0)), getRetention: () => of(new Retention()).pipe(delay(0)),
}; };
const mockActivatedRoute = { const mockActivatedRoute = {
@ -115,6 +104,10 @@ describe('TagRetentionComponent', () => {
provide: TagRetentionService, provide: TagRetentionService,
useValue: mockTagRetentionService, useValue: mockTagRetentionService,
}, },
{
provide: RetentionService,
useValue: mockRetentionService,
},
{ provide: ActivatedRoute, useValue: mockActivatedRoute }, { provide: ActivatedRoute, useValue: mockActivatedRoute },
], ],
}).compileComponents(); }).compileComponents();

View File

@ -14,12 +14,17 @@
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { AddRuleComponent } from './add-rule/add-rule.component'; import { AddRuleComponent } from './add-rule/add-rule.component';
import { import { ClrDatagridStateInterface } from '@clr/angular';
ClrDatagridStateInterface,
ClrDatagridStringFilterInterface,
} from '@clr/angular';
import { TagRetentionService } from './tag-retention.service'; import { TagRetentionService } from './tag-retention.service';
import { PENDING, Retention, Rule, RUNNING, TIMEOUT } from './retention'; import {
PENDING,
Retention,
RetentionAction,
Rule,
RuleMetadate,
RUNNING,
TIMEOUT,
} from './retention';
import { finalize } from 'rxjs/operators'; import { finalize } from 'rxjs/operators';
import { CronScheduleComponent } from '../../../../shared/components/cron-schedule'; import { CronScheduleComponent } from '../../../../shared/components/cron-schedule';
import { ErrorHandler } from '../../../../shared/units/error-handler'; import { ErrorHandler } from '../../../../shared/units/error-handler';
@ -30,6 +35,9 @@ import {
PageSizeMapKeys, PageSizeMapKeys,
setPageSizeToLocalStorage, setPageSizeToLocalStorage,
} from '../../../../shared/units/utils'; } from '../../../../shared/units/utils';
import { RetentionService } from '../../../../../../ng-swagger-gen/services/retention.service';
import { RetentionPolicy } from '../../../../../../ng-swagger-gen/models/retention-policy';
import { ProjectService } from '../../../../../../ng-swagger-gen/services/project.service';
const MIN = 60000; const MIN = 60000;
const SEC = 1000; const SEC = 1000;
@ -53,24 +61,6 @@ const DECORATION = {
styleUrls: ['./tag-retention.component.scss'], styleUrls: ['./tag-retention.component.scss'],
}) })
export class TagRetentionComponent implements OnInit, OnDestroy { export class TagRetentionComponent implements OnInit, OnDestroy {
serialFilter: ClrDatagridStringFilterInterface<any> = {
accepts(item: any, search: string): boolean {
return item.id.toString().indexOf(search) !== -1;
},
};
statusFilter: ClrDatagridStringFilterInterface<any> = {
accepts(item: any, search: string): boolean {
return (
item.status.toLowerCase().indexOf(search.toLowerCase()) !== -1
);
},
};
dryRunFilter: ClrDatagridStringFilterInterface<any> = {
accepts(item: any, search: string): boolean {
let str = item.dry_run ? 'YES' : 'NO';
return str.indexOf(search) !== -1;
},
};
projectId: number; projectId: number;
isRetentionRunOpened: boolean = false; isRetentionRunOpened: boolean = false;
isAbortedOpened: boolean = false; isAbortedOpened: boolean = false;
@ -98,7 +88,9 @@ export class TagRetentionComponent implements OnInit, OnDestroy {
constructor( constructor(
private route: ActivatedRoute, private route: ActivatedRoute,
private tagRetentionService: TagRetentionService, private tagRetentionService: TagRetentionService,
private errorHandler: ErrorHandler private retentionService: RetentionService,
private errorHandler: ErrorHandler,
private projectService: ProjectService
) {} ) {}
originCron(): OriginCron { originCron(): OriginCron {
let originCron: OriginCron = { let originCron: OriginCron = {
@ -149,67 +141,74 @@ export class TagRetentionComponent implements OnInit, OnDestroy {
this.updateCron(this.cron); this.updateCron(this.cron);
} }
updateCron(cron: string) { updateCron(cron: string) {
let retention: Retention = clone(this.retention); let retention: RetentionPolicy = clone(this.retention);
retention.trigger.settings.cron = cron; retention.trigger.settings['cron'] = cron;
if (!this.retentionId) { if (!this.retentionId) {
this.tagRetentionService.createRetention(retention).subscribe( this.retentionService
response => { .createRetention({
this.cronScheduleComponent.isEditMode = false; policy: retention,
this.refreshAfterCreatRetention(); })
}, .subscribe({
error => { next: res => {
this.errorHandler.error(error); this.cronScheduleComponent.isEditMode = false;
} this.refreshAfterCreatRetention();
); },
error: err => {
this.errorHandler.error(err);
},
});
} else { } else {
this.tagRetentionService this.retentionService
.updateRetention(this.retentionId, retention) .updateRetention({
.subscribe( id: this.retentionId,
response => { policy: retention,
})
.subscribe({
next: res => {
this.cronScheduleComponent.isEditMode = false; this.cronScheduleComponent.isEditMode = false;
this.getRetention(); this.getRetention();
}, },
error => { error: err => {
this.errorHandler.error(error); this.errorHandler.error(err);
} },
); });
} }
} }
getMetadata() { getMetadata() {
this.tagRetentionService.getRetentionMetadata().subscribe( this.retentionService.getRentenitionMetadata().subscribe({
response => { next: res => {
this.addRuleComponent.metadata = response; this.addRuleComponent.metadata = res as RuleMetadate;
}, },
error => { error: err => {
this.errorHandler.error(error); this.errorHandler.error(err);
} },
); });
} }
getRetention() { getRetention() {
if (this.retentionId) { if (this.retentionId) {
this.tagRetentionService.getRetention(this.retentionId).subscribe( this.retentionService
response => { .getRetention({
if ( id: this.retentionId,
response && })
response.rules && .subscribe({
response.rules.length > 0 next: res => {
) { if (res?.rules?.length) {
response.rules.forEach(item => { res.rules.forEach(item => {
if (!item.params) { if (!item.params) {
item.params = {}; item.params = {};
} }
this.setRuleUntagged(item); this.setRuleUntagged(item);
}); });
} }
this.retention = response; this.retention = res as Retention;
this.loadingRule = false; this.loadingRule = false;
}, },
error => { error: err => {
this.errorHandler.error(error); this.errorHandler.error(err);
this.loadingRule = false; this.loadingRule = false;
} },
); });
} }
} }
@ -224,42 +223,48 @@ export class TagRetentionComponent implements OnInit, OnDestroy {
this.ruleIndex = -1; this.ruleIndex = -1;
} }
toggleDisable(index, isActionDisable) { toggleDisable(index, isActionDisable) {
let retention: Retention = clone(this.retention); let retention: RetentionPolicy = clone(this.retention);
retention.rules[index].disabled = isActionDisable; retention.rules[index].disabled = isActionDisable;
this.ruleIndex = -1; this.ruleIndex = -1;
this.loadingRule = true; this.loadingRule = true;
this.tagRetentionService this.retentionService
.updateRetention(this.retentionId, retention) .updateRetention({
.subscribe( id: this.retentionId,
response => { policy: retention,
})
.subscribe({
next: res => {
this.getRetention(); this.getRetention();
}, },
error => { error: err => {
this.loadingRule = false; this.loadingRule = false;
this.errorHandler.error(error); this.errorHandler.error(err);
} },
); });
} }
deleteRule(index) { deleteRule(index) {
let retention: Retention = clone(this.retention); let retention: RetentionPolicy = clone(this.retention);
retention.rules.splice(index, 1); retention.rules.splice(index, 1);
// if rules is empty, clear schedule. // if rules is empty, clear schedule.
if (retention.rules && retention.rules.length === 0) { if (retention.rules && retention.rules.length === 0) {
retention.trigger.settings.cron = ''; retention.trigger.settings['cron'] = '';
} }
this.ruleIndex = -1; this.ruleIndex = -1;
this.loadingRule = true; this.loadingRule = true;
this.tagRetentionService this.retentionService
.updateRetention(this.retentionId, retention) .updateRetention({
.subscribe( id: this.retentionId,
response => { policy: retention,
})
.subscribe({
next: res => {
this.getRetention(); this.getRetention();
}, },
error => { error: err => {
this.loadingRule = false; this.loadingRule = false;
this.errorHandler.error(error); this.errorHandler.error(err);
} },
); });
} }
setRuleUntagged(rule) { setRuleUntagged(rule) {
if (!rule.tag_selectors[0].extras) { if (!rule.tag_selectors[0].extras) {
@ -294,25 +299,39 @@ export class TagRetentionComponent implements OnInit, OnDestroy {
runRetention() { runRetention() {
this.isRetentionRunOpened = false; this.isRetentionRunOpened = false;
this.tagRetentionService.runNowTrigger(this.retentionId).subscribe( this.retentionService
response => { .triggerRetentionExecution({
this.refreshList(); id: this.retentionId,
}, body: {
error => { dry_run: false,
this.errorHandler.error(error); },
} })
); .subscribe({
next: res => {
this.refreshList();
},
error: err => {
this.errorHandler.error(err);
},
});
} }
whatIfRun() { whatIfRun() {
this.tagRetentionService.whatIfRunTrigger(this.retentionId).subscribe( this.retentionService
response => { .triggerRetentionExecution({
this.refreshList(); id: this.retentionId,
}, body: {
error => { dry_run: true,
this.errorHandler.error(error); },
} })
); .subscribe({
next: res => {
this.refreshList();
},
error: err => {
this.errorHandler.error(err);
},
});
} }
loopGettingExecutions() { loopGettingExecutions() {
if ( if (
@ -323,12 +342,12 @@ export class TagRetentionComponent implements OnInit, OnDestroy {
}) })
) { ) {
this.executionTimeout = setTimeout(() => { this.executionTimeout = setTimeout(() => {
this.tagRetentionService this.retentionService
.getRunNowList( .listRetentionExecutionsResponse({
this.retentionId, id: this.retentionId,
this.currentPage, page: this.currentPage,
this.pageSize pageSize: this.pageSize,
) })
.pipe(finalize(() => (this.loadingExecutions = false))) .pipe(finalize(() => (this.loadingExecutions = false)))
.subscribe(res => { .subscribe(res => {
// Get total count // Get total count
@ -370,33 +389,33 @@ export class TagRetentionComponent implements OnInit, OnDestroy {
); );
} }
this.loadingExecutions = true; this.loadingExecutions = true;
this.tagRetentionService this.retentionService
.getRunNowList( .listRetentionExecutionsResponse({
this.retentionId, id: this.retentionId,
this.currentPage, page: this.currentPage,
this.pageSize pageSize: this.pageSize,
) })
.pipe(finalize(() => (this.loadingExecutions = false))) .pipe(finalize(() => (this.loadingExecutions = false)))
.subscribe( .subscribe({
(response: any) => { next: res => {
// Get total count // Get total count
if (response.headers) { if (res.headers) {
let xHeader: string = let xHeader: string =
response.headers.get('x-total-count'); res.headers.get('x-total-count');
if (xHeader) { if (xHeader) {
this.totalCount = parseInt(xHeader, 0); this.totalCount = parseInt(xHeader, 0);
} }
} }
this.executionList = response.body as Array<any>; this.executionList = res.body as Array<any>;
TagRetentionComponent.calculateDuration( TagRetentionComponent.calculateDuration(
this.executionList this.executionList
); );
this.loopGettingExecutions(); this.loopGettingExecutions();
}, },
error => { error: err => {
this.errorHandler.error(error); this.errorHandler.error(err);
} },
); });
} else { } else {
setTimeout(() => { setTimeout(() => {
this.loadingExecutions = false; this.loadingExecutions = false;
@ -433,16 +452,22 @@ export class TagRetentionComponent implements OnInit, OnDestroy {
abortRun() { abortRun() {
this.isAbortedOpened = true; this.isAbortedOpened = true;
this.tagRetentionService this.retentionService
.AbortRun(this.retentionId, this.selectedItem.id) .operateRetentionExecution({
.subscribe( id: this.retentionId,
res => { eid: this.selectedItem.id,
body: {
action: RetentionAction.STOP,
},
})
.subscribe({
next: res => {
this.refreshList(); this.refreshList();
}, },
error => { error: err => {
this.errorHandler.error(error); this.errorHandler.error(err);
} },
); });
} }
abortRetention() { abortRetention() {
@ -457,95 +482,88 @@ export class TagRetentionComponent implements OnInit, OnDestroy {
} }
} }
refreshAfterCreatRetention() { refreshAfterCreatRetention() {
this.tagRetentionService.getProjectInfo(this.projectId).subscribe( this.projectService
response => { .getProject({
this.retentionId = response.metadata.retention_id; projectNameOrId: this.projectId.toString(),
this.refreshList(); })
this.getRetention(); .subscribe({
}, next: res => {
error => { this.retentionId = +res.metadata.retention_id;
this.loadingRule = false; this.refreshList();
this.errorHandler.error(error); this.getRetention();
} },
); error: err => {
this.loadingRule = false;
this.errorHandler.error(err);
},
});
} }
clickAdd(rule) { clickAdd(rule) {
this.loadingRule = true; this.loadingRule = true;
this.addRuleComponent.onGoing = true; this.addRuleComponent.onGoing = true;
if (this.addRuleComponent.isAdd) { if (this.addRuleComponent.isAdd) {
let retention: Retention = clone(this.retention); let retention: RetentionPolicy = clone(this.retention);
retention.rules.push(rule); retention.rules.push(rule);
if (!this.retentionId) { if (!this.retentionId) {
this.tagRetentionService.createRetention(retention).subscribe( this.retentionService
response => { .createRetention({
this.refreshAfterCreatRetention(); policy: retention,
this.addRuleComponent.close(); })
this.addRuleComponent.onGoing = false; .subscribe({
}, next: res => {
error => { this.refreshAfterCreatRetention();
if (error && error.error && error.error.message) {
error = this.tagRetentionService.getI18nKey(
error.error.message
);
}
this.addRuleComponent.inlineAlert.showInlineError(
error
);
this.loadingRule = false;
this.addRuleComponent.onGoing = false;
}
);
} else {
this.tagRetentionService
.updateRetention(this.retentionId, retention)
.subscribe(
response => {
this.getRetention();
this.addRuleComponent.close(); this.addRuleComponent.close();
this.addRuleComponent.onGoing = false; this.addRuleComponent.onGoing = false;
}, },
error => { error: err => {
this.loadingRule = false; if (err && err.error && err.error.message) {
this.addRuleComponent.onGoing = false; err = this.tagRetentionService.getI18nKey(
if (error && error.error && error.error.message) { err.error.message
error = this.tagRetentionService.getI18nKey(
error.error.message
); );
} }
this.addRuleComponent.inlineAlert.showInlineError( this.addRuleComponent.inlineAlert.showInlineError(
error err
); );
} this.loadingRule = false;
); this.addRuleComponent.onGoing = false;
},
});
} else {
this.updateRetention(retention);
} }
} else { } else {
let retention: Retention = clone(this.retention); let retention: RetentionPolicy = clone(this.retention);
retention.rules[this.editIndex] = rule; retention.rules[this.editIndex] = rule;
this.tagRetentionService this.updateRetention(retention);
.updateRetention(this.retentionId, retention)
.subscribe(
response => {
this.getRetention();
this.addRuleComponent.close();
this.addRuleComponent.onGoing = false;
},
error => {
if (error && error.error && error.error.message) {
error = this.tagRetentionService.getI18nKey(
error.error.message
);
}
this.addRuleComponent.inlineAlert.showInlineError(
error
);
this.loadingRule = false;
this.addRuleComponent.onGoing = false;
}
);
} }
} }
updateRetention(retention: RetentionPolicy) {
this.retentionService
.updateRetention({
id: this.retentionId,
policy: retention,
})
.subscribe({
next: res => {
this.getRetention();
this.addRuleComponent.close();
this.addRuleComponent.onGoing = false;
},
error: err => {
this.loadingRule = false;
this.addRuleComponent.onGoing = false;
if (err && err.error && err.error.message) {
err = this.tagRetentionService.getI18nKey(
err.error.message
);
}
this.addRuleComponent.inlineAlert.showInlineError(err);
},
});
}
seeLog(executionId, taskId) { seeLog(executionId, taskId) {
this.tagRetentionService.seeLog(this.retentionId, executionId, taskId); this.tagRetentionService.seeLog(this.retentionId, executionId, taskId);
} }

View File

@ -1,11 +1,9 @@
import { TestBed, inject } from '@angular/core/testing'; import { TestBed, inject } from '@angular/core/testing';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { TagRetentionService } from './tag-retention.service'; import { TagRetentionService } from './tag-retention.service';
describe('TagRetentionService', () => { describe('TagRetentionService', () => {
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [TagRetentionService], providers: [TagRetentionService],
}); });
}); });

View File

@ -12,15 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { HttpClient, HttpParams, HttpResponse } from '@angular/common/http'; import { CURRENT_BASE_HREF } from '../../../../shared/units/utils';
import { Retention, RuleMetadate } from './retention';
import { Observable, throwError as observableThrowError } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { Project } from '../../project';
import {
buildHttpRequestOptionsWithObserveResponse,
CURRENT_BASE_HREF,
} from '../../../../shared/units/utils';
@Injectable() @Injectable()
export class TagRetentionService { export class TagRetentionService {
@ -55,8 +47,6 @@ export class TagRetentionService {
'Parameters latestPulledN is too large': 'COUNT_LARGE', 'Parameters latestPulledN is too large': 'COUNT_LARGE',
}; };
constructor(private http: HttpClient) {}
getI18nKey(str: string): string { getI18nKey(str: string): string {
if (this.I18nMap[str.trim()]) { if (this.I18nMap[str.trim()]) {
return 'TAG_RETENTION.' + this.I18nMap[str.trim()]; return 'TAG_RETENTION.' + this.I18nMap[str.trim()];
@ -64,99 +54,6 @@ export class TagRetentionService {
return str; return str;
} }
getRetentionMetadata(): Observable<RuleMetadate> {
return this.http
.get(`${CURRENT_BASE_HREF}/retentions/metadatas`)
.pipe(map(response => response as RuleMetadate))
.pipe(catchError(error => observableThrowError(error)));
}
getRetention(retentionId): Observable<Retention> {
return this.http
.get(`${CURRENT_BASE_HREF}/retentions/${retentionId}`)
.pipe(map(response => response as Retention))
.pipe(catchError(error => observableThrowError(error)));
}
createRetention(retention: Retention) {
return this.http
.post(`${CURRENT_BASE_HREF}/retentions`, retention)
.pipe(catchError(error => observableThrowError(error)));
}
updateRetention(retentionId, retention: Retention) {
return this.http
.put(`${CURRENT_BASE_HREF}/retentions/${retentionId}`, retention)
.pipe(catchError(error => observableThrowError(error)));
}
getProjectInfo(projectId) {
return this.http
.get(`${CURRENT_BASE_HREF}/projects/${projectId}`)
.pipe(map(response => response as Project))
.pipe(catchError(error => observableThrowError(error)));
}
runNowTrigger(retentionId) {
return this.http
.post(`${CURRENT_BASE_HREF}/retentions/${retentionId}/executions`, {
dry_run: false,
})
.pipe(catchError(error => observableThrowError(error)));
}
whatIfRunTrigger(retentionId) {
return this.http
.post(`${CURRENT_BASE_HREF}/retentions/${retentionId}/executions`, {
dry_run: true,
})
.pipe(catchError(error => observableThrowError(error)));
}
AbortRun(retentionId, executionId) {
return this.http
.patch(
`${CURRENT_BASE_HREF}/retentions/${retentionId}/executions/${executionId}`,
{ action: 'stop' }
)
.pipe(catchError(error => observableThrowError(error)));
}
getRunNowList(retentionId, page: number, pageSize: number) {
let params = new HttpParams();
if (page && pageSize) {
params = params
.set('page', page + '')
.set('page_size', pageSize + '');
}
return this.http
.get<HttpResponse<Array<any>>>(
`${CURRENT_BASE_HREF}/retentions/${retentionId}/executions`,
buildHttpRequestOptionsWithObserveResponse(params)
)
.pipe(catchError(error => observableThrowError(error)));
}
getExecutionHistory(
retentionId,
executionId,
page: number,
pageSize: number
) {
let params = new HttpParams();
if (page && pageSize) {
params = params
.set('page', page + '')
.set('page_size', pageSize + '');
}
return this.http
.get<HttpResponse<Array<any>>>(
`${CURRENT_BASE_HREF}/retentions/${retentionId}/executions/${executionId}/tasks`,
buildHttpRequestOptionsWithObserveResponse(params)
)
.pipe(catchError(error => observableThrowError(error)));
}
seeLog(retentionId, executionId, taskId) { seeLog(retentionId, executionId, taskId) {
window.open( window.open(
`${CURRENT_BASE_HREF}/retentions/${retentionId}/executions/${executionId}/tasks/${taskId}`, `${CURRENT_BASE_HREF}/retentions/${retentionId}/executions/${executionId}/tasks/${taskId}`,