UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

265 lines 37.8 kB
import { Injectable } from '@angular/core'; import { isUndefined, sortBy } from 'lodash-es'; import { debounceTime, take } from 'rxjs/operators'; import { ApplicationType, ApplicationService, TenantService, TenantOptionsService } from '@c8y/client'; import { HumanizeAppNamePipe } from '@c8y/ngx-components'; import { DefaultSubscriptionsContext as DefaultSubscriptionsContextTenant } from './default-subscriptions.model'; import * as i0 from "@angular/core"; import * as i1 from "@c8y/client"; import * as i2 from "@c8y/ngx-components"; export class DefaultSubscriptionsService { constructor(applicationService, tenantService, tenantOptionsService, humanizeAppNamePipe) { this.applicationService = applicationService; this.tenantService = tenantService; this.tenantOptionsService = tenantOptionsService; this.humanizeAppNamePipe = humanizeAppNamePipe; } /** * Gets the list of applications which can be used in default subscriptions, i.e.: * - current tenant's all own applications, * - inherited applications, which do not have the same names as current tenant's own apps. * The list is sorted alphabetically by humanized app name and contains up to 2000 items. * @returns The list of applications, which can be used in default subscriptions. */ async getSubscribableTenantApps() { const currentTenant = (await this.tenantService.current()).data; const allApps = (await this.applicationService.listByTenant(null, { pageSize: 2000 })).data; const ownApps = allApps.filter(app => app.owner.tenant.id === currentTenant.name); const inheritedApps = allApps.filter(app => app.owner.tenant.id !== currentTenant.name); const filteredApps = [...ownApps]; inheritedApps.forEach(inheritedApp => { if (!filteredApps.some(filteredApp => filteredApp.name === inheritedApp.name)) { filteredApps.push(inheritedApp); } }); const filteredAppsWithHumanizedNames = await Promise.all(filteredApps.map(async (app) => { const humanizedName = await this.humanizeAppNamePipe .transform(app.name) .pipe(debounceTime(250), take(1)) .toPromise(); return { app, humanizedName }; })); const sortedAppsWithHumanizedNames = sortBy(filteredAppsWithHumanizedNames, ['humanizedName']); const sortedApps = sortedAppsWithHumanizedNames.map(({ app }) => app); return sortedApps; } /** * Gets the default subscriptions configuration inherited from parent tenant. * @returns The default subscriptions object with settings from parent tenant. */ async getDefaultSubscriptionsEvaluatedFromParentTenant() { return this.getDefaultSubscriptions(DefaultSubscriptionsContextTenant.PARENT_TENANT); } /** * Gets the default subscriptions configuration from the current tenant. * @returns The default subscriptions object with settings from the current tenant. */ async getDefaultSubscriptionsFromCurrentTenant() { return this.getDefaultSubscriptions(DefaultSubscriptionsContextTenant.CURRENT_TENANT); } /** * Saves given default subscriptions configuration to the current tenant * (either sets, updates, or deletes corresponding tenant options). * @param defaultSubscriptions The default subscriptions configuration to be saved. */ async saveDefaultSubscriptionsToCurrentTenant(defaultSubscriptions) { await this.saveOnCreationSubscriptions(defaultSubscriptions); await this.saveOnUpgradeSubscriptions(defaultSubscriptions); } /** * Gets default subscriptions in the context of current or parent tenant. * @param contextTenant Tells whether to use current or parent tenant as context. */ async getDefaultSubscriptions(contextTenant) { let tenantOptionsParams; let overridable; switch (contextTenant) { case DefaultSubscriptionsContextTenant.CURRENT_TENANT: tenantOptionsParams = { evaluate: 'current' }; overridable = true; break; case DefaultSubscriptionsContextTenant.PARENT_TENANT: tenantOptionsParams = { evaluate: 'inherited' }; overridable = false; break; } const { onCreationApps, onCreationMicroservices, onUpgradeAppsEnabled, onUpgradeApps, onUpgradeMicroservicesEnabled, onUpgradeMicroservices } = await this.getTenantOptions(tenantOptionsParams); const onCreationSubscriptions = this.namesToPartialApps({ appsNamesStr: onCreationApps, microservicesNamesStr: onCreationMicroservices }); const onUpgradeAppsDefault = overridable ? null : onCreationApps; const onUpgradeMicroservicesDefault = overridable ? null : onCreationMicroservices; const onUpgradeSubscriptions = this.namesToPartialApps({ appsNamesStr: onUpgradeAppsEnabled ? onUpgradeApps : onUpgradeAppsDefault, microservicesNamesStr: onUpgradeMicroservicesEnabled ? onUpgradeMicroservices : onUpgradeMicroservicesDefault }); const defaultSubscriptions = { onCreationSubscriptions, onUpgradeSubscriptions }; if (overridable) { defaultSubscriptions.overrideOnCreationSubscriptions = onCreationApps !== null || onCreationMicroservices !== null; defaultSubscriptions.overrideOnUpgradeSubscriptions = onUpgradeAppsEnabled || onUpgradeMicroservicesEnabled; } return defaultSubscriptions; } async getTenantOptions(params = {}) { return { onCreationApps: await this.getTenantOption({ category: 'configuration', key: 'default.tenant.applications' }, null, params), onCreationMicroservices: await this.getTenantOption({ category: 'configuration', key: 'default.tenant.microservices' }, null, params), onUpgradeAppsEnabled: await this.getTenantOption({ category: 'configuration', key: 'on-update.tenant.applications.enabled' }, false, params), onUpgradeApps: await this.getTenantOption({ category: 'configuration', key: 'on-update.tenant.applications' }, null, params), onUpgradeMicroservicesEnabled: await this.getTenantOption({ category: 'configuration', key: 'on-update.tenant.microservices.enabled' }, false, params), onUpgradeMicroservices: await this.getTenantOption({ category: 'configuration', key: 'on-update.tenant.microservices' }, null, params) }; } async saveOnCreationSubscriptions(defaultSubscriptions) { if (defaultSubscriptions.overrideOnCreationSubscriptions) { await this.setTenantOption({ category: 'configuration', key: 'default.tenant.applications', value: this.partialAppsListToAppsNames(defaultSubscriptions.onCreationSubscriptions) }); await this.setTenantOption({ category: 'configuration', key: 'default.tenant.microservices', value: this.partialAppsToMicroservicesNames(defaultSubscriptions.onCreationSubscriptions) }); } else { await this.unsetTenantOption({ category: 'configuration', key: 'default.tenant.applications' }); await this.unsetTenantOption({ category: 'configuration', key: 'default.tenant.microservices' }); } } async saveOnUpgradeSubscriptions(defaultSubscriptions) { if (defaultSubscriptions.overrideOnUpgradeSubscriptions) { await this.setTenantOption({ category: 'configuration', key: 'on-update.tenant.applications.enabled', value: 'true' }); await this.setTenantOption({ category: 'configuration', key: 'on-update.tenant.microservices.enabled', value: 'true' }); await this.setTenantOption({ category: 'configuration', key: 'on-update.tenant.applications', value: this.partialAppsListToAppsNames(defaultSubscriptions.onUpgradeSubscriptions) }); await this.setTenantOption({ category: 'configuration', key: 'on-update.tenant.microservices', value: this.partialAppsToMicroservicesNames(defaultSubscriptions.onUpgradeSubscriptions) }); } else { await this.unsetTenantOption({ category: 'configuration', key: 'on-update.tenant.applications.enabled' }); await this.unsetTenantOption({ category: 'configuration', key: 'on-update.tenant.microservices.enabled' }); await this.unsetTenantOption({ category: 'configuration', key: 'on-update.tenant.applications' }); await this.unsetTenantOption({ category: 'configuration', key: 'on-update.tenant.microservices' }); } } async getTenantOption(option, defaultValue = null, params = {}) { let value; try { value = (await this.tenantOptionsService.detail(option, params)).data.value; value = JSON.parse(value); } catch (ex) { value = !isUndefined(value) ? value : defaultValue; } return value; } async setTenantOption(option) { return this.tenantOptionsService.update(option); } async unsetTenantOption(option) { try { await this.tenantOptionsService.delete(option); } catch (ex) { if (!ex || !ex.res || ex.res.status !== 404) { throw ex; } } } namesToPartialApps({ appsNamesStr, microservicesNamesStr }) { if (appsNamesStr === null && microservicesNamesStr === null) { return null; } return [ ...(appsNamesStr || '') .split(',') .filter(name => name.length) .map(name => ({ name: name.trim() })), ...(microservicesNamesStr || '') .split(',') .filter(name => name.length) .map(name => ({ name: name.trim(), type: ApplicationType.MICROSERVICE })) ]; } partialAppsListToAppsNames(apps) { return apps .filter(app => app.type !== ApplicationType.MICROSERVICE) .map(app => app.name) .join(','); } partialAppsToMicroservicesNames(apps) { return apps .filter(app => app.type === ApplicationType.MICROSERVICE) .map(app => app.name) .join(','); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DefaultSubscriptionsService, deps: [{ token: i1.ApplicationService }, { token: i1.TenantService }, { token: i1.TenantOptionsService }, { token: i2.HumanizeAppNamePipe }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DefaultSubscriptionsService }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DefaultSubscriptionsService, decorators: [{ type: Injectable }], ctorParameters: () => [{ type: i1.ApplicationService }, { type: i1.TenantService }, { type: i1.TenantOptionsService }, { type: i2.HumanizeAppNamePipe }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVmYXVsdC1zdWJzY3JpcHRpb25zLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9kZWZhdWx0LXN1YnNjcmlwdGlvbnMvZGVmYXVsdC1zdWJzY3JpcHRpb25zLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNoRCxPQUFPLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXBELE9BQU8sRUFFTCxlQUFlLEVBQ2Ysa0JBQWtCLEVBRWxCLGFBQWEsRUFDYixvQkFBb0IsRUFDckIsTUFBTSxhQUFhLENBQUM7QUFDckIsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFMUQsT0FBTyxFQUdMLDJCQUEyQixJQUFJLGlDQUFpQyxFQUNqRSxNQUFNLCtCQUErQixDQUFDOzs7O0FBR3ZDLE1BQU0sT0FBTywyQkFBMkI7SUFDdEMsWUFDVSxrQkFBc0MsRUFDdEMsYUFBNEIsRUFDNUIsb0JBQTBDLEVBQzFDLG1CQUF3QztRQUh4Qyx1QkFBa0IsR0FBbEIsa0JBQWtCLENBQW9CO1FBQ3RDLGtCQUFhLEdBQWIsYUFBYSxDQUFlO1FBQzVCLHlCQUFvQixHQUFwQixvQkFBb0IsQ0FBc0I7UUFDMUMsd0JBQW1CLEdBQW5CLG1CQUFtQixDQUFxQjtJQUMvQyxDQUFDO0lBRUo7Ozs7OztPQU1HO0lBQ0gsS0FBSyxDQUFDLHlCQUF5QjtRQUM3QixNQUFNLGFBQWEsR0FBRyxDQUFDLE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUVoRSxNQUFNLE9BQU8sR0FBRyxDQUFDLE1BQU0sSUFBSSxDQUFDLGtCQUFrQixDQUFDLFlBQVksQ0FBQyxJQUFJLEVB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QkFDN0IsS0FBSyxDQUFDLEdBQUcsQ0FBQztpQkFDVixNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO2lCQUMzQixHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUNaLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFO2dCQUNqQixJQUFJLEVBQUUsZUFBZSxDQUFDLFlBQVk7YUFDbkMsQ0FBQyxDQUFDO1NBQ04sQ0FBQztJQUNKLENBQUM7SUFFTywwQkFBMEIsQ0FBQyxJQUFxQjtRQUN0RCxPQUFPLElBQUk7YUFDUixNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsSUFBSSxLQUFLLGVBQWUsQ0FBQyxZQUFZLENBQUM7YUFDeEQsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQzthQUNwQixJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDZixDQUFDO0lBRU8sK0JBQStCLENBQUMsSUFBcUI7UUFDM0QsT0FBTyxJQUFJO2FBQ1IsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLElBQUksS0FBSyxlQUFlLENBQUMsWUFBWSxDQUFDO2FBQ3hELEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUM7YUFDcEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ2YsQ0FBQzsrR0F4VFUsMkJBQTJCO21IQUEzQiwyQkFBMkI7OzRGQUEzQiwyQkFBMkI7a0JBRHZDLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBpc1VuZGVmaW5lZCwgc29ydEJ5IH0gZnJvbSAnbG9kYXNoLWVzJztcbmltcG9ydCB7IGRlYm91bmNlVGltZSwgdGFrZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHtcbiAgSUFwcGxpY2F0aW9uLFxuICBBcHBsaWNhdGlvblR5cGUsXG4gIEFwcGxpY2F0aW9uU2VydmljZSxcbiAgSVN5c3RlbU9wdGlvbixcbiAgVGVuYW50U2VydmljZSxcbiAgVGVuYW50T3B0aW9uc1NlcnZpY2Vcbn0gZnJvbSAnQGM4eS9jbGllbnQnO1xuaW1wb3J0IHsgSHVtYW5pemVBcHBOYW1lUGlwZSB9IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMnO1xuXG5pbXBvcnQge1xuICBQYXJ0aWFsQXBwc0xpc3QsXG4gIERlZmF1bHRTdWJzY3JpcHRpb25zLFxuICBEZWZhdWx0U3Vic2NyaXB0aW9uc0NvbnRleHQgYXMgRGVmYXVsdFN1YnNjcmlwdGlvbnNDb250ZXh0VGVuYW50XG59IGZyb20gJy4vZGVmYXVsdC1zdWJzY3JpcHRpb25zLm1vZGVsJztcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIERlZmF1bHRTdWJzY3JpcHRpb25zU2VydmljZSB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgYXBwbGljYXRpb25TZXJ2aWNlOiBBcHBsaWNhdGlvblNlcnZpY2UsXG4gICAgcHJpdmF0ZSB0ZW5hbnRTZXJ2aWNlOiBUZW5hbnRTZXJ2aWNlLFxuICAgIHByaXZhdGUgdGVuYW50T3B0aW9uc1NlcnZpY2U6IFRlbmFudE9wdGlvbnNTZXJ2aWNlLFxuICAgIHByaXZhdGUgaHVtYW5pemVBcHBOYW1lUGlwZTogSHVtYW5pemVBcHBOYW1lUGlwZVxuICApIHt9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGxpc3Qgb2YgYXBwbGljYXRpb25zIHdoaWNoIGNhbiBiZSB1c2VkIGluIGRlZmF1bHQgc3Vic2NyaXB0aW9ucywgaS5lLjpcbiAgICogLSBjdXJyZW50IHRlbmFudCdzIGFsbCBvd24gYXBwbGljYXRpb25zLFxuICAgKiAtIGluaGVyaXRlZCBhcHBsaWNhdGlvbnMsIHdoaWNoIGRvIG5vdCBoYXZlIHRoZSBzYW1lIG5hbWVzIGFzIGN1cnJlbnQgdGVuYW50J3Mgb3duIGFwcHMuXG4gICAqIFRoZSBsaXN0IGlzIHNvcnRlZCBhbHBoYWJldGljYWxseSBieSBodW1hbml6ZWQgYXBwIG5hbWUgYW5kIGNvbnRhaW5zIHVwIHRvIDIwMDAgaXRlbXMuXG4gICAqIEByZXR1cm5zIFRoZSBsaXN0IG9mIGFwcGxpY2F0aW9ucywgd2hpY2ggY2FuIGJlIHVzZWQgaW4gZGVmYXVsdCBzdWJzY3JpcHRpb25zLlxuICAgKi9cbiAgYXN5bmMgZ2V0U3Vic2NyaWJhYmxlVGVuYW50QXBwcygpOiBQcm9taXNlPElBcHBsaWNhdGlvbltdPiB7XG4gICAgY29uc3QgY3VycmVudFRlbmFudCA9IChhd2FpdCB0aGlzLnRlbmFudFNlcnZpY2UuY3VycmVudCgpKS5kYXRhO1xuXG4gICAgY29uc3QgYWxsQXBwcyA9IChhd2FpdCB0aGlzLmFwcGxpY2F0aW9uU2VydmljZS5saXN0QnlUZW5hbnQobnVsbCwgeyBwYWdlU2l6ZTogMjAwMCB9KSkuZGF0YTtcbiAgICBjb25zdCBvd25BcHBzID0gYWxsQXBwcy5maWx0ZXIoYXBwID0+IGFwcC5vd25lci50ZW5hbnQuaWQgPT09IGN1cnJlbnRUZW5hbnQubmFtZSk7XG4gICAgY29uc3QgaW5oZXJpdGVkQXBwcyA9IGFsbEFwcHMuZmlsdGVyKGFwcCA9PiBhcHAub3duZXIudGVuYW50LmlkICE9PSBjdXJyZW50VGVuYW50Lm5hbWUpO1xuXG4gICAgY29uc3QgZmlsdGVyZWRBcHBzOiBJQXBwbGljYXRpb25bXSA9IFsuLi5vd25BcHBzXTtcbiAgICBpbmhlcml0ZWRBcHBzLmZvckVhY2goaW5oZXJpdGVkQXBwID0+IHtcbiAgICAgIGlmICghZmlsdGVyZWRBcHBzLnNvbWUoZmlsdGVyZWRBcHAgPT4gZmlsdGVyZWRBcHAubmFtZSA9PT0gaW5oZXJpdGVkQXBwLm5hbWUpKSB7XG4gICAgICAgIGZpbHRlcmVkQXBwcy5wdXNoKGluaGVyaXRlZEFwcCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBjb25zdCBmaWx0ZXJlZEFwcHNXaXRoSHVtYW5pemVkTmFtZXMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIGZpbHRlcmVkQXBwcy5tYXAoYXN5bmMgYXBwID0+IHtcbiAgICAgICAgY29uc3QgaHVtYW5pemVkTmFtZSA9IGF3YWl0IHRoaXMuaHVtYW5pemVBcHBOYW1lUGlwZVxuICAgICAgICAgIC50cmFuc2Zvcm0oYXBwLm5hbWUpXG4gICAgICAgICAgLnBpcGUoZGVib3VuY2VUaW1lKDI1MCksIHRha2UoMSkpXG4gICAgICAgICAgLnRvUHJvbWlzZSgpO1xuICAgICAgICByZXR1cm4geyBhcHAsIGh1bWFuaXplZE5hbWUgfTtcbiAgICAgIH0pXG4gICAgKTtcbiAgICBjb25zdCBzb3J0ZWRBcHBzV2l0aEh1bWFuaXplZE5hbWVzID0gc29ydEJ5KGZpbHRlcmVkQXBwc1dpdGhIdW1hbml6ZWROYW1lcywgWydodW1hbml6ZWROYW1lJ10pO1xuICAgIGNvbnN0IHNvcnRlZEFwcHMgPSBzb3J0ZWRBcHBzV2l0aEh1bWFuaXplZE5hbWVzLm1hcCgoeyBhcHAgfSkgPT4gYXBwKTtcblxuICAgIHJldHVybiBzb3J0ZWRBcHBzO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGRlZmF1bHQgc3Vic2NyaXB0aW9ucyBjb25maWd1cmF0aW9uIGluaGVyaXRlZCBmcm9tIHBhcmVudCB0ZW5hbnQuXG4gICAqIEByZXR1cm5zIFRoZSBkZWZhdWx0IHN1YnNjcmlwdGlvbnMgb2JqZWN0IHdpdGggc2V0dGluZ3MgZnJvbSBwYXJlbnQgdGVuYW50LlxuICAgKi9cbiAgYXN5bmMgZ2V0RGVmYXVsdFN1YnNjcmlwdGlvbnNFdmFsdWF0ZWRGcm9tUGFyZW50VGVuYW50KCk6IFByb21pc2U8RGVmYXVsdFN1YnNjcmlwdGlvbnM+IHtcbiAgICByZXR1cm4gdGhpcy5nZXREZWZhdWx0U3Vic2NyaXB0aW9ucyhEZWZhdWx0U3Vic2NyaXB0aW9uc0NvbnRleHRUZW5hbnQuUEFSRU5UX1RFTkFOVCk7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgZGVmYXVsdCBzdWJzY3JpcHRpb25zIGNvbmZpZ3VyYXRpb24gZnJvbSB0aGUgY3VycmVudCB0ZW5hbnQuXG4gICAqIEByZXR1cm5zIFRoZSBkZWZhdWx0IHN1YnNjcmlwdGlvbnMgb2JqZWN0IHdpdGggc2V0dGluZ3MgZnJvbSB0aGUgY3VycmVudCB0ZW5hbnQuXG4gICAqL1xuICBhc3luYyBnZXREZWZhdWx0U3Vic2NyaXB0aW9uc0Zyb21DdXJyZW50VGVuYW50KCk6IFByb21pc2U8RGVmYXVsdFN1YnNjcmlwdGlvbnM+IHtcbiAgICByZXR1cm4gdGhpcy5nZXREZWZhdWx0U3Vic2NyaXB0aW9ucyhEZWZhdWx0U3Vic2NyaXB0aW9uc0NvbnRleHRUZW5hbnQuQ1VSUkVOVF9URU5BTlQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNhdmVzIGdpdmVuIGRlZmF1bHQgc3Vic2NyaXB0aW9ucyBjb25maWd1cmF0aW9uIHRvIHRoZSBjdXJyZW50IHRlbmFudFxuICAgKiAoZWl0aGVyIHNldHMsIHVwZGF0ZXMsIG9yIGRlbGV0ZXMgY29ycmVzcG9uZGluZyB0ZW5hbnQgb3B0aW9ucykuXG4gICAqIEBwYXJhbSBkZWZhdWx0U3Vic2NyaXB0aW9ucyBUaGUgZGVmYXVsdCBzdWJzY3JpcHRpb25zIGNvbmZpZ3VyYXRpb24gdG8gYmUgc2F2ZWQuXG4gICAqL1xuICBhc3luYyBzYXZlRGVmYXVsdFN1YnNjcmlwdGlvbnNUb0N1cnJlbnRUZW5hbnQoZGVmYXVsdFN1YnNjcmlwdGlvbnM6IERlZmF1bHRTdWJzY3JpcHRpb25zKSB7XG4gICAgYXdhaXQgdGhpcy5zYXZlT25DcmVhdGlvblN1YnNjcmlwdGlvbnMoZGVmYXVsdFN1YnNjcmlwdGlvbnMpO1xuICAgIGF3YWl0IHRoaXMuc2F2ZU9uVXBncmFkZVN1YnNjcmlwdGlvbnMoZGVmYXVsdFN1YnNjcmlwdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgZGVmYXVsdCBzdWJzY3JpcHRpb25zIGluIHRoZSBjb250ZXh0IG9mIGN1cnJlbnQgb3IgcGFyZW50IHRlbmFudC5cbiAgICogQHBhcmFtIGNvbnRleHRUZW5hbnQgVGVsbHMgd2hldGhlciB0byB1c2UgY3VycmVudCBvciBwYXJlbnQgdGVuYW50IGFzIGNvbnRleHQuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGdldERlZmF1bHRTdWJzY3JpcHRpb25zKFxuICAgIGNvbnRleHRUZW5hbnQ6IERlZmF1bHRTdWJzY3JpcHRpb25zQ29udGV4dFRlbmFudFxuICApOiBQcm9taXNlPERlZmF1bHRTdWJzY3JpcHRpb25zPiB7XG4gICAgbGV0IHRlbmFudE9wdGlvbnNQYXJhbXM6IG9iamVjdDtcbiAgICBsZXQgb3ZlcnJpZGFibGU6IGJvb2xlYW47XG5cbiAgICBzd2l0Y2ggKGNvbnRleHRUZW5hbnQpIHtcbiAgICAgIGNhc2UgRGVmYXVsdFN1YnNjcmlwdGlvbnNDb250ZXh0VGVuYW50LkNVUlJFTlRfVEVOQU5UOlxuICAgICAgICB0ZW5hbnRPcHRpb25zUGFyYW1zID0geyBldmFsdWF0ZTogJ2N1cnJlbnQnIH07XG4gICAgICAgIG92ZXJyaWRhYmxlID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgRGVmYXVsdFN1YnNjcmlwdGlvbnNDb250ZXh0VGVuYW50LlBBUkVOVF9URU5BTlQ6XG4gICAgICAgIHRlbmFudE9wdGlvbnNQYXJhbXMgPSB7IGV2YWx1YXRlOiAnaW5oZXJpdGVkJyB9O1xuICAgICAgICBvdmVycmlkYWJsZSA9IGZhbHNlO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICBjb25zdCB7XG4gICAgICBvbkNyZWF0aW9uQXBwcyxcbiAgICAgIG9uQ3JlYXRpb25NaWNyb3NlcnZpY2VzLFxuICAgICAgb25VcGdyYWRlQXBwc0VuYWJsZWQsXG4gICAgICBvblVwZ3JhZGVBcHBzLFxuICAgICAgb25VcGdyYWRlTWljcm9zZXJ2aWNlc0VuYWJsZWQsXG4gICAgICBvblVwZ3JhZGVNaWNyb3NlcnZpY2VzXG4gICAgfSA9IGF3YWl0IHRoaXMuZ2V0VGVuYW50T3B0aW9ucyh0ZW5hbnRPcHRpb25zUGFyYW1zKTtcblxuICAgIGNvbnN0IG9uQ3JlYXRpb25TdWJzY3JpcHRpb25zID0gdGhpcy5uYW1lc1RvUGFydGlhbEFwcHMoe1xuICAgICAgYXBwc05hbWVzU3RyOiBvbkNyZWF0aW9uQXBwcyxcbiAgICAgIG1pY3Jvc2VydmljZXNOYW1lc1N0cjogb25DcmVhdGlvbk1pY3Jvc2VydmljZXNcbiAgICB9KTtcblxuICAgIGNvbnN0IG9uVXBncmFkZUFwcHNEZWZhdWx0ID0gb3ZlcnJpZGFibGUgPyBudWxsIDogb25DcmVhdGlvbkFwcHM7XG4gICAgY29uc3Qgb25VcGdyYWRlTWljcm9zZXJ2aWNlc0RlZmF1bHQgPSBvdmVycmlkYWJsZSA/IG51bGwgOiBvbkNyZWF0aW9uTWljcm9zZXJ2aWNlcztcbiAgICBjb25zdCBvblVwZ3JhZGVTdWJzY3JpcHRpb25zID0gdGhpcy5uYW1lc1RvUGFydGlhbEFwcHMoe1xuICAgICAgYXBwc05hbWVzU3RyOiBvblVwZ3JhZGVBcHBzRW5hYmxlZCA/IG9uVXBncmFkZUFwcHMgOiBvblVwZ3JhZGVBcHBzRGVmYXVsdCxcbiAgICAgIG1pY3Jvc2VydmljZXNOYW1lc1N0cjogb25VcGdyYWRlTWljcm9zZXJ2aWNlc0VuYWJsZWRcbiAgICAgICAgPyBvblVwZ3JhZGVNaWNyb3NlcnZpY2VzXG4gICAgICAgIDogb25VcGdyYWRlTWljcm9zZXJ2aWNlc0RlZmF1bHRcbiAgICB9KTtcblxuICAgIGNvbnN0IGRlZmF1bHRTdWJzY3JpcHRpb25zOiBEZWZhdWx0U3Vic2NyaXB0aW9ucyA9IHtcbiAgICAgIG9uQ3JlYXRpb25TdWJzY3JpcHRpb25zLFxuICAgICAgb25VcGdyYWRlU3Vic2NyaXB0aW9uc1xuICAgIH07XG5cbiAgICBpZiAob3ZlcnJpZGFibGUpIHtcbiAgICAgIGRlZmF1bHRTdWJzY3JpcHRpb25zLm92ZXJyaWRlT25DcmVhdGlvblN1YnNjcmlwdGlvbnMgPVxuICAgICAgICBvbkNyZWF0aW9uQXBwcyAhPT0gbnVsbCB8fCBvbkNyZWF0aW9uTWljcm9zZXJ2aWNlcyAhPT0gbnVsbDtcbiAgICAgIGRlZmF1bHRTdWJzY3JpcHRpb25zLm92ZXJyaWRlT25VcGdyYWRlU3Vic2NyaXB0aW9ucyA9XG4gICAgICAgIG9uVXBncmFkZUFwcHNFbmFibGVkIHx8IG9uVXBncmFkZU1pY3Jvc2VydmljZXNFbmFibGVkO1xuICAgIH1cblxuICAgIHJldHVybiBkZWZhdWx0U3Vic2NyaXB0aW9ucztcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZ2V0VGVuYW50T3B0aW9ucyhwYXJhbXMgPSB7fSkge1xuICAgIHJldHVybiB7XG4gICAgICBvbkNyZWF0aW9uQXBwczogYXdhaXQgdGhpcy5nZXRUZW5hbnRPcHRpb24oXG4gICAgICAgIHtcbiAgICAgICAgICBjYXRlZ29yeTogJ2NvbmZpZ3VyYXRpb24nLFxuICAgICAgICAgIGtleTogJ2RlZmF1bHQudGVuYW50LmFwcGxpY2F0aW9ucydcbiAgICAgICAgfSxcbiAgICAgICAgbnVsbCxcbiAgICAgICAgcGFyYW1zXG4gICAgICApLFxuICAgICAgb25DcmVhdGlvbk1pY3Jvc2VydmljZXM6IGF3YWl0IHRoaXMuZ2V0VGVuYW50T3B0aW9uKFxuICAgICAgICB7XG4gICAgICAgICAgY2F0ZWdvcnk6ICdjb25maWd1cmF0aW9uJyxcbiAgICAgICAgICBrZXk6ICdkZWZhdWx0LnRlbmFudC5taWNyb3NlcnZpY2VzJ1xuICAgICAgICB9LFxuICAgICAgICBudWxsLFxuICAgICAgICBwYXJhbXNcbiAgICAgICksXG4gICAgICBvblVwZ3JhZGVBcHBzRW5hYmxlZDogYXdhaXQgdGhpcy5nZXRUZW5hbnRPcHRpb24oXG4gICAgICAgIHtcbiAgICAgICAgICBjYXRlZ29yeTogJ2NvbmZpZ3VyYXRpb24nLFxuICAgICAgICAgIGtleTogJ29uLXVwZGF0ZS50ZW5hbnQuYXBwbGljYXRpb25zLmVuYWJsZWQnXG4gICAgICAgIH0sXG4gICAgICAgIGZhbHNlLFxuICAgICAgICBwYXJhbXNcbiAgICAgICksXG4gICAgICBvblVwZ3JhZGVBcHBzOiBhd2FpdCB0aGlzLmdldFRlbmFudE9wdGlvbihcbiAgICAgICAge1xuICAgICAgICAgIGNhdGVnb3J5OiAnY29uZmlndXJhdGlvbicsXG4gICAgICAgICAga2V5OiAnb24tdXBkYXRlLnRlbmFudC5hcHBsaWNhdGlvbnMnXG4gICAgICAgIH0sXG4gICAgICAgIG51bGwsXG4gICAgICAgIHBhcmFtc1xuICAgICAgKSxcbiAgICAgIG9uVXBncmFkZU1pY3Jvc2VydmljZXNFbmFibGVkOiBhd2FpdCB0aGlzLmdldFRlbmFudE9wdGlvbihcbiAgICAgICAge1xuICAgICAgICAgIGNhdGVnb3J5OiAnY29uZmlndXJhdGlvbicsXG4gICAgICAgICAga2V5OiAnb24tdXBkYXRlLnRlbmFudC5taWNyb3NlcnZpY2VzLmVuYWJsZWQnXG4gICAgICAgIH0sXG4gICAgICAgIGZhbHNlLFxuICAgICAgICBwYXJhbXNcbiAgICAgICksXG4gICAgICBvblVwZ3JhZGVNaWNyb3NlcnZpY2VzOiBhd2FpdCB0aGlzLmdldFRlbmFudE9wdGlvbihcbiAgICAgICAge1xuICAgICAgICAgIGNhdGVnb3J5OiAnY29uZmlndXJhdGlvbicsXG4gICAgICAgICAga2V5OiAnb24tdXBkYXRlLnRlbmFudC5taWNyb3NlcnZpY2VzJ1xuICAgICAgICB9LFxuICAgICAgICBudWxsLFxuICAgICAgICBwYXJhbXNcbiAgICAgIClcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzYXZlT25DcmVhdGlvblN1YnNjcmlwdGlvbnMoZGVmYXVsdFN1YnNjcmlwdGlvbnM6IERlZmF1bHRTdWJzY3JpcHRpb25zKSB7XG4gICAgaWYgKGRlZmF1bHRTdWJzY3JpcHRpb25zLm92ZXJyaWRlT25DcmVhdGlvblN1YnNjcmlwdGlvbnMpIHtcbiAgICAgIGF3YWl0IHRoaXMuc2V0VGVuYW50T3B0aW9uKHtcbiAgICAgICAgY2F0ZWdvcnk6ICdjb25maWd1cmF0aW9uJyxcbiAgICAgICAga2V5OiAnZGVmYXVsdC50ZW5hbnQuYXBwbGljYXRpb25zJyxcbiAgICAgICAgdmFsdWU6IHRoaXMucGFydGlhbEFwcHNMaXN0VG9BcHBzTmFtZXMoZGVmYXVsdFN1YnNjcmlwdGlvbnMub25DcmVhdGlvblN1YnNjcmlwdGlvbnMpXG4gICAgICB9KTtcbiAgICAgIGF3YWl0IHRoaXMuc2V0VGVuYW50T3B0aW9uKHtcbiAgICAgICAgY2F0ZWdvcnk6ICdjb25maWd1cmF0aW9uJyxcbiAgICAgICAga2V5OiAnZGVmYXVsdC50ZW5hbnQubWljcm9zZXJ2aWNlcycsXG4gICAgICAgIHZhbHVlOiB0aGlzLnBhcnRpYWxBcHBzVG9NaWNyb3NlcnZpY2VzTmFtZXMoZGVmYXVsdFN1YnNjcmlwdGlvbnMub25DcmVhdGlvblN1YnNjcmlwdGlvbnMpXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXdhaXQgdGhpcy51bnNldFRlbmFudE9wdGlvbih7XG4gICAgICAgIGNhdGVnb3J5OiAnY29uZmlndXJhdGlvbicsXG4gICAgICAgIGtleTogJ2RlZmF1bHQudGVuYW50LmFwcGxpY2F0aW9ucydcbiAgICAgIH0pO1xuICAgICAgYXdhaXQgdGhpcy51bnNldFRlbmFudE9wdGlvbih7XG4gICAgICAgIGNhdGVnb3J5OiAnY29uZmlndXJhdGlvbicsXG4gICAgICAgIGtleTogJ2RlZmF1bHQudGVuYW50Lm1pY3Jvc2VydmljZXMnXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNhdmVPblVwZ3JhZGVTdWJzY3JpcHRpb25zKGRlZmF1bHRTdWJzY3JpcHRpb25zOiBEZWZhdWx0U3Vic2NyaXB0aW9ucykge1xuICAgIGlmIChkZWZhdWx0U3Vic2NyaXB0aW9ucy5vdmVycmlkZU9uVXBncmFkZVN1YnNjcmlwdGlvbnMpIHtcbiAgICAgIGF3YWl0IHRoaXMuc2V0VGVuYW50T3B0aW9uKHtcbiAgICAgICAgY2F0ZWdvcnk6ICdjb25maWd1cmF0aW9uJyxcbiAgICAgICAga2V5OiAnb24tdXBkYXRlLnRlbmFudC5hcHBsaWNhdGlvbnMuZW5hYmxlZCcsXG4gICAgICAgIHZhbHVlOiAndHJ1ZSdcbiAgICAgIH0pO1xuICAgICAgYXdhaXQgdGhpcy5zZXRUZW5hbnRPcHRpb24oe1xuICAgICAgICBjYXRlZ29yeTogJ2NvbmZpZ3VyYXRpb24nLFxuICAgICAgICBrZXk6ICdvbi11cGRhdGUudGVuYW50Lm1pY3Jvc2VydmljZXMuZW5hYmxlZCcsXG4gICAgICAgIHZhbHVlOiAndHJ1ZSdcbiAgICAgIH0pO1xuICAgICAgYXdhaXQgdGhpcy5zZXRUZW5hbnRPcHRpb24oe1xuICAgICAgICBjYXRlZ29yeTogJ2NvbmZpZ3VyYXRpb24nLFxuICAgICAgICBrZXk6ICdvbi11cGRhdGUudGVuYW50LmFwcGxpY2F0aW9ucycsXG4gICAgICAgIHZhbHVlOiB0aGlzLnBhcnRpYWxBcHBzTGlzdFRvQXBwc05hbWVzKGRlZmF1bHRTdWJzY3JpcHRpb25zLm9uVXBncmFkZVN1YnNjcmlwdGlvbnMpXG4gICAgICB9KTtcbiAgICAgIGF3YWl0IHRoaXMuc2V0VGVuYW50T3B0aW9uKHtcbiAgICAgICAgY2F0ZWdvcnk6ICdjb25maWd1cmF0aW9uJyxcbiAgICAgICAga2V5OiAnb24tdXBkYXRlLnRlbmFudC5taWNyb3NlcnZpY2VzJyxcbiAgICAgICAgdmFsdWU6IHRoaXMucGFydGlhbEFwcHNUb01pY3Jvc2VydmljZXNOYW1lcyhkZWZhdWx0U3Vic2NyaXB0aW9ucy5vblVwZ3JhZGVTdWJzY3JpcHRpb25zKVxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGF3YWl0IHRoaXMudW5zZXRUZW5hbnRPcHRpb24oe1xuICAgICAgICBjYXRlZ29yeTogJ2NvbmZpZ3VyYXRpb24nLFxuICAgICAgICBrZXk6ICdvbi11cGRhdGUudGVuYW50LmFwcGxpY2F0aW9ucy5lbmFibGVkJ1xuICAgICAgfSk7XG4gICAgICBhd2FpdCB0aGlzLnVuc2V0VGVuYW50T3B0aW9uKHtcbiAgICAgICAgY2F0ZWdvcnk6ICdjb25maWd1cmF0aW9uJyxcbiAgICAgICAga2V5OiAnb24tdXBkYXRlLnRlbmFudC5taWNyb3NlcnZpY2VzLmVuYWJsZWQnXG4gICAgICB9KTtcbiAgICAgIGF3YWl0IHRoaXMudW5zZXRUZW5hbnRPcHRpb24oe1xuICAgICAgICBjYXRlZ29yeTogJ2NvbmZpZ3VyYXRpb24nLFxuICAgICAgICBrZXk6ICdvbi11cGRhdGUudGVuYW50LmFwcGxpY2F0aW9ucydcbiAgICAgIH0pO1xuICAgICAgYXdhaXQgdGhpcy51bnNldFRlbmFudE9wdGlvbih7XG4gICAgICAgIGNhdGVnb3J5OiAnY29uZmlndXJhdGlvbicsXG4gICAgICAgIGtleTogJ29uLXVwZGF0ZS50ZW5hbnQubWljcm9zZXJ2aWNlcydcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZ2V0VGVuYW50T3B0aW9uKG9wdGlvbjogSVN5c3RlbU9wdGlvbiwgZGVmYXVsdFZhbHVlID0gbnVsbCwgcGFyYW1zID0ge30pIHtcbiAgICBsZXQgdmFsdWU7XG4gICAgdHJ5IHtcbiAgICAgIHZhbHVlID0gKGF3YWl0IHRoaXMudGVuYW50T3B0aW9uc1NlcnZpY2UuZGV0YWlsKG9wdGlvbiwgcGFyYW1zKSkuZGF0YS52YWx1ZTtcbiAgICAgIHZhbHVlID0gSlNPTi5wYXJzZSh2YWx1ZSk7XG4gICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgIHZhbHVlID0gIWlzVW5kZWZpbmVkKHZhbHVlKSA/IHZhbHVlIDogZGVmYXVsdFZhbHVlO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNldFRlbmFudE9wdGlvbihvcHRpb246IElTeXN0ZW1PcHRpb24pIHtcbiAgICByZXR1cm4gdGhpcy50ZW5hbnRPcHRpb25zU2VydmljZS51cGRhdGUob3B0aW9uKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgdW5zZXRUZW5hbnRPcHRpb24ob3B0aW9uOiBJU3lzdGVtT3B0aW9uKSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMudGVuYW50T3B0aW9uc1NlcnZpY2UuZGVsZXRlKG9wdGlvbik7XG4gICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgIGlmICghZXggfHwgIWV4LnJlcyB8fCBleC5yZXMuc3RhdHVzICE9PSA0MDQpIHtcbiAgICAgICAgdGhyb3cgZXg7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBuYW1lc1RvUGFydGlhbEFwcHMoe1xuICAgIGFwcHNOYW1lc1N0cixcbiAgICBtaWNyb3NlcnZpY2VzTmFtZXNTdHJcbiAgfToge1xuICAgIGFwcHNOYW1lc1N0cj86IHN0cmluZztcbiAgICBtaWNyb3NlcnZpY2VzTmFtZXNTdHI/OiBzdHJpbmc7XG4gIH0pOiBQYXJ0aWFsQXBwc0xpc3Qge1xuICAgIGlmIChhcHBzTmFtZXNTdHIgPT09IG51bGwgJiYgbWljcm9zZXJ2aWNlc05hbWVzU3RyID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gW1xuICAgICAgLi4uKGFwcHNOYW1lc1N0ciB8fCAnJylcbiAgICAgICAgLnNwbGl0KCcsJylcbiAgICAgICAgLmZpbHRlcihuYW1lID0+IG5hbWUubGVuZ3RoKVxuICAgICAgICAubWFwKG5hbWUgPT4gKHsgbmFtZTogbmFtZS50cmltKCkgfSkpLFxuICAgICAgLi4uKG1pY3Jvc2VydmljZXNOYW1lc1N0ciB8fCAnJylcbiAgICAgICAgLnNwbGl0KCcsJylcbiAgICAgICAgLmZpbHRlcihuYW1lID0+IG5hbWUubGVuZ3RoKVxuICAgICAgICAubWFwKG5hbWUgPT4gKHtcbiAgICAgICAgICBuYW1lOiBuYW1lLnRyaW0oKSxcbiAgICAgICAgICB0eXBlOiBBcHBsaWNhdGlvblR5cGUuTUlDUk9TRVJWSUNFXG4gICAgICAgIH0pKVxuICAgIF07XG4gIH1cblxuICBwcml2YXRlIHBhcnRpYWxBcHBzTGlzdFRvQXBwc05hbWVzKGFwcHM6IFBhcnRpYWxBcHBzTGlzdCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGFwcHNcbiAgICAgIC5maWx0ZXIoYXBwID0+IGFwcC50eXBlICE9PSBBcHBsaWNhdGlvblR5cGUuTUlDUk9TRVJWSUNFKVxuICAgICAgLm1hcChhcHAgPT4gYXBwLm5hbWUpXG4gICAgICAuam9pbignLCcpO1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJ0aWFsQXBwc1RvTWljcm9zZXJ2aWNlc05hbWVzKGFwcHM6IFBhcnRpYWxBcHBzTGlzdCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGFwcHNcbiAgICAgIC5maWx0ZXIoYXBwID0+IGFwcC50eXBlID09PSBBcHBsaWNhdGlvblR5cGUuTUlDUk9TRVJWSUNFKVxuICAgICAgLm1hcChhcHAgPT4gYXBwLm5hbWUpXG4gICAgICAuam9pbignLCcpO1xuICB9XG59XG4iXX0=