20219: Perform log file root path filtering in listLogFiles
[arvados-workbench2.git] / src / services / log-service / log-service.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { AxiosInstance } from "axios";
6 import { LogEventType, LogResource } from 'models/log';
7 import { CommonResourceService } from "services/common-service/common-resource-service";
8 import { ApiActions } from "services/api/api-actions";
9 import { WebDAV } from "common/webdav";
10 import { extractFilesData } from "services/collection-service/collection-service-files-response";
11 import { CollectionFile } from "models/collection-file";
12
13 export type LogFragment = {
14     logType: LogEventType;
15     contents: string[];
16 }
17
18 export class LogService extends CommonResourceService<LogResource> {
19     constructor(serverApi: AxiosInstance, private apiWebdavClient: WebDAV, actions: ApiActions) {
20         super(serverApi, "logs", actions);
21     }
22
23     async listLogFiles(containerRequestUuid: string) {
24         const request = await this.apiWebdavClient.propfind(`container_requests/${containerRequestUuid}/log`);
25         if (request.responseXML != null) {
26             return extractFilesData(request.responseXML)
27                 .filter((file) => (
28                     file.path === `/arvados/v1/container_requests/${containerRequestUuid}/log`
29                 ));
30         }
31         return Promise.reject();
32     }
33
34     async getLogFileContents(containerRequestUuid: string, fileRecord: CollectionFile, startByte: number, endByte: number): Promise<LogFragment | undefined> {
35         try {
36             const request = await this.apiWebdavClient.get(
37                 `container_requests/${containerRequestUuid}/log/${fileRecord.name}`,
38                 {headers: {Range: `bytes=${startByte}-${endByte}`}}
39             );
40             const logFileType = logFileToLogType(fileRecord);
41
42             if (request.responseText && logFileType) {
43                 return {
44                     logType: logFileType,
45                     contents: request.responseText.split(/\r?\n/),
46                 };
47             } else {
48                 return undefined;
49             }
50         } catch(e) {
51             return undefined;
52         }
53     }
54 }
55
56 export const logFileToLogType = (file: CollectionFile) => (file.name.replace(/\.(txt|json)$/, '') as LogEventType);