gateway-admin-ui/admin-ui/app/resource/resource.service.ts (331 lines of code) (raw):

/* * 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 {Injectable} from '@angular/core'; import {HttpClient, HttpErrorResponse, HttpHeaders} from '@angular/common/http'; import 'rxjs/add/operator/toPromise'; import {Subject} from 'rxjs/Subject'; import {Resource} from './resource'; import {ProviderConfig} from '../resource-detail/provider-config'; import {Descriptor} from '../resource-detail/descriptor'; @Injectable() export class ResourceService { discoveryTypes: Array<string>; apiUrl = window.location.pathname.replace(new RegExp('admin-ui/.*'), 'api/v1/'); providersUrl = this.apiUrl + 'providerconfig'; descriptorsUrl = this.apiUrl + 'descriptors'; topologiesUrl = this.apiUrl + 'topologies'; serviceDiscoveriesUrl = this.apiUrl + 'servicediscoveries'; serviceDefinitionsUrl = this.apiUrl + 'servicedefinitions'; selectedResourceTypeSource = new Subject<string>(); selectedResourceType$ = this.selectedResourceTypeSource.asObservable(); selectedResourceSource = new Subject<Resource>(); selectedResource$ = this.selectedResourceSource.asObservable(); changedResourceSource = new Subject<string>(); changedResource$ = this.changedResourceSource.asObservable(); changedProviderConfigurationSource = new Subject<Array<ProviderConfig>>(); changedProviderConfiguration$ = this.changedProviderConfigurationSource.asObservable(); constructor(private http: HttpClient) { this.initSupportedDiscoveryTypes(); } initSupportedDiscoveryTypes(): void { if (this.discoveryTypes == null || this.discoveryTypes.length === 0) { let headers = this.addJsonHeaders(new HttpHeaders()); this.getServiceDiscoveryResources() .then(response => this.discoveryTypes = response.knoxServiceDiscoveries.knoxServiceDiscovery.map(sd => sd.type)) .catch((err: HttpErrorResponse) => { console.debug('ResourceService --> getServiceDiscoveryResources() --> error: HTTP ' + err.status + ' ' + err.message); if (err.status === 401) { window.location.assign(document.location.pathname); } else { return this.handleError(err); } }); } } getServiceDiscoveryResources(): Promise<any> { let headers = this.addJsonHeaders(new HttpHeaders()); return this.http.get(this.serviceDiscoveriesUrl, {headers: headers}).toPromise(); } getResources(resType: string): Promise<Resource[]> { switch (resType) { case 'Provider Configurations': { return this.getProviderConfigResources(); } case 'Descriptors': { return this.getDescriptorResources(); } case 'Service Definitions': { return this.getServiceDefinitionResources(); } case 'Topologies': { return this.getTopologyResources(); } } } getProviderConfigResources(): Promise<Resource[]> { let headers = this.addJsonHeaders(new HttpHeaders()); return this.http.get(this.providersUrl, {headers: headers}) .toPromise() .then(response => response['items'] as Resource[]) .catch((err: HttpErrorResponse) => { console.debug('ResourceService --> getProviderConfigResources() --> error: HTTP ' + err.status + ' ' + err.message); if (err.status === 401) { window.location.assign(document.location.pathname); } else { return this.handleError(err); } }); } getDescriptorResources(): Promise<Resource[]> { let headers = this.addJsonHeaders(new HttpHeaders()); return this.http.get(this.descriptorsUrl, {headers: headers}) .toPromise() .then(response => response['items'] as Resource[]) .catch((err: HttpErrorResponse) => { console.debug('ResourceService --> getDescriptorResources() --> error: HTTP ' + err.status + ' ' + err.message); if (err.status === 401) { window.location.assign(document.location.pathname); } else { return this.handleError(err); } }); } getTopologyResources(): Promise<Resource[]> { let headers = this.addJsonHeaders(new HttpHeaders()); return this.http.get(this.topologiesUrl, {headers: headers}) .toPromise() .then(response => response['topologies'].topology as Resource[]) .catch((err: HttpErrorResponse) => { console.debug('ResourceService --> getTopologyResources() --> error: HTTP ' + err.status + ' ' + err.message); if (err.status === 401) { window.location.assign(document.location.pathname); } else { return this.handleError(err); } }); } getServiceDefinitionResources(): Promise<Resource[]> { let headers = this.addJsonHeaders(new HttpHeaders()); return this.http.get(this.serviceDefinitionsUrl + '?serviceOnly=true', {headers: headers}) .toPromise() .then(response => response['serviceDefinitions'].serviceDefinition as Resource[]) .catch((err: HttpErrorResponse) => { console.debug('ResourceService --> getServiceDefinitionResources() --> error: HTTP ' + err.status + ' ' + err.message); if (err.status === 401) { window.location.assign(document.location.pathname); } else { return this.handleError(err); } }); } getResource(resType: string, res: Resource): Promise<string> { if (res) { let href = res.href; if (resType === 'Service Definitions') { href = this.serviceDefinitionsUrl + '/' + res.service['name'] + '/' + res.service['role'] + '/' + res.service['version'] + '?serviceOnly=true'; } let headers = new HttpHeaders(); headers = (resType === 'Topologies' || resType === 'Service Definitions') ? this.addXmlHeaders(headers) : this.addHeaders(headers, res.name); return this.http.get(href, {headers: headers, responseType: 'text'}) .toPromise() .then(response => { console.debug('ResourceService --> Loading resource ' + res.name + ' :\n' + response); return response; }) .catch((err: HttpErrorResponse) => { console.debug('ResourceService --> getResource() ' + res.name + '\n error: ' + err.status + ' ' + err.message); if (err.status === 401) { window.location.assign(document.location.pathname); } else { return this.handleError(err); } }); } else { return Promise.resolve(null); } } saveResource(resource: Resource, content: string): Promise<string> { let headers = this.addHeaders(new HttpHeaders(), resource.name); console.debug('ResourceService --> Persisting ' + resource.name + '\n' + content); return this.http.put(resource.href, content, {headers: headers}) .toPromise() .then(() => content) .catch((err: HttpErrorResponse) => { console.debug('ResourceService --> saveResource() ' + resource.name + '\n error: ' + err.message); if (err.status === 401) { window.location.assign(document.location.pathname); } else { return this.handleError(err); } }); } createResource(resType: string, resource: Resource, content: string): Promise<string> { let headers = this.addHeaders(new HttpHeaders(), resource.name); let url = ((resType === 'Descriptors') ? this.descriptorsUrl : this.providersUrl) + '/' + resource.name; return this.http.put(url, content, {headers: headers}) .toPromise() .then(() => content) .catch((err: HttpErrorResponse) => { console.debug('ResourceService --> createResource() --> ' + resource.name + '\n error: ' + err.message); if (err.status === 401) { window.location.assign(document.location.pathname); } else { return this.handleError(err); } }); } deleteResource(href: string): Promise<string> { let headers = this.addJsonHeaders(new HttpHeaders()); return this.http.delete(href, {headers: headers}) .toPromise() .then(response => response) .catch((err: HttpErrorResponse) => { console.debug('ResourceService --> deleteResource() --> ' + href + '\n error: ' + err.message); if (err.status === 401) { window.location.assign(document.location.pathname); } else { return this.handleError(err); } }); } serializeDescriptor(desc: Descriptor, format: string): string { let serialized: string; let tmp = {}; if (desc.discoveryType) { tmp['discovery-type'] = desc.discoveryType; } if (desc.discoveryAddress) { tmp['discovery-address'] = desc.discoveryAddress; } if (desc.discoveryUser) { tmp['discovery-user'] = desc.discoveryUser; } if (desc.discoveryPassAlias) { tmp['discovery-pwd-alias'] = desc.discoveryPassAlias; } if (desc.discoveryCluster) { tmp['cluster'] = desc.discoveryCluster; } if (desc.readOnly) { tmp['read-only'] = desc.readOnly; } tmp['provider-config-ref'] = desc.providerConfig; tmp['services'] = desc.services; switch (format) { case 'json': { serialized = JSON.stringify(tmp, (key, value) => { let result = value; switch (typeof value) { case 'string': // Don't serialize empty string value properties result = (value.length > 0) ? value : undefined; break; case 'object': if (Array.isArray(value)) { // Don't serialize empty array value properties result = (value.length) > 0 ? value : undefined; } else { // Don't serialize object value properties result = (Object.getOwnPropertyNames(value).length > 0) ? value : undefined; } break; } return result; }, 2); break; } case 'yaml': { let yaml = require('js-yaml'); serialized = '---\n' + yaml.safeDump(tmp); break; } } return serialized; } serializeProviderConfiguration(providers: Array<ProviderConfig>, format: string): string { let serialized: string; let tmp = {}; tmp['providers'] = providers; switch (format) { case 'json': { serialized = JSON.stringify(tmp, null, 2); break; } case 'yaml': { let yaml = require('js-yaml'); serialized = '---\n' + yaml.dump(tmp); break; } } return serialized; } addHeaders(headers: HttpHeaders, resName: string): HttpHeaders { let ext = resName.split('.').pop(); switch (ext) { case 'xml': { headers = this.addXmlHeaders(headers); break; } case 'json': { headers = this.addJsonHeaders(headers); break; } case 'yaml': case 'yml': { headers = this.addTextPlainHeaders(headers); break; } } return headers; } addTextPlainHeaders(headers: HttpHeaders) { return this.addCsrfHeaders(headers.append('Accept', 'text/plain') .append('Content-Type', 'text/plain')); } addJsonHeaders(headers: HttpHeaders): HttpHeaders { return this.addCsrfHeaders(headers.append('Accept', 'application/json') .append('Content-Type', 'application/json')); } addXmlHeaders(headers: HttpHeaders): HttpHeaders { return this.addCsrfHeaders(headers.append('Accept', 'application/xml') .append('Content-Type', 'application/xml')); } addCsrfHeaders(headers: HttpHeaders): HttpHeaders { return this.addXHRHeaders(headers.append('X-XSRF-Header', 'admin-ui')); } addXHRHeaders(headers: HttpHeaders): HttpHeaders { return headers.append('X-Requested-With', 'XMLHttpRequest'); } selectedResourceType(value: string) { this.selectedResourceTypeSource.next(value); } selectedResource(value: Resource) { this.selectedResourceSource.next(value); } resourceChanged(value: string) { this.changedResourceSource.next(value); } providerConfigurationChanged(pc: Array<ProviderConfig>) { this.changedProviderConfigurationSource.next(pc); } public getResourceDisplayName(res: Resource): string { if (res) { if (res.service) { return res.service['role'] + ' (' + res.service['version'] + ')'; } else if (res.name) { let index = res.name.lastIndexOf('.'); return index > 0 ? res.name.substring(0, index) : res.name; } } return null; } private handleError(error: any): Promise<any> { return Promise.reject(error); } private logHeaders(headers: HttpHeaders) { let debugMsg = 'ResourceService --> Request headers:\n'; headers.keys().forEach(key => { debugMsg += ' ' + key + '=' + headers.get(key) + '\n'; }); console.debug(debugMsg); } }