blob: 92707d07de39fc67a8e7f9fbd301691bcd34d13b [file] [log] [blame]
/**
* 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 {URLSearchParams, Response, ResponseOptions} from '@angular/http';
import {InMemoryDbService, InMemoryBackendService, createErrorResponse} from 'angular-in-memory-web-api';
import {Observable} from 'rxjs/Observable';
import {Subscriber} from 'rxjs/Subscriber';
import 'rxjs/add/operator/delay';
import * as moment from 'moment';
import {mockDataGet} from '@mockdata/mock-data-get';
import {mockDataPost} from '@mockdata/mock-data-post';
export class MockBackendService extends InMemoryBackendService {
getLocation(url: string): any {
return super.getLocation(url);
}
}
export class MockApiDataService implements InMemoryDbService {
private filterByMessage = (value: string, filterValue: string): boolean => {
return value.toLowerCase().indexOf(filterValue.toLowerCase()) > -1;
}
private filterByStartTime = (value: number, filterValue: number | string | Date | moment.Moment): boolean => {
return value >= moment(filterValue).valueOf();
}
private filterByEndTime = (value: number, filterValue: number | string | Date | moment.Moment): boolean => {
return value <= moment(filterValue).valueOf();
}
private readonly filterMap = {
'api/v1/service/logs': {
pathToCollection: 'logList',
totalCountKey: 'totalCount',
filters: {
clusters: {
key: 'cluster',
isValuesList: true
},
mustBe: {
key: 'type',
isValuesList: true
},
level: {
key: 'level',
isValuesList: true
},
includeMessage: {
key: 'log_message',
filterFunction: this.filterByMessage
},
from: {
key: 'logtime',
filterFunction: this.filterByStartTime
},
to: {
key: 'logtime',
filterFunction: this.filterByEndTime
},
hostList: {
key: 'host',
isValuesList: true
}
}
},
'api/v1/audit/logs': {
pathToCollection: 'logList',
totalCountKey: 'totalCount',
filters: {
clusters: {
key: 'cluster',
isValuesList: true
},
includeMessage: {
key: 'log_message',
filterFunction: this.filterByMessage
},
from: {
key: 'evtTime',
filterFunction: this.filterByStartTime
},
to: {
key: 'evtTime',
filterFunction: this.filterByEndTime
},
userList: {
key: 'reqUser',
isValuesList: true
}
}
}
};
parseUrl(url: string): any {
const urlLocation = MockBackendService.prototype.getLocation(url),
query = urlLocation.search && new URLSearchParams(urlLocation.search.substr(1), {
encodeKey: key => key,
encodeValue: value => value
}),
splitUrl = urlLocation.pathname.substr(1).split('/'),
urlPartsCount = splitUrl.length,
collectionName = splitUrl[urlPartsCount - 1],
base = splitUrl.slice(0, urlPartsCount - 1).join('/') + '/';
return {
base: base,
collectionName: collectionName,
query: query
};
}
private findDataByUrlPatter(path: string, mockDataObj: {[key: string]: any}): {[key: string]: any} | undefined | Function {
const paths: string[] = Object.keys(mockDataObj);
const matchedPath: string = paths.find((key: string): boolean => {
const test: RegExp = new RegExp(key);
return test.test(path);
});
return mockDataObj[matchedPath];
}
/**
* The goal here is to check if the given real api url should be always POST or not.\
* See https://issues.apache.org/jira/browse/AMBARI-23779
* @param {string} url The full url for the api end point.
* @returns {boolean}
*/
private shouldTurnGetToPost(url: string): boolean {
return /(audit|service)/.test(url);
}
get(interceptorArgs: any): Observable<Response> {
const query = interceptorArgs.requestInfo.query;
const path = interceptorArgs.requestInfo.base + interceptorArgs.requestInfo.collectionName;
if (query && query.paramsMap.has('static') && interceptorArgs.passThruBackend) {
return interceptorArgs.passThruBackend.createConnection(interceptorArgs.requestInfo.req).response;
} else {
let allData = mockDataGet[path];
if (!allData) {
allData = this.findDataByUrlPatter(path, mockDataGet);
}
if (typeof allData === 'function') {
try {
allData = allData(query, interceptorArgs.requestInfo.req);
} catch (error) {
return new Observable<Response>((subscriber: Subscriber<Response>) => subscriber.error(
new Response(createErrorResponse(
interceptorArgs.requestInfo.req, 500, error
)))
);
}
}
const is404 = !allData;
if (is404) {
return new Observable<Response>((subscriber: Subscriber<Response>) => subscriber.error(
new Response(createErrorResponse(
interceptorArgs.requestInfo.req, 404, 'Not found'
)))
);
} else {
let filteredData;
const filterMapItem = this.filterMap[path];
if (query && filterMapItem) {
filteredData = {};
const pathToCollection = filterMapItem.pathToCollection,
collection = allData[pathToCollection];
let filteredCollection = collection.filter(item => {
let result = true;
query.paramsMap.forEach((value, key) => {
const paramValue = decodeURIComponent(value[0]),
paramFilter = filterMapItem.filters[key],
paramValuesList = paramFilter && paramFilter.isValuesList && paramValue ? paramValue.split(',') : [],
currentValue = paramFilter && item[paramFilter.key];
if (
paramFilter && ((paramFilter.filterFunction && !paramFilter.filterFunction(currentValue, paramValue)) ||
(!paramFilter.filterFunction && !paramFilter.isValuesList && currentValue !== paramValue) ||
(!paramFilter.filterFunction && paramFilter.isValuesList && paramValuesList.indexOf(currentValue) === -1))
) {
result = false;
}
});
return result;
});
if (query.paramsMap.has('sortBy') && query.paramsMap.has('sortType')) {
const sortKey = query.paramsMap.get('sortBy')[0],
sortType = query.paramsMap.get('sortType')[0];
filteredCollection.sort((a, b) => {
const itemA = a[sortKey],
itemB = b[sortKey];
let ascResult;
if (itemA > itemB) {
ascResult = 1;
} else if (itemA < itemB) {
ascResult = -1;
} else {
ascResult = 0;
}
return ascResult * Math.pow(-1, Number(sortType === 'desc'));
});
}
if (filterMapItem.totalCountKey) {
filteredData[filterMapItem.totalCountKey] = filteredCollection.length;
}
if (query && query.paramsMap.has('page') && query.paramsMap.has('pageSize')) {
const page = parseInt(query.paramsMap.get('page')[0], 0),
pageSize = parseInt(query.paramsMap.get('pageSize')[0], 0);
filteredCollection = filteredCollection.slice(page * pageSize, (page + 1) * pageSize);
}
filteredData[pathToCollection] = filteredCollection;
} else {
filteredData = allData;
}
return new Observable<Response>((subscriber: Subscriber<Response>) => subscriber.next(
new Response(new ResponseOptions({
status: 200,
body: filteredData
})))
);
}
}
}
post(interceptorArgs: any): Observable<Response> {
const query = interceptorArgs.requestInfo.query;
const path = interceptorArgs.requestInfo.base + interceptorArgs.requestInfo.collectionName;
if (query && query.paramsMap.has('static') && interceptorArgs.passThruBackend) {
return interceptorArgs.passThruBackend.createConnection(interceptorArgs.requestInfo.req).response;
}
let responseBody = mockDataPost[path];
if (!responseBody) {
responseBody = this.findDataByUrlPatter(path, mockDataPost);
}
if (typeof responseBody === 'function') {
try {
responseBody = responseBody(query, interceptorArgs.requestInfo.req);
} catch (error) {
return new Observable<Response>((subscriber: Subscriber<Response>) => subscriber.error(
new Response(createErrorResponse(
interceptorArgs.requestInfo.req, 500, error
)))
);
}
}
const is404 = !responseBody;
if (is404) {
return new Observable<Response>((subscriber: Subscriber<Response>) => subscriber.error(
new Response(createErrorResponse(
interceptorArgs.requestInfo.req, 404, 'Not found'
)))
);
} else {
return new Observable<Response>((subscriber: Subscriber<Response>) => subscriber.next(
new Response(new ResponseOptions({
status: 200,
body: responseBody
})))
);
}
}
put(interceptorArgs: any): Observable<Response> {
return this.post(interceptorArgs);
}
createDb() {
return {};
}
}