20219: Replace API & websocket log loading with webdav polling
[arvados-workbench2.git] / src / services / log-service / log-service.ts
index 9772e0b61ca0a9a08e5c2fc7494704cddd141012..b96d8223ffd96ae1bd536c61bde147a3bfc783b1 100644 (file)
@@ -3,12 +3,51 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import { AxiosInstance } from "axios";
-import { LogResource } from 'models/log';
+import { LogEventType, LogResource } from 'models/log';
 import { CommonResourceService } from "services/common-service/common-resource-service";
 import { ApiActions } from "services/api/api-actions";
+import { WebDAV } from "common/webdav";
+import { extractFilesData } from "services/collection-service/collection-service-files-response";
+import { CollectionDirectory, CollectionFile } from "models/collection-file";
+
+export type LogFragment = {
+    logType: LogEventType;
+    contents: string[];
+}
 
 export class LogService extends CommonResourceService<LogResource> {
-    constructor(serverApi: AxiosInstance, actions: ApiActions) {
+    constructor(serverApi: AxiosInstance, private apiWebdavClient: WebDAV, actions: ApiActions) {
         super(serverApi, "logs", actions);
     }
+
+    async listLogFiles(containerRequestUuid: string) {
+        const request = await this.apiWebdavClient.propfind(`container_requests/${containerRequestUuid}/log`);
+        if (request.responseXML != null) {
+            return extractFilesData(request.responseXML);
+        }
+        return Promise.reject();
+    }
+
+    async getLogFileContents(containerRequestUuid: string, fileRecord: CollectionFile, startByte: number, endByte: number): Promise<LogFragment | undefined> {
+        try {
+            const request = await this.apiWebdavClient.get(
+                `container_requests/${containerRequestUuid}/log/${fileRecord.name}`,
+                {headers: {Range: `bytes=${startByte}-${endByte}`}}
+            );
+            const logFileType = logFileToLogType(fileRecord);
+
+            if (request.responseText && logFileType) {
+                return {
+                    logType: logFileType,
+                    contents: request.responseText.split(/\r?\n/),
+                };
+            } else {
+                return undefined;
+            }
+        } catch(e) {
+            return undefined;
+        }
+    }
 }
+
+export const logFileToLogType = (file: CollectionFile | CollectionDirectory) => (file.name.replace(/\.(txt|json)$/, '') as LogEventType);