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);
}
}