| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| import {Component, OnInit, ViewChild} from '@angular/core'; |
| import {ResourceService} from '../resource/resource.service'; |
| import {Resource} from '../resource/resource'; |
| import {ProviderConfig} from './provider-config'; |
| import {Descriptor} from './descriptor'; |
| import {Service} from '../resource/service'; |
| import {parseString} from 'xml2js'; |
| |
| import 'brace/theme/monokai'; |
| import 'brace/mode/xml'; |
| |
| import {ProviderConfigSelectorComponent} from '../provider-config-selector/provider-config-selector.component'; |
| import {ResourceTypesService} from '../resourcetypes/resourcetypes.service'; |
| import {HttpErrorResponse} from '@angular/common/http'; |
| |
| @Component({ |
| selector: 'app-resource-detail', |
| templateUrl: './resource-detail.component.html', |
| styleUrls: ['./resource-detail.component.css'] |
| }) |
| export class ResourceDetailComponent implements OnInit { |
| |
| // Static "empty" Resource used for clearing the display between resource selections |
| private static emptyResource: Resource = new Resource(); |
| |
| private static emptyDescriptor: Descriptor = new Descriptor(); |
| |
| title: string; |
| |
| resourceType: string; |
| resource: Resource; |
| resourceContent: string; |
| |
| providers: Array<ProviderConfig>; |
| readOnlyProviderConfig: boolean; |
| changedProviders: Array<ProviderConfig>; |
| |
| descriptor: Descriptor; |
| |
| @ViewChild('choosePC') |
| chooseProviderConfigModal: ProviderConfigSelectorComponent; |
| |
| referencedProviderConfigError = false; |
| |
| constructor(private resourceService: ResourceService, private resourceTypesService: ResourceTypesService) { |
| } |
| |
| ngOnInit() { |
| this.resourceService.selectedResourceType$.subscribe(type => this.setResourceType(type)); |
| this.resourceService.selectedResource$.subscribe(value => this.setResource(value)); |
| } |
| |
| setResourceType(resType: string) { |
| // Clear the current resource details |
| if (this.resource) { |
| this.resource.name = ''; |
| } // This clears the details title when the type context changes |
| this.resource = ResourceDetailComponent.emptyResource; |
| this.providers = null; |
| this.descriptor = ResourceDetailComponent.emptyDescriptor; |
| this.resourceContent = ''; // Clear the content area |
| this.resourceType = resType; |
| } |
| |
| setResource(res: Resource) { |
| this.referencedProviderConfigError = false; |
| this.resource = res; |
| this.providers = []; |
| this.changedProviders = null; |
| this.descriptor = ResourceDetailComponent.emptyDescriptor; |
| if (res) { |
| this.resourceService.getResource(this.resourceType, res) |
| .then(content => this.setResourceContent(res, content)) |
| .catch((error: HttpErrorResponse) => { |
| console.debug('Error accessing content for ' + res.name + ' : ' + error); |
| }); |
| } |
| } |
| |
| setResourceContent(res: Resource, content: string) { |
| switch (this.resourceType) { |
| case 'Provider Configurations': { |
| this.setProviderConfigContent(res, content); |
| break; |
| } |
| case 'Descriptors': { |
| this.setDescriptorContent(res, content); |
| break; |
| } |
| } |
| } |
| |
| setProviderConfigContent(res: Resource, content: string) { |
| this.resourceContent = content; |
| if (this.resourceContent) { |
| try { |
| let contentObj; |
| if (res.name.endsWith('json')) { |
| // Parse the JSON representation |
| contentObj = JSON.parse(this.resourceContent); |
| this.providers = contentObj['providers']; |
| this.readOnlyProviderConfig = contentObj['readOnly']; |
| } else if (res.name.endsWith('yaml') || res.name.endsWith('yml')) { |
| // Parse the YAML representation |
| let yaml = require('js-yaml'); |
| contentObj = yaml.safeLoad(this.resourceContent); |
| this.providers = contentObj['providers']; |
| this.readOnlyProviderConfig = contentObj['readOnly']; |
| } else if (res.name.endsWith('xml')) { |
| // Parse the XML representation |
| parseString(this.resourceContent, |
| (error, result) => { |
| if (error) { |
| console.log('Error parsing ' + res.name + ' error: ' + error); |
| } else { |
| // Parsing the XML is a bit less straight-forward |
| let tempProviders = new Array<ProviderConfig>(); |
| result['gateway'].provider.forEach(entry => { |
| let providerConfig: ProviderConfig = new ProviderConfig(); |
| providerConfig.role = entry.role[0]; |
| providerConfig.name = entry.name[0]; |
| providerConfig.enabled = entry.enabled[0]; |
| |
| // There may not be params |
| if (entry.param) { |
| let params = new Map<string, string>(); |
| for (let i = 0; i < entry.param.length; i++) { |
| let param = entry.param[i]; |
| params[param.name[0]] = param.value[0]; |
| } |
| providerConfig.params = params; |
| } |
| tempProviders.push(providerConfig); |
| }); |
| this.providers = tempProviders; |
| this.readOnlyProviderConfig = result['gateway'].readOnly; |
| } |
| }); |
| } |
| } catch (e) { |
| console.error('ResourceDetailComponent --> setProviderConfigContent() --> Error parsing ' + res.name + ' content: ' + e); |
| this.providers = null; // Clear detail display |
| } |
| } |
| } |
| |
| setDescriptorContent(res: Resource, content: string) { |
| this.resourceContent = content; |
| if (this.resourceContent) { |
| try { |
| let contentObj; |
| if (res.name.endsWith('json')) { |
| contentObj = JSON.parse(this.resourceContent); |
| } else if (res.name.endsWith('yaml') || res.name.endsWith('yml')) { |
| let yaml = require('js-yaml'); |
| contentObj = yaml.load(this.resourceContent); |
| } |
| let tempDesc = new Descriptor(); |
| if (contentObj) { |
| tempDesc.discoveryType = contentObj['discovery-type']; |
| tempDesc.discoveryAddress = contentObj['discovery-address']; |
| tempDesc.discoveryUser = contentObj['discovery-user']; |
| tempDesc.discoveryPassAlias = contentObj['discovery-pwd-alias']; |
| tempDesc.discoveryCluster = contentObj['cluster']; |
| tempDesc.providerConfig = contentObj['provider-config-ref']; |
| tempDesc.readOnly = contentObj['read-only']; |
| tempDesc.services = contentObj['services']; |
| } |
| this.descriptor = tempDesc; |
| } catch (e) { |
| console.error('ResourceDetailComponent.setDescriptorContent: Error parsing ' + res.name + ' content: ' + e); |
| } |
| } |
| } |
| |
| persistChanges() { |
| switch (this.resourceType) { |
| case 'Provider Configurations' : { |
| this.persistProviderConfiguration(); |
| break; |
| } |
| case 'Descriptors': { |
| this.persistDescriptor(); |
| } |
| } |
| } |
| |
| persistProviderConfiguration() { |
| let content; |
| let ext = this.resource.name.split('.').pop(); |
| switch (ext) { |
| case 'json': { |
| content = this.resourceService.serializeProviderConfiguration(this.providers, 'json'); |
| break; |
| } |
| case 'yaml': |
| case 'yml': { |
| content = this.resourceService.serializeProviderConfiguration(this.providers, 'yaml'); |
| break; |
| } |
| case 'xml': { |
| // We're not going to bother serializing XML. Rather, delete the original XML resource, and replace it |
| // with JSON |
| console.debug('Replacing XML provider configuration ' + this.resource.name + ' with JSON...'); |
| |
| // Generate the JSON representation of the updated provider configuration |
| content = this.resourceService.serializeProviderConfiguration(this.providers, 'json'); |
| |
| let replacementResource = new Resource(); |
| replacementResource.name = this.resource.name.slice(0, -4) + '.json'; |
| replacementResource.href = this.resource.href; |
| |
| // Delete the XML resource |
| this.resourceService.deleteResource(this.resource.href + '?force=true') |
| .then(() => { |
| // Save the updated content |
| this.resourceService.saveResource(replacementResource, content).then(() => { |
| // Update the list of provider configuration to ensure that the XML one is replaced with the JSON one |
| this.resourceTypesService.selectResourceType(this.resourceType); |
| // Update the detail view |
| this.resourceService.selectedResource(replacementResource); |
| }) |
| .catch(err => { |
| console.error('Error persisting ' + replacementResource.name + ' : ' + err); |
| }); |
| }); |
| break; |
| } |
| } |
| |
| // For the non-XML provider configuration cases, simply save the changes |
| if (ext !== 'xml') { |
| // Save the updated content |
| this.resourceService.saveResource(this.resource, content) |
| .then(() => { |
| // Refresh the presentation |
| this.resourceService.selectedResource(this.resource); |
| }) |
| .catch(err => { |
| console.error('Error persisting ' + this.resource.name + ' : ' + err); |
| }); |
| } |
| } |
| |
| persistDescriptor() { |
| let content; |
| let ext = this.resource.name.split('.').pop(); |
| switch (ext) { |
| case 'json': { |
| content = this.resourceService.serializeDescriptor(this.descriptor, 'json'); |
| break; |
| } |
| case 'yaml': |
| case 'yml': { |
| content = this.resourceService.serializeDescriptor(this.descriptor, 'yaml'); |
| break; |
| } |
| } |
| |
| // Save the updated content |
| this.resourceService.saveResource(this.resource, content) |
| .then(() => { |
| // Refresh the presentation |
| this.resourceService.selectedResource(this.resource); |
| }) |
| .catch(err => { |
| console.error('Error persisting ' + this.resource.name + ' : ' + err); |
| }); |
| } |
| |
| discardChanges() { |
| this.resourceService.selectedResource(this.resource); |
| } |
| |
| |
| deleteResource() { |
| let resourceName = this.resource.name; |
| this.resourceService.deleteResource(this.resource.href) |
| .then(() => { |
| console.debug('Deleted ' + resourceName); |
| // This refreshes the list of resources |
| this.resourceTypesService.selectResourceType(this.resourceType); |
| }) |
| .catch((err: HttpErrorResponse) => { |
| if (err.status === 304) { // Not Modified |
| console.log(resourceName + ' cannot be deleted while there are descriptors actively referencing it.'); |
| this.referencedProviderConfigError = true; |
| } else { |
| console.error('Error deleting ' + resourceName + ' : ' + err.message); |
| } |
| }); |
| } |
| |
| onRemoveProvider(name: string) { |
| for (let i = 0; i < this.providers.length; i++) { |
| if (this.providers[i].name === name) { |
| this.providers.splice(i, 1); |
| break; |
| } |
| } |
| this.changedProviders = this.providers; |
| } |
| |
| onProviderEnabled(provider: ProviderConfig) { |
| provider.enabled = this.isProviderEnabled(provider) ? 'false' : 'true'; |
| this.changedProviders = this.providers; |
| } |
| |
| onRemoveProviderParam(pc: ProviderConfig, paramName: string) { |
| if (pc.params.hasOwnProperty(paramName)) { |
| delete pc.params[paramName]; |
| } |
| this.changedProviders = this.providers; |
| } |
| |
| onRemoveDescriptorService(serviceName: string) { |
| for (let i = 0; i < this.descriptor.services.length; i++) { |
| if (this.descriptor.services[i].name === serviceName) { |
| this.descriptor.services.splice(i, 1); |
| this.descriptor.setDirty(); |
| break; |
| } |
| } |
| } |
| |
| onRemoveDescriptorServiceParam(serviceName: string, paramName: string) { |
| let done = false; |
| for (let i = 0; i < this.descriptor.services.length; i++) { |
| if (this.descriptor.services[i].name === serviceName) { |
| let service = this.descriptor.services[i]; |
| if (service.params.hasOwnProperty(paramName)) { |
| delete service.params[paramName]; |
| this.descriptor.setDirty(); |
| done = true; |
| break; |
| } |
| } |
| if (done) { // Stop checking services if it has already been handled |
| break; |
| } |
| } |
| } |
| |
| onRemoveDescriptorServiceURL(serviceName: string, serviceUrl: string) { |
| let done = false; |
| for (let i = 0; i < this.descriptor.services.length; i++) { |
| if (this.descriptor.services[i].name === serviceName) { |
| let service = this.descriptor.services[i]; |
| for (let j = 0; j < service.urls.length; j++) { |
| if (service.urls[j] === serviceUrl) { |
| service.urls.splice(j, 1); |
| this.descriptor.setDirty(); |
| done = true; |
| break; |
| } |
| } |
| } |
| if (done) { // Stop checking services if it has already been handled |
| break; |
| } |
| } |
| } |
| |
| toggleShowProvider(provider: ProviderConfig) { |
| this[this.resource.name + provider.name + 'Show'] = !this.isShowProvider(provider); |
| } |
| |
| isShowProvider(provider: ProviderConfig): boolean { |
| return this[this.resource.name + provider.name + 'Show']; |
| } |
| |
| toggleShowProviderParams(provider: ProviderConfig) { |
| this[this.resource.name + provider.name + 'ShowParams'] = !this.isShowProviderParams(provider); |
| } |
| |
| showProviderParams(provider: ProviderConfig) { |
| this[this.resource.name + provider.name + 'ShowParams'] = true; |
| } |
| |
| isShowProviderParams(provider: ProviderConfig): boolean { |
| return this[this.resource.name + provider.name + 'ShowParams']; |
| } |
| |
| toggleShowServices() { |
| this[this.resource.name + 'ShowServices'] = !this.isShowServices(); |
| } |
| |
| showServices() { |
| this[this.resource.name + 'ShowServices'] = true; |
| } |
| |
| isShowServices(): boolean { |
| return this[this.resource.name + 'ShowServices']; |
| } |
| |
| toggleShowServiceDiscovery() { |
| this[this.resource.name + 'ShowDiscovery'] = !this.isShowServiceDiscovery(); |
| } |
| |
| isShowServiceDiscovery(): boolean { |
| return this[this.resource.name + 'ShowDiscovery']; |
| } |
| |
| toggleShowServiceParams(service: Service) { |
| this[this.resource.name + service.name + 'ShowParams'] = !this.isShowServiceParams(service); |
| } |
| |
| showServiceParams(service: Service) { |
| this[this.resource.name + service.name + 'ShowParams'] = true; |
| } |
| |
| isShowServiceParams(service: Service): boolean { |
| return this[this.resource.name + service.name + 'ShowParams']; |
| } |
| |
| toggleShowServiceURLs(service: Service) { |
| this[this.resource.name + service.name + 'ShowURLs'] = !this.isShowServiceURLs(service); |
| } |
| |
| showServiceURLs(service: Service) { |
| this[this.resource.name + service.name + 'ShowURLs'] = true; |
| } |
| |
| isShowServiceURLs(service: Service): boolean { |
| return this[this.resource.name + service.name + 'ShowURLs']; |
| } |
| |
| setProviderParamEditFlag(provider: ProviderConfig, paramName: string, value: boolean) { |
| this[provider.name + paramName + 'EditMode'] = value; |
| this.changedProviders = this.providers; |
| } |
| |
| getProviderParamEditFlag(provider: ProviderConfig, paramName: string): boolean { |
| return this[provider.name + paramName + 'EditMode']; |
| } |
| |
| setServiceVersionEditFlag(service: Service, value: boolean) { |
| this[service.name + 'EditMode'] = value; |
| this.descriptor.setDirty(); |
| } |
| |
| getServiceVersionEditFlag(service: Service): boolean { |
| return this[service.name + 'EditMode']; |
| } |
| |
| setServiceParamEditFlag(service: Service, paramName: string, value: boolean) { |
| this[service.name + paramName + 'EditMode'] = value; |
| this.descriptor.setDirty(); |
| } |
| |
| getServiceParamEditFlag(service: Service, paramName: string): boolean { |
| return this[service.name + paramName + 'EditMode']; |
| } |
| |
| setServiceURLEditFlag(service: Service, index: number, value: boolean) { |
| this[service.name + index + 'EditMode'] = value; |
| this.descriptor.setDirty(); |
| } |
| |
| getServiceURLEditFlag(service: Service, index: number): boolean { |
| return this[service.name + index + 'EditMode']; |
| } |
| |
| isAddingServiceParam(service: Service): boolean { |
| return this['addParam' + service.name]; |
| } |
| |
| setAddingServiceParam(service: Service, value: boolean) { |
| this['addParam' + service.name] = value; |
| } |
| |
| isAddingServiceURL(service: Service): boolean { |
| return this['addURL' + service.name]; |
| } |
| |
| setAddingServiceURL(service: Service, value: boolean) { |
| this['addURL' + service.name] = value; |
| } |
| |
| isAddingProviderParam(provider: ProviderConfig): boolean { |
| return this['addParam' + provider.name]; |
| } |
| |
| setAddingProviderParam(provider: ProviderConfig, value: boolean) { |
| this['addParam' + provider.name] = value; |
| } |
| |
| addProvider(name: string, role: string) { |
| let p = new ProviderConfig(); |
| p.name = name; |
| p.role = role; |
| this.providers.push(p); |
| this.changedProviders = this.providers; |
| } |
| |
| addProviderParam(provider: ProviderConfig, name: string, value: string) { |
| if (!provider.params) { |
| provider.params = new Map<string, string>(); |
| } |
| provider.params[name] = value; |
| this.changedProviders = this.providers; |
| } |
| |
| getProviderParamNames(provider: ProviderConfig): string[] { |
| if (!provider.params) { |
| provider.params = new Map<string, string>(); |
| } |
| return Object.keys(provider.params); |
| } |
| |
| isProviderEnabled(pc: ProviderConfig): boolean { |
| let result = false; |
| |
| if (pc) { |
| if (typeof (pc.enabled) === 'string') { |
| let lowered = pc.enabled.toLowerCase().trim(); |
| result = (lowered === 'true'); |
| } else if (typeof (pc.enabled) === 'boolean') { |
| result = pc.enabled; |
| } |
| } |
| |
| return result; |
| } |
| |
| // This method is required to maintain focus on descriptor service URLs when they're being edited. |
| trackByServiceURLIndex(index: any, item: any) { |
| return index; |
| } |
| |
| hasSelectedResource(): boolean { |
| return Boolean(this.resource) && Boolean(this.resource.name); |
| } |
| |
| getTitleSubject(): string { |
| switch (this.resourceType) { |
| case 'Topologies': { |
| return 'Topology'; |
| } |
| case 'Provider Configurations': |
| case 'Descriptors': { |
| return this.resourceType.substring(0, this.resourceType.length - 1); |
| } |
| default: { |
| return 'Resource'; |
| } |
| } |
| } |
| |
| showEditOptions(): boolean { |
| if (this.resourceType === 'Descriptors' && this.descriptor.readOnly) { |
| return !Boolean(this.descriptor.readOnly); |
| } |
| |
| if (this.resourceType === 'Provider Configurations' && this.readOnlyProviderConfig) { |
| return !this.readOnlyProviderConfig; |
| } |
| |
| return true; |
| } |
| } |