UNPKG

@mcma/client

Version:

Node module with classes and functions used to access services in an MCMA environment

207 lines (206 loc) 8.49 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ResourceManager = exports.QuerySortOrder = void 0; const core_1 = require("@mcma/core"); const http_1 = require("../http"); const service_client_1 = require("./service-client"); var QuerySortOrder; (function (QuerySortOrder) { QuerySortOrder["Ascending"] = "asc"; QuerySortOrder["Descending"] = "desc"; })(QuerySortOrder || (exports.QuerySortOrder = QuerySortOrder = {})); class ResourceManager { config; authProvider; httpClient; serviceClients = []; constructor(config, authProvider) { this.config = config; this.authProvider = authProvider; if (!config.serviceRegistryUrl) { throw new core_1.McmaException("Missing property 'serviceRegistryUrl' in ResourceManager config"); } if (config.serviceRegistryUrl.endsWith("/")) { config.serviceRegistryUrl = config.serviceRegistryUrl.substring(0, config.serviceRegistryUrl.length - 1); } this.httpClient = new http_1.HttpClient(authProvider.getDefault(), config.httpClientConfig); } async init() { try { this.serviceClients.length = 0; let serviceRegistry = new core_1.Service({ name: "Service Registry", authType: this.config.serviceRegistryAuthType, resources: [ new core_1.ResourceEndpoint({ resourceType: "Service", httpEndpoint: this.config.serviceRegistryUrl + "/services", }), new core_1.ResourceEndpoint({ resourceType: "JobProfile", httpEndpoint: this.config.serviceRegistryUrl + "/job-profiles", }) ] }); let serviceRegistryClient = new service_client_1.ServiceClient(serviceRegistry, this.authProvider, this.config.httpClientConfig); this.serviceClients.push(serviceRegistryClient); let servicesEndpoint = serviceRegistryClient.getResourceEndpointClient("Service"); let response = await servicesEndpoint.get(); for (const service of response.data.results) { try { if (service.name !== serviceRegistry.name) { this.serviceClients.push(new service_client_1.ServiceClient(new core_1.Service(service), this.authProvider, this.config.httpClientConfig)); } } catch (error) { console.warn("Failed to instantiate json " + JSON.stringify(service) + " as a Service due to error " + error.message); } } } catch (error) { throw new core_1.McmaException("ResourceManager: Failed to initialize", error); } } ; async query(resourceType, filter, sortBy, sortOrder) { if (typeof resourceType === "function" && resourceType.name) { resourceType = resourceType.name; } if (this.serviceClients.length === 0) { await this.init(); } const results = []; const usedHttpEndpoints = []; const errors = []; let params = {}; if (sortBy !== undefined && sortBy !== null) { params.sortBy = sortBy; } if (sortOrder !== undefined && sortOrder !== null) { params.sortOrder = sortOrder; } if (filter) { params = Object.assign(params, filter); } for (const serviceClient of this.serviceClients) { let resourceEndpoint = serviceClient.getResourceEndpointClient(resourceType); if (resourceEndpoint === undefined) { continue; } try { if (!usedHttpEndpoints.includes(resourceEndpoint.httpEndpoint)) { let response = await resourceEndpoint.get({ params }); results.push(...response.data.results); } usedHttpEndpoints.push(resourceEndpoint.httpEndpoint); } catch (error) { const wrappingError = new core_1.McmaException("Failed to retrieve '" + resourceType + "' from endpoint '" + resourceEndpoint.httpEndpoint + "'", error); errors.push(wrappingError); console.error(wrappingError); } } if (errors.length > 0) { throw new core_1.McmaException("Failed to query any available resource endpoints for resource type '" + resourceType + "'\n" + "Errors:\n" + errors.join("\n")); } return results; } async create(resource) { if (this.serviceClients.length === 0) { await this.init(); } let resourceType = resource["@type"]; for (const service of this.serviceClients) { let resourceEndpoint = service.getResourceEndpointClient(resourceType); if (resourceEndpoint === undefined) { continue; } let response = await resourceEndpoint.post(resource); return response.data; } throw new core_1.McmaException("ResourceManager: Failed to find service to create resource of type '" + resourceType + "'."); } ; async get(resource) { let resolvedResource; let http = await this.getResourceEndpointClient(resource) || this.httpClient; try { let response = await http.get(resource); resolvedResource = response.data; } catch (error) { throw new core_1.McmaException("ResourceManager: Failed to get resource from URL '" + resource + "'", error); } if (!resolvedResource) { return null; } let resolvedType = typeof resolvedResource; if (resolvedType === "object") { if (Array.isArray(resolvedResource)) { throw new core_1.McmaException("ResourceManager: Resource at '" + resource + "' has illegal type 'Array'"); } } else { throw new core_1.McmaException("ResourceManager: Resource at '" + resource + "' has illegal type '" + resolvedType + "'"); } return resolvedResource; } async update(resource) { if (this.serviceClients.length === 0) { await this.init(); } let http = await this.getResourceEndpointClient(resource.id) || this.httpClient; let response = await http.put(resource, resource.id); return response.data; } async delete(resource) { let resourceId; if (typeof resource === "string") { resourceId = resource; } else if (typeof resource === "object" && resource.id) { resourceId = resource.id; } else { throw new core_1.McmaException("Unexpected input of type '" + typeof resource + "' for ResourceManager.delete"); } if (this.serviceClients.length === 0) { await this.init(); } let http = await this.getResourceEndpointClient(resourceId) || this.httpClient; await http.delete(resourceId); } ; async getResourceEndpointClient(url) { if (this.serviceClients.length === 0) { await this.init(); } for (const serviceClient of this.serviceClients) { for (const resourceEndpoint of serviceClient.getAllResourceEndpointClients()) { if (url.startsWith(resourceEndpoint.httpEndpoint)) { return resourceEndpoint; } } } return undefined; } ; async sendNotification(resource) { if (resource.notificationEndpoint) { try { let http = await this.getResourceEndpointClient(resource.notificationEndpoint.httpEndpoint) ?? this.httpClient; let notification = new core_1.Notification({ source: resource.id, content: resource }); await http.post(notification, resource.notificationEndpoint.httpEndpoint); } catch (error) { throw new core_1.McmaException("ResourceManager: Failed to send notification.", error); } } } ; } exports.ResourceManager = ResourceManager;