20251: Fix flaky collection file browser by using race-free state update callback
[arvados-workbench2.git] / src / services / services.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import Axios from "axios";
6 import { AxiosInstance } from "axios";
7 import { ApiClientAuthorizationService } from 'services/api-client-authorization-service/api-client-authorization-service';
8 import { AuthService } from "./auth-service/auth-service";
9 import { GroupsService } from "./groups-service/groups-service";
10 import { ProjectService } from "./project-service/project-service";
11 import { LinkService } from "./link-service/link-service";
12 import { FavoriteService } from "./favorite-service/favorite-service";
13 import { CollectionService } from "./collection-service/collection-service";
14 import { TagService } from "./tag-service/tag-service";
15 import { KeepService } from "./keep-service/keep-service";
16 import { WebDAV } from "common/webdav";
17 import { Config } from "common/config";
18 import { UserService } from './user-service/user-service';
19 import { AncestorService } from "services/ancestors-service/ancestors-service";
20 import { ResourceKind } from "models/resource";
21 import { ContainerRequestService } from './container-request-service/container-request-service';
22 import { ContainerService } from './container-service/container-service';
23 import { LogService } from './log-service/log-service';
24 import { ApiActions } from "services/api/api-actions";
25 import { WorkflowService } from "services/workflow-service/workflow-service";
26 import { SearchService } from 'services/search-service/search-service';
27 import { PermissionService } from "services/permission-service/permission-service";
28 import { VirtualMachinesService } from "services/virtual-machines-service/virtual-machines-service";
29 import { RepositoriesService } from 'services/repositories-service/repositories-service';
30 import { AuthorizedKeysService } from 'services/authorized-keys-service/authorized-keys-service';
31 import { VocabularyService } from 'services/vocabulary-service/vocabulary-service';
32 import { FileViewersConfigService } from 'services/file-viewers-config-service/file-viewers-config-service';
33 import { LinkAccountService } from "./link-account-service/link-account-service";
34 import parse from "parse-duration";
35
36 export type ServiceRepository = ReturnType<typeof createServices>;
37
38 export function setAuthorizationHeader(services: ServiceRepository, token: string) {
39     services.apiClient.defaults.headers.common = {
40         Authorization: `Bearer ${token}`
41     };
42     services.webdavClient.setAuthorization(`Bearer ${token}`);
43 }
44
45 export function removeAuthorizationHeader(services: ServiceRepository) {
46     delete services.apiClient.defaults.headers.common;
47     services.webdavClient.setAuthorization(undefined);
48 }
49
50 export const createServices = (config: Config, actions: ApiActions, useApiClient?: AxiosInstance) => {
51     // Need to give empty 'headers' object or it will create an
52     // instance with a reference to the global default headers object,
53     // which is very bad because that means setAuthorizationHeader
54     // would update the global default instead of the instance default.
55     const apiClient = useApiClient || Axios.create({ headers: {} });
56     apiClient.defaults.baseURL = config.baseUrl;
57
58     const webdavClient = new WebDAV({
59         baseURL: config.keepWebServiceUrl
60     });
61
62     const apiClientAuthorizationService = new ApiClientAuthorizationService(apiClient, actions);
63     const authorizedKeysService = new AuthorizedKeysService(apiClient, actions);
64     const containerRequestService = new ContainerRequestService(apiClient, actions);
65     const containerService = new ContainerService(apiClient, actions);
66     const groupsService = new GroupsService(apiClient, actions);
67     const keepService = new KeepService(apiClient, actions);
68     const linkService = new LinkService(apiClient, actions);
69     const logService = new LogService(apiClient, actions);
70     const permissionService = new PermissionService(apiClient, actions);
71     const projectService = new ProjectService(apiClient, actions);
72     const repositoriesService = new RepositoriesService(apiClient, actions);
73     const userService = new UserService(apiClient, actions);
74     const virtualMachineService = new VirtualMachinesService(apiClient, actions);
75     const workflowService = new WorkflowService(apiClient, actions);
76     const linkAccountService = new LinkAccountService(apiClient, actions);
77
78     const ancestorsService = new AncestorService(groupsService, userService);
79
80     const idleTimeout = (config && config.clusterConfig && config.clusterConfig.Workbench.IdleTimeout) || '0s';
81     const authService = new AuthService(apiClient, config.rootUrl, actions,
82         (parse(idleTimeout, 's') || 0) > 0);
83
84     const collectionService = new CollectionService(apiClient, webdavClient, authService, actions);
85     const favoriteService = new FavoriteService(linkService, groupsService);
86     const tagService = new TagService(linkService);
87     const searchService = new SearchService();
88     const vocabularyService = new VocabularyService(config.vocabularyUrl);
89     const fileViewersConfig = new FileViewersConfigService(config.fileViewersConfigUrl);
90
91     return {
92         ancestorsService,
93         apiClient,
94         apiClientAuthorizationService,
95         authService,
96         authorizedKeysService,
97         collectionService,
98         containerRequestService,
99         containerService,
100         favoriteService,
101         fileViewersConfig,
102         groupsService,
103         keepService,
104         linkService,
105         logService,
106         permissionService,
107         projectService,
108         repositoriesService,
109         searchService,
110         tagService,
111         userService,
112         virtualMachineService,
113         webdavClient,
114         workflowService,
115         vocabularyService,
116         linkAccountService
117     };
118 };
119
120 export const getResourceService = (kind?: ResourceKind) => (serviceRepository: ServiceRepository) => {
121     switch (kind) {
122         case ResourceKind.USER:
123             return serviceRepository.userService;
124         case ResourceKind.GROUP:
125             return serviceRepository.groupsService;
126         case ResourceKind.COLLECTION:
127             return serviceRepository.collectionService;
128         default:
129             return undefined;
130     }
131 };