Repository: ambari Updated Branches: refs/heads/trunk b4eddc977 -> 15cec1cb7
http://git-wip-us.apache.org/repos/asf/ambari/blob/15cec1cb/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.ts index fc0f6ae..af4933a 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.ts +++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/time-range-picker/time-range-picker.component.ts @@ -20,6 +20,8 @@ import {Component, OnInit, Input, forwardRef} from '@angular/core'; import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms'; import {Moment} from 'moment'; import {FilteringService} from '@app/services/filtering.service'; +import {ListItem} from '@app/classes/list-item'; +import {TimeUnitListItem} from '@app/classes/filtering'; @Component({ selector: 'time-range-picker', @@ -53,7 +55,7 @@ export class TimeRangePickerComponent implements OnInit, ControlValueAccessor { private onChange: (fn: any) => void; - get quickRanges(): any[][] { + get quickRanges(): (ListItem | TimeUnitListItem[])[] { return this.filtering.filters.timeRange.options; } http://git-wip-us.apache.org/repos/asf/ambari/blob/15cec1cb/ambari-logsearch/ambari-logsearch-web/src/app/components/timezone-picker/timezone-picker.component.spec.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/timezone-picker/timezone-picker.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/timezone-picker/timezone-picker.component.spec.ts index 7105624..53afc47 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/components/timezone-picker/timezone-picker.component.spec.ts +++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/timezone-picker/timezone-picker.component.spec.ts @@ -30,6 +30,7 @@ import {ServiceLogsService, serviceLogs} from '@app/services/storage/service-log import {ServiceLogsFieldsService, serviceLogsFields} from '@app/services/storage/service-logs-fields.service'; import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/services/storage/service-logs-histogram-data.service'; import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service'; +import {TabsService, tabs} from '@app/services/storage/tabs.service'; import {ComponentActionsService} from '@app/services/component-actions.service'; import {FilteringService} from '@app/services/filtering.service'; import {HttpClientService} from '@app/services/http-client.service'; @@ -44,6 +45,14 @@ describe('TimeZonePickerComponent', () => { let fixture: ComponentFixture<TimeZonePickerComponent>; beforeEach(async(() => { + const httpClient = { + get: () => { + return { + subscribe: () => { + } + } + } + }; TestBed.configureTestingModule({ declarations: [ TimeZonePickerComponent, @@ -62,7 +71,8 @@ describe('TimeZonePickerComponent', () => { serviceLogs, serviceLogsFields, serviceLogsHistogramData, - serviceLogsTruncated + serviceLogsTruncated, + tabs }), ...TranslationModules ], @@ -78,9 +88,13 @@ describe('TimeZonePickerComponent', () => { ServiceLogsFieldsService, ServiceLogsHistogramDataService, ServiceLogsTruncatedService, + TabsService, ComponentActionsService, FilteringService, - HttpClientService, + { + provide: HttpClientService, + useValue: httpClient + }, LogsContainerService ], }) http://git-wip-us.apache.org/repos/asf/ambari/blob/15cec1cb/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.spec.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.spec.ts index 3dbd992..e6a02c0 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.spec.ts +++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.spec.ts @@ -29,6 +29,7 @@ import {AuditLogsFieldsService, auditLogsFields} from '@app/services/storage/aud import {ServiceLogsFieldsService, serviceLogsFields} from '@app/services/storage/service-logs-fields.service'; import {ServiceLogsHistogramDataService, serviceLogsHistogramData} from '@app/services/storage/service-logs-histogram-data.service'; import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service'; +import {TabsService, tabs} from '@app/services/storage/tabs.service'; import {FilteringService} from '@app/services/filtering.service'; import {HttpClientService} from '@app/services/http-client.service'; import {LogsContainerService} from '@app/services/logs-container.service'; @@ -59,7 +60,8 @@ describe('ComponentActionsService', () => { auditLogsFields, serviceLogsFields, serviceLogsHistogramData, - serviceLogsTruncated + serviceLogsTruncated, + tabs }) ], providers: [ @@ -75,6 +77,7 @@ describe('ComponentActionsService', () => { ServiceLogsFieldsService, ServiceLogsHistogramDataService, ServiceLogsTruncatedService, + TabsService, FilteringService, { provide: HttpClientService, http://git-wip-us.apache.org/repos/asf/ambari/blob/15cec1cb/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.ts index 19b873c..c483cd8 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.ts +++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/component-actions.service.ts @@ -18,16 +18,17 @@ import {Injectable} from '@angular/core'; import {AppSettingsService} from '@app/services/storage/app-settings.service'; -import {AppStateService} from '@app/services/storage/app-state.service'; +import {TabsService} from '@app/services/storage/tabs.service'; import {CollectionModelService} from '@app/classes/models/store'; import {FilteringService} from '@app/services/filtering.service'; import {LogsContainerService} from '@app/services/logs-container.service'; import {ServiceLog} from '@app/classes/models/service-log'; +import {getFiltersForm} from '@app/classes/filtering'; @Injectable() export class ComponentActionsService { - constructor(private appSettings: AppSettingsService, private appState: AppStateService, private filtering: FilteringService, private logsContainer: LogsContainerService) { + constructor(private appSettings: AppSettingsService, private tabsStorage: TabsService, private filtering: FilteringService, private logsContainer: LogsContainerService) { } //TODO implement actions @@ -39,8 +40,7 @@ export class ComponentActionsService { } refresh(): void { - // TODO implement dynamic definition of logs type - this.logsContainer.loadLogs('serviceLogs'); + this.logsContainer.loadLogs(); } openHistory() { @@ -78,14 +78,25 @@ export class ComponentActionsService { } openLog(log: ServiceLog): void { - this.appState.setParameters({ - isServiceLogsFileView: true, - activeLog: { - id: log.id, - host_name: log.host, - component_name: log.type + const tab = { + id: log.id, + type: 'serviceLogs', + isActive: true, + isCloseable: true, + label: `${log.host} >> ${log.type}`, + appState: { + activeLogsType: 'serviceLogs', + isServiceLogsFileView: true, + activeLog: { + id: log.id, + host_name: log.host, + component_name: log.type + }, + activeFiltersForm: getFiltersForm('serviceLogs') } - }); + }; + this.tabsStorage.addInstance(tab); + this.logsContainer.switchTab(tab); } openContext(log: ServiceLog): void { http://git-wip-us.apache.org/repos/asf/ambari/blob/15cec1cb/ambari-logsearch/ambari-logsearch-web/src/app/services/component-generator.service.spec.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/component-generator.service.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/component-generator.service.spec.ts index f043f42..5dc38b4 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/services/component-generator.service.spec.ts +++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/component-generator.service.spec.ts @@ -29,6 +29,7 @@ import {AppStateService, appState} from '@app/services/storage/app-state.service import {ClustersService, clusters} from '@app/services/storage/clusters.service'; import {ComponentsService, components} from '@app/services/storage/components.service'; import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service'; +import {TabsService, tabs} from '@app/services/storage/tabs.service'; import {LogsContainerService} from '@app/services/logs-container.service'; import {HttpClientService} from '@app/services/http-client.service'; import {FilteringService} from '@app/services/filtering.service'; @@ -58,7 +59,8 @@ describe('ComponentGeneratorService', () => { appState, clusters, components, - serviceLogsTruncated + serviceLogsTruncated, + tabs }) ], providers: [ @@ -79,7 +81,8 @@ describe('ComponentGeneratorService', () => { AppStateService, ClustersService, ComponentsService, - ServiceLogsTruncatedService + ServiceLogsTruncatedService, + TabsService ] }); }); http://git-wip-us.apache.org/repos/asf/ambari/blob/15cec1cb/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.spec.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.spec.ts index 5d79902..2b3e326 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.spec.ts +++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.spec.ts @@ -19,6 +19,7 @@ import {TestBed, inject} from '@angular/core/testing'; import {StoreModule} from '@ngrx/store'; import {AppSettingsService, appSettings} from '@app/services/storage/app-settings.service'; +import {AppStateService, appState} from '@app/services/storage/app-state.service'; import {ClustersService, clusters} from '@app/services/storage/clusters.service'; import {ComponentsService, components} from '@app/services/storage/components.service'; import {HostsService, hosts} from '@app/services/storage/hosts.service'; @@ -43,6 +44,7 @@ describe('FilteringService', () => { imports: [ StoreModule.provideStore({ appSettings, + appState, clusters, components, hosts @@ -51,6 +53,7 @@ describe('FilteringService', () => { providers: [ FilteringService, AppSettingsService, + AppStateService, ClustersService, ComponentsService, HostsService, http://git-wip-us.apache.org/repos/asf/ambari/blob/15cec1cb/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.ts index c3177cc..85dc408 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.ts +++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/filtering.service.ts @@ -17,7 +17,7 @@ */ import {Injectable, Input} from '@angular/core'; -import {FormControl, FormGroup} from '@angular/forms'; +import {FormGroup} from '@angular/forms'; import {Response} from '@angular/http'; import {Subject} from 'rxjs/Subject'; import {Observable} from 'rxjs/Observable'; @@ -25,17 +25,22 @@ import 'rxjs/add/observable/timer'; import 'rxjs/add/operator/takeUntil'; import * as moment from 'moment-timezone'; import {ListItem} from '@app/classes/list-item'; +import {FilterCondition, filters} from '@app/classes/filtering'; import {Node} from '@app/classes/models/node'; import {AppSettingsService} from '@app/services/storage/app-settings.service'; import {ClustersService} from '@app/services/storage/clusters.service'; import {ComponentsService} from '@app/services/storage/components.service'; import {HostsService} from '@app/services/storage/hosts.service'; +import {AppStateService} from '@app/services/storage/app-state.service'; import {HttpClientService} from '@app/services/http-client.service'; @Injectable() export class FilteringService { - constructor(private httpClient: HttpClientService, private appSettings: AppSettingsService, private clustersStorage: ClustersService, private componentsStorage: ComponentsService, private hostsStorage: HostsService) { + constructor(private httpClient: HttpClientService, private appSettings: AppSettingsService, private clustersStorage: ClustersService, private componentsStorage: ComponentsService, private hostsStorage: HostsService, private appState: AppStateService) { + this.loadClusters(); + this.loadComponents(); + this.loadHosts(); appSettings.getParameter('timeZone').subscribe(value => this.timeZone = value || this.defaultTimeZone); clustersStorage.getAll().subscribe((clusters: string[]): void => { this.filters.clusters.options = [...this.filters.clusters.options, ...clusters.map(this.getListItemFromString)]; @@ -46,6 +51,7 @@ export class FilteringService { hostsStorage.getAll().subscribe((hosts: Node[]): void => { this.filters.hosts.options = [...this.filters.hosts.options, ...hosts.map(this.getListItemFromNode)]; }); + appState.getParameter('activeFiltersForm').subscribe((form: FormGroup) => this.activeFiltersForm = form); } /** @@ -62,7 +68,7 @@ export class FilteringService { /** * Get instance for dropdown list from Node object - * @param name {Node} + * @param node {Node} * @returns {ListItem} */ private getListItemFromNode(node: Node): ListItem { @@ -74,8 +80,6 @@ export class FilteringService { private readonly defaultTimeZone = moment.tz.guess(); - private readonly paginationOptions = ['10', '25', '50', '100']; - timeZone: string = this.defaultTimeZone; /** @@ -86,326 +90,9 @@ export class FilteringService { @Input() maximumCaptureTimeLimit: number = 600000; - filters = { - clusters: { - label: 'filter.clusters', - options: [], - defaultValue: '' - }, - timeRange: { - options: [ - [ - { - label: 'filter.timeRange.7d', - value: { - type: 'LAST', - unit: 'd', - interval: 7 - } - }, - { - label: 'filter.timeRange.30d', - value: { - type: 'LAST', - unit: 'd', - interval: 30 - } - }, - { - label: 'filter.timeRange.60d', - value: { - type: 'LAST', - unit: 'd', - interval: 60 - } - }, - { - label: 'filter.timeRange.90d', - value: { - type: 'LAST', - unit: 'd', - interval: 90 - } - }, - { - label: 'filter.timeRange.6m', - value: { - type: 'LAST', - unit: 'M', - interval: 6 - } - }, - { - label: 'filter.timeRange.1y', - value: { - type: 'LAST', - unit: 'Y', - interval: 1 - } - }, - { - label: 'filter.timeRange.2y', - value: { - type: 'LAST', - unit: 'Y', - interval: 2 - } - }, - { - label: 'filter.timeRange.5y', - value: { - type: 'LAST', - unit: 'Y', - interval: 5 - } - } - ], - [ - { - label: 'filter.timeRange.yesterday', - value: { - type: 'PAST', - unit: 'd' - } - }, - // TODO implement time range calculation - /* - { - label: 'filter.timeRange.beforeYesterday', - value: { - type: 'PAST', - unit: 'd' - } - }, - { - label: 'filter.timeRange.thisDayLastWeek', - value: { - type: 'PAST', - unit: 'd' - } - }, - */ - { - label: 'filter.timeRange.previousWeek', - value: { - type: 'PAST', - unit: 'w' - } - }, - { - label: 'filter.timeRange.previousMonth', - value: { - type: 'PAST', - unit: 'M' - } - }, - { - label: 'filter.timeRange.previousYear', - value: { - type: 'PAST', - unit: 'Y' - } - } - ], - [ - { - label: 'filter.timeRange.today', - value: { - type: 'CURRENT', - unit: 'd' - } - }, - { - label: 'filter.timeRange.thisWeek', - value: { - type: 'CURRENT', - unit: 'w' - } - }, - { - label: 'filter.timeRange.thisMonth', - value: { - type: 'CURRENT', - unit: 'M' - } - }, - { - label: 'filter.timeRange.thisYear', - value: { - type: 'CURRENT', - unit: 'Y' - } - } - ], - [ - { - label: 'filter.timeRange.5min', - value: { - type: 'LAST', - unit: 'm', - interval: 5 - } - }, - { - label: 'filter.timeRange.15min', - value: { - type: 'LAST', - unit: 'm', - interval: 15 - } - }, - { - label: 'filter.timeRange.30min', - value: { - type: 'LAST', - unit: 'm', - interval: 30 - } - }, - { - label: 'filter.timeRange.1hr', - value: { - type: 'LAST', - unit: 'h', - interval: 1 - } - }, - { - label: 'filter.timeRange.3hr', - value: { - type: 'LAST', - unit: 'h', - interval: 3 - } - }, - { - label: 'filter.timeRange.6hr', - value: { - type: 'LAST', - unit: 'h', - interval: 6 - } - }, - { - label: 'filter.timeRange.12hr', - value: { - type: 'LAST', - unit: 'h', - interval: 12 - } - }, - { - label: 'filter.timeRange.24hr', - value: { - type: 'LAST', - unit: 'h', - interval: 24 - } - }, - ] - ], - defaultValue: { - type: 'LAST', - unit: 'h', - interval: 1 - }, - defaultLabel: 'filter.timeRange.1hr' - }, - components: { - label: 'filter.components', - iconClass: 'fa fa-cubes', - options: [], - defaultValue: '' - }, - levels: { - label: 'filter.levels', - iconClass: 'fa fa-sort-amount-asc', - options: [ - { - label: 'levels.fatal', - value: 'FATAL' - }, - { - label: 'levels.error', - value: 'ERROR' - }, - { - label: 'levels.warn', - value: 'WARN' - }, - { - label: 'levels.info', - value: 'INFO' - }, - { - label: 'levels.debug', - value: 'DEBUG' - }, - { - label: 'levels.trace', - value: 'TRACE' - }, - { - label: 'levels.unknown', - value: 'UNKNOWN' - } - ], - defaultValue: '' - }, - hosts: { - label: 'filter.hosts', - iconClass: 'fa fa-server', - options: [], - defaultValue: '' - }, - sorting: { - label: 'sorting.title', - options: [ - { - label: 'sorting.time.asc', - value: { - key: 'logtime', - type: 'asc' - } - }, - { - label: 'sorting.time.desc', - value: { - key: 'logtime', - type: 'desc' - } - } - ], - defaultValue: '', - defaultLabel: '' - }, - pageSize: { - label: 'pagination.title', - options: this.paginationOptions.map(option => { - return { - label: option, - value: option - } - }), - defaultValue: '10', - defaultLabel: '10' - }, - page: { - defaultValue: 0 - }, - query: {} - }; - - private filtersFormItems = Object.keys(this.filters).reduce((currentObject, key) => { - let formControl = new FormControl(), - item = { - [key]: formControl - }; - formControl.setValue(this.filters[key].defaultValue); - return Object.assign(currentObject, item); - }, {}); + filters: {[key: string]: FilterCondition} = Object.assign({}, filters); - filtersForm = new FormGroup(this.filtersFormItems); + activeFiltersForm: FormGroup; queryParameterNameChange: Subject<any> = new Subject(); @@ -428,7 +115,7 @@ export class FilteringService { startCaptureTimer(): void { this.startCaptureTime = new Date().valueOf(); const maxCaptureTimeInSeconds = this.maximumCaptureTimeLimit / 1000; - Observable.timer(0, 1000).takeUntil(this.stopTimer).subscribe(seconds => { + Observable.timer(0, 1000).takeUntil(this.stopTimer).subscribe((seconds: number): void => { this.captureSeconds = seconds; if (this.captureSeconds >= maxCaptureTimeInSeconds) { this.stopCaptureTimer(); @@ -442,7 +129,7 @@ export class FilteringService { this.captureSeconds = 0; this.stopTimer.next(); this.setCustomTimeRange(this.startCaptureTime, this.stopCaptureTime); - Observable.timer(0, 1000).takeUntil(this.stopAutoRefreshCountdown).subscribe(seconds => { + Observable.timer(0, 1000).takeUntil(this.stopAutoRefreshCountdown).subscribe((seconds: number): void => { this.autoRefreshRemainingSeconds = autoRefreshIntervalSeconds - seconds; if (!this.autoRefreshRemainingSeconds) { this.stopAutoRefreshCountdown.next(); @@ -485,7 +172,7 @@ export class FilteringService { } setCustomTimeRange(startTime: number, endTime: number): void { - this.filtersForm.controls.timeRange.setValue({ + this.activeFiltersForm.controls.timeRange.setValue({ type: 'CUSTOM', start: moment(startTime), end: moment(endTime) http://git-wip-us.apache.org/repos/asf/ambari/blob/15cec1cb/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.spec.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.spec.ts index a762fef..ee0e1e7 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.spec.ts +++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.spec.ts @@ -29,6 +29,7 @@ import {ClustersService, clusters} from '@app/services/storage/clusters.service' import {ComponentsService, components} from '@app/services/storage/components.service'; import {HostsService, hosts} from '@app/services/storage/hosts.service'; import {ServiceLogsTruncatedService, serviceLogsTruncated} from '@app/services/storage/service-logs-truncated.service'; +import {TabsService, tabs} from '@app/services/storage/tabs.service'; import {HttpClientService} from '@app/services/http-client.service'; import {FilteringService} from '@app/services/filtering.service'; @@ -57,7 +58,8 @@ describe('LogsContainerService', () => { clusters, components, hosts, - serviceLogsTruncated + serviceLogsTruncated, + tabs }) ], providers: [ @@ -72,6 +74,7 @@ describe('LogsContainerService', () => { ComponentsService, HostsService, ServiceLogsTruncatedService, + TabsService, LogsContainerService, { provide: HttpClientService, http://git-wip-us.apache.org/repos/asf/ambari/blob/15cec1cb/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.ts index 0319262..e187b00 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.ts +++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/logs-container.service.ts @@ -17,6 +17,7 @@ */ import {Injectable} from '@angular/core'; +import {Response} from '@angular/http'; import {HttpClientService} from '@app/services/http-client.service'; import {FilteringService} from '@app/services/filtering.service'; import {AuditLogsService} from '@app/services/storage/audit-logs.service'; @@ -26,22 +27,28 @@ import {ServiceLogsFieldsService} from '@app/services/storage/service-logs-field import {ServiceLogsHistogramDataService} from '@app/services/storage/service-logs-histogram-data.service'; import {ServiceLogsTruncatedService} from '@app/services/storage/service-logs-truncated.service'; import {AppStateService} from '@app/services/storage/app-state.service'; +import {TabsService} from '@app/services/storage/tabs.service'; import {ActiveServiceLogEntry} from '@app/classes/active-service-log-entry'; +import {Tab} from '@app/classes/models/tab'; +import {AuditLogField} from '@app/classes/models/audit-log-field'; +import {ServiceLogField} from '@app/classes/models/service-log-field'; +import {BarGraph} from '@app/classes/models/bar-graph'; @Injectable() export class LogsContainerService { - constructor(private httpClient: HttpClientService, private auditLogsStorage: AuditLogsService, private auditLogsFieldsStorage: AuditLogsFieldsService, private serviceLogsStorage: ServiceLogsService, private serviceLogsFieldsStorage: ServiceLogsFieldsService, private serviceLogsHistogramStorage: ServiceLogsHistogramDataService, private serviceLogsTruncatedStorage: ServiceLogsTruncatedService, private appState: AppStateService, private filtering: FilteringService) { + constructor(private httpClient: HttpClientService, private auditLogsStorage: AuditLogsService, private auditLogsFieldsStorage: AuditLogsFieldsService, private serviceLogsStorage: ServiceLogsService, private serviceLogsFieldsStorage: ServiceLogsFieldsService, private serviceLogsHistogramStorage: ServiceLogsHistogramDataService, private serviceLogsTruncatedStorage: ServiceLogsTruncatedService, private appState: AppStateService, private tabsStorage: TabsService, private filtering: FilteringService) { appState.getParameter('activeLog').subscribe((value: ActiveServiceLogEntry | null) => this.activeLog = value); appState.getParameter('isServiceLogsFileView').subscribe((value: boolean): void => { const activeLog = this.activeLog, - filtersForm = this.filtering.filtersForm; + filtersForm = this.filtering.activeFiltersForm; if (value && activeLog) { filtersForm.controls.hosts.setValue(activeLog.host_name); filtersForm.controls.components.setValue(activeLog.component_name); } this.isServiceLogsFileView = value; }); + appState.getParameter('activeLogsType').subscribe((value: string) => this.activeLogsType = value); } readonly colors = { @@ -78,13 +85,11 @@ export class LogsContainerService { readonly logsTypeMap = { auditLogs: { logsModel: this.auditLogsStorage, - fieldsModel: this.auditLogsFieldsStorage, - isSetFlag: 'isAuditLogsSet' + fieldsModel: this.auditLogsFieldsStorage }, serviceLogs: { logsModel: this.serviceLogsStorage, - fieldsModel: this.serviceLogsFieldsStorage, - isSetFlag: 'isServiceLogsSet' + fieldsModel: this.serviceLogsFieldsStorage } }; @@ -94,8 +99,10 @@ export class LogsContainerService { activeLog: ActiveServiceLogEntry | null = null; - loadLogs(logsType: string): void { - this.httpClient.get(logsType, this.getParams('listFilters')).subscribe(response => { + activeLogsType: string; + + loadLogs = (logsType: string = this.activeLogsType): void => { + this.httpClient.get(logsType, this.getParams('listFilters')).subscribe((response: Response): void => { const jsonResponse = response.json(), model = this.logsTypeMap[logsType].logsModel; model.clear(); @@ -110,7 +117,7 @@ export class LogsContainerService { }); if (logsType === 'serviceLogs') { // TODO rewrite to implement conditional data loading for service logs histogram or audit logs graph - this.httpClient.get('serviceLogsHistogram', this.getParams('histogramFilters')).subscribe(response => { + this.httpClient.get('serviceLogsHistogram', this.getParams('histogramFilters')).subscribe((response: Response): void => { const jsonResponse = response.json(); this.serviceLogsHistogramStorage.clear(); if (jsonResponse) { @@ -130,7 +137,7 @@ export class LogsContainerService { component_name: componentName, scrollType: scrollType }; - this.httpClient.get('serviceLogsTruncated', params).subscribe(response => { + this.httpClient.get('serviceLogsTruncated', params).subscribe((response: Response): void => { const jsonResponse = response.json(); if (!scrollType) { this.serviceLogsTruncatedStorage.clear(); @@ -156,8 +163,8 @@ export class LogsContainerService { private getParams(filtersMapName: string): any { let params = {}; - Object.keys(this[filtersMapName]).forEach(key => { - const inputValue = this.filtering.filtersForm.getRawValue()[key], + Object.keys(this[filtersMapName]).forEach((key: string): void => { + const inputValue = this.filtering.activeFiltersForm.getRawValue()[key], paramNames = this[filtersMapName][key]; paramNames.forEach(paramName => { let value; @@ -179,7 +186,7 @@ export class LogsContainerService { return params; } - getHistogramData(data: any[]): any { + getHistogramData(data: BarGraph[]): {[key: string]: number} { let histogramData = {}; data.forEach(type => { const name = type.name; @@ -196,4 +203,31 @@ export class LogsContainerService { return histogramData; } + loadColumnsNames(): void { + this.httpClient.get('serviceLogsFields').subscribe((response: Response): void => { + const jsonResponse = response.json(); + if (jsonResponse) { + this.serviceLogsFieldsStorage.addInstances(this.getColumnsArray(jsonResponse, ServiceLogField)); + } + }); + this.httpClient.get('auditLogsFields').subscribe((response: Response): void => { + const jsonResponse = response.json(); + if (jsonResponse) { + this.auditLogsFieldsStorage.addInstances(this.getColumnsArray(jsonResponse, AuditLogField)); + } + }); + } + + private getColumnsArray(keysObject: any, fieldClass: any): any[] { + return Object.keys(keysObject).map((key: string): {fieldClass} => new fieldClass(key)); + } + + switchTab(activeTab: Tab): void { + this.appState.setParameters(activeTab.appState); + this.tabsStorage.mapCollection((tab: Tab): Tab => Object.assign({}, tab, { + isActive: tab.id === activeTab.id + })); + this.loadLogs(); + } + } http://git-wip-us.apache.org/repos/asf/ambari/blob/15cec1cb/ambari-logsearch/ambari-logsearch-web/src/app/services/storage/reducers.service.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/storage/reducers.service.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/storage/reducers.service.ts index ca8a632..d700b16 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/app/services/storage/reducers.service.ts +++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/storage/reducers.service.ts @@ -31,6 +31,7 @@ import {serviceLogsTruncated} from '@app/services/storage/service-logs-truncated import {serviceLogsFields} from '@app/services/storage/service-logs-fields.service'; import {auditLogsFields} from '@app/services/storage/audit-logs-fields.service'; import {userConfigs} from '@app/services/storage/user-configs.service'; +import {tabs} from '@app/services/storage/tabs.service'; export const reducers = { appSettings, @@ -46,7 +47,8 @@ export const reducers = { clusters, components, serviceLogsFields, - auditLogsFields + auditLogsFields, + tabs }; export function reducer(state: any, action: any) { http://git-wip-us.apache.org/repos/asf/ambari/blob/15cec1cb/ambari-logsearch/ambari-logsearch-web/src/app/services/storage/tabs.service.ts ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/storage/tabs.service.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/storage/tabs.service.ts new file mode 100644 index 0000000..93bf985 --- /dev/null +++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/storage/tabs.service.ts @@ -0,0 +1,33 @@ +/** + * 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 {Store} from '@ngrx/store'; +import {initialTabs} from '@app/classes/models/tab'; +import {AppStore, CollectionModelService, getCollectionReducer} from '@app/classes/models/store'; + +export const modelName = 'tabs'; + +@Injectable() +export class TabsService extends CollectionModelService { + constructor(store: Store<AppStore>) { + super(modelName, store); + } +} + +export const tabs = getCollectionReducer(modelName, initialTabs); http://git-wip-us.apache.org/repos/asf/ambari/blob/15cec1cb/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json b/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json index 99ddbe5..16b4b32 100644 --- a/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json +++ b/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json @@ -2,6 +2,8 @@ "common.title": "Log Search", "common.hide": "Hide", "common.show": "Show", + "common.serviceLogs": "Service Logs", + "common.auditLogs": "Audit Logs", "modal.submit": "OK", "modal.cancel": "Cancel",