69940: Process files request

This commit is contained in:
Kristof De Langhe
2020-03-23 17:38:36 +01:00
committed by Art Lowel
parent cf492a92c8
commit 3bac6cc1b3
5 changed files with 106 additions and 3 deletions

View File

@@ -138,6 +138,7 @@ import { Script } from '../process-page/scripts/script.model';
import { Process } from '../process-page/processes/process.model'; import { Process } from '../process-page/processes/process.model';
import { ProcessDataService } from './data/processes/process-data.service'; import { ProcessDataService } from './data/processes/process-data.service';
import { ScriptDataService } from './data/processes/script-data.service'; import { ScriptDataService } from './data/processes/script-data.service';
import { ProcessFilesResponseParsingService } from './data/process-files-response-parsing.service';
/** /**
* When not in production, endpoint responses can be mocked for testing purposes * When not in production, endpoint responses can be mocked for testing purposes
@@ -260,6 +261,7 @@ const PROVIDERS = [
ItemTypeDataService, ItemTypeDataService,
ProcessDataService, ProcessDataService,
ScriptDataService, ScriptDataService,
ProcessFilesResponseParsingService,
// register AuthInterceptor as HttpInterceptor // register AuthInterceptor as HttpInterceptor
{ {
provide: HTTP_INTERCEPTORS, provide: HTTP_INTERCEPTORS,

View File

@@ -0,0 +1,39 @@
import { ResponseParsingService } from './parsing.service';
import { RestRequest } from './request.models';
import { GenericSuccessResponse, RestResponse } from '../cache/response.models';
import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model';
import { isEmpty, isNotEmpty } from '../../shared/empty.util';
import { PaginatedList } from './paginated-list';
import { PageInfo } from '../shared/page-info.model';
import { Injectable } from '@angular/core';
@Injectable()
/**
* A ResponseParsingService used to parse DSpaceRESTV2Response coming from the REST API to a GenericSuccessResponse
* containing a PaginatedList of a process's output files
*/
export class ProcessFilesResponseParsingService implements ResponseParsingService {
parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
const payload = data.payload;
let page;
if (isNotEmpty(payload._embedded) && isNotEmpty(Object.keys(payload._embedded))) {
const bitstreams = payload._embedded[Object.keys(payload._embedded)[0]];
if (isNotEmpty(bitstreams)) {
page = new PaginatedList(Object.assign(new PageInfo(), {
elementsPerPage: bitstreams.length,
totalElements: bitstreams.length,
totalPages: 1,
currentPage: 1
}), bitstreams);
}
}
if (isEmpty(page)) {
page = new PaginatedList(new PageInfo(), []);
}
return new GenericSuccessResponse(page, data.statusCode, data.statusText);
}
}

View File

@@ -12,6 +12,14 @@ import { DefaultChangeAnalyzer } from '../default-change-analyzer.service';
import { Process } from '../../../process-page/processes/process.model'; import { Process } from '../../../process-page/processes/process.model';
import { dataService } from '../../cache/builders/build-decorators'; import { dataService } from '../../cache/builders/build-decorators';
import { PROCESS } from '../../../process-page/processes/process.resource-type'; import { PROCESS } from '../../../process-page/processes/process.resource-type';
import { Observable } from 'rxjs/internal/Observable';
import { map, switchMap } from 'rxjs/operators';
import { ProcessFilesRequest, RestRequest } from '../request.models';
import { configureRequest, filterSuccessfulResponses } from '../../shared/operators';
import { GenericSuccessResponse } from '../../cache/response.models';
import { PaginatedList } from '../paginated-list';
import { Bitstream } from '../../shared/bitstream.model';
import { RemoteData } from '../remote-data';
@Injectable() @Injectable()
@dataService(PROCESS) @dataService(PROCESS)
@@ -29,4 +37,34 @@ export class ProcessDataService extends DataService<Process> {
protected comparator: DefaultChangeAnalyzer<Process>) { protected comparator: DefaultChangeAnalyzer<Process>) {
super(); super();
} }
/**
* Get the endpoint for a process his files
* @param processId The ID of the process
*/
getFilesEndpoint(processId: string): Observable<string> {
return this.getBrowseEndpoint().pipe(
switchMap((href) => this.halService.getEndpoint('files', `${href}/${processId}`))
);
}
/**
* Get a process his output files
* @param processId The ID of the process
*/
getFiles(processId: string): Observable<RemoteData<PaginatedList<Bitstream>>> {
const request$ = this.getFilesEndpoint(processId).pipe(
map((href) => new ProcessFilesRequest(this.requestService.generateRequestId(), href)),
configureRequest(this.requestService)
);
const requestEntry$ = request$.pipe(
switchMap((request: RestRequest) => this.requestService.getByHref(request.href))
);
const payload$ = requestEntry$.pipe(
filterSuccessfulResponses(),
map((response: GenericSuccessResponse<PaginatedList<Bitstream>>) => response.payload)
);
return this.rdbService.toRemoteDataObservable(requestEntry$, payload$);
}
} }

View File

@@ -20,6 +20,7 @@ import { URLCombiner } from '../url-combiner/url-combiner';
import { TaskResponseParsingService } from '../tasks/task-response-parsing.service'; import { TaskResponseParsingService } from '../tasks/task-response-parsing.service';
import { ContentSourceResponseParsingService } from './content-source-response-parsing.service'; import { ContentSourceResponseParsingService } from './content-source-response-parsing.service';
import { MappedCollectionsReponseParsingService } from './mapped-collections-reponse-parsing.service'; import { MappedCollectionsReponseParsingService } from './mapped-collections-reponse-parsing.service';
import { ProcessFilesResponseParsingService } from './process-files-response-parsing.service';
/* tslint:disable:max-classes-per-file */ /* tslint:disable:max-classes-per-file */
@@ -226,6 +227,15 @@ export class MappedCollectionsRequest extends GetRequest {
} }
} }
/**
* Request to fetch the files of a process
*/
export class ProcessFilesRequest extends GetRequest {
getResponseParser(): GenericConstructor<ResponseParsingService> {
return ProcessFilesResponseParsingService;
}
}
export class ConfigRequest extends GetRequest { export class ConfigRequest extends GetRequest {
constructor(uuid: string, href: string, public options?: HttpOptions) { constructor(uuid: string, href: string, public options?: HttpOptions) {
super(uuid, href, null, options); super(uuid, href, null, options);

View File

@@ -3,9 +3,12 @@ import { ActivatedRoute, Router } from '@angular/router';
import { Observable } from 'rxjs/internal/Observable'; import { Observable } from 'rxjs/internal/Observable';
import { RemoteData } from '../../core/data/remote-data'; import { RemoteData } from '../../core/data/remote-data';
import { Process } from '../processes/process.model'; import { Process } from '../processes/process.model';
import { map } from 'rxjs/operators'; import { map, switchMap } from 'rxjs/operators';
import { redirectToPageNotFoundOn404 } from '../../core/shared/operators'; import { getFirstSucceededRemoteDataPayload, redirectToPageNotFoundOn404 } from '../../core/shared/operators';
import { AlertType } from '../../shared/alert/aletr-type'; import { AlertType } from '../../shared/alert/aletr-type';
import { ProcessDataService } from '../../core/data/processes/process-data.service';
import { PaginatedList } from '../../core/data/paginated-list';
import { Bitstream } from '../../core/shared/bitstream.model';
@Component({ @Component({
selector: 'ds-process-detail', selector: 'ds-process-detail',
@@ -27,8 +30,14 @@ export class ProcessDetailComponent implements OnInit {
*/ */
processRD$: Observable<RemoteData<Process>>; processRD$: Observable<RemoteData<Process>>;
/**
* The Process's Output Files
*/
filesRD$: Observable<RemoteData<PaginatedList<Bitstream>>>;
constructor(protected route: ActivatedRoute, constructor(protected route: ActivatedRoute,
protected router: Router) { protected router: Router,
protected processService: ProcessDataService) {
} }
/** /**
@@ -40,6 +49,11 @@ export class ProcessDetailComponent implements OnInit {
map((data) => data.process as RemoteData<Process>), map((data) => data.process as RemoteData<Process>),
redirectToPageNotFoundOn404(this.router) redirectToPageNotFoundOn404(this.router)
); );
this.filesRD$ = this.processRD$.pipe(
getFirstSucceededRemoteDataPayload(),
switchMap((process: Process) => this.processService.getFiles(process.processId))
);
} }
} }