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() {
+ //
+ }
+
+}