From e3929f0e95a3c839bdfe61d7e622a9e70758bd4f Mon Sep 17 00:00:00 2001 From: Steven Zou Date: Wed, 10 May 2017 15:41:20 +0800 Subject: [PATCH] Implement replication service interface --- .../src/service/access-log.service.spec.ts | 20 ++- src/ui_ng/lib/src/service/interface.ts | 25 ++- .../src/service/replication.service.spec.ts | 23 +++ .../lib/src/service/replication.service.ts | 155 ++++++++++++++---- .../src/service/repository.service.spec.ts | 18 +- src/ui_ng/lib/src/service/tag.service.spec.ts | 8 +- 6 files changed, 199 insertions(+), 50 deletions(-) diff --git a/src/ui_ng/lib/src/service/access-log.service.spec.ts b/src/ui_ng/lib/src/service/access-log.service.spec.ts index 254c29552..66bee5788 100644 --- a/src/ui_ng/lib/src/service/access-log.service.spec.ts +++ b/src/ui_ng/lib/src/service/access-log.service.spec.ts @@ -5,11 +5,13 @@ import { SharedModule } from '../shared/shared.module'; import { SERVICE_CONFIG, IServiceConfig } from '../service.config'; describe('AccessLogService', () => { - beforeEach(() => { - const mockConfig:IServiceConfig = { - logBaseEndpoint:"/api/logs/testing" - }; + const mockConfig: IServiceConfig = { + logBaseEndpoint: "/api/logs/testing" + }; + let config: IServiceConfig; + + beforeEach(() => { TestBed.configureTestingModule({ imports: [ SharedModule @@ -19,14 +21,22 @@ describe('AccessLogService', () => { { provide: AccessLogService, useClass: AccessLogDefaultService - },{ + }, { provide: SERVICE_CONFIG, useValue: mockConfig }] }); + + config = TestBed.get(SERVICE_CONFIG); }); it('should be initialized', inject([AccessLogDefaultService], (service: AccessLogService) => { expect(service).toBeTruthy(); })); + + it('should inject the right config', () => { + expect(config).toBeTruthy(); + expect(config.logBaseEndpoint).toEqual("/api/logs/testing"); + }); + }); diff --git a/src/ui_ng/lib/src/service/interface.ts b/src/ui_ng/lib/src/service/interface.ts index d72edce88..7c21fef29 100644 --- a/src/ui_ng/lib/src/service/interface.ts +++ b/src/ui_ng/lib/src/service/interface.ts @@ -5,7 +5,7 @@ * @interface Base */ export interface Base { - id?: string; + id?: string | number; name?: string; creation_time?: Date; update_time?: Date; @@ -59,7 +59,7 @@ export interface Repository extends Base { * @interface Tag * @extends {Base} */ -export interface Tag extends Base { +export interface Tag extends Base { tag: string; manifest: TagManifest; signed?: number; //May NOT exist @@ -80,7 +80,18 @@ export interface Endpoint extends Base { } * @export * @interface ReplicationRule */ -export interface ReplicationRule { } +export interface ReplicationRule extends Base { + project_id: number; + project_name: string; + target_id: number; + target_name: string; + enabled: number; + description?: string; + cron_str?: string; + start_time?: Date; + error_job_count?: number; + deleted: number; +} /** * Interface for replication job. @@ -88,7 +99,13 @@ export interface ReplicationRule { } * @export * @interface ReplicationJob */ -export interface ReplicationJob { } +export interface ReplicationJob extends Base { + status: string; + repository: string; + policy_id: number; + operation: string; + tags: string; +} /** * Interface for access log. diff --git a/src/ui_ng/lib/src/service/replication.service.spec.ts b/src/ui_ng/lib/src/service/replication.service.spec.ts index aa8285319..b5022e1cb 100644 --- a/src/ui_ng/lib/src/service/replication.service.spec.ts +++ b/src/ui_ng/lib/src/service/replication.service.spec.ts @@ -1,20 +1,43 @@ import { TestBed, inject } from '@angular/core/testing'; import { ReplicationService, ReplicationDefaultService } from './replication.service'; +import { SharedModule } from '../shared/shared.module'; +import { SERVICE_CONFIG, IServiceConfig } from '../service.config'; describe('ReplicationService', () => { + const mockConfig: IServiceConfig = { + replicationRuleEndpoint: "/api/policies/replication/testing", + replicationJobEndpoint: "/api/jobs/replication/testing" + }; + + let config: IServiceConfig; + beforeEach(() => { TestBed.configureTestingModule({ + imports: [ + SharedModule + ], providers: [ ReplicationDefaultService, { provide: ReplicationService, useClass: ReplicationDefaultService + }, { + provide: SERVICE_CONFIG, + useValue: mockConfig }] }); + + config = TestBed.get(SERVICE_CONFIG); }); it('should be initialized', inject([ReplicationDefaultService], (service: ReplicationService) => { expect(service).toBeTruthy(); })); + + it('should inject the right config', () => { + expect(config).toBeTruthy(); + expect(config.replicationRuleEndpoint).toEqual("/api/policies/replication/testing"); + expect(config.replicationJobEndpoint).toEqual("/api/jobs/replication/testing"); + }); }); diff --git a/src/ui_ng/lib/src/service/replication.service.ts b/src/ui_ng/lib/src/service/replication.service.ts index e70780fd6..249ba4caa 100644 --- a/src/ui_ng/lib/src/service/replication.service.ts +++ b/src/ui_ng/lib/src/service/replication.service.ts @@ -1,8 +1,11 @@ import { Observable } from 'rxjs/Observable'; import { RequestQueryParams } from './RequestQueryParams'; import { ReplicationJob, ReplicationRule } from './interface'; -import { Injectable } from "@angular/core"; +import { Injectable, Inject } from "@angular/core"; import 'rxjs/add/observable/of'; +import { Http, RequestOptions } from '@angular/http'; +import { SERVICE_CONFIG, IServiceConfig } from '../service.config'; +import { buildHttpRequestOptions, HTTP_JSON_OPTIONS } from '../utils'; /** * Define the service methods to handle the replication (rule and job) related things. @@ -22,77 +25,77 @@ export abstract class ReplicationService { * @param {(number | string)} [projectId] * @param {string} [ruleName] * @param {RequestQueryParams} [queryParams] - * @returns {(Observable | ReplicationRule[])} + * @returns {(Observable | Promise | ReplicationRule[])} * * @memberOf ReplicationService */ - abstract getReplicationRules(projectId?: number | string, ruleName?: string, queryParams?: RequestQueryParams): Observable | ReplicationRule[]; + abstract getReplicationRules(projectId?: number | string, ruleName?: string, queryParams?: RequestQueryParams): Observable | Promise | ReplicationRule[]; /** * Get the specified replication rule. * * @abstract * @param {(number | string)} ruleId - * @returns {(Observable | ReplicationRule)} + * @returns {(Observable | Promise | ReplicationRule)} * * @memberOf ReplicationService */ - abstract getReplicationRule(ruleId: number | string): Observable | ReplicationRule; + abstract getReplicationRule(ruleId: number | string): Observable | Promise | ReplicationRule; /** * Create new replication rule. * * @abstract * @param {ReplicationRule} replicationRule - * @returns {(Observable | any)} + * @returns {(Observable | Promise | any)} * * @memberOf ReplicationService */ - abstract createReplicationRule(replicationRule: ReplicationRule): Observable | any; + abstract createReplicationRule(replicationRule: ReplicationRule): Observable | Promise | any; /** * Update the specified replication rule. * * @abstract * @param {ReplicationRule} replicationRule - * @returns {(Observable | any)} + * @returns {(Observable | Promise | any)} * * @memberOf ReplicationService */ - abstract updateReplicationRule(replicationRule: ReplicationRule): Observable | any; + abstract updateReplicationRule(replicationRule: ReplicationRule): Observable | Promise | any; /** * Delete the specified replication rule. * * @abstract * @param {(number | string)} ruleId - * @returns {(Observable | any)} + * @returns {(Observable | Promise | any)} * * @memberOf ReplicationService */ - abstract deleteReplicationRule(ruleId: number | string): Observable | any; + abstract deleteReplicationRule(ruleId: number | string): Observable | Promise | any; /** * Enable the specified replication rule. * * @abstract * @param {(number | string)} ruleId - * @returns {(Observable | any)} + * @returns {(Observable | Promise | any)} * * @memberOf ReplicationService */ - abstract enableReplicationRule(ruleId: number | string): Observable | any; + abstract enableReplicationRule(ruleId: number | string): Observable | Promise | any; /** * Disable the specified replication rule. * * @abstract * @param {(number | string)} ruleId - * @returns {(Observable | any)} + * @returns {(Observable | Promise | any)} * * @memberOf ReplicationService */ - abstract disableReplicationRule(ruleId: number | string): Observable | any; + abstract disableReplicationRule(ruleId: number | string): Observable | Promise | any; /** * Get the jobs for the specified replication rule. @@ -106,11 +109,11 @@ export abstract class ReplicationService { * @abstract * @param {(number | string)} ruleId * @param {RequestQueryParams} [queryParams] - * @returns {(Observable | ReplicationJob)} + * @returns {(Observable | Promise | ReplicationJob)} * * @memberOf ReplicationService */ - abstract getJobs(ruleId: number | string, queryParams?: RequestQueryParams): Observable | ReplicationJob[]; + abstract getJobs(ruleId: number | string, queryParams?: RequestQueryParams): Observable | Promise | ReplicationJob[]; } @@ -123,35 +126,121 @@ export abstract class ReplicationService { */ @Injectable() export class ReplicationDefaultService extends ReplicationService { - public getReplicationRules(projectId?: number | string, ruleName?: string, queryParams?: RequestQueryParams): Observable | ReplicationRule[] { - return Observable.of([]); + _ruleBaseUrl: string; + _jobBaseUrl: string; + + constructor( + private http: Http, + @Inject(SERVICE_CONFIG) private config: IServiceConfig + ) { + super(); + this._ruleBaseUrl = this.config.replicationRuleEndpoint ? + this.config.replicationRuleEndpoint : '/api/policies/replication'; + this._jobBaseUrl = this.config.replicationJobEndpoint ? + this.config.replicationJobEndpoint : '/api/jobs/replication'; } - public getReplicationRule(ruleId: number | string): Observable | ReplicationRule { - return Observable.of({}); + //Private methods + //Check if the rule object is valid + _isValidRule(rule: ReplicationRule): boolean { + return rule !== undefined && rule != null && rule.name !== undefined && rule.name.trim() !== '' && rule.target_id !== 0; } - public createReplicationRule(replicationRule: ReplicationRule): Observable | any { - return Observable.of({}); + public getReplicationRules(projectId?: number | string, ruleName?: string, queryParams?: RequestQueryParams): Observable | Promise | ReplicationRule[] { + if (!queryParams) { + queryParams = new RequestQueryParams(); + } + + if (projectId) { + queryParams.set('project_id', '' + projectId); + } + + if (ruleName) { + queryParams.set('name', ruleName); + } + + return this.http.get(this._ruleBaseUrl, buildHttpRequestOptions(queryParams)).toPromise() + .then(response => response.json() as ReplicationRule[]) + .catch(error => Promise.reject(error)) } - public updateReplicationRule(replicationRule: ReplicationRule): Observable | any { - return Observable.of({}); + public getReplicationRule(ruleId: number | string): Observable | Promise | ReplicationRule { + if (!ruleId) { + return Promise.reject("Bad argument"); + } + + let url: string = `${this._ruleBaseUrl}/${ruleId}`; + return this.http.get(url, HTTP_JSON_OPTIONS).toPromise() + .then(response => response.json() as ReplicationRule) + .catch(error => Promise.reject(error)); } - public deleteReplicationRule(ruleId: number | string): Observable | any { - return Observable.of({}); + public createReplicationRule(replicationRule: ReplicationRule): Observable | Promise | any { + if (!this._isValidRule(replicationRule)) { + return Promise.reject('Bad argument'); + } + + return this.http.post(this._ruleBaseUrl, JSON.stringify(replicationRule), HTTP_JSON_OPTIONS).toPromise() + .then(response => response) + .catch(error => Promise.reject(error)); } - public enableReplicationRule(ruleId: number | string): Observable | any { - return Observable.of({}); + public updateReplicationRule(replicationRule: ReplicationRule): Observable | Promise | any { + if (!this._isValidRule(replicationRule) || !replicationRule.id) { + return Promise.reject('Bad argument'); + } + + let url: string = `${this._ruleBaseUrl}/${replicationRule.id}`; + return this.http.put(url, JSON.stringify(replicationRule), HTTP_JSON_OPTIONS).toPromise() + .then(response => response) + .catch(error => Promise.reject(error)); } - public disableReplicationRule(ruleId: number | string): Observable | any { - return Observable.of({}); + public deleteReplicationRule(ruleId: number | string): Observable | Promise | any { + if (!ruleId || ruleId <= 0) { + return Promise.reject('Bad argument'); + } + + let url: string = `${this._ruleBaseUrl}/${ruleId}`; + return this.http.delete(url, HTTP_JSON_OPTIONS).toPromise() + .then(response => response) + .catch(error => Promise.reject(error)); } - public getJobs(ruleId: number | string, queryParams?: RequestQueryParams): Observable | ReplicationJob[] { - return Observable.of([]); + public enableReplicationRule(ruleId: number | string): Observable | Promise | any { + if (!ruleId || ruleId <= 0) { + return Promise.reject('Bad argument'); + } + + let url: string = `${this._ruleBaseUrl}/${ruleId}/enablement`; + return this.http.put(url, { enabled: 1 }, HTTP_JSON_OPTIONS).toPromise() + .then(response => response) + .catch(error => Promise.reject(error)); + } + + public disableReplicationRule(ruleId: number | string): Observable | Promise | any { + if (!ruleId || ruleId <= 0) { + return Promise.reject('Bad argument'); + } + + let url: string = `${this._ruleBaseUrl}/${ruleId}/enablement`; + return this.http.put(url, { enabled: 0 }, HTTP_JSON_OPTIONS).toPromise() + .then(response => response) + .catch(error => Promise.reject(error)); + } + + public getJobs(ruleId: number | string, queryParams?: RequestQueryParams): Observable | Promise | ReplicationJob[] { + if (!ruleId || ruleId <= 0) { + return Promise.reject('Bad argument'); + } + + if (!queryParams) { + queryParams = new RequestQueryParams(); + } + + queryParams.set('policy_id', '' + ruleId); + return this.http.get(this._jobBaseUrl, buildHttpRequestOptions(queryParams)).toPromise() + .then(response => response.json() as ReplicationJob[]) + .catch(error => Promise.reject(error)); } } \ No newline at end of file diff --git a/src/ui_ng/lib/src/service/repository.service.spec.ts b/src/ui_ng/lib/src/service/repository.service.spec.ts index 32314dd6b..2984ba543 100644 --- a/src/ui_ng/lib/src/service/repository.service.spec.ts +++ b/src/ui_ng/lib/src/service/repository.service.spec.ts @@ -5,11 +5,13 @@ import { SharedModule } from '../shared/shared.module'; import { SERVICE_CONFIG, IServiceConfig } from '../service.config'; describe('RepositoryService', () => { - beforeEach(() => { - const mockConfig: IServiceConfig = { - repositoryBaseEndpoint: "/api/repositories/testing" - }; + const mockConfig: IServiceConfig = { + repositoryBaseEndpoint: "/api/repositories/testing" + }; + let config: IServiceConfig; + + beforeEach(() => { TestBed.configureTestingModule({ imports: [ SharedModule @@ -24,9 +26,17 @@ describe('RepositoryService', () => { useValue: mockConfig }] }); + + config = TestBed.get(SERVICE_CONFIG); }); it('should be initialized', inject([RepositoryDefaultService], (service: RepositoryService) => { expect(service).toBeTruthy(); })); + + it('should inject the right config', () => { + expect(config).toBeTruthy(); + expect(config.repositoryBaseEndpoint).toEqual("/api/repositories/testing"); + }); + }); diff --git a/src/ui_ng/lib/src/service/tag.service.spec.ts b/src/ui_ng/lib/src/service/tag.service.spec.ts index 4ea229a98..c55e89914 100644 --- a/src/ui_ng/lib/src/service/tag.service.spec.ts +++ b/src/ui_ng/lib/src/service/tag.service.spec.ts @@ -40,11 +40,11 @@ describe('TagService', () => { } }]; - beforeEach(() => { - const mockConfig: IServiceConfig = { - repositoryBaseEndpoint: "/api/repositories/testing" - }; + const mockConfig: IServiceConfig = { + repositoryBaseEndpoint: "/api/repositories/testing" + }; + beforeEach(() => { TestBed.configureTestingModule({ imports: [ SharedModule