File

src/app/jobs/step-execution-details/step-execution-details.component.ts

Description

Step Execution Details

Implements

OnInit

Example

Metadata

selector app-step-execution-details
styleUrls styles.scss
templateUrl ./step-execution-details.component.html

Index

Properties
Methods

Constructor

constructor(jobsService: JobsService, route: ActivatedRoute, loggerService: LoggerService, routingStateService: RoutingStateService, notificationService: NotificationService, router: Router)

Constructor

Parameters :
Name Type Optional Description
jobsService JobsService
route ActivatedRoute
loggerService LoggerService
routingStateService RoutingStateService
notificationService NotificationService
router Router

Methods

back
back()

Navigate to the previous page

Returns : void
ngOnInit
ngOnInit()

Init component

Returns : void
refresh
refresh()

Refresh

Returns : void
viewStepExecutionProgress
viewStepExecutionProgress(item: StepExecutionResource)

Navigates to the step execution progress page.

Parameters :
Name Type Optional Description
item StepExecutionResource

the id of the StepExecution is used to construct the URI parameters along with the JobExecutionId.

Returns : void

Properties

jobId
jobId: number
Type : number

Job ID

stepExecutionDetails$
stepExecutionDetails$: Observable<any>
Type : Observable<any>

Observable Step Execution Informations

import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { JobsService } from '../jobs.service';
import { StepExecutionResource } from '../model/step-execution-resource.model';
import { Observable, forkJoin } from 'rxjs';
import { mergeMap, map, catchError } from 'rxjs/operators';
import { HttpAppError, AppError } from '../../shared/model/error.model';
import { LoggerService } from '../../shared/services/logger.service';
import { NotificationService } from '../../shared/services/notification.service';
import { RoutingStateService } from '../../shared/services/routing-state.service';
import { EMPTY } from 'rxjs';

/**
 * Step Execution Details
 *
 * @author Glenn Renfro
 * @author Gunnar Hillert
 * @author Damien Vitrac
 */
@Component({
  selector: 'app-step-execution-details',
  styleUrls: ['styles.scss'],
  templateUrl: './step-execution-details.component.html'
})
export class StepExecutionDetailsComponent implements OnInit {

  /**
   * Observable Step Execution Informations
   */
  stepExecutionDetails$: Observable<any>;

  /**
   * Job ID
   */
  jobId: number;

  /**
   * Constructor
   *
   * @param {JobsService} jobsService
   * @param {ActivatedRoute} route
   * @param {LoggerService} loggerService
   * @param {RoutingStateService} routingStateService
   * @param {NotificationService} notificationService
   * @param {Router} router
   */
  constructor(private jobsService: JobsService,
              private route: ActivatedRoute,
              private loggerService: LoggerService,
              private routingStateService: RoutingStateService,
              private notificationService: NotificationService,
              private router: Router) {
  }

  /**
   * Init component
   */
  ngOnInit() {
    this.refresh();
  }

  /**
   * Refresh
   */
  refresh() {
    this.stepExecutionDetails$ = this.route.params
      .pipe(mergeMap(
        val => forkJoin([
          this.jobsService.getJobExecution(val.jobid),
          this.jobsService.getStepExecution(val.jobid, val.stepid),
          this.jobsService.getStepExecutionProgress(val.jobid, val.stepid)
        ]).pipe(map((val2) => {
          this.jobId = val.jobid;
          return val2;
        }))
      ))
      .pipe(
        map(
          val => ({ jobExecution: val[0], stepExecution: val[1], stepExecutionProgress: val[2] })
        ),
        catchError((error) => {
          if (HttpAppError.is404(error) || HttpAppError.is400(error)) {
            this.routingStateService.back(`/jobs/executions/`);
          }
          this.loggerService.log('error while loading Step Execution Progress', error);
          this.notificationService.error(AppError.is(error) ? error.getMessage() : error);
          return EMPTY;
        })
      );
  }

  /**
   * Navigates to the step execution progress page.
   *
   * @param {StepExecutionResource} item the id of the StepExecution is used to construct the URI parameters along
   * with the JobExecutionId.
   */
  viewStepExecutionProgress(item: StepExecutionResource) {
    this.router.navigate([`jobs/executions/${item.jobExecutionId}/${item.stepExecution.id}/progress`]);
  }

  /**
   * Navigate to the previous page
   */
  back() {
    this.routingStateService.back(`jobs/executions/${this.jobId}`);
  }

}
<app-page *ngIf="stepExecutionDetails$ | async as stepExecutionDetails; else loading">

  <app-page-head>
    <app-page-head-back [defaultUrl]="'/jobs/executions/' + jobId"></app-page-head-back>
    <app-page-head-title>
      Step Execution <strong>{{ stepExecutionDetails.stepExecution.stepExecution.name }}
      ({{ stepExecutionDetails.stepExecution.stepExecution.id }})</strong>
      - Job execution  <strong>{{ stepExecutionDetails.jobExecution.name }}</strong>
      ({{ stepExecutionDetails.jobExecution.jobExecutionId }})
    </app-page-head-title>
    <app-page-head-actions>
      <button id="stats" class="btn btn-primary btn-fa" title="Details"
              (click)="viewStepExecutionProgress(stepExecutionDetails.stepExecution)">
        <span class="fa fa-info-circle"></span>
        More details
      </button>
      <button id="refresh" class="btn btn-primary btn-fa" (click)="refresh()">
        <span class="fa fa-refresh"></span>
        Refresh
      </button>
    </app-page-head-actions>
  </app-page-head>

  <div *ngIf="stepExecutionDetails.stepExecutionProgress.percentageComplete < 1">
    <h4>Step Execution Progress</h4>
    <progressbar [animate]="false" max="100"
                 [value]="stepExecutionDetails.stepExecutionProgress.percentageComplete * 100"
                 type="success">
      <b>{{ stepExecutionDetails.stepExecutionProgress.percentageComplete * 100}}%</b>
    </progressbar>
  </div>

  <div>
    <h4>Step Execution</h4>
    <div id="nostepexecution" *ngIf="!stepExecutionDetails?.stepExecution.stepExecution">
      No Step Execution available.
    </div>

    <table id="stepExecution" *ngIf="stepExecutionDetails?.stepExecution?.stepExecution" class="table table-hover">
      <thead>
      <tr>
        <th style="width: 250px">Property</th>
        <th>Value</th>
      </tr>
      </thead>
      <tbody>
      <tr>
        <td>Step Execution Id</td>
        <td>{{ stepExecutionDetails.stepExecution.stepExecution.id }}</td>
      </tr>
      <tr>
        <td>Job Execution Id</td>
        <td>{{ stepExecutionDetails.stepExecution.jobExecutionId }}</td>
      </tr>
      <tr>
        <td>Step Name</td>
        <td>{{ stepExecutionDetails.stepExecution.stepExecution.name }}</td>
      </tr>
      <tr>
        <td>Step Type</td>
        <td>{{ stepExecutionDetails.stepExecution.stepType }}</td>
      </tr>
      <tr>
        <td>Status</td>
        <td>
          <app-job-execution-status
            [status]="stepExecutionDetails.stepExecution.stepExecution.status"></app-job-execution-status>
        </td>
      </tr>
      <tr>
        <td>Commits</td>
        <td>{{ stepExecutionDetails.stepExecution.stepExecution.commitCount }}</td>
      </tr>
      <tr>
        <td>Duration</td>
        <td>{{ stepExecutionDetails.stepExecution.stepExecution.startTime | dataflowDuration:
          stepExecutionDetails.stepExecution.stepExecution.endTime }}
        </td>
      </tr>
      <tr>
        <td>Filter Count</td>
        <td>{{ stepExecutionDetails.stepExecution.stepExecution.filterCount }}</td>
      </tr>
      <tr>
        <td>Process Skips</td>
        <td>{{ stepExecutionDetails.stepExecution.stepExecution.processSkipCount }}</td>
      </tr>
      <tr>
        <td>Reads</td>
        <td>{{ stepExecutionDetails.stepExecution.stepExecution.readCount }}</td>
      </tr>
      <tr>
        <td>Read Skips</td>
        <td>{{ stepExecutionDetails.stepExecution.stepExecution.readSkipCount }}</td>
      </tr>
      <tr>
        <td>Rollbacks</td>
        <td>{{ stepExecutionDetails.stepExecution.stepExecution.rollbackCount }}</td>
      </tr>
      <tr>
        <td>Skips</td>
        <td>{{ stepExecutionDetails.stepExecution.stepExecution.skipCount }}</td>
      </tr>
      <tr>
        <td>Writes</td>
        <td>{{ stepExecutionDetails.stepExecution.stepExecution.writeCount }}</td>
      </tr>
      <tr>
        <td>Write Skips</td>
        <td>{{ stepExecutionDetails.stepExecution.stepExecution.writeSkipCount }}</td>
      </tr>
      </tbody>
    </table>
  </div>

  <div *ngIf="stepExecutionDetails?.stepExecution?.stepExecution?.exitMessage">
    <h4>Exit Description</h4>
    <pre class="exit">{{ stepExecutionDetails?.stepExecution?.stepExecution?.exitMessage || 'N/A' }}</pre>
  </div>

  <div *ngIf="stepExecutionDetails?.stepExecution?.stepExecution?.executionContext?.values">
    <h4>Step Execution Context</h4>
    <table id="stepExecutionContext" class="table table-hover">
      <thead>
      <tr>
        <th style="width: 250px">Key</th>
        <th>Value</th>
      </tr>
      </thead>
      <tbody>
      <ng-template ngFor let-item
                   [ngForOf]="stepExecutionDetails.stepExecution.stepExecution.executionContext.values | keyvalue">
        <tr>
          <td>{{ item.key }}</td>
          <td>{{ item.value }}</td>
        </tr>
      </ng-template>
      </tbody>
    </table>
  </div>

</app-page>
<ng-template #loading>
  <app-loader></app-loader>
</ng-template>

Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""