| /** |
| * 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 {Router, NavigationStart} from '@angular/router'; |
| import {SensorParserConfig} from '../../model/sensor-parser-config'; |
| import {SensorParserConfigService} from '../../service/sensor-parser-config.service'; |
| import {MetronAlerts} from '../../shared/metron-alerts'; |
| import {MetronDialogBox} from '../../shared/metron-dialog-box'; |
| import {Sort} from '../../util/enums'; |
| import {SortEvent} from '../../shared/metron-table/metron-table.directive'; |
| import {StormService} from '../../service/storm.service'; |
| import {TopologyStatus} from '../../model/topology-status'; |
| import {SensorParserConfigHistory} from '../../model/sensor-parser-config-history'; |
| import {SensorParserConfigHistoryService} from '../../service/sensor-parser-config-history.service'; |
| |
| @Component({ |
| selector: 'metron-config-sensor-parser-list', |
| templateUrl: 'sensor-parser-list.component.html', |
| styleUrls: ['sensor-parser-list.component.scss'] |
| }) |
| export class SensorParserListComponent implements OnInit { |
| |
| componentName: string = 'Sensors'; |
| @ViewChild('table') table; |
| |
| count: number = 0; |
| sensors: SensorParserConfigHistory[] = []; |
| sensorsStatus: TopologyStatus[] = []; |
| selectedSensor: SensorParserConfigHistory; |
| selectedSensors: SensorParserConfigHistory[] = []; |
| enableAutoRefresh: boolean = true; |
| |
| constructor(private sensorParserConfigService: SensorParserConfigService, |
| private sensorParserConfigHistoryService: SensorParserConfigHistoryService, |
| private stormService: StormService, |
| private router: Router, |
| private metronAlerts: MetronAlerts, |
| private metronDialogBox: MetronDialogBox) { |
| router.events.subscribe(event => { |
| if (event instanceof NavigationStart && event.url === '/sensors') { |
| this.onNavigationStart(); |
| } |
| }); |
| } |
| |
| getSensors(justOnce: boolean) { |
| this.sensorParserConfigService.getAll().subscribe( |
| (results: {string: SensorParserConfig}) => { |
| this.sensors = []; |
| for (let sensorName of Object.keys(results)) { |
| let sensorParserConfigHistory = new SensorParserConfigHistory(); |
| sensorParserConfigHistory.sensorName = sensorName; |
| sensorParserConfigHistory.config = results[sensorName]; |
| this.sensors.push(sensorParserConfigHistory); |
| } |
| this.selectedSensors = []; |
| this.count = this.sensors.length; |
| if (!justOnce) { |
| this.getStatus(); |
| this.pollStatus(); |
| } else { |
| this.getStatus(); |
| } |
| |
| } |
| ); |
| } |
| |
| onSort($event: SortEvent) { |
| switch ($event.sortBy) { |
| case 'sensorName': |
| this.sensors.sort((obj1: SensorParserConfigHistory, obj2: SensorParserConfigHistory) => { |
| if ($event.sortOrder === Sort.ASC) { |
| return obj1.sensorName.localeCompare(obj2.sensorName); |
| } |
| return obj2.sensorName.localeCompare(obj1.sensorName); |
| }); |
| break; |
| case 'parserClassName': |
| this.sensors.sort((obj1: SensorParserConfigHistory, obj2: SensorParserConfigHistory) => { |
| if ($event.sortOrder === Sort.ASC) { |
| return this.getParserType(obj1.config).localeCompare(this.getParserType(obj2.config)); |
| } |
| return this.getParserType(obj2.config).localeCompare(this.getParserType(obj1.config)); |
| }); |
| break; |
| case 'status': |
| case 'modifiedBy': |
| case 'modifiedByDate': |
| case 'latency': |
| case 'throughput': |
| this.sensors.sort((obj1: SensorParserConfigHistory, obj2: SensorParserConfigHistory) => { |
| if (!obj1[$event.sortBy] || !obj1[$event.sortBy]) { |
| return 0; |
| } |
| if ($event.sortOrder === Sort.ASC) { |
| return obj1[$event.sortBy].localeCompare(obj2[$event.sortBy]); |
| } |
| |
| return obj2[$event.sortBy].localeCompare(obj1[$event.sortBy]); |
| }); |
| break; |
| } |
| } |
| |
| private pollStatus() { |
| this.stormService.pollGetAll().subscribe( |
| (results: TopologyStatus[]) => { |
| this.sensorsStatus = results; |
| this.updateSensorStatus(); |
| }, |
| error => { |
| this.updateSensorStatus(); |
| } |
| ); |
| } |
| |
| private getStatus() { |
| this.stormService.getAll().subscribe( |
| (results: TopologyStatus[]) => { |
| this.sensorsStatus = results; |
| this.updateSensorStatus(); |
| }, |
| error => { |
| this.updateSensorStatus(); |
| } |
| ); |
| } |
| |
| updateSensorStatus() { |
| for (let sensor of this.sensors) { |
| |
| let status: TopologyStatus = this.sensorsStatus.find(status => { |
| return status.name === sensor.sensorName; |
| }); |
| |
| if (status) { |
| if (status.status === 'ACTIVE') { |
| sensor['status'] = 'Running'; |
| } |
| if (status.status === 'KILLED') { |
| sensor['status'] = 'Stopped'; |
| } |
| if (status.status === 'INACTIVE') { |
| sensor['status'] = 'Disabled'; |
| } |
| } else { |
| sensor['status'] = 'Stopped'; |
| } |
| |
| sensor['latency'] = status && status.status === 'ACTIVE' ? (status.latency + 's') : '-'; |
| sensor['throughput'] = status && status.status === 'ACTIVE' ? (Math.round(status.throughput * 100) / 100) + 'kb/s' : '-'; |
| } |
| } |
| |
| getParserType(sensor: SensorParserConfig): string { |
| let items = sensor.parserClassName.split('.'); |
| return items[items.length - 1].replace('Basic', '').replace('Parser', ''); |
| } |
| |
| ngOnInit() { |
| this.getSensors(false); |
| this.sensorParserConfigService.dataChanged$.subscribe( |
| data => { |
| this.getSensors(true); |
| } |
| ); |
| } |
| |
| addAddSensor() { |
| this.router.navigateByUrl('/sensors(dialog:sensors-config/new)'); |
| } |
| |
| navigateToSensorEdit(selectedSensor: SensorParserConfigHistory, event) { |
| this.selectedSensor = selectedSensor; |
| this.router.navigateByUrl('/sensors(dialog:sensors-config/' + selectedSensor.sensorName + ')'); |
| event.stopPropagation(); |
| } |
| |
| onRowSelected(sensor: SensorParserConfigHistory, $event) { |
| if ($event.target.checked) { |
| this.selectedSensors.push(sensor); |
| } else { |
| this.selectedSensors.splice(this.selectedSensors.indexOf(sensor), 1); |
| } |
| } |
| |
| onSelectDeselectAll($event) { |
| let checkBoxes = this.table.nativeElement.querySelectorAll('tr td:last-child input[type="checkbox"]'); |
| |
| for (let ele of checkBoxes) { |
| ele.checked = $event.target.checked; |
| } |
| |
| if ($event.target.checked) { |
| this.selectedSensors = this.sensors.slice(0).map((sensorParserInfo: SensorParserConfigHistory) => sensorParserInfo); |
| } else { |
| this.selectedSensors = []; |
| } |
| } |
| |
| onSensorRowSelect(sensor: SensorParserConfigHistory, $event) { |
| if ($event.target.type !== 'checkbox' && $event.target.parentElement.firstChild.type !== 'checkbox') { |
| |
| if (this.selectedSensor === sensor) { |
| this.selectedSensor = null; |
| this.router.navigateByUrl('/sensors'); |
| return; |
| } |
| this.selectedSensor = sensor; |
| this.router.navigateByUrl('/sensors(dialog:sensors-readonly/' + sensor.sensorName + ')'); |
| } |
| } |
| |
| deleteSensor($event, selectedSensorsToDelete: SensorParserConfigHistory[]) { |
| if ($event) { |
| $event.stopPropagation(); |
| } |
| |
| let sensorNames = selectedSensorsToDelete.map(sensor => { return sensor.sensorName; }); |
| let confirmationsMsg = 'Are you sure you want to delete sensor(s) ' + sensorNames.join(', ') + ' ?'; |
| |
| this.metronDialogBox.showConfirmationMessage(confirmationsMsg).subscribe(result => { |
| if (result) { |
| this.sensorParserConfigService.deleteSensorParserConfigs(sensorNames) |
| .subscribe((deleteResult: {success: Array<string>, failure: Array<string>}) => { |
| if (deleteResult.success.length > 0) { |
| this.metronAlerts.showSuccessMessage('Deleted sensors: ' + deleteResult.success.join(', ')); |
| } |
| |
| if (deleteResult.failure.length > 0) { |
| this.metronAlerts.showErrorMessage('Unable to deleted sensors: ' + deleteResult.failure.join(', ')); |
| } |
| }); |
| } |
| }); |
| } |
| |
| onDeleteSensor() { |
| this.deleteSensor(null, this.selectedSensors); |
| } |
| |
| onStopSensors() { |
| for (let sensor of this.selectedSensors) { |
| if (sensor['status'] === 'Running' || sensor['status'] === 'Disabled') { |
| this.onStopSensor(sensor, null); |
| } |
| } |
| } |
| |
| onStopSensor(sensor: SensorParserConfigHistory, event) { |
| this.toggleStartStopInProgress(sensor); |
| |
| this.stormService.stopParser(sensor.sensorName).subscribe(result => { |
| this.metronAlerts.showSuccessMessage('Stopped sensor ' + sensor.sensorName); |
| this.toggleStartStopInProgress(sensor); |
| }, |
| error => { |
| this.metronAlerts.showErrorMessage('Unable to stop sensor ' + sensor.sensorName); |
| this.toggleStartStopInProgress(sensor); |
| }); |
| |
| if (event !== null) { |
| event.stopPropagation(); |
| } |
| } |
| |
| onStartSensors() { |
| for (let sensor of this.selectedSensors) { |
| if (sensor['status'] === 'Stopped') { |
| this.onStartSensor(sensor, null); |
| } |
| } |
| } |
| |
| onStartSensor(sensor: SensorParserConfigHistory, event) { |
| this.toggleStartStopInProgress(sensor); |
| |
| this.stormService.startParser(sensor.sensorName).subscribe(result => { |
| if (result['status'] === 'ERROR') { |
| this.metronAlerts.showErrorMessage('Unable to start sensor ' + sensor.sensorName + ': ' + result['message']); |
| } else { |
| this.metronAlerts.showSuccessMessage('Started sensor ' + sensor.sensorName); |
| } |
| |
| this.toggleStartStopInProgress(sensor); |
| }, |
| error => { |
| this.metronAlerts.showErrorMessage('Unable to start sensor ' + sensor.sensorName); |
| this.toggleStartStopInProgress(sensor); |
| }); |
| |
| if (event !== null) { |
| event.stopPropagation(); |
| } |
| } |
| |
| onDisableSensors() { |
| for (let sensor of this.selectedSensors) { |
| if (sensor['status'] === 'Running') { |
| this.onDisableSensor(sensor, null); |
| } |
| } |
| } |
| |
| onDisableSensor(sensor: SensorParserConfigHistory, event) { |
| this.toggleStartStopInProgress(sensor); |
| |
| this.stormService.deactivateParser(sensor.sensorName).subscribe(result => { |
| this.metronAlerts.showSuccessMessage('Disabled sensor ' + sensor.sensorName); |
| this.toggleStartStopInProgress(sensor); |
| }, |
| error => { |
| this.metronAlerts.showErrorMessage('Unable to disable sensor ' + sensor.sensorName); |
| this.toggleStartStopInProgress(sensor); |
| }); |
| |
| if (event !== null) { |
| event.stopPropagation(); |
| } |
| } |
| |
| onEnableSensors() { |
| for (let sensor of this.selectedSensors) { |
| if (sensor['status'] === 'Disabled') { |
| this.onEnableSensor(sensor, null); |
| } |
| } |
| } |
| |
| onEnableSensor(sensor: SensorParserConfigHistory, event) { |
| this.toggleStartStopInProgress(sensor); |
| |
| this.stormService.activateParser(sensor.sensorName).subscribe(result => { |
| this.metronAlerts.showSuccessMessage('Enabled sensor ' + sensor.sensorName); |
| this.toggleStartStopInProgress(sensor); |
| }, |
| error => { |
| this.metronAlerts.showErrorMessage('Unable to enabled sensor ' + sensor.sensorName); |
| this.toggleStartStopInProgress(sensor); |
| }); |
| |
| if (event != null) { |
| event.stopPropagation(); |
| } |
| } |
| |
| toggleStartStopInProgress(sensor: SensorParserConfigHistory) { |
| sensor.config['startStopInProgress'] = !sensor.config['startStopInProgress']; |
| } |
| |
| onNavigationStart() { |
| this.selectedSensor = null; |
| this.selectedSensors = []; |
| } |
| } |