You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@streampipes.apache.org by oe...@apache.org on 2026/06/24 15:16:14 UTC
(streampipes) 01/02: Update measurement count endpoint
This is an automated email from the ASF dual-hosted git repository.
SvenO3 pushed a commit to branch 4633-move-dataset-count-display-into-dataset-overview
in repository https://gitbox.apache.org/repos/asf/streampipes.git
commit f0fa876af3d488073f80935ab69143baf0095224
Author: Sven Oehler <oe...@web.de>
AuthorDate: Wed Jun 24 15:07:08 2026 +0200
Update measurement count endpoint
---
.../impl/datalake/DataLakeMeasureResource.java | 59 +++++++++++++++-------
.../src/lib/apis/datalake-rest.service.ts | 16 +++---
.../datalake-configuration.component.ts | 38 +++++++-------
3 files changed, 68 insertions(+), 45 deletions(-)
diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/DataLakeMeasureResource.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/DataLakeMeasureResource.java
index 57dfb7553e..166b3dd4be 100644
--- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/DataLakeMeasureResource.java
+++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/DataLakeMeasureResource.java
@@ -29,9 +29,9 @@ import org.apache.streampipes.storage.api.explorer.IChartStorage;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
+import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
-import org.springframework.security.access.prepost.PostFilter;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
@@ -44,7 +44,6 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
-import java.util.Map;
import java.util.Objects;
@RestController
@@ -80,29 +79,53 @@ public class DataLakeMeasureResource extends AbstractDataLakeResource {
}
/**
- * Handles HTTP GET requests to retrieve the entry counts of specified
- * measurements.
+ * Handles HTTP GET requests to retrieve the entry count of a specified
+ * measurement.
*
- * @param measurementNames A list of measurement names to return the count.
- * @return A ResponseEntity containing a map of measurement names and their
- * corresponding entry counts.
+ * @param elementId The measurement id to return the count for.
+ * @return The entry count of the measurement.
*/
- @Operation(summary = "Retrieve measurement counts", description = "Retrieves the entry counts for the specified measurements from the data lake.")
- @GetMapping(path = "/count", produces = MediaType.APPLICATION_JSON_VALUE)
- @PreAuthorize("this.hasReadAuthority()")
- @PostFilter("this.checkPermissionByName(filterObject.key, 'READ')")
- public Map<String, Integer> getEntryCountsOfMeasurements(
- @Parameter(description = "A list of measurement names to return the count.") @RequestParam(value = "measurementNames") List<String> measurementNames,
- @Parameter(description = "The number of days from today where the count should start") @RequestParam(value = "daysBack", defaultValue = "-1") int daysBack) {
+ @Operation(
+ summary = "Retrieve measurement count",
+ description = "Retrieves the entry count for the specified measurement from the data lake."
+ )
+ @GetMapping(path = "{id}/count", produces = MediaType.APPLICATION_JSON_VALUE)
+ @PreAuthorize("this.hasReadAuthority() and hasPermission(#elementId, 'READ')")
+ public ResponseEntity<?> getEntryCountOfMeasurement(
+ @Parameter(description = "The measurement id to return the count for.")
+ @PathVariable("id") String elementId,
+ @Parameter(description = "The number of days from today where the count should start")
+ @RequestParam(value = "daysBack", defaultValue = "-1") int daysBack) {
+ var measure = this.dataLakeMeasureManagement.getById(elementId);
+ if (Objects.isNull(measure)) {
+ return notFound();
+ }
+
var allMeasurements = this.dataLakeMeasureManagement.getAllMeasurements();
- var result = new DataExplorerDispatcher()
+ return ok(new DataExplorerDispatcher()
.getDataExplorerManager()
.getMeasurementCounter(
allMeasurements,
- measurementNames,
+ List.of(measure.getMeasureName()),
daysBack)
- .countMeasurementSizes();
- return result;
+ .countMeasurementSizes()
+ .getOrDefault(measure.getMeasureName(), 0));
+ }
+
+ @Operation(
+ summary = "Deprecated measurement count endpoint",
+ description = "Use /api/v4/datalake/measure/{id}/count instead.",
+ deprecated = true
+ )
+ @GetMapping(path = "/count", produces = MediaType.APPLICATION_JSON_VALUE)
+ @PreAuthorize("this.hasReadAuthority()")
+ public ResponseEntity<?> getDeprecatedEntryCountOfMeasurement() {
+ return ResponseEntity
+ .status(HttpStatus.GONE)
+ .body(SpLogMessage.warn(
+ "Deprecated endpoint",
+ "Use /api/v4/datalake/measure/{id}/count instead."
+ ));
}
@GetMapping(path = "{id}", produces = MediaType.APPLICATION_JSON_VALUE)
diff --git a/ui/projects/streampipes/platform-services/src/lib/apis/datalake-rest.service.ts b/ui/projects/streampipes/platform-services/src/lib/apis/datalake-rest.service.ts
index fb2ccafeff..8ab764a7ea 100644
--- a/ui/projects/streampipes/platform-services/src/lib/apis/datalake-rest.service.ts
+++ b/ui/projects/streampipes/platform-services/src/lib/apis/datalake-rest.service.ts
@@ -64,18 +64,18 @@ export class DatalakeRestService {
return this.baseUrl + '/api/v4/datalake/import';
}
- getMeasurementEntryCounts(
- measurementNames: string[],
+ getMeasurementEntryCount(
+ measurementId: string,
daysBack = -1,
- ): Observable<Record<string, number>> {
- return this.http
- .get(`${this.dataLakeMeasureUrl}/count`, {
+ ): Observable<number> {
+ return this.http.get<number>(
+ `${this.dataLakeMeasureUrl}/${encodeURIComponent(measurementId)}/count`,
+ {
params: {
- measurementNames,
daysBack,
},
- })
- .pipe(map(r => r as Record<string, number>));
+ },
+ );
}
getAllMeasurementSeries(): Observable<DataLakeMeasure[]> {
diff --git a/ui/src/app/dataset/components/datalake-configuration/datalake-configuration.component.ts b/ui/src/app/dataset/components/datalake-configuration/datalake-configuration.component.ts
index cf53cd6441..b98ac2278a 100644
--- a/ui/src/app/dataset/components/datalake-configuration/datalake-configuration.component.ts
+++ b/ui/src/app/dataset/components/datalake-configuration/datalake-configuration.component.ts
@@ -91,7 +91,7 @@ import { MatProgressSpinner } from '@angular/material/progress-spinner';
import { DatePipe, DecimalPipe, NgStyle } from '@angular/common';
import { StyleDirective } from '@ngbracket/ngx-layout/extended';
import { MatMenuItem } from '@angular/material/menu';
-import { Subscription } from 'rxjs';
+import { forkJoin, Subscription } from 'rxjs';
@Component({
selector: 'sp-datalake-configuration',
@@ -436,7 +436,7 @@ export class DatalakeConfigurationComponent
}
receiveTotalMeasurementSize(entry: DataLakeConfigurationEntry): void {
- this.queryEntryCounts([entry.name], 'eventsTotal');
+ this.queryEntryCounts([entry], 'eventsTotal');
}
receiveMeasurementSizes(pageIndex: number): void {
@@ -444,8 +444,7 @@ export class DatalakeConfigurationComponent
const end = start + this.pageSize;
const measurements = this.filteredMeasurements
.slice(start, end)
- .filter(m => m.eventsLatest === -1)
- .map(m => m.name);
+ .filter(m => m.eventsLatest === -1);
if (measurements.length > 0) {
this.queryEntryCounts(measurements, 'eventsLatest', 7);
}
@@ -489,33 +488,34 @@ export class DatalakeConfigurationComponent
}
queryEntryCounts(
- measurements: string[],
+ measurements: DataLakeConfigurationEntry[],
targetField: string,
daysBack = -1,
): void {
this.applyLoadingStatus(measurements, targetField, true);
- this.datalakeRestService
- .getMeasurementEntryCounts(measurements, daysBack)
- .subscribe(res => {
- this.applyLoadingStatus(measurements, targetField, false);
- this.availableMeasurements.forEach(m => {
- if (res[m.name] !== undefined) {
- m[targetField] = res[m.name];
- }
- });
+ forkJoin(
+ measurements.map(measurement =>
+ this.datalakeRestService.getMeasurementEntryCount(
+ measurement.elementId,
+ daysBack,
+ ),
+ ),
+ ).subscribe(res => {
+ this.applyLoadingStatus(measurements, targetField, false);
+ measurements.forEach((measurement, index) => {
+ measurement[targetField] = res[index];
});
+ });
}
applyLoadingStatus(
- measurements: string[],
+ measurements: DataLakeConfigurationEntry[],
targetField: string,
status: boolean,
): void {
const loadingField = targetField + 'Loading';
- this.availableMeasurements.forEach(m => {
- if (measurements.includes(m.name)) {
- m[loadingField] = status;
- }
+ measurements.forEach(measurement => {
+ measurement[loadingField] = status;
});
}