You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@streampipes.apache.org by ze...@apache.org on 2021/08/31 15:33:24 UTC

[incubator-streampipes] branch dev updated (3a9af99 -> 98e4343)

This is an automated email from the ASF dual-hosted git repository.

zehnder pushed a change to branch dev
in repository https://gitbox.apache.org/repos/asf/incubator-streampipes.git.


    from 3a9af99  [STREAMPIPES-421] Configure collection static properties CSV file
     new 6f9bc09  [STREAMPIPES-79] Add configuration dashboard for stored data
     new 98e4343  [STREAMPIPES-79] Meadurements in data explorer can be truncated

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../dataexplorer/v4/query/DataExplorerQueryV4.java |   2 +-
 ui/src/app/configuration/configuration.module.ts   |  62 ++---
 .../datalake-configuration-entry.ts                |  11 +-
 .../datalake-configuration.component.html          |  81 +++++-
 .../datalake-configuration.component.ts            | 111 ++++++--
 .../delete-datalake-index-dialog.component.html}   |  10 +-
 .../delete-datalake-index-dialog.component.scss}   |   0
 .../delete-datalake-index-dialog.component.ts      |  61 +++++
 .../existing-adapters.component.html               |  39 +--
 .../existing-adapters.component.ts                 |  16 +-
 .../datalake/DatalakeQueryParameterBuilder.ts      |   9 +-
 ...data-explorer-widget-data-settings.component.ts |   7 +-
 .../grid/data-explorer-dashboard-grid.component.ts |  31 +--
 .../data-explorer-dashboard-overview.component.ts  | 130 ++++-----
 .../data-explorer-dashboard-panel.component.ts     |   7 +-
 .../data-explorer-dashboard-widget.component.ts    |  15 +-
 .../app/data-explorer/data-explorer.component.ts   |   4 +-
 ui/src/app/data-explorer/data-explorer.module.ts   |  20 +-
 ...ata-explorer-edit-data-view-dialog.component.ts |  51 ++--
 .../apis}/data-view-data-explorer.service.ts       |  12 +-
 .../apis/datalake-rest.service.ts                  | 293 +++++++++++----------
 21 files changed, 580 insertions(+), 392 deletions(-)
 copy streampipes-performance-tests/src/main/java/org/apache/streampipes/performance/PerformanceTest.java => ui/src/app/configuration/datalake-configuration/datalake-configuration-entry.ts (83%)
 copy ui/src/app/{connect/dialog/delete-adapter-dialog/delete-adapter-dialog.component.html => configuration/dialog/delete-datalake-index/delete-datalake-index-dialog.component.html} (85%)
 copy ui/src/app/{pipelines/dialog/start-all-pipelines/start-all-pipelines-dialog.component.scss => configuration/dialog/delete-datalake-index/delete-datalake-index-dialog.component.scss} (100%)
 create mode 100644 ui/src/app/configuration/dialog/delete-datalake-index/delete-datalake-index-dialog.component.ts
 rename ui/src/app/{data-explorer/services => platform-services/apis}/data-view-data-explorer.service.ts (91%)

[incubator-streampipes] 01/02: [STREAMPIPES-79] Add configuration dashboard for stored data

Posted by ze...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

zehnder pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/incubator-streampipes.git

commit 6f9bc0956b0cb2ff99caa3d76c979e291080102e
Author: Philipp Zehnder <ze...@fzi.de>
AuthorDate: Tue Aug 31 15:29:23 2021 +0200

    [STREAMPIPES-79] Add configuration dashboard for stored data
---
 .../datalake-configuration-entry.ts                |  27 ++
 .../datalake-configuration.component.html          |  78 +++++-
 .../datalake-configuration.component.ts            |  95 +++++--
 .../existing-adapters.component.html               |  39 +--
 .../existing-adapters.component.ts                 |  16 +-
 ...data-explorer-widget-data-settings.component.ts |   7 +-
 .../grid/data-explorer-dashboard-grid.component.ts |  31 +--
 .../data-explorer-dashboard-overview.component.ts  | 130 ++++-----
 .../data-explorer-dashboard-panel.component.ts     |   7 +-
 .../data-explorer-dashboard-widget.component.ts    |  15 +-
 .../app/data-explorer/data-explorer.component.ts   |   4 +-
 ui/src/app/data-explorer/data-explorer.module.ts   |  20 +-
 ...ata-explorer-edit-data-view-dialog.component.ts |  51 ++--
 .../apis}/data-view-data-explorer.service.ts       |  12 +-
 .../apis/datalake-rest.service.ts                  | 302 +++++++++++----------
 15 files changed, 488 insertions(+), 346 deletions(-)

diff --git a/ui/src/app/configuration/datalake-configuration/datalake-configuration-entry.ts b/ui/src/app/configuration/datalake-configuration/datalake-configuration-entry.ts
new file mode 100644
index 0000000..fefacbd
--- /dev/null
+++ b/ui/src/app/configuration/datalake-configuration/datalake-configuration-entry.ts
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ *
+ */
+export class DataLakeConfigurationEntry {
+
+  public name: string;
+  public pipelines: string[] = [];
+  public events = 0;
+  public remove = true;
+
+  constructor() {
+  }
+}
diff --git a/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.html b/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.html
index 6130038..0068824 100644
--- a/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.html
+++ b/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.html
@@ -24,13 +24,77 @@
                 <span flex></span>
             </div>
         </div>
-        <div fxFlex="100" fxLayout="column" fxLayoutAlign="center center" class="sp-blue-border page-container-padding-inner">
-            <form (ngSubmit)="removeDataFromDataLake()" class="form-width mt-10" fxFlex="100" fxLayout="column">
-                <div fxLayoutAlign="center center">
-                    <button mat-raised-button color="warn" type="submit" class="md-raised md-primary submit-button">Clean</button>
-                </div>
-                <h4 style="color: var(--color-warn)">All data in the datalake will be deleted. This is a BETA feature and could break things!</h4>
-            </form>
+
+        <div fxFlex="100" class="sp-blue-border">
+            <table fxFlex="100" mat-table [dataSource]="dataSource" style="width: 100%;" matSort>
+
+                <ng-container matColumnDef="name">
+                    <th mat-header-cell mat-sort-header *matHeaderCellDef>Name</th>
+                    <td mat-cell *matCellDef="let configurationEntry">
+                        <h4 style="margin-bottom:0px;">{{configurationEntry.name}}</h4>
+                        <!--                        <h5>{{adapter.description != '' ? adapter.description : '-'}}</h5>-->
+                    </td>
+                </ng-container>
+
+                <ng-container matColumnDef="pipeline">
+                    <th mat-header-cell mat-sort-header *matHeaderCellDef>Related Pipeline</th>
+                    <td mat-cell *matCellDef="let configurationEntry">
+                        {{configurationEntry.pipelines}}
+                    </td>
+                </ng-container>
+
+                <ng-container matColumnDef="events">
+                    <th mat-header-cell mat-sort-header *matHeaderCellDef># Events</th>
+                    <td mat-cell *matCellDef="let configurationEntry">
+                        {{configurationEntry.events | number}}
+                    </td>
+                </ng-container>
+
+                <ng-container matColumnDef="truncate">
+                    <th mat-header-cell *matHeaderCellDef>Truncate</th>
+                    <td mat-cell *matCellDef="let measurement">
+                        <div fxLayout="row">
+                            <span fxFlex fxFlexOrder="3" fxLayout="row" fxLayoutAlign="center center">
+                                    <button color="accent" mat-button mat-icon-button matTooltip="Delete adapter"
+                                            data-cy="delete" matTooltipPosition="above"
+                                            (click)="cleanDatalakeIndex(measurement)">
+                                        <i class="material-icons">local_fire_department</i>
+                                    </button>
+                                </span>
+                        </div>
+                    </td>
+                </ng-container>
+
+                <ng-container matColumnDef="remove">
+                    <th mat-header-cell *matHeaderCellDef>Remove</th>
+                    <td mat-cell *matCellDef="let configurationEntry">
+                        <div fxLayout="row">
+                            <span fxFlex fxFlexOrder="3" fxLayout="row" fxLayoutAlign="center center">
+                                    <button color="accent"
+                                            mat-button
+                                            mat-icon-button
+                                            matTooltip="Delete data lake index"
+                                            data-cy="delete"
+                                            matTooltipPosition="above"
+                                            [disabled]="!configurationEntry.remove"
+                                            (click)="deleteDatalakeIndex(configurationEntry)">
+                                        <i class="material-icons">delete</i>
+                                    </button>
+                                </span>
+                        </div>
+                    </td>
+                </ng-container>
+
+                <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
+                <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
+
+            </table>
+        </div>
+        <div fxFlex="100" fxLayoutAlign="end end">
+            <mat-paginator [pageSizeOptions]="[5, 10, 25, 100]" [pageSize]="20"></mat-paginator>
+        </div>
+        <div fxFlex="100" fxLayout="column" fxLayoutAlign="center center" *ngIf="availableMeasurements.length == 0">
+            <h5>(no stored measurements)</h5>
         </div>
     </div>
 </div>
diff --git a/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.ts b/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.ts
index fc7453c..07fae0a 100644
--- a/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.ts
+++ b/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.ts
@@ -16,9 +16,16 @@
  *
  */
 
-import { Component, OnInit } from '@angular/core';
-import { DatalakeRestService } from '../../core-services/datalake/datalake-rest.service';
+import { Component, OnInit, ViewChild } from '@angular/core';
 import { MatSnackBar } from '@angular/material/snack-bar';
+import { DatalakeRestService } from '../../platform-services/apis/datalake-rest.service';
+import { MatTableDataSource } from '@angular/material/table';
+import { DataViewDataExplorerService } from '../../platform-services/apis/data-view-data-explorer.service';
+import { DataLakeConfigurationEntry } from './datalake-configuration-entry';
+import { DatalakeQueryParameters } from '../../core-services/datalake/DatalakeQueryParameters';
+import { DatalakeQueryParameterBuilder } from '../../core-services/datalake/DatalakeQueryParameterBuilder';
+import { MatPaginator } from '@angular/material/paginator';
+import { MatSort } from '@angular/material/sort';
 
 @Component({
   selector: 'sp-datalake-configuration',
@@ -27,31 +34,79 @@ import { MatSnackBar } from '@angular/material/snack-bar';
 })
 export class DatalakeConfigurationComponent implements OnInit {
 
+  @ViewChild(MatPaginator) paginator: MatPaginator;
+  pageSize = 1;
+  @ViewChild(MatSort) sort: MatSort;
+
+  dataSource: MatTableDataSource<DataLakeConfigurationEntry>;
+  availableMeasurements: DataLakeConfigurationEntry[] = [];
+
+  displayedColumns: string[] = ['name', 'pipeline', 'events', 'truncate', 'remove'];
+
   constructor(
-    protected dataLakeRestService: DatalakeRestService,
-    private snackBar: MatSnackBar) { }
+    // protected dataLakeRestService: DatalakeRestService,
+    private datalakeRestService: DatalakeRestService,
+    private dataViewDataExplorerService: DataViewDataExplorerService,
+    private snackBar: MatSnackBar) {
+  }
 
   ngOnInit(): void {
+    this.loadAvailableMeasurements();
   }
 
-  removeDataFromDataLake(): void {
-    console.log('Delete');
-    this.dataLakeRestService.removeAllData().subscribe(
-      res => {
-        let message = '';
-
-        if (res) {
-          message = 'Data successfully deleted!';
-        } else {
-          message = 'There was a problem when deleting the data!';
-        }
-
-        this.snackBar.open(message, '', {
-          duration: 2000,
-          verticalPosition: 'top',
-          horizontalPosition: 'right'
+  loadAvailableMeasurements() {
+    // get all available measurements that are stored in the data lake
+    this.datalakeRestService.getAllMeasurementSeries().subscribe(allMeasurements => {
+      // get all measurements that are still used in pipelines
+      this.dataViewDataExplorerService.getAllPersistedDataStreams().subscribe(inUseMeasurements => {
+        console.log('Pipelines');
+        console.log(inUseMeasurements);
+        allMeasurements.forEach(measurement => {
+          const entry = new DataLakeConfigurationEntry();
+          entry.name = measurement.measureName;
+
+          inUseMeasurements.forEach(inUseMeasurement => {
+            if (inUseMeasurement.measureName === measurement.measureName) {
+              entry.pipelines.push(inUseMeasurement.pipelineName);
+              entry.remove = false;
+            }
+          });
+
+          // get the amount of events from the database
+          this.datalakeRestService.getData(
+            measurement.measureName,
+            this.buildQ(measurement.eventSchema.eventProperties[0].label.toLocaleLowerCase())).subscribe(res => {
+            entry.events = res.rows[0][1];
+          });
+
+          this.availableMeasurements.push(entry);
+        });
+
+        this.dataSource = new MatTableDataSource(this.availableMeasurements);
+        setTimeout(() => {
+          this.dataSource.paginator = this.paginator;
+          this.dataSource.sort = this.sort;
         });
       });
+      // this.availableMeasurements = response;
+    });
+  }
+
+  cleanDatalakeIndex(measurementIndex: string) {
+    // TODO give user confirmation
+    this.datalakeRestService.removeData(measurementIndex);
+  }
+
+  deleteDatalakeIndex(measurmentIndex: string) {
+    // TODO give user confirmation
+    this.datalakeRestService.dropSingleMeasurementSeries(measurmentIndex);
+  }
+
+  private buildQ(column: string): DatalakeQueryParameters {
+    return DatalakeQueryParameterBuilder.create(0, new Date().getTime())
+      .withColumnFilter([column])
+      .withAggregationFunction('COUNT')
+      .build();
   }
 
 }
diff --git a/ui/src/app/connect/components/data-marketplace/existing-adapters/existing-adapters.component.html b/ui/src/app/connect/components/data-marketplace/existing-adapters/existing-adapters.component.html
index dfd1b26..13c90cc 100644
--- a/ui/src/app/connect/components/data-marketplace/existing-adapters/existing-adapters.component.html
+++ b/ui/src/app/connect/components/data-marketplace/existing-adapters/existing-adapters.component.html
@@ -61,12 +61,13 @@
                 <td mat-cell *matCellDef="let adapter">
                     <div class="type-data" fxLayout="row" fxLayoutAlign="start start">
                         <div fxLayout="row" fxLayoutAlign="center center">
-                            <mat-icon *ngIf="connectService.isDataSetDescription(adapter)" class="historic">lens</mat-icon>
+                            <mat-icon *ngIf="connectService.isDataSetDescription(adapter)" class="historic">lens
+                            </mat-icon>
                             <mat-icon *ngIf="connectService.isDataStreamDescription(adapter)" class="real-time">lens
                             </mat-icon>
                             <div fxFlex="100" fxLayoutAlign="center center">
-                            <span *ngIf="connectService.isDataSetDescription(adapter)">&nbsp;Data Set</span>
-                            <span *ngIf="connectService.isDataStreamDescription(adapter)">&nbsp;Data Stream</span>
+                                <span *ngIf="connectService.isDataSetDescription(adapter)">&nbsp;Data Set</span>
+                                <span *ngIf="connectService.isDataStreamDescription(adapter)">&nbsp;Data Stream</span>
                             </div>
                         </div>
                     </div>
@@ -83,26 +84,26 @@
                 <th mat-header-cell *matHeaderCellDef> Action</th>
                 <td mat-cell *matCellDef="let adapter">
                     <div fxLayout="row">
-<!--                <span fxFlex fxFlexOrder="1" fxLayout="row" fxLayoutAlign="center center">-->
-<!--                    <button color="primary" mat-button mat-icon-button matTooltip="Show adapter"-->
-<!--                            matTooltipPosition="above"><i-->
-<!--                            class="material-icons">search</i>-->
-<!--                    </button>-->
-<!--                </span>-->
-<!--                        <span fxFlex fxFlexOrder="2" fxLayout="row" fxLayoutAlign="center center">-->
-<!--                    <button color="primary" mat-button mat-icon-button matTooltip="Modify adapter"-->
-<!--                            matTooltipPosition="above"-->
-<!--                            [disabled]="adapter.running">-->
-<!--                        <i class="material-icons">mode_edit</i>-->
-<!--                    </button>-->
-<!--                </span>-->
-                <span fxFlex fxFlexOrder="1" fxLayout="row" fxLayoutAlign="center center">
+                        <!--                <span fxFlex fxFlexOrder="1" fxLayout="row" fxLayoutAlign="center center">-->
+                        <!--                    <button color="primary" mat-button mat-icon-button matTooltip="Show adapter"-->
+                        <!--                            matTooltipPosition="above"><i-->
+                        <!--                            class="material-icons">search</i>-->
+                        <!--                    </button>-->
+                        <!--                </span>-->
+                        <!--                        <span fxFlex fxFlexOrder="2" fxLayout="row" fxLayoutAlign="center center">-->
+                        <!--                    <button color="primary" mat-button mat-icon-button matTooltip="Modify adapter"-->
+                        <!--                            matTooltipPosition="above"-->
+                        <!--                            [disabled]="adapter.running">-->
+                        <!--                        <i class="material-icons">mode_edit</i>-->
+                        <!--                    </button>-->
+                        <!--                </span>-->
+                        <span fxFlex fxFlexOrder="1" fxLayout="row" fxLayoutAlign="center center">
                     <button color="accent" mat-button mat-icon-button matTooltip="Create adapter template"
                             matTooltipPosition="above" (click)="createTemplate(adapter)"><i
                             class="material-icons">content_copy</i>
                     </button>
                 </span>
-                <span fxFlex fxFlexOrder="3" fxLayout="row" fxLayoutAlign="center center">
+                        <span fxFlex fxFlexOrder="3" fxLayout="row" fxLayoutAlign="center center">
                     <button color="accent" mat-button mat-icon-button matTooltip="Delete adapter"
                             data-cy="delete" matTooltipPosition="above" (click)="deleteAdapter(adapter)">
                         <i class="material-icons">delete</i>
@@ -121,6 +122,6 @@
         <mat-paginator [pageSizeOptions]="[5, 10, 25, 100]" [pageSize]="20"></mat-paginator>
     </div>
     <div fxFlex="100" fxLayout="column" fxLayoutAlign="center center" *ngIf="existingAdapters.length == 0">
-        <h5>(no pipelines available)</h5>
+        <h5>(no adapters available)</h5>
     </div>
 </div>
diff --git a/ui/src/app/connect/components/data-marketplace/existing-adapters/existing-adapters.component.ts b/ui/src/app/connect/components/data-marketplace/existing-adapters/existing-adapters.component.ts
index 2bc08df..1e75705 100644
--- a/ui/src/app/connect/components/data-marketplace/existing-adapters/existing-adapters.component.ts
+++ b/ui/src/app/connect/components/data-marketplace/existing-adapters/existing-adapters.component.ts
@@ -16,7 +16,7 @@
  *
  */
 
-import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
+import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
 import { AdapterDescriptionUnion } from '../../../../core-model/gen/streampipes-model';
 import { MatTableDataSource } from '@angular/material/table';
 import { ConnectService } from '../../../services/connect.service';
@@ -25,11 +25,13 @@ import { DialogRef } from '../../../../core-ui/dialog/base-dialog/dialog-ref';
 import { PanelType } from '../../../../core-ui/dialog/base-dialog/base-dialog.model';
 import { DialogService } from '../../../../core-ui/dialog/base-dialog/base-dialog.service';
 import { DeleteAdapterDialogComponent } from '../../../dialog/delete-adapter-dialog/delete-adapter-dialog.component';
+import { MatPaginator } from '@angular/material/paginator';
+import { MatSort } from '@angular/material/sort';
 
 @Component({
   selector: 'sp-existing-adapters',
   templateUrl: './existing-adapters.component.html',
-  styleUrls: ['./existing-adapters.component.scss'],
+  styleUrls: ['./existing-adapters.component.scss']
 })
 export class ExistingAdaptersComponent implements OnInit {
 
@@ -44,6 +46,10 @@ export class ExistingAdaptersComponent implements OnInit {
   @Output()
   createTemplateEmitter: EventEmitter<AdapterDescriptionUnion> = new EventEmitter<AdapterDescriptionUnion>();
 
+  @ViewChild(MatPaginator) paginator: MatPaginator;
+  pageSize = 1;
+  @ViewChild(MatSort) sort: MatSort;
+
   displayedColumns: string[] = ['start', 'name', 'adapterBase', 'adapterType', 'lastModified', 'action'];
 
   dataSource: MatTableDataSource<AdapterDescriptionUnion>;
@@ -56,6 +62,10 @@ export class ExistingAdaptersComponent implements OnInit {
 
   ngOnInit(): void {
     this.dataSource = new MatTableDataSource(this.existingAdapters);
+    setTimeout(() => {
+      this.dataSource.paginator = this.paginator;
+      this.dataSource.sort = this.sort;
+    });
   }
 
   startAdapter(adapter: AdapterDescriptionUnion) {
@@ -84,7 +94,7 @@ export class ExistingAdaptersComponent implements OnInit {
       title: 'Delete Adapter',
       width: '70vw',
       data: {
-        'adapter': adapter,
+        'adapter': adapter
       }
     });
 
diff --git a/ui/src/app/data-explorer/components/designer-panel/data-settings/data-explorer-widget-data-settings.component.ts b/ui/src/app/data-explorer/components/designer-panel/data-settings/data-explorer-widget-data-settings.component.ts
index 58c88bf..ee2983c 100644
--- a/ui/src/app/data-explorer/components/designer-panel/data-settings/data-explorer-widget-data-settings.component.ts
+++ b/ui/src/app/data-explorer/components/designer-panel/data-settings/data-explorer-widget-data-settings.component.ts
@@ -17,11 +17,8 @@
  */
 
 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
-import {
-  DataExplorerWidgetModel,
-  DataLakeMeasure
-} from '../../../../core-model/gen/streampipes-model';
-import { DataViewDataExplorerService } from '../../../services/data-view-data-explorer.service';
+import { DataExplorerWidgetModel, DataLakeMeasure } from '../../../../core-model/gen/streampipes-model';
+import { DataViewDataExplorerService } from '../../../../platform-services/apis/data-view-data-explorer.service';
 import { MatSelectChange } from '@angular/material/select';
 import { Tuple2 } from '../../../../core-model/base/Tuple2';
 import { DatalakeRestService } from '../../../../platform-services/apis/datalake-rest.service';
diff --git a/ui/src/app/data-explorer/components/grid/data-explorer-dashboard-grid.component.ts b/ui/src/app/data-explorer/components/grid/data-explorer-dashboard-grid.component.ts
index 265b240..1d102f4 100644
--- a/ui/src/app/data-explorer/components/grid/data-explorer-dashboard-grid.component.ts
+++ b/ui/src/app/data-explorer/components/grid/data-explorer-dashboard-grid.component.ts
@@ -16,33 +16,20 @@
  *
  */
 
-import {
-  Component,
-  EventEmitter,
-  Input,
-  OnChanges,
-  OnInit,
-  Output,
-  QueryList,
-  SimpleChanges,
-  ViewChildren
-} from '@angular/core';
+import { Component, EventEmitter, Input, OnChanges, OnInit, Output, QueryList, SimpleChanges, ViewChildren } from '@angular/core';
 import { GridsterItemComponent, GridType } from 'angular-gridster2';
 import { GridsterInfo } from '../../../dashboard/models/gridster-info.model';
-import { IDataViewDashboardConfig, } from '../../models/dataview-dashboard.model';
-import { DataViewDataExplorerService } from '../../services/data-view-data-explorer.service';
+import { IDataViewDashboardConfig } from '../../models/dataview-dashboard.model';
+import { DataViewDataExplorerService } from '../../../platform-services/apis/data-view-data-explorer.service';
 import { ResizeService } from '../../services/resize.service';
-import {
-  DataExplorerWidgetModel,
-  DataLakeMeasure
-} from '../../../core-model/gen/streampipes-model';
+import { DataExplorerWidgetModel, DataLakeMeasure } from '../../../core-model/gen/streampipes-model';
 import { Tuple2 } from '../../../core-model/base/Tuple2';
-import { Dashboard, DashboardItem, TimeSettings } from '../../../dashboard/models/dashboard.model';
+import { Dashboard, TimeSettings } from '../../../dashboard/models/dashboard.model';
 
 @Component({
   selector: 'sp-data-explorer-dashboard-grid',
   templateUrl: './data-explorer-dashboard-grid.component.html',
-  styleUrls: ['./data-explorer-dashboard-grid.component.scss'],
+  styleUrls: ['./data-explorer-dashboard-grid.component.scss']
 })
 export class DataExplorerDashboardGridComponent implements OnInit, OnChanges {
 
@@ -77,7 +64,7 @@ export class DataExplorerDashboardGridComponent implements OnInit, OnChanges {
   ngOnInit(): void {
     this.options = {
       disablePushOnDrag: true,
-      draggable: {enabled: this.editMode},
+      draggable: { enabled: this.editMode },
       gridType: GridType.VerticalFixed,
       minCols: 8,
       maxCols: 8,
@@ -86,7 +73,7 @@ export class DataExplorerDashboardGridComponent implements OnInit, OnChanges {
       fixedColWidth: 100,
       margin: 5,
       displayGrid: this.editMode ? 'always' : 'none',
-      resizable: {enabled: this.editMode},
+      resizable: { enabled: this.editMode },
       itemResizeCallback: ((item, itemComponent) => {
         this.resizeService.notify({
           gridsterItem: item,
@@ -125,7 +112,7 @@ export class DataExplorerDashboardGridComponent implements OnInit, OnChanges {
       this.dataViewDataExplorerService.getPersistedDataStream(response.pipelineId, response.measureName).subscribe(ps => {
         this.dataLakeMeasures.set(widgetId, ps);
         if (setCurrentlyConfigured) {
-          this.propagateWidgetSelection({a: this.configuredWidgets.get(widgetId), b: this.dataLakeMeasures.get(widgetId)});
+          this.propagateWidgetSelection({ a: this.configuredWidgets.get(widgetId), b: this.dataLakeMeasures.get(widgetId) });
         }
       });
     });
diff --git a/ui/src/app/data-explorer/components/overview/data-explorer-dashboard-overview.component.ts b/ui/src/app/data-explorer/components/overview/data-explorer-dashboard-overview.component.ts
index c0e4b00..5c6ef8a 100644
--- a/ui/src/app/data-explorer/components/overview/data-explorer-dashboard-overview.component.ts
+++ b/ui/src/app/data-explorer/components/overview/data-explorer-dashboard-overview.component.ts
@@ -19,78 +19,78 @@
 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
 import { MatTableDataSource } from '@angular/material/table';
 import { DataExplorerEditDataViewDialogComponent } from '../../dialogs/edit-dashboard/data-explorer-edit-data-view-dialog.component';
-import { DataViewDataExplorerService } from '../../services/data-view-data-explorer.service';
+import { DataViewDataExplorerService } from '../../../platform-services/apis/data-view-data-explorer.service';
 import { Dashboard } from '../../../dashboard/models/dashboard.model';
 import { Tuple2 } from '../../../core-model/base/Tuple2';
 import { PanelType } from '../../../core-ui/dialog/base-dialog/base-dialog.model';
 import { DialogService } from '../../../core-ui/dialog/base-dialog/base-dialog.service';
 
 @Component({
-    selector: 'sp-data-explorer-dashboard-overview',
-    templateUrl: './data-explorer-dashboard-overview.component.html',
-    styleUrls: ['./data-explorer-dashboard-overview.component.scss']
+  selector: 'sp-data-explorer-dashboard-overview',
+  templateUrl: './data-explorer-dashboard-overview.component.html',
+  styleUrls: ['./data-explorer-dashboard-overview.component.scss']
 })
 export class DataExplorerDashboardOverviewComponent implements OnInit {
 
-    @Input() dataViewDashboards: Dashboard[];
-    @Output() reloadDashboardsEmitter = new EventEmitter<void>();
-    @Output() selectDashboardEmitter = new EventEmitter<Tuple2<Dashboard, boolean>>();
-
-    dataSource = new MatTableDataSource<Dashboard>();
-    displayedColumns: string[] = ['name', 'open', 'edit', 'delete'];
-
-    editLabels: boolean;
-
-    constructor(private dashboardService: DataViewDataExplorerService,
-                public dialogService: DialogService) {
-
-    }
-
-    ngOnInit(): void {
-        this.dataSource.data = this.dataViewDashboards;
-        this.editLabels = false;
-    }
-
-    openNewDataViewDialog() {
-        const dataViewDashboard: Dashboard = {};
-        dataViewDashboard.widgets = [];
-
-        this.openDataViewModificationDialog(true, dataViewDashboard);
-    }
-
-    openEditLabelView() {
-       this.editLabels = true;
-    }
-
-    openDataViewModificationDialog(createMode: boolean, dashboard: Dashboard) {
-        const dialogRef = this.dialogService.open(DataExplorerEditDataViewDialogComponent, {
-            panelType: PanelType.STANDARD_PANEL,
-            title: createMode ? 'New Data View' : 'Edit Data View',
-            width: '70vw',
-            data: {
-                'createMode': createMode,
-                'dashboard': dashboard
-            }
-        });
-
-        dialogRef.afterClosed().subscribe(result => {
-            this.reloadDashboardsEmitter.emit();
-        });
-    }
-
-    openEditDataViewDialog(dashboard: Dashboard) {
-        this.openDataViewModificationDialog(false, dashboard);
-    }
-
-    openDeleteDashboardDialog(dashboard: Dashboard) {
-        // TODO add confirm dialog
-        this.dashboardService.deleteDashboard(dashboard).subscribe(result => {
-            this.reloadDashboardsEmitter.emit();
-        });
-    }
-
-    showDashboard(dashboard: Dashboard, editMode: boolean) {
-        const dashboardSettings: Tuple2<Dashboard, boolean> = {a: dashboard, b: editMode};
-        this.selectDashboardEmitter.emit(dashboardSettings);
-    }
+  @Input() dataViewDashboards: Dashboard[];
+  @Output() reloadDashboardsEmitter = new EventEmitter<void>();
+  @Output() selectDashboardEmitter = new EventEmitter<Tuple2<Dashboard, boolean>>();
+
+  dataSource = new MatTableDataSource<Dashboard>();
+  displayedColumns: string[] = ['name', 'open', 'edit', 'delete'];
+
+  editLabels: boolean;
+
+  constructor(private dashboardService: DataViewDataExplorerService,
+              public dialogService: DialogService) {
+
+  }
+
+  ngOnInit(): void {
+    this.dataSource.data = this.dataViewDashboards;
+    this.editLabels = false;
+  }
+
+  openNewDataViewDialog() {
+    const dataViewDashboard: Dashboard = {};
+    dataViewDashboard.widgets = [];
+
+    this.openDataViewModificationDialog(true, dataViewDashboard);
+  }
+
+  openEditLabelView() {
+    this.editLabels = true;
+  }
+
+  openDataViewModificationDialog(createMode: boolean, dashboard: Dashboard) {
+    const dialogRef = this.dialogService.open(DataExplorerEditDataViewDialogComponent, {
+      panelType: PanelType.STANDARD_PANEL,
+      title: createMode ? 'New Data View' : 'Edit Data View',
+      width: '70vw',
+      data: {
+        'createMode': createMode,
+        'dashboard': dashboard
+      }
+    });
+
+    dialogRef.afterClosed().subscribe(result => {
+      this.reloadDashboardsEmitter.emit();
+    });
+  }
+
+  openEditDataViewDialog(dashboard: Dashboard) {
+    this.openDataViewModificationDialog(false, dashboard);
+  }
+
+  openDeleteDashboardDialog(dashboard: Dashboard) {
+    // TODO add confirm dialog
+    this.dashboardService.deleteDashboard(dashboard).subscribe(result => {
+      this.reloadDashboardsEmitter.emit();
+    });
+  }
+
+  showDashboard(dashboard: Dashboard, editMode: boolean) {
+    const dashboardSettings: Tuple2<Dashboard, boolean> = { a: dashboard, b: editMode };
+    this.selectDashboardEmitter.emit(dashboardSettings);
+  }
 }
diff --git a/ui/src/app/data-explorer/components/panel/data-explorer-dashboard-panel.component.ts b/ui/src/app/data-explorer/components/panel/data-explorer-dashboard-panel.component.ts
index 8fcb4ae..24e7a00 100644
--- a/ui/src/app/data-explorer/components/panel/data-explorer-dashboard-panel.component.ts
+++ b/ui/src/app/data-explorer/components/panel/data-explorer-dashboard-panel.component.ts
@@ -19,12 +19,9 @@
 import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
 import { MatDialog } from '@angular/material/dialog';
 import { Observable } from 'rxjs';
-import { DataViewDataExplorerService } from '../../services/data-view-data-explorer.service';
+import { DataViewDataExplorerService } from '../../../platform-services/apis/data-view-data-explorer.service';
 import { RefreshDashboardService } from '../../services/refresh-dashboard.service';
-import {
-  DataExplorerWidgetModel,
-  DataLakeMeasure
-} from '../../../core-model/gen/streampipes-model';
+import { DataExplorerWidgetModel, DataLakeMeasure } from '../../../core-model/gen/streampipes-model';
 import { DataExplorerDashboardGridComponent } from '../grid/data-explorer-dashboard-grid.component';
 import { MatDrawer } from '@angular/material/sidenav';
 import { Tuple2 } from '../../../core-model/base/Tuple2';
diff --git a/ui/src/app/data-explorer/components/widget/data-explorer-dashboard-widget.component.ts b/ui/src/app/data-explorer/components/widget/data-explorer-dashboard-widget.component.ts
index 34ea154..a78fd97 100644
--- a/ui/src/app/data-explorer/components/widget/data-explorer-dashboard-widget.component.ts
+++ b/ui/src/app/data-explorer/components/widget/data-explorer-dashboard-widget.component.ts
@@ -18,16 +18,13 @@
 
 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
 import { MatDialog } from '@angular/material/dialog';
-import { GridsterItem, GridsterItemComponent } from 'angular-gridster2';
+import { GridsterItemComponent } from 'angular-gridster2';
 import { DateRange } from '../../../core-model/datalake/DateRange';
-import { DataViewDataExplorerService } from '../../services/data-view-data-explorer.service';
-import {
-  DataExplorerWidgetModel,
-  DataLakeMeasure
-} from '../../../core-model/gen/streampipes-model';
+import { DataViewDataExplorerService } from '../../../platform-services/apis/data-view-data-explorer.service';
+import { DataExplorerWidgetModel, DataLakeMeasure } from '../../../core-model/gen/streampipes-model';
 import { DataDownloadDialog } from '../datadownloadDialog/dataDownload.dialog';
 import { Tuple2 } from '../../../core-model/base/Tuple2';
-import { Dashboard, DashboardItem, TimeSettings } from '../../../dashboard/models/dashboard.model';
+import { DashboardItem, TimeSettings } from '../../../dashboard/models/dashboard.model';
 
 @Component({
   selector: 'sp-data-explorer-dashboard-widget',
@@ -60,7 +57,7 @@ export class DataExplorerDashboardWidgetComponent implements OnInit {
   @Output() deleteCallback: EventEmitter<DataExplorerWidgetModel> = new EventEmitter<DataExplorerWidgetModel>();
   @Output() updateCallback: EventEmitter<DataExplorerWidgetModel> = new EventEmitter<DataExplorerWidgetModel>();
   @Output() configureWidgetCallback: EventEmitter<Tuple2<DataExplorerWidgetModel, DataLakeMeasure>>
-      = new EventEmitter<Tuple2<DataExplorerWidgetModel, DataLakeMeasure>>();
+    = new EventEmitter<Tuple2<DataExplorerWidgetModel, DataLakeMeasure>>();
 
   title = '';
   widgetLoaded = false;
@@ -90,6 +87,6 @@ export class DataExplorerDashboardWidgetComponent implements OnInit {
   }
 
   triggerWidgetEditMode() {
-    this.configureWidgetCallback.emit({a: this.configuredWidget, b: this.dataLakeMeasure});
+    this.configureWidgetCallback.emit({ a: this.configuredWidget, b: this.dataLakeMeasure });
   }
 }
diff --git a/ui/src/app/data-explorer/data-explorer.component.ts b/ui/src/app/data-explorer/data-explorer.component.ts
index 9333daa..f73d398 100644
--- a/ui/src/app/data-explorer/data-explorer.component.ts
+++ b/ui/src/app/data-explorer/data-explorer.component.ts
@@ -17,7 +17,7 @@
  */
 
 import { Component, OnInit, ViewChild } from '@angular/core';
-import { DataViewDataExplorerService } from './services/data-view-data-explorer.service';
+import { DataViewDataExplorerService } from '../platform-services/apis/data-view-data-explorer.service';
 import { RefreshDashboardService } from './services/refresh-dashboard.service';
 import { DataExplorerDashboardPanelComponent } from './components/panel/data-explorer-dashboard-panel.component';
 import { Dashboard, TimeSettings } from '../dashboard/models/dashboard.model';
@@ -52,7 +52,7 @@ export class DataExplorerComponent implements OnInit {
 
   public ngOnInit() {
     this.route.queryParams.subscribe(params => {
-      this.routeParams = {startTime: params['startTime'], endTime: params['endTime'], dashboardId: params['dashboardId']};
+      this.routeParams = { startTime: params['startTime'], endTime: params['endTime'], dashboardId: params['dashboardId'] };
       this.getDashboards();
     });
     this.refreshDashboardService.refreshSubject.subscribe(currentDashboardId => {
diff --git a/ui/src/app/data-explorer/data-explorer.module.ts b/ui/src/app/data-explorer/data-explorer.module.ts
index ffe31a9..75fe001 100644
--- a/ui/src/app/data-explorer/data-explorer.module.ts
+++ b/ui/src/app/data-explorer/data-explorer.module.ts
@@ -29,11 +29,7 @@ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
 import { MatSliderModule } from '@angular/material/slider';
 import { MatSnackBarModule } from '@angular/material/snack-bar';
 import { MatTabsModule } from '@angular/material/tabs';
-import {
-  OWL_DATE_TIME_FORMATS,
-  OwlDateTimeModule,
-  OwlNativeDateTimeModule
-} from '@danielmoncada/angular-datetime-picker';
+import { OWL_DATE_TIME_FORMATS, OwlDateTimeModule, OwlNativeDateTimeModule } from '@danielmoncada/angular-datetime-picker';
 import { NgxChartsModule } from '@swimlane/ngx-charts';
 import { GridsterModule } from 'angular-gridster2';
 import { PlotlyViaWindowModule } from 'angular-plotly.js';
@@ -57,7 +53,7 @@ import { NoDataInDateRangeComponent } from './components/widgets/utils/no-data/n
 import { SelectPropertiesComponent } from './components/widgets/utils/select-properties/select-properties.component';
 import { DataExplorerComponent } from './data-explorer.component';
 import { DataExplorerEditDataViewDialogComponent } from './dialogs/edit-dashboard/data-explorer-edit-data-view-dialog.component';
-import { DataViewDataExplorerService } from './services/data-view-data-explorer.service';
+import { DataViewDataExplorerService } from '../platform-services/apis/data-view-data-explorer.service';
 import { RefreshDashboardService } from './services/refresh-dashboard.service';
 import { ResizeService } from './services/resize.service';
 import { GroupConfigurationComponent } from './components/widgets/utils/group-configuration/group-configuration.component';
@@ -89,11 +85,11 @@ export const MY_NATIVE_FORMATS = {
     minute: 'numeric',
     hour12: false
   },
-  datePickerInput: {year: 'numeric', month: 'numeric', day: 'numeric', hour12: false},
-  timePickerInput: {hour: 'numeric', minute: 'numeric', hour12: false},
-  monthYearLabel: {year: 'numeric', month: 'short', hour12: false},
-  dateA11yLabel: {year: 'numeric', month: 'long', day: 'numeric', hour12: false},
-  monthYearA11yLabel: {year: 'numeric', month: 'long', hour12: false}
+  datePickerInput: { year: 'numeric', month: 'numeric', day: 'numeric', hour12: false },
+  timePickerInput: { hour: 'numeric', minute: 'numeric', hour12: false },
+  monthYearLabel: { year: 'numeric', month: 'short', hour12: false },
+  dateA11yLabel: { year: 'numeric', month: 'long', day: 'numeric', hour12: false },
+  monthYearA11yLabel: { year: 'numeric', month: 'long', hour12: false }
 };
 
 
@@ -153,7 +149,7 @@ export const MY_NATIVE_FORMATS = {
     SelectPropertiesComponent,
     TableWidgetComponent,
     TableWidgetConfigComponent,
-    TimeRangeSelectorComponent,
+    TimeRangeSelectorComponent
   ],
   providers: [
     DatalakeRestService,
diff --git a/ui/src/app/data-explorer/dialogs/edit-dashboard/data-explorer-edit-data-view-dialog.component.ts b/ui/src/app/data-explorer/dialogs/edit-dashboard/data-explorer-edit-data-view-dialog.component.ts
index c2004f4..955a024 100644
--- a/ui/src/app/data-explorer/dialogs/edit-dashboard/data-explorer-edit-data-view-dialog.component.ts
+++ b/ui/src/app/data-explorer/dialogs/edit-dashboard/data-explorer-edit-data-view-dialog.component.ts
@@ -17,45 +17,44 @@
  */
 
 import { Component, Input, OnInit } from '@angular/core';
-import { DataViewDataExplorerService } from '../../services/data-view-data-explorer.service';
+import { DataViewDataExplorerService } from '../../../platform-services/apis/data-view-data-explorer.service';
 import { Dashboard } from '../../../dashboard/models/dashboard.model';
 import { DialogRef } from '../../../core-ui/dialog/base-dialog/dialog-ref';
 
 @Component({
-    selector: 'sp-data-explorer-edit-data-view-dialog-component',
-    templateUrl: './data-explorer-edit-data-view-dialog.component.html',
-    styleUrls: ['./data-explorer-edit-data-view-dialog.component.scss']
+  selector: 'sp-data-explorer-edit-data-view-dialog-component',
+  templateUrl: './data-explorer-edit-data-view-dialog.component.html',
+  styleUrls: ['./data-explorer-edit-data-view-dialog.component.scss']
 })
 export class DataExplorerEditDataViewDialogComponent implements OnInit {
 
-    @Input() createMode: boolean;
-    @Input() dashboard: Dashboard;
+  @Input() createMode: boolean;
+  @Input() dashboard: Dashboard;
 
-    constructor(
-        private dialogRef: DialogRef<DataExplorerEditDataViewDialogComponent>,
-        private dashboardService: DataViewDataExplorerService) {
-    }
+  constructor(
+    private dialogRef: DialogRef<DataExplorerEditDataViewDialogComponent>,
+    private dashboardService: DataViewDataExplorerService) {
+  }
 
-    ngOnInit() {
+  ngOnInit() {
 
-    }
+  }
 
-    onCancel(): void {
-        this.dialogRef.close();
-    }
+  onCancel(): void {
+    this.dialogRef.close();
+  }
 
-    onSave(): void {
-        if (this.createMode) {
-            this.dashboardService.saveDataView(this.dashboard).subscribe(() => {
-                this.dialogRef.close();
-            });
-        } else {
-            this.dashboardService.updateDashboard(this.dashboard).subscribe( () => {
-                this.dialogRef.close();
-            });
-        }
+  onSave(): void {
+    if (this.createMode) {
+      this.dashboardService.saveDataView(this.dashboard).subscribe(() => {
+        this.dialogRef.close();
+      });
+    } else {
+      this.dashboardService.updateDashboard(this.dashboard).subscribe(() => {
+        this.dialogRef.close();
+      });
     }
-
+  }
 
 
 }
diff --git a/ui/src/app/data-explorer/services/data-view-data-explorer.service.ts b/ui/src/app/platform-services/apis/data-view-data-explorer.service.ts
similarity index 91%
rename from ui/src/app/data-explorer/services/data-view-data-explorer.service.ts
rename to ui/src/app/platform-services/apis/data-view-data-explorer.service.ts
index e8a7100..4b17bab 100644
--- a/ui/src/app/data-explorer/services/data-view-data-explorer.service.ts
+++ b/ui/src/app/platform-services/apis/data-view-data-explorer.service.ts
@@ -21,10 +21,10 @@ import { Observable } from 'rxjs';
 import { map } from 'rxjs/operators';
 import { SharedDatalakeRestService } from '../../core-services/shared/shared-dashboard.service';
 import { AuthStatusService } from '../../services/auth-status.service';
-import { DataExplorerWidgetModel, DataLakeMeasure, } from '../../core-model/gen/streampipes-model';
+import { DataExplorerWidgetModel, DataLakeMeasure } from '../../core-model/gen/streampipes-model';
 import { Dashboard } from '../../dashboard/models/dashboard.model';
 import { Injectable } from '@angular/core';
-import { DatalakeRestService } from '../../platform-services/apis/datalake-rest.service';
+import { DatalakeRestService } from './datalake-rest.service';
 
 
 @Injectable()
@@ -98,13 +98,13 @@ export class DataViewDataExplorerService {
 
   getPersistedDataStream(pipelineId: string, measureName: string): Observable<DataLakeMeasure> {
     return this.http.get(`${this.persistedDataStreamsUrl}/${pipelineId}/${measureName}`)
-        .pipe(map(response => DataLakeMeasure.fromData(response as any)));
+      .pipe(map(response => DataLakeMeasure.fromData(response as any)));
   }
 
   getAllPersistedDataStreams(): Observable<DataLakeMeasure[]> {
     return this.http.get(this.persistedDataStreamsUrl)
-        .pipe(map(response => {
-          return (response as any[]).map(p => DataLakeMeasure.fromData(p));
-        }));
+      .pipe(map(response => {
+        return (response as any[]).map(p => DataLakeMeasure.fromData(p));
+      }));
   }
 }
diff --git a/ui/src/app/platform-services/apis/datalake-rest.service.ts b/ui/src/app/platform-services/apis/datalake-rest.service.ts
index 2b4857d..e89a9f8 100644
--- a/ui/src/app/platform-services/apis/datalake-rest.service.ts
+++ b/ui/src/app/platform-services/apis/datalake-rest.service.ts
@@ -29,172 +29,184 @@ import { GroupedDataResult } from '../../core-model/datalake/GroupedDataResult';
 
 @Injectable()
 export class DatalakeRestService {
-    constructor(private http: HttpClient,
-                private authStatusService: AuthStatusService) {
+  constructor(private http: HttpClient,
+              private authStatusService: AuthStatusService) {
+  }
+
+  private get baseUrl() {
+    return '/streampipes-backend';
+  }
+
+  private get dataLakeUrl() {
+    return this.baseUrl + '/api/v4/users/' + this.authStatusService.email + '/datalake';
+  }
+
+  getAllMeasurementSeries(): Observable<DataLakeMeasure[]> {
+    const url = this.dataLakeUrl + '/measurements/';
+    return this.http.get(url).pipe(map(response => {
+      return (response as any[]).map(p => DataLakeMeasure.fromData(p));
+    }));
+  }
+
+  getData(index: string,
+          queryParams: DatalakeQueryParameters): Observable<DataResult> {
+    const url = this.dataLakeUrl + '/measurements/' + index;
+
+    // @ts-ignore
+    return this.http.get<DataResult>(url, { params: queryParams });
+  }
+
+  // getData(index, startDate, endDate, columns, aggregationFunction, aggregationTimeUnit, aggregationTimeValue): Observable<DataResult> {
+  //     const timeInterval = aggregationTimeValue + aggregationTimeUnit;
+  //
+  //     const queryParams: DatalakeQueryParameters = this.getQueryParameters(columns, startDate, endDate, undefined, undefined,
+  //         undefined, undefined, undefined, aggregationFunction, timeInterval);
+  //
+  //     // @ts-ignore
+  //     return this.http.get<DataResult>(url, {params: queryParams});
+  // }
+
+  getPagedData(index: string, itemsPerPage: number, page: number, columns?: string, order?: string): Observable<PageResult> {
+    const url = this.dataLakeUrl + '/measurements/' + index;
+
+    const queryParams: DatalakeQueryParameters = this.getQueryParameters(columns, undefined, undefined, page,
+      itemsPerPage, undefined, undefined, order, undefined, undefined);
+
+    // @ts-ignore
+    return this.http.get<PageResult>(url, { params: queryParams });
+  }
+
+  getGroupedData(index: string, groupingTags: string, aggregationFunction?: string, columns?: string, startDate?: number, endDate?:
+    number, aggregationTimeUnit?: string, aggregationTimeValue?: number, order?: string, limit?: number):
+    Observable<GroupedDataResult> {
+
+    const url = this.dataLakeUrl + '/measurements/' + index;
+    let _aggregationFunction = 'mean';
+    let timeInterval = '2000ms';
+
+    if (aggregationFunction) {
+      _aggregationFunction = aggregationFunction;
     }
 
-    private get baseUrl() {
-        return '/streampipes-backend';
+    if (aggregationTimeUnit && aggregationTimeValue) {
+      timeInterval = aggregationTimeValue + aggregationTimeUnit;
     }
 
-    private get dataLakeUrl() {
-        return this.baseUrl + '/api/v4/users/' + this.authStatusService.email + '/datalake';
+    const queryParams: DatalakeQueryParameters = this.getQueryParameters(columns, startDate, endDate, undefined, limit,
+      undefined, groupingTags, order, _aggregationFunction, timeInterval);
+
+    // @ts-ignore
+    return this.http.get<GroupedDataResult>(url, { params: queryParams });
+  }
+
+  downloadRawData(index, format) {
+    const url = this.dataLakeUrl + '/measurements/' + index + '/download?format=' + format;
+
+    const request = new HttpRequest('GET', url, {
+      reportProgress: true,
+      responseType: 'text'
+    });
+
+    return this.http.request(request);
+  }
+
+  downloadQueriedData(
+    index,
+    format,
+    startDate?,
+    endDate?,
+    columns?,
+    aggregationFunction?,
+    aggregationTimeUnit?,
+    aggregationTimeValue?,
+    groupingsTags?,
+    order?,
+    limit?,
+    offset?) {
+    const url = this.dataLakeUrl + '/measurements/' + index + '/download?format=' + format;
+    const timeInterval = aggregationTimeValue + aggregationTimeUnit;
+
+    const queryParams: DatalakeQueryParameters = this.getQueryParameters(columns, startDate, endDate, undefined,
+      limit, offset, groupingsTags, order, aggregationFunction, timeInterval);
+
+    const request = new HttpRequest('GET', url, {
+      reportProgress: true,
+      responseType: 'text',
+      params: queryParams
+    });
+
+    return this.http.request(request);
+  }
+
+  removeData(index: string, startDate?: number, endDate?: number) {
+    const url = this.dataLakeUrl + '/measurements/' + index;
+
+    const queryParams: DatalakeQueryParameters = this.getQueryParameters(undefined, startDate, endDate, undefined,
+      undefined, undefined, undefined, undefined, undefined, undefined);
+
+    const request = new HttpRequest('DELETE', url, {
+      reportProgress: true,
+      responseType: 'text',
+      params: queryParams
+    });
+
+    return this.http.request(request);
+  }
+
+  dropSingleMeasurementSeries(index: string) {
+    const url = this.dataLakeUrl + '/measurements/' + index + '/drop';
+    return this.http.delete(url);
+  }
+
+  dropAllMeasurementSeries() {
+    const url = this.dataLakeUrl + '/measurements/';
+    return this.http.delete(url);
+  }
+
+  private getQueryParameters(columns?: string, startDate?: number, endDate?: number, page?: number, limit?: number,
+                             offset?: number, groupBy?: string, order?: string, aggregationFunction?: string, timeInterval?: string):
+    DatalakeQueryParameters {
+    const queryParams: DatalakeQueryParameters = new DatalakeQueryParameters();
+
+    if (columns) {
+      queryParams.columns = columns;
     }
 
-    getAllMeasurementSeries(): Observable<DataLakeMeasure[]> {
-        const url = this.dataLakeUrl + '/measurements/';
-        return this.http.get(url).pipe(map(response => {
-            return (response as any[]).map(p => DataLakeMeasure.fromData(p));
-        }));
+    if (startDate) {
+      queryParams.startDate = startDate;
     }
 
-    getData(index: string,
-            queryParams: DatalakeQueryParameters): Observable<DataResult> {
-        const url = this.dataLakeUrl + '/measurements/' + index;
-
-        // @ts-ignore
-        return this.http.get<DataResult>(url, {params: queryParams});
+    if (endDate) {
+      queryParams.endDate = endDate;
     }
-
-    // getData(index, startDate, endDate, columns, aggregationFunction, aggregationTimeUnit, aggregationTimeValue): Observable<DataResult> {
-    //     const timeInterval = aggregationTimeValue + aggregationTimeUnit;
-    //
-    //     const queryParams: DatalakeQueryParameters = this.getQueryParameters(columns, startDate, endDate, undefined, undefined,
-    //         undefined, undefined, undefined, aggregationFunction, timeInterval);
-    //
-    //     // @ts-ignore
-    //     return this.http.get<DataResult>(url, {params: queryParams});
-    // }
-
-    getPagedData(index: string, itemsPerPage: number, page: number, columns?: string, order?: string): Observable<PageResult> {
-        const url = this.dataLakeUrl + '/measurements/' + index;
-
-        const queryParams: DatalakeQueryParameters = this.getQueryParameters(columns, undefined, undefined, page,
-            itemsPerPage, undefined, undefined, order, undefined, undefined);
-
-        // @ts-ignore
-        return this.http.get<PageResult>(url, {params: queryParams});
+    if (page) {
+      queryParams.page = page;
     }
 
-    getGroupedData(index: string, groupingTags: string, aggregationFunction?: string, columns?: string, startDate?: number, endDate?:
-        number, aggregationTimeUnit?: string, aggregationTimeValue?: number, order?: string, limit?: number):
-        Observable<GroupedDataResult> {
-
-        const url = this.dataLakeUrl + '/measurements/' + index;
-        let _aggregationFunction = 'mean';
-        let timeInterval = '2000ms';
-
-        if (aggregationFunction) {
-            _aggregationFunction = aggregationFunction;
-        }
-
-        if (aggregationTimeUnit && aggregationTimeValue) {
-            timeInterval = aggregationTimeValue + aggregationTimeUnit;
-        }
-
-        const queryParams: DatalakeQueryParameters = this.getQueryParameters(columns, startDate, endDate, undefined, limit,
-            undefined, groupingTags, order, _aggregationFunction, timeInterval);
-
-        // @ts-ignore
-        return this.http.get<GroupedDataResult>(url, {params: queryParams});
+    if (limit) {
+      queryParams.limit = limit;
     }
 
-    downloadRawData(index, format) {
-        const url = this.dataLakeUrl + '/measurements/' + index + '/download?format=' + format;
-
-        const request = new HttpRequest('GET', url, {
-            reportProgress: true,
-            responseType: 'text'
-        });
-
-        return this.http.request(request);
+    if (offset) {
+      queryParams.offset = offset;
     }
 
-    downloadQueriedData(index, format, startDate?, endDate?, columns?, aggregationFunction?, aggregationTimeUnit?, aggregationTimeValue?, groupingsTags?, order?, limit?, offset?) {
-        const url = this.dataLakeUrl + '/measurements/' + index + '/download?format=' + format;
-        const timeInterval = aggregationTimeValue + aggregationTimeUnit;
-
-        const queryParams: DatalakeQueryParameters = this.getQueryParameters(columns, startDate, endDate, undefined,
-            limit, offset, groupingsTags, order, aggregationFunction, timeInterval);
-
-        const request = new HttpRequest('GET', url, {
-            reportProgress: true,
-            responseType: 'text',
-            params: queryParams
-        },);
-
-        return this.http.request(request);
+    if (groupBy) {
+      queryParams.groupBy = groupBy;
     }
 
-    removeData(index: string, startDate?: number, endDate?: number) {
-        const url = this.dataLakeUrl + '/measurements/' + index;
-
-        const queryParams: DatalakeQueryParameters = this.getQueryParameters(undefined, startDate, endDate, undefined,
-            undefined, undefined, undefined, undefined, undefined, undefined);
-
-        const request = new HttpRequest('DELETE', url, {
-            reportProgress: true,
-            responseType: 'text',
-            params: queryParams
-        });
-
-        return this.http.request(request);
+    if (order) {
+      queryParams.order = order;
     }
 
-    dropSingleMeasurementSeries(index: string) {
-        const url = this.dataLakeUrl + '/measurements/' + index + '/drop';
-        return this.http.delete(url);
+    if (aggregationFunction) {
+      queryParams.aggregationFunction = aggregationFunction;
     }
 
-    dropAllMeasurementSeries() {
-        const url = this.dataLakeUrl + '/measurements/';
-        return this.http.delete(url);
+    if (timeInterval) {
+      queryParams.timeInterval = timeInterval;
     }
 
-    private getQueryParameters(columns?: string, startDate?: number, endDate?: number, page?: number, limit?: number,
-                               offset?: number, groupBy?: string, order?: string, aggregationFunction?: string, timeInterval?: string):
-        DatalakeQueryParameters {
-        const queryParams: DatalakeQueryParameters = new DatalakeQueryParameters();
-
-        if (columns) {
-            queryParams.columns = columns;
-        }
-
-        if (startDate) {
-            queryParams.startDate = startDate;
-        }
-
-        if (endDate) {
-            queryParams.endDate = endDate;
-        }
-        if (page) {
-            queryParams.page = page;
-        }
-
-        if (limit) {
-            queryParams.limit = limit;
-        }
-
-        if (offset) {
-            queryParams.offset = offset;
-        }
-
-        if (groupBy) {
-            queryParams.groupBy = groupBy;
-        }
-
-        if (order) {
-            queryParams.order = order;
-        }
-
-        if (aggregationFunction) {
-            queryParams.aggregationFunction = aggregationFunction;
-        }
-
-        if (timeInterval) {
-            queryParams.timeInterval = timeInterval;
-        }
-
-        return queryParams;
-    }
+    return queryParams;
+  }
 }

[incubator-streampipes] 02/02: [STREAMPIPES-79] Meadurements in data explorer can be truncated

Posted by ze...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

zehnder pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/incubator-streampipes.git

commit 98e43434dd583265c47a32414e4135a2950310b0
Author: Philipp Zehnder <ze...@fzi.de>
AuthorDate: Tue Aug 31 17:32:55 2021 +0200

    [STREAMPIPES-79] Meadurements in data explorer can be truncated
---
 .../dataexplorer/v4/query/DataExplorerQueryV4.java |  2 +-
 ui/src/app/configuration/configuration.module.ts   | 62 +++++++++++-----------
 .../datalake-configuration.component.html          | 15 +++---
 .../datalake-configuration.component.ts            | 28 +++++++---
 .../delete-datalake-index-dialog.component.html    | 48 +++++++++++++++++
 .../delete-datalake-index-dialog.component.scss    | 19 +++++++
 .../delete-datalake-index-dialog.component.ts      | 61 +++++++++++++++++++++
 .../datalake/DatalakeQueryParameterBuilder.ts      |  9 ++--
 .../apis/datalake-rest.service.ts                  | 13 +----
 9 files changed, 198 insertions(+), 59 deletions(-)

diff --git a/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/query/DataExplorerQueryV4.java b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/query/DataExplorerQueryV4.java
index 799d89c..ee0847a 100644
--- a/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/query/DataExplorerQueryV4.java
+++ b/streampipes-data-explorer/src/main/java/org/apache/streampipes/dataexplorer/v4/query/DataExplorerQueryV4.java
@@ -108,7 +108,7 @@ public class DataExplorerQueryV4 {
         if (this.params.containsKey(DataLakeManagementUtils.SELECT_FROM)) {
             queryElements.add(new SelectFromStatement((SelectFromStatementParams) this.params.get(DataLakeManagementUtils.SELECT_FROM)));
         } else {
-            queryElements.add(new DeleteFromStatement((DeleteFromStatementParams) this.params.get(DataLakeManagementUtils.SELECT_FROM)));
+            queryElements.add(new DeleteFromStatement((DeleteFromStatementParams) this.params.get(DataLakeManagementUtils.DELETE_FROM)));
         }
 
         if (this.params.containsKey(DataLakeManagementUtils.WHERE)) {
diff --git a/ui/src/app/configuration/configuration.module.ts b/ui/src/app/configuration/configuration.module.ts
index 8248189..92828c5 100644
--- a/ui/src/app/configuration/configuration.module.ts
+++ b/ui/src/app/configuration/configuration.module.ts
@@ -41,38 +41,40 @@ import { MessagingConfigurationComponent } from './messaging-configuration/messa
 import { DragDropModule } from '@angular/cdk/drag-drop';
 import { DatalakeConfigurationComponent } from './datalake-configuration/datalake-configuration.component';
 import { DatalakeRestService } from '../core-services/datalake/datalake-rest.service';
+import { DeleteDatalakeIndexComponent } from './dialog/delete-datalake-index/delete-datalake-index-dialog.component';
 
 @NgModule({
-    imports: [
-        CommonModule,
-        CustomMaterialModule,
-        FlexLayoutModule,
-        MatGridListModule,
-        MatButtonModule,
-        MatIconModule,
-        MatInputModule,
-        MatCheckboxModule,
-        MatTooltipModule,
-        FormsModule,
-        DragDropModule
-    ],
-    declarations: [
-        ConfigurationComponent,
-        ConsulServiceComponent,
-        ConsulConfigsComponent,
-        ConsulConfigsTextComponent,
-        ConsulConfigsPasswordComponent,
-        ConsulConfigsBooleanComponent,
-        ConsulConfigsNumberComponent,
-        PipelineElementConfigurationComponent,
-        MessagingConfigurationComponent,
-        DatalakeConfigurationComponent
-    ],
-    providers: [
-      ConfigurationService,
-      DatalakeRestService
-    ],
-    entryComponents: [ConfigurationComponent],
+  imports: [
+    CommonModule,
+    CustomMaterialModule,
+    FlexLayoutModule,
+    MatGridListModule,
+    MatButtonModule,
+    MatIconModule,
+    MatInputModule,
+    MatCheckboxModule,
+    MatTooltipModule,
+    FormsModule,
+    DragDropModule
+  ],
+  declarations: [
+    ConfigurationComponent,
+    ConsulServiceComponent,
+    ConsulConfigsComponent,
+    ConsulConfigsTextComponent,
+    ConsulConfigsPasswordComponent,
+    ConsulConfigsBooleanComponent,
+    ConsulConfigsNumberComponent,
+    DeleteDatalakeIndexComponent,
+    PipelineElementConfigurationComponent,
+    MessagingConfigurationComponent,
+    DatalakeConfigurationComponent
+  ],
+  providers: [
+    ConfigurationService,
+    DatalakeRestService
+  ],
+  entryComponents: [ConfigurationComponent]
 })
 export class ConfigurationModule {
 }
diff --git a/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.html b/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.html
index 0068824..9383fcb 100644
--- a/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.html
+++ b/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.html
@@ -32,7 +32,6 @@
                     <th mat-header-cell mat-sort-header *matHeaderCellDef>Name</th>
                     <td mat-cell *matCellDef="let configurationEntry">
                         <h4 style="margin-bottom:0px;">{{configurationEntry.name}}</h4>
-                        <!--                        <h5>{{adapter.description != '' ? adapter.description : '-'}}</h5>-->
                     </td>
                 </ng-container>
 
@@ -55,9 +54,13 @@
                     <td mat-cell *matCellDef="let measurement">
                         <div fxLayout="row">
                             <span fxFlex fxFlexOrder="3" fxLayout="row" fxLayoutAlign="center center">
-                                    <button color="accent" mat-button mat-icon-button matTooltip="Delete adapter"
-                                            data-cy="delete" matTooltipPosition="above"
-                                            (click)="cleanDatalakeIndex(measurement)">
+                                    <button color="accent"
+                                            mat-button
+                                            mat-icon-button
+                                            matTooltip="Truncate all data from index"
+                                            matTooltipPosition="above"
+                                            data-cy="truncate-datalake-index"
+                                            (click)="cleanDatalakeIndex(measurement.name)">
                                         <i class="material-icons">local_fire_department</i>
                                     </button>
                                 </span>
@@ -73,8 +76,8 @@
                                     <button color="accent"
                                             mat-button
                                             mat-icon-button
-                                            matTooltip="Delete data lake index"
-                                            data-cy="delete"
+                                            matTooltip="Remove index from database"
+                                            data-cy="delete-datalake-index"
                                             matTooltipPosition="above"
                                             [disabled]="!configurationEntry.remove"
                                             (click)="deleteDatalakeIndex(configurationEntry)">
diff --git a/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.ts b/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.ts
index 07fae0a..3a5adb1 100644
--- a/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.ts
+++ b/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.ts
@@ -17,7 +17,6 @@
  */
 
 import { Component, OnInit, ViewChild } from '@angular/core';
-import { MatSnackBar } from '@angular/material/snack-bar';
 import { DatalakeRestService } from '../../platform-services/apis/datalake-rest.service';
 import { MatTableDataSource } from '@angular/material/table';
 import { DataViewDataExplorerService } from '../../platform-services/apis/data-view-data-explorer.service';
@@ -26,6 +25,10 @@ import { DatalakeQueryParameters } from '../../core-services/datalake/DatalakeQu
 import { DatalakeQueryParameterBuilder } from '../../core-services/datalake/DatalakeQueryParameterBuilder';
 import { MatPaginator } from '@angular/material/paginator';
 import { MatSort } from '@angular/material/sort';
+import { DialogRef } from '../../core-ui/dialog/base-dialog/dialog-ref';
+import { PanelType } from '../../core-ui/dialog/base-dialog/base-dialog.model';
+import { DialogService } from '../../core-ui/dialog/base-dialog/base-dialog.service';
+import { DeleteDatalakeIndexComponent } from '../dialog/delete-datalake-index/delete-datalake-index-dialog.component';
 
 @Component({
   selector: 'sp-datalake-configuration',
@@ -47,7 +50,7 @@ export class DatalakeConfigurationComponent implements OnInit {
     // protected dataLakeRestService: DatalakeRestService,
     private datalakeRestService: DatalakeRestService,
     private dataViewDataExplorerService: DataViewDataExplorerService,
-    private snackBar: MatSnackBar) {
+    private dialogService: DialogService) {
   }
 
   ngOnInit(): void {
@@ -55,12 +58,11 @@ export class DatalakeConfigurationComponent implements OnInit {
   }
 
   loadAvailableMeasurements() {
+    this.availableMeasurements = [];
     // get all available measurements that are stored in the data lake
     this.datalakeRestService.getAllMeasurementSeries().subscribe(allMeasurements => {
       // get all measurements that are still used in pipelines
       this.dataViewDataExplorerService.getAllPersistedDataStreams().subscribe(inUseMeasurements => {
-        console.log('Pipelines');
-        console.log(inUseMeasurements);
         allMeasurements.forEach(measurement => {
           const entry = new DataLakeConfigurationEntry();
           entry.name = measurement.measureName;
@@ -93,12 +95,24 @@ export class DatalakeConfigurationComponent implements OnInit {
   }
 
   cleanDatalakeIndex(measurementIndex: string) {
-    // TODO give user confirmation
-    this.datalakeRestService.removeData(measurementIndex);
+    const dialogRef: DialogRef<DeleteDatalakeIndexComponent> = this.dialogService.open(DeleteDatalakeIndexComponent, {
+      panelType: PanelType.STANDARD_PANEL,
+      title: 'Truncate data',
+      width: '70vw',
+      data: {
+        'measurementIndex': measurementIndex
+      }
+    });
+
+    dialogRef.afterClosed().subscribe(data => {
+      if (data) {
+        this.loadAvailableMeasurements();
+      }
+    });
   }
 
   deleteDatalakeIndex(measurmentIndex: string) {
-    // TODO give user confirmation
+    // add user confirmation
     this.datalakeRestService.dropSingleMeasurementSeries(measurmentIndex);
   }
 
diff --git a/ui/src/app/configuration/dialog/delete-datalake-index/delete-datalake-index-dialog.component.html b/ui/src/app/configuration/dialog/delete-datalake-index/delete-datalake-index-dialog.component.html
new file mode 100644
index 0000000..72d1f65
--- /dev/null
+++ b/ui/src/app/configuration/dialog/delete-datalake-index/delete-datalake-index-dialog.component.html
@@ -0,0 +1,48 @@
+<!--
+  ~ 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.
+  ~
+  -->
+
+<div class="sp-dialog-container">
+    <div class="sp-dialog-content p-15">
+        <div *ngIf="!isInProgress" fxLayout="column">
+            <div fxFlex="100" fxLayoutAlign="center center" fxLayout="column">
+                <b><h4>Do you really want to truncate the data in {{measurementIndex}}?</h4></b>
+                <b><h5>This operation cannot be undone.</h5></b>
+            </div>
+
+            <div fxFlex="100" fxLayoutAlign="center center" fxLayout="column">
+                <button mat-button mat-raised-button color="accent"
+                        (click)="truncateData()"
+                        data-cy="truncate-datalake-index">Truncate Data
+                </button>
+            </div>
+        </div>
+        <div fxFlex="100" fxLayoutAlign="center center" fxLayout="column" *ngIf="isInProgress"
+             data-cy="adapter-deletion-in-progress">
+            <div fxLayout="row" fxLayoutAlign="space-around">
+                <mat-spinner [mode]="'indeterminate'" color="accent"></mat-spinner>
+            </div>
+            <b><h4>{{currentStatus}}</h4></b>
+        </div>
+    </div>
+    <mat-divider></mat-divider>
+    <div class="sp-dialog-actions actions-align-right">
+        <button mat-button mat-raised-button class="mat-basic" (click)="close(false)">
+            Close
+        </button>
+    </div>
+</div>
diff --git a/ui/src/app/configuration/dialog/delete-datalake-index/delete-datalake-index-dialog.component.scss b/ui/src/app/configuration/dialog/delete-datalake-index/delete-datalake-index-dialog.component.scss
new file mode 100644
index 0000000..0a776e5
--- /dev/null
+++ b/ui/src/app/configuration/dialog/delete-datalake-index/delete-datalake-index-dialog.component.scss
@@ -0,0 +1,19 @@
+/*
+ * 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 '../../../../scss/sp/sp-dialog.scss';
\ No newline at end of file
diff --git a/ui/src/app/configuration/dialog/delete-datalake-index/delete-datalake-index-dialog.component.ts b/ui/src/app/configuration/dialog/delete-datalake-index/delete-datalake-index-dialog.component.ts
new file mode 100644
index 0000000..f4aefd8
--- /dev/null
+++ b/ui/src/app/configuration/dialog/delete-datalake-index/delete-datalake-index-dialog.component.ts
@@ -0,0 +1,61 @@
+/*
+ * 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, Input } from '@angular/core';
+import { DialogRef } from '../../../core-ui/dialog/base-dialog/dialog-ref';
+import { DatalakeRestService } from '../../../platform-services/apis/datalake-rest.service';
+
+@Component({
+  selector: 'sp-delete-datalake-index-dialog',
+  templateUrl: './delete-datalake-index-dialog.component.html',
+  styleUrls: ['./delete-datalake-index-dialog.component.scss']
+})
+export class DeleteDatalakeIndexComponent {
+
+  @Input()
+  measurementIndex: string;
+
+  isInProgress = false;
+  currentStatus: any;
+
+  constructor(private dialogRef: DialogRef<DeleteDatalakeIndexComponent>,
+              private datalakeRestService: DatalakeRestService) {
+  }
+
+  close(refreshDataLakeIndex: boolean) {
+    this.dialogRef.close(refreshDataLakeIndex);
+  }
+
+  truncateData() {
+    this.isInProgress = true;
+    this.currentStatus = 'Truncating data...';
+    this.datalakeRestService.removeData(this.measurementIndex).subscribe(data => {
+      this.close(true);
+    });
+  }
+
+  deleteData() {
+    this.isInProgress = true;
+    this.currentStatus = 'Deleting data...';
+
+    this.datalakeRestService.dropSingleMeasurementSeries(this.measurementIndex).subscribe(data => {
+      this.close(true);
+    });
+  }
+
+}
diff --git a/ui/src/app/core-services/datalake/DatalakeQueryParameterBuilder.ts b/ui/src/app/core-services/datalake/DatalakeQueryParameterBuilder.ts
index 50c057f..9ab43c8 100644
--- a/ui/src/app/core-services/datalake/DatalakeQueryParameterBuilder.ts
+++ b/ui/src/app/core-services/datalake/DatalakeQueryParameterBuilder.ts
@@ -23,14 +23,15 @@ export class DatalakeQueryParameterBuilder {
 
   private queryParams: DatalakeQueryParameters;
 
-  static create(startTime: number,
-                endTime: number): DatalakeQueryParameterBuilder {
+  static create(startTime?: number,
+                endTime?: number): DatalakeQueryParameterBuilder {
 
     return new DatalakeQueryParameterBuilder(startTime, endTime);
   }
 
-  private constructor(startTime: number,
-                      endTime: number) {
+
+  private constructor(startTime?: number,
+                      endTime?: number) {
     this.queryParams = new DatalakeQueryParameters();
     this.queryParams.startDate = startTime;
     this.queryParams.endDate = endTime;
diff --git a/ui/src/app/platform-services/apis/datalake-rest.service.ts b/ui/src/app/platform-services/apis/datalake-rest.service.ts
index e89a9f8..42f66dd 100644
--- a/ui/src/app/platform-services/apis/datalake-rest.service.ts
+++ b/ui/src/app/platform-services/apis/datalake-rest.service.ts
@@ -138,19 +138,10 @@ export class DatalakeRestService {
     return this.http.request(request);
   }
 
-  removeData(index: string, startDate?: number, endDate?: number) {
+  removeData(index: string) {
     const url = this.dataLakeUrl + '/measurements/' + index;
 
-    const queryParams: DatalakeQueryParameters = this.getQueryParameters(undefined, startDate, endDate, undefined,
-      undefined, undefined, undefined, undefined, undefined, undefined);
-
-    const request = new HttpRequest('DELETE', url, {
-      reportProgress: true,
-      responseType: 'text',
-      params: queryParams
-    });
-
-    return this.http.request(request);
+    return this.http.delete(url);
   }
 
   dropSingleMeasurementSeries(index: string) {