X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?p=it%2Fotf.git;a=blobdiff_plain;f=otf-frontend%2Fclient%2Fsrc%2Fapp%2Flayout%2Fcontrol-panel%2Fcontrol-panel.component.ts;fp=otf-frontend%2Fclient%2Fsrc%2Fapp%2Flayout%2Fcontrol-panel%2Fcontrol-panel.component.ts;h=f9144bea179f3dfee98f8eb7c89238cddd59f347;hp=0000000000000000000000000000000000000000;hb=14f6f95c84a4a1fa8774190db4a03fd0214ec55f;hpb=f49bd1efeaaddd4891c1f329b18d8cfb28b3e75b diff --git a/otf-frontend/client/src/app/layout/control-panel/control-panel.component.ts b/otf-frontend/client/src/app/layout/control-panel/control-panel.component.ts new file mode 100644 index 0000000..f9144be --- /dev/null +++ b/otf-frontend/client/src/app/layout/control-panel/control-panel.component.ts @@ -0,0 +1,564 @@ +/* Copyright (c) 2019 AT&T Intellectual Property. # +# # +# Licensed 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, OnDestroy, HostListener, ViewChild, ElementRef } from '@angular/core'; +import { routerTransition } from 'app/router.animations'; +import { ActivatedRoute } from '@angular/router'; +import { TestExecutionService } from 'app/shared/services/test-execution.service'; +import { TestDefinitionService } from 'app/shared/services/test-definition.service'; +import BpmnJS from 'bpmn-js/lib/NavigatedViewer'; +import beautify from 'json-beautify'; +import { trigger, state, style, transition, animate } from '@angular/animations'; +import { interval } from 'rxjs'; +import { FileTransferService } from 'app/shared/services/file-transfer.service'; +import { Buffer } from 'buffer'; +import 'codemirror/mode/javascript/javascript.js'; +import { toInteger } from '@ng-bootstrap/ng-bootstrap/util/util'; +import { RequiredValidator } from '@angular/forms'; +import { UserService } from 'app/shared/services/user.service'; +import { ExecuteService } from 'app/shared/services/execute.service'; +import { BpmnFactoryService } from 'app/shared/factories/bpmn-factory.service'; +import { Bpmn } from 'app/shared/models/bpmn.model'; + +//import 'datatables.net'; + +@Component({ + selector: 'app-control-panel', + templateUrl: './control-panel.component.pug', + styleUrls: ['./control-panel.component.scss'], + animations: [routerTransition(), + trigger('detailExpand', [ + state('collapsed', style({ height: '0px', minHeight: '0', display: 'none' })), + state('expanded', style({ height: '*' })), + transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')), + ]) + ] +}) +export class ControlPanelComponent implements OnInit, OnDestroy { + + @ViewChild('canvas-card') canvas: ElementRef; + + public params; + public displayedColumns = ['startTime', 'endTime', 'totalTime']; + public dataSource = {}; + public instanceDataSource = {}; + public data = {}; + public testHeads = []; + public testResult; + public expandedElement; + public selectedTestHead; + public selectedTestInstance; + public objectKeys = Object.keys; + private pullData = true; + public showFireworks = false; + public refreshData = false; + public spin = false; + public lastVTHResultsLength = 0; + // Create an Observable that will publish a value on an interval + public refreshCounter = interval(5000); + + public isResizing = false; + public lastDownY; + + public viewer: Bpmn; + public taskLog = ''; + + public executionJobLog = []; + public executionExternalTaskLog = []; + public executionVariables = []; + + public executionJobLogDataSource; + public executionExternalTaskLogDataSource; + public executionVariablesDataSource; + + public selectedExecutionJobLog; + public selectedExecutionExternalTaskLog; + public selectedExecutionVariable; + + + public codeConfig = { + mode: "application/json", + theme: "eclipse", + readonly: true, + lineNumbers: true + }; + + public taskLogConfig = { + mode: "Shell", + theme: "3024-night", + readonly: true + }; + + private processInstanceId; + public processState; + + + constructor( + private route: ActivatedRoute, + private executionService: ExecuteService, + private user: UserService, + private testExecution: TestExecutionService, + private fileTransfer: FileTransferService, + private bpmnFactory: BpmnFactoryService + ) { } + + ngOnInit() { + this.route.queryParams.subscribe(params => { + this.params = params; + if(params.id){ + this.refreshData = false; + this.populateData(); + + this.refreshCounter.subscribe(n => { + if (this.pullData){ + this.populateData(n + 1); + this.updateFlowData(); + + } + }); + } + }); + + $('#canvas-card').on('mousedown', (e) => { + this.isResizing = true; + this.lastDownY = $('#canvas-card').position().top + $('#canvas-card').outerHeight(true); + }) + + $(document).on('mousemove', (e) => { + if(!this.isResizing){ + return; + } + + var bottom = $('#canvas-card').position().top + $('#canvas-card').outerHeight(true);//$('#canvas-card').height() - (e.clientY - $('#canvas-card').offset().top); + + if(bottom != this.lastDownY){ + this.lastDownY = $('#canvas-card').position().top + $('#canvas-card').outerHeight(true); + this.onResize(null); + } + + }).on('mouseup', () => { + this.isResizing = false; + }) + } + + ngOnDestroy() { + this.pullData = false; + } + + refreshAllData() { + this.spin = true; + this.refreshData = true; + this.populateData(); + this.updateFlowData(); + + } + + populateData(loopNum = 0) { + this.testExecution.get(this.params.id).subscribe( + data => { + console.log(data); + let result = JSON.parse(JSON.stringify(data)); + + this.processInstanceId = result['processInstanceId']; + + this.calcTime(result); + + if(result['testInstanceResults']){ + this.instanceDataSource = {}; + for(var val = 0; val < result['testInstanceResults'].length; val++){ + var elem = result['testInstanceResults'][val]; + this.calcTime(elem); + let exists = false; + Object.keys(this.instanceDataSource).forEach((e, val) => { + if(e == elem.historicTestInstance._id){ + exists = true; + return; + } + }); + + if(!exists){ + this.instanceDataSource[elem.historicTestInstance._id] = [elem]; + } + else{ + var found = false; + + this.instanceDataSource[elem.historicTestInstance._id].forEach( (value, index) => { + if(this.instanceDataSource[elem.historicTestInstance._id][index]._id == elem._id){ + this.instanceDataSource[elem.historicTestInstance._id][index] = elem; + found = true; + } + }) + if(!found){ + this.instanceDataSource[elem.historicTestInstance._id].push(elem); + } + } + if(val == 0){ + this.selectTestInstance(elem.historicTestInstance._id); + } + }; + } + + if (result['testHeadResults']) { + for (var i = 0 + this.lastVTHResultsLength; i < result['testHeadResults'].length; i++) { + + var exists = false; + this.testHeads.forEach(elem => { + if (elem.testHeadId == result['testHeadResults'][i].testHeadId && elem.bpmnVthTaskId == result['testHeadResults'][i].bpmnVthTaskId) { + exists = true; + } + }); + + if (!exists) { + this.testHeads.push(result['testHeadResults'][i]); + this.dataSource[result['testHeadResults'][i].testHeadId + result['testHeadResults'][i].bpmnVthTaskId] = []; + } + + let sDate = new Date(result['testHeadResults'][i].startTime); + let eDate = new Date(result['testHeadResults'][i].endTime); + let tDate = (eDate.getTime() - sDate.getTime()) / 1000; + + result['testHeadResults'][i].startTime = sDate.getHours() + ":" + sDate.getMinutes() + ":" + sDate.getSeconds(); // + " " + sDate.getMonth() + "/" + sDate.getDate() + "/" + sDate.getFullYear(); + result['testHeadResults'][i].endTime = eDate.getHours() + ":" + eDate.getMinutes() + ":" + eDate.getSeconds(); // + " " + eDate.getMonth() + "/" + eDate.getDate() + "/" + eDate.getFullYear(); + result['testHeadResults'][i].totalTime = tDate + " secs"; + result['testHeadResults'][i].testHeadRequestResponse = { + "testHeadRequest": result['testHeadResults'][i].testHeadRequest, + "testHeadResponse": result['testHeadResults'][i].testHeadResponse, + "statusCode": result['testHeadResults'][i].statusCode + }; + //result['testHeadResults'][i].testHeadResponse = beautify(result['testHeadResults'][i].testHeadResponse, null, 2, 50); + + this.dataSource[result['testHeadResults'][i].testHeadId + result['testHeadResults'][i].bpmnVthTaskId].push(result['testHeadResults'][i]); + + if (i == 0) { + this.selectTestHead(result['testHeadResults'][i].testHeadId + result['testHeadResults'][i].bpmnVthTaskId); + } + } + //keep track of previous results so you don't reload them + this.lastVTHResultsLength = result['testHeadResults'].length; + + this.testResult = Object.assign({}, result); + // this.user.get(result['executor']).subscribe(res => { + // this.testResult['executor'] = res; + // }); + // + + + this.spin = false; + } + + + //only gets called once + if (!this.refreshData && loopNum == 0 && (result['historicTestDefinition'] && result['historicTestDefinition']['bpmnInstances'][0])) { + let id = result['historicTestDefinition']['bpmnInstances'][0]['bpmnFileId'] + + if(!this.viewer){ + this.bpmnFactory.setup({ + mode: 'viewer', + options: { + container: '#canvas' + }, + fileId: id + }).then(res => { + this.viewer = res; + this.updateFlowData(); + }); + }else{ + this.bpmnFactory.getXml({ + fileId: id + }).then(res => { + this.viewer.setBpmnXml(res); + this.updateFlowData(); + }) + } + + } + } + ); + + } + + updateExecutionData(){ + if(this.executionJobLog){ + this.executionJobLogDataSource = {}; + for(var val = 0; val < this.executionJobLog.length; val++){ + var elem = this.executionJobLog[val]; + + let exists = false; + Object.keys(this.executionJobLogDataSource).forEach((e, val) => { + if(e == elem.activityId){ + exists = true; + return; + } + }); + + if(!exists){ + this.executionJobLogDataSource[elem.activityId] = [elem]; + } + else{ + var found = false; + + this.executionJobLogDataSource[elem.activityId].forEach( (value, index) => { + if(this.executionJobLogDataSource[elem.activityId][index].id == elem.id){ + this.executionJobLogDataSource[elem.activityId][index] = elem; + found = true; + } + }) + if(!found){ + this.executionJobLogDataSource[elem.activityId].push(elem); + } + } + if(val == 0){ + this.selectExecutionJobLog(elem.activityId); + } + }; + } + + if(this.executionExternalTaskLog){ + this.executionExternalTaskLogDataSource = {}; + for(var val = 0; val < this.executionExternalTaskLog.length; val++){ + var elem = this.executionExternalTaskLog[val]; + + let exists = false; + Object.keys(this.executionExternalTaskLogDataSource).forEach((e, val) => { + if(e == elem.activityId){ + exists = true; + return; + } + }); + + if(!exists){ + this.executionExternalTaskLogDataSource[elem.activityId] = [elem]; + } + else{ + var found = false; + + this.executionExternalTaskLogDataSource[elem.activityId].forEach( (value, index) => { + if(this.executionExternalTaskLogDataSource[elem.activityId][index].id == elem.id){ + this.executionExternalTaskLogDataSource[elem.activityId][index] = elem; + found = true; + } + }) + if(!found){ + this.executionExternalTaskLogDataSource[elem.activityId].push(elem); + } + } + if(val == 0){ + this.selectExecutionExternalTaskLog(elem.activityId); + } + }; + } + + + + if(this.executionVariables){ + this.executionVariablesDataSource = {}; + for(var val = 0; val < this.executionVariables.length; val++){ + var elem = this.executionVariables[val]; + + let exists = false; + Object.keys(this.executionVariablesDataSource).forEach((e, val) => { + if(e == elem.variableName){ + exists = true; + return; + } + }); + + if(!exists){ + this.executionVariablesDataSource[elem.variableName] = [elem]; + } + else{ + var found = false; + + this.executionVariablesDataSource[elem.variableName].forEach( (value, index) => { + if(this.executionVariablesDataSource[elem.variableName][index].id == elem.id){ + this.executionVariablesDataSource[elem.variableName][index] = elem; + found = true; + } + }) + if(!found){ + this.executionVariablesDataSource[elem.variableName].push(elem); + } + } + if(val == 0){ + this.selectExecutionVariable(elem.variableName); + } + }; + } + + } + + calcTime(result) { + let tsDate = new Date(result['startTime']); + let teDate = new Date(result['endTime']); + let ttDate = (teDate.getTime() - tsDate.getTime()) / 1000; + + result['date'] = tsDate.getMonth() + 1 + "/" + tsDate.getDate() + "/" + tsDate.getFullYear(); + result['startTime'] = tsDate.getHours() + ":" + tsDate.getMinutes() + ":" + tsDate.getSeconds(); + result['endTime'] = teDate.getHours() + ":" + teDate.getMinutes() + ":" + teDate.getSeconds(); + result['totalTime'] = ttDate + ' secs'; + + + } + + updateFlowData() { + console.log(this.processInstanceId); + this.testExecution.status(this.processInstanceId).subscribe( + result => { + if (result) { + let data = result['body']; + //check process state + if (data.historicProcessInstance.state == 'COMPLETED') { + this.processState = 'Completed'; + this.pullData = false; + } else if (data.historicProcessInstance.state == 'ACTIVE') { + this.processState = 'Running'; + } else { + this.processState = 'Failed'; + this.pullData = false; + } + + if(data.historicJobLog){ + this.executionJobLog = data.historicJobLog; + } + if(data.historicExternalTaskLog){ + this.executionExternalTaskLog = data.historicExternalTaskLog; + } + if(data.historicVariableInstance){ + this.executionVariables = data.historicVariableInstance; + } + //update execution tabs -- job log, external task log, variables + this.updateExecutionData(); + + + //loop through processes to get their info + for (let i = 0; i < data.historicActivityInstance.length; i++) { + let p = data.historicActivityInstance[i]; + let state = null; + if (p.startTime && p.endTime && !p.canceled) { // process completed successfully + state = 'completed'; + } else if (p.startTime && !p.endTime) { // process is still running + state = 'running'; + } else if (p.canceled) { + state = 'failed'; + } + + //get task id + + //highlight task boxes based on their state + this.viewer.getModel().get('canvas').addMarker(p.activityId, 'highlight-task-' + state); + } + + + + for (let i = 0; i < data.historicIncident.length; i++) { + let p = data.historicIncident[i]; + if (p.incidentMessage) { + this.taskLog += p.activityId + ': ' + p.incidentMessage + '\n'; + } + this.viewer.getModel().get('canvas').addMarker(p.activityId, 'highlight-task-failed'); + } + } + }, + err => { + + } + ); + } + + cancelExecution() { + this.executionService.delete(this.testResult._id).subscribe(result => { + this.updateFlowData(); + }); + } + + expand(element) { + if (this.expandedElement == element) + this.expandedElement = null; + else + this.expandedElement = element; + } + + beauty(json) { + return beautify(json, null, 2, 50); + } + + @HostListener('window:resize', ['$event']) + onResize(event){ + // console.log("hi") + if(this.viewer) + this.viewer.resize(); + } + + + json2html(json: any = [{ }], tabs = 0) { + var html = ''; + var tabHtml = ''; + if (typeof json === 'string') { + json = JSON.parse(json); + } + for (let i = 0; i < tabs; i++) { + tabHtml += '    '; + } + for (let key in json) { + if (json.hasOwnProperty(key)) { + if (typeof json[key] === "object") { + html += tabHtml + '' + key + ':
'; + if (json.constructor === Array && toInteger(key) > 0) { + tabs--; + } + html += this.json2html(json[key], ++tabs); + } else { + html += tabHtml + '' + key + ':' + '
'; + if (typeof json[key] === 'string') { + json[key] = json[key].replace(/\\n/g, '
' + tabHtml); + } + html += tabHtml + json[key] + '
'; + html += '
'; + } + } + } + return html; + } + + selectTestHead(key) { + this.selectedTestHead = key; + } + + selectTestInstance(key){ + this.selectedTestInstance = key; + + } + + selectExecutionJobLog(key){ + this.selectedExecutionJobLog = key; + + } + + selectExecutionExternalTaskLog(key){ + this.selectedExecutionExternalTaskLog = key; + + } + + selectExecutionVariable(key){ + this.selectedExecutionVariable = key; + + } + + call() { + // + } + +}