@mcma/client
Version:
Node module with classes and functions used to access services in an MCMA environment
207 lines (206 loc) • 8.49 kB
JavaScript
"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;