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/streampipes.git
The following commit(s) were added to refs/heads/dev by this push:
new 3ebe611381 feat: Add connection test to export provider (#3942)
3ebe611381 is described below
commit 3ebe611381df5e8fadf39e806e23e427e504431c
Author: Jacqueline Höllig <[email protected]>
AuthorDate: Tue Nov 25 12:50:24 2025 +0100
feat: Add connection test to export provider (#3942)
Co-authored-by: Dominik Riemer <[email protected]>
---
.../export/ObjectStorge/IObjectStorage.java | 1 +
.../export/ObjectStorge/LocalFolder.java | 5 ++
.../dataexplorer/export/ObjectStorge/S3.java | 5 ++
.../ObjectStorge/TestExportProviderConnection.java | 71 +++++++++++++++++++
.../admin/ExportProviderConfigurationResource.java | 40 +++++++++--
ui/deployment/i18n/de.json | 72 +++++++++-----------
ui/deployment/i18n/en.json | 72 +++++++++-----------
.../src/lib/apis/export-provider.service.ts | 10 ++-
.../model/config/export-provider-config.model.ts | 15 ++--
ui/src/app/configuration/configuration.module.ts | 2 +
.../datalake-configuration.component.html | 38 +++++++++++
.../datalake-configuration.component.ts | 21 ++++++
.../export-provider-connection-test.component.html | 79 ++++++++++++++++++++++
.../export-provider-connection-test.component.ts | 79 ++++++++++++++++++++++
14 files changed, 413 insertions(+), 97 deletions(-)
diff --git
a/streampipes-data-explorer-export/src/main/java/org/apache/streampipes/dataexplorer/export/ObjectStorge/IObjectStorage.java
b/streampipes-data-explorer-export/src/main/java/org/apache/streampipes/dataexplorer/export/ObjectStorge/IObjectStorage.java
index c913db65d4..3d291277e4 100644
---
a/streampipes-data-explorer-export/src/main/java/org/apache/streampipes/dataexplorer/export/ObjectStorge/IObjectStorage.java
+++
b/streampipes-data-explorer-export/src/main/java/org/apache/streampipes/dataexplorer/export/ObjectStorge/IObjectStorage.java
@@ -23,4 +23,5 @@ import java.io.IOException;
public interface IObjectStorage {
void store(StreamingResponseBody datastream) throws IOException;
+ String getFileName();
}
\ No newline at end of file
diff --git
a/streampipes-data-explorer-export/src/main/java/org/apache/streampipes/dataexplorer/export/ObjectStorge/LocalFolder.java
b/streampipes-data-explorer-export/src/main/java/org/apache/streampipes/dataexplorer/export/ObjectStorge/LocalFolder.java
index 1e59f24d9c..2e449aa164 100644
---
a/streampipes-data-explorer-export/src/main/java/org/apache/streampipes/dataexplorer/export/ObjectStorge/LocalFolder.java
+++
b/streampipes-data-explorer-export/src/main/java/org/apache/streampipes/dataexplorer/export/ObjectStorge/LocalFolder.java
@@ -42,6 +42,11 @@ public class LocalFolder implements IObjectStorage {
+ Instant.now().toString() + "." + format);
}
+
+ @Override
+ public String getFileName(){
+ return this.filePath.toString();
+ }
@Override
public void store(StreamingResponseBody datastream) throws IOException {
diff --git
a/streampipes-data-explorer-export/src/main/java/org/apache/streampipes/dataexplorer/export/ObjectStorge/S3.java
b/streampipes-data-explorer-export/src/main/java/org/apache/streampipes/dataexplorer/export/ObjectStorge/S3.java
index 885e4f9e90..118813e4b6 100644
---
a/streampipes-data-explorer-export/src/main/java/org/apache/streampipes/dataexplorer/export/ObjectStorge/S3.java
+++
b/streampipes-data-explorer-export/src/main/java/org/apache/streampipes/dataexplorer/export/ObjectStorge/S3.java
@@ -59,6 +59,11 @@ public class S3 implements IObjectStorage{
}
+ @Override
+ public String getFileName(){
+ return this.fileName;
+ }
+
@Override
public void store(StreamingResponseBody datastream) throws IOException {
diff --git
a/streampipes-data-explorer-export/src/main/java/org/apache/streampipes/dataexplorer/export/ObjectStorge/TestExportProviderConnection.java
b/streampipes-data-explorer-export/src/main/java/org/apache/streampipes/dataexplorer/export/ObjectStorge/TestExportProviderConnection.java
new file mode 100644
index 0000000000..eca9e743f0
--- /dev/null
+++
b/streampipes-data-explorer-export/src/main/java/org/apache/streampipes/dataexplorer/export/ObjectStorge/TestExportProviderConnection.java
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ *
+ */
+
+package org.apache.streampipes.dataexplorer.export.ObjectStorge;
+
+
+import org.apache.streampipes.model.configuration.ExportProviderSettings;
+import org.apache.streampipes.model.configuration.ProviderType;
+
+import
org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+
+public class TestExportProviderConnection {
+
+ public static Map<String, Object> connectionTest(ExportProviderSettings
setting) throws Exception {
+
+ ProviderType providerType = setting.getProviderType();
+
+ IObjectStorage exportProvider =
ExportProviderFactory.createExportProvider(
+ providerType, "TEST", setting,
+ "csv");
+
+
+ String filePath = exportProvider.getFileName();
+
+ String csvData = "Message\nThis test file was automatically created as
a connectivity test by StreamPipes.\n";
+ InputStream csvInputStream = new
ByteArrayInputStream(csvData.getBytes());
+ StreamingResponseBody responseBody = outputStream -> {
+ byte[] buffer = new byte[1024];
+ int length;
+ while ((length = csvInputStream.read(buffer)) > 0) {
+ outputStream.write(buffer, 0, length);
+ }
+ };
+ try {
+ exportProvider.store(responseBody);
+ } catch (IOException e) {
+ throw new IOException("Failed to store data in the export
provider.",e);
+
+ }
+
+
+
+ Map<String, Object> response = new HashMap<>();
+ response.put("filePath", filePath);
+ response.put("setting", setting);
+
+ return response;
+ }
+}
\ No newline at end of file
diff --git
a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/admin/ExportProviderConfigurationResource.java
b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/admin/ExportProviderConfigurationResource.java
index 774e9805be..9e3e2639e9 100644
---
a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/admin/ExportProviderConfigurationResource.java
+++
b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/admin/ExportProviderConfigurationResource.java
@@ -17,7 +17,9 @@
*/
package org.apache.streampipes.rest.impl.admin;
+import
org.apache.streampipes.dataexplorer.export.ObjectStorge.TestExportProviderConnection;
import org.apache.streampipes.model.configuration.ExportProviderSettings;
+import org.apache.streampipes.model.monitoring.SpLogMessage;
import
org.apache.streampipes.rest.core.base.impl.AbstractAuthGuardedRestResource;
import org.apache.streampipes.rest.security.AuthConstants;
import
org.apache.streampipes.user.management.encryption.SecretEncryptionManager;
@@ -35,6 +37,8 @@ import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
+import java.util.Optional;
import java.util.stream.Collectors;
@RestController
@@ -48,14 +52,40 @@ public class ExportProviderConfigurationResource extends
AbstractAuthGuardedRest
}
@GetMapping(value = "/{providerId}", produces =
MediaType.APPLICATION_JSON_VALUE)
-@PreAuthorize(AuthConstants.IS_ADMIN_ROLE)
-public ResponseEntity<ExportProviderSettings>
getExportProviderSettingById(@PathVariable String providerId) {
+ @PreAuthorize(AuthConstants.IS_ADMIN_ROLE)
+ public ResponseEntity<ExportProviderSettings>
getExportProviderSettingById(@PathVariable String providerId) {
return
getSpCoreConfigurationStorage().get().getExportProviderSettings().stream()
.filter(setting ->
setting.getProviderId().equalsIgnoreCase(providerId))
.findFirst()
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
-}
+ }
+
+ @GetMapping(value = "/test/{providerId}", produces =
MediaType.APPLICATION_JSON_VALUE)
+ @PreAuthorize(AuthConstants.IS_ADMIN_ROLE)
+ public ResponseEntity<?> testExportProviderSettingById(@PathVariable String
providerId) {
+ // Get Export Provider Settings
+ Optional<ExportProviderSettings> exportProviderSetting =
getSpCoreConfigurationStorage().get()
+ .getExportProviderSettings().stream()
+ .filter(setting ->
setting.getProviderId().equalsIgnoreCase(providerId))
+ .findFirst();
+
+ if (exportProviderSetting.isPresent()) {
+ try {
+ Map<String, Object> response =
TestExportProviderConnection.connectionTest(exportProviderSetting.get());
+
+
+ return ok(response);
+
+ } catch (Exception e) {
+ return serverError(SpLogMessage.from(e));
+ }
+
+
+ } else {
+ return serverError("No provider found.");
+ }
+ }
@PutMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
@PreAuthorize(AuthConstants.IS_ADMIN_ROLE)
@@ -74,8 +104,8 @@ public ResponseEntity<ExportProviderSettings>
getExportProviderSettingById(@Path
}
List<ExportProviderSettings> providerSettingsWithoutExisting =
providerSettings.stream()
- .filter(existing -> existing != null &&
!existing.getProviderId().equals(config.getProviderId()))
- .collect(Collectors.toList());
+ .filter(existing -> existing != null &&
!existing.getProviderId().equals(config.getProviderId()))
+ .collect(Collectors.toList());
providerSettingsWithoutExisting.add(config);
diff --git a/ui/deployment/i18n/de.json b/ui/deployment/i18n/de.json
index cb3ad1b92f..60ecb8a773 100644
--- a/ui/deployment/i18n/de.json
+++ b/ui/deployment/i18n/de.json
@@ -238,8 +238,8 @@
"Add Mapping": "Mapping hinzufügen",
"Value": "Wert",
"Remove Mapping": "Mapping entfernen",
- "Charts": "Diagramme",
"New chart": "Neues Diagramm",
+ "Charts": "Diagramme",
"Chart": "Diagramm",
"Created": "Erstellt",
"Edit chart": "Diagramm bearbeiten",
@@ -368,18 +368,6 @@
"Store as template": "Als Vorlage speichern",
"You can perform a forced stop, which will stop and reset the pipeline
status.": "Sie können einen erzwungenen Stopp durchführen, der die Pipeline
anhält und zurücksetzt.",
"Force stop": "Stopp erzwingen",
- "Owner": "Eigentümer",
- "Public Element": "Öffentliches Element",
- "visible to registered users": "sichtbar für registrierte Benutzer",
- "Users": "Nutzer",
- "Authorized Users": "Autorisierte Nutzer",
- "User selection": "Auswahl der Nutzer",
- "Groups": "Gruppen",
- "Authorized Groups": "Autorisierte Gruppen",
- "Group selection": "Auswahl der Gruppe",
- "Public Link": "Öffentlicher Link",
- "Allow anonymous access through public link": "Anonymen Zugang über einen
öffentlichen Link ermöglichen",
- "URL": "URL",
"(no log messages available)": "(keine Protokollmeldungen verfügbar)",
"You are about to start the following adapters:": "Sie sind dabei, die
folgenden Adapter zu starten:",
"You are about to stop the following adapters:": "Sie sind dabei, die
folgenden Adapter zu stoppen:",
@@ -402,16 +390,13 @@
"will be stopped and needs manual review": "wird gestoppt und muss manuell
überprüft werden",
"Please check and possibly modify existing dashboards and data views
afterwards.": "Bitte überprüfen Sie die bestehenden Dashboards und
Datenansichten und ändern Sie diese gegebenenfalls.",
"Update adapter and migrate pipelines": "Adapter aktualisieren und Pipelines
migrieren",
- "Adapters": "Adapter",
"New adapter": "Neuer Adapter",
"Start all adapters": "Alle Adapter starten",
"Stop all adapters": "Alle Adapter anhalten",
"Refresh adapters": "Adapter neu laden",
+ "Adapters": "Adapter",
"Messages": "Nachrichten",
"Last message": "Letzte Nachricht",
- "Select Adapter": "Adapter auswählen",
- "Create adapter": "Adapter erstellen",
- "Docs": "Doku",
"Refresh": "Neu laden",
"The desired adapter was not found!": "Der gewünschte Adapter wurde nicht
gefunden!",
"Last published message": "Zuletzt veröffentlichte Nachricht",
@@ -456,9 +441,12 @@
"Save as template": "Als Vorlage speichern",
"Any available service": "Jeder verfügbare Service",
"Restrict to service tags": "Auf Service-Tags beschränken",
+ "Select Adapter": "Adapter auswählen",
+ "Create adapter": "Adapter erstellen",
+ "Docs": "Doku",
"Sites & Areas": "Standorte & Bereiche",
"Manage your organization's sites and production areas": "Verwaltung der
Standorte und Produktionsbereiche",
- "New site": "Neuer Standort",
+ "New": "Neu",
"Site": "Standort",
"Areas": "Bereiche",
"Geo features": "Geo-Features",
@@ -468,30 +456,23 @@
"Copyright notice if required by the tile server": "Copyright-Hinweis, falls
vom Tile-Server erforderlich",
"User Accounts": "Benutzerkonten",
"Add and edit user accounts": "Benutzerkonten hinzufügen und bearbeiten",
- "Existing user accounts": "Bestehende Benutzerkonten",
"Service Accounts": "Servicekonten",
"Add and edit service accounts": "Servicekonten hinzufügen und bearbeiten",
- "Existing service accounts": "Bestehende Servicekonten",
+ "Groups": "Gruppen",
"Manage user groups": "Benutzergruppen verwalten",
- "Existing groups": "Bestehende Gruppen",
"Roles": "Rollen",
"Manage roles": "Rollen verwalten",
- "Existing roles": "Bestehende Rollen",
"Authentication": "Authentifizierung",
"Auth & token settings": "Authentifizierung- und Token-Einstellungen",
"JWT Signature": "JWT-Signature",
- "New User Group": "Neue Benutzergruppe",
"Group name": "Name der Benutzergruppe",
"Group ID": "Gruppen-ID",
"Edit user": "Benutzer bearbeiten",
"Delete service": "Service löschen",
- "New User": "Neuer Benutzer",
"Full Name": "Vor- und Nachname",
"Last Login": "Letzte Anmeldung",
"Delete user": "Benutzer löschen",
- "New Service Account": "Neues Servicekonto",
"Username": "Benutzername",
- "New Role": "Neue Rolle",
"Role name": "Rollenbezeichnung",
"Default Role": "Standardrolle",
"Settings of externally-managed users cannot be changed.": "Die
Einstellungen von extern verwalteten Benutzern können nicht geändert werden.",
@@ -520,7 +501,6 @@
"Message Max Bytes": "Message Max Bytes",
"Acks": "Acks",
"Linger MS": "Linger MS",
- "Update": "Aktualisieren",
"Protocols": "Protokolle",
"Manage the priority of protocols used": "Priorität der verwendeten
Protokolle verwalten",
"Broker Configuration": "Broker-Konfiguration",
@@ -529,8 +509,6 @@
"Port": "Port",
"Labels": "Labels",
"Configure labels which can be assigned to assets and other resources":
"Labels konfigurieren, die Assets und anderen Ressourcen zugewiesen werden
können",
- "New label": "Neues Label",
- "Available labels": "Verfügbare Label",
"Edit label": "Label bearbeiten",
"Delete label": "Label löschen",
"Basic": "Allgemein",
@@ -552,13 +530,10 @@
"Links": "Links",
"Configure application links": "Anwendungslinks konfigurieren",
"Documentation Link": "Dokumentations-Link",
- "Documentation URL": "Dokumentations-URL",
"Show documentation link on login page": "Link zur Dokumentation auf
Anmeldeseite anzeigen",
"Show documentation link in user menu": "Link zur Dokumentation im
Benutzermenü anzeigen",
- "API Documentation Link": "Link zur API-Dokumentation",
"Show API documentation link on login page": "Link zur API-Dokumentation auf
der Login-Seite anzeigen",
"Support Link": "Support-Link",
- "Support URL": "Support-URL",
"Show support link on login page": "Support-Link auf der Anmeldeseite
anzeigen",
"Files": "Dateien",
"Upload and manage files that are used by adapters or pipeline elements.":
"Hochladen und Verwalten von Dateien, die von Adaptern oder Pipeline-Elementen
verwendet werden.",
@@ -577,6 +552,7 @@
"Service ID": "Service-ID",
"View service details": "Service-Details anzeigen",
"Service Name": "Service-Name",
+ "Update": "Aktualisieren",
"Issuer": "Aussteller",
"Expires": "Läuft aus",
"Certificate Details": "Zertifikat-Details",
@@ -603,11 +579,9 @@
"Install": "Installieren",
"Uninstall": "Deinstallieren",
"Export": "Exportieren",
- "Export application data": "Anwendungsdaten exportieren",
"Export assets and all linked resources": "Assets und alle damit verbundenen
Ressourcen exportieren",
"Start export process": "Exportvorgang starten",
"Import": "Importieren",
- "Import application data": "Anwendungsdaten importieren",
"Import from application package": "Import aus Anwendungspaket",
"Start import process": "Importvorgang starten",
"Upload application package file": "Anwendungspaket-Datei hochladen",
@@ -653,6 +627,7 @@
"You can set various placeholder variables that will be replaced with the
actual values when sending an email:": "Platzhalter festlegen, die beim Senden
einer E-Mail ersetzt werden:",
"Save changes": "Änderungen speichern",
"Choose a name for your site": "Name des Standorts festlegen",
+ "New site": "Neuer Standort",
"Site name is required": "Standortname erforderlich",
"Available areas within the site (e.g. plants or facilities)": "Verfügbare
Flächen innerhalb des Standorts (z.B. Werke oder Anlagen)",
"Location": "Lage",
@@ -691,8 +666,6 @@
"Do you really want to delete the export provider?": "Exportprovider
wirklich löschen?",
"This operation cannot be undone. Please ensure that the data provider is
not used in a datalake retention.": "Dieser Vorgang kann nicht rückgängig
gemacht werden. Bitte stellen Sie sicher, dass der Provider in keiner
Speicherrichtlinie verwendet wird.",
"Delete Data": "Daten löschen",
- "Do you really want to delete the data index {{index}}?": "Möchten Sie die
Daten in {{index}} wirklich löschen?",
- "Do you really want to truncate the data in {{index}}?": "Möchten Sie die
Daten in {{index}} wirklich leeren?",
"Truncate Data": "Daten leeren",
"Start Sync": "Synchronisierung starten",
"Delete Sync": "Sync löschen",
@@ -711,7 +684,6 @@
"No export providers found. Please create one first.": "Keine Exportanbieter
gefunden. Bitte erstellen Sie zuerst einen.",
"Data Lake Settings": "Data Lake Einstellungen",
"Manage persisted data streams": "Verwalten von gespeicherten Datenströmen",
- "Existing data lake indices": "Bestehende Data-Lake-Indizes",
"Related Pipeline": "Zugehörige Pipelines",
"# Events": "# Ereignisse",
"Loading": "Laden",
@@ -725,11 +697,11 @@
"(no stored measurements)": "(keine gespeicherten Measurements)",
"Export Providers": "Exportanbieter",
"Add, Edit, and Delete export providers used for backing up data lakes.":
"Hinzufügen, Bearbeiten und Löschen von Exportanbietern, die für die Sicherung
von Data Lakes verwendet werden.",
- "Existing Export Providers": "Bestehende Exportanbieter",
- "New Export Provider": "Neuer Exportanbieter",
"Provider Type": "Anbieter Typ",
"Edit Export Provider": "Exportanbieter bearbeiten",
"Remove export provider configuration": "Konfiguration des Exportanbieters
entfernen",
+ "Test": "Test",
+ "Test export provider configuration": "Konfiguration des Exportanbieters
testen",
"no stored export providers": "keine gespeicherten Exportanbieter",
"success": "Erfolg",
"error": "Fehler",
@@ -825,13 +797,14 @@
"Location configuration updated": "Standortkonfiguration aktualisiert",
"Ok": "Ok",
"Edit user {{user}}": "Benutzer bearbeiten {{user}}",
- "Add group": "Gruppe hinzufügen",
+ "Add user": "Benutzer hinzufügen",
"Are you sure you want to delete this account?": "Sind Sie sicher, dass Sie
dieses Konto löschen möchten?",
"This action cannot be reversed!": "Diese Aktion kann nicht rückgängig
gemacht werden!",
"Delete User": "Benutzer löschen",
"Are you sure you want to delete this group?": "Sind Sie sicher, dass Sie
diese Gruppe löschen wollen?",
"Delete Group": "Gruppe löschen",
"Edit group {{groupName}}": "Gruppe {{groupName}} bearbeiten",
+ "Add group": "Gruppe hinzufügen",
"Are you sure you want to delete this role?": "Sind Sie sicher, dass Sie
diese Rolle löschen wollen?",
"Delete Role": "Rolle löschen",
"Edit role {{label}}": "Rolle {{label}} bearbeiten",
@@ -855,12 +828,29 @@
"Email title": "E-Mail-Titel",
"Email preheader": "E-Mail Pre-Header",
"Email custom inner content (mandatory)": "Benutzerdefinierter E-Mail-Inhalt
(erforderlich)",
+ "Testing the connection.": "Testen der Verbindung.",
+ "Connection was established and test file was successfully saved:": "Die
Verbindung wurde hergestellt und die Testdatei wurde erfolgreich gespeichert:",
+ "Connection could not be established.": "Die Verbindung konnte nicht
hergestellt werden.",
"Truncating data...": "Daten leeren...",
"Deleting data...": "Daten löschen...",
+ "New Export Provider": "Neuer Exportanbieter",
"Truncate data": "Daten leeren",
"Delete data": "Daten löschen",
"Delete Export Provider": "Exportanbieter löschen",
+ " Test Export Provider Connection": " Test der Export-Provider-Verbindung",
"Set Data Retention": "Speicherrichtlinie bearbeiten",
+ "Owner": "Eigentümer",
+ "Public Element": "Öffentliches Element",
+ "visible to registered users": "sichtbar für registrierte Benutzer",
+ "Users": "Nutzer",
+ "Authorized Users": "Autorisierte Nutzer",
+ "User selection": "Auswahl der Nutzer",
+ "Authorized Groups": "Autorisierte Gruppen",
+ "Group selection": "Auswahl der Gruppe",
+ "Public Link": "Öffentlicher Link",
+ "Allow anonymous access through public link": "Anonymen Zugang über einen
öffentlichen Link ermöglichen",
+ "URL": "URL",
+ "Only admins and owners can manage permissions for this resource.": "Nur
Administratoren und Eigentümer können die Berechtigungen für diese Ressource
verwalten.",
"Select Data": "Daten auswählen",
"Previous": "Zurück",
"Download": "Download",
@@ -901,8 +891,8 @@
"No assets found - use assets to better organize resources!": "Keine Assets
gefunden - verwenden Sie Assets, um Ressourcen besser zu organisieren!",
"Manage assets": "Assets verwalten",
"Asset Browser": "Asset-Browser",
- "Browse assets": "Assets durchsuchen",
"Filter assets": "Assets filtern",
+ "All assets": "Alle Assets",
"Reset filters": "Filter zurücksetzen",
"None": "Keine",
"Quick Selection": "Schnellauswahl",
diff --git a/ui/deployment/i18n/en.json b/ui/deployment/i18n/en.json
index 779a67008c..025fe9df76 100644
--- a/ui/deployment/i18n/en.json
+++ b/ui/deployment/i18n/en.json
@@ -238,8 +238,8 @@
"Add Mapping": null,
"Value": null,
"Remove Mapping": null,
- "Charts": null,
"New chart": null,
+ "Charts": null,
"Chart": null,
"Created": null,
"Edit chart": null,
@@ -368,18 +368,6 @@
"Store as template": null,
"You can perform a forced stop, which will stop and reset the pipeline
status.": null,
"Force stop": null,
- "Owner": null,
- "Public Element": null,
- "visible to registered users": null,
- "Users": null,
- "Authorized Users": null,
- "User selection": null,
- "Groups": null,
- "Authorized Groups": null,
- "Group selection": null,
- "Public Link": null,
- "Allow anonymous access through public link": null,
- "URL": null,
"(no log messages available)": null,
"You are about to start the following adapters:": null,
"You are about to stop the following adapters:": null,
@@ -402,16 +390,13 @@
"will be stopped and needs manual review": null,
"Please check and possibly modify existing dashboards and data views
afterwards.": null,
"Update adapter and migrate pipelines": null,
- "Adapters": null,
"New adapter": null,
"Start all adapters": null,
"Stop all adapters": null,
"Refresh adapters": null,
+ "Adapters": null,
"Messages": null,
"Last message": null,
- "Select Adapter": null,
- "Create adapter": null,
- "Docs": null,
"Refresh": null,
"The desired adapter was not found!": null,
"Last published message": null,
@@ -456,9 +441,12 @@
"Save as template": null,
"Any available service": null,
"Restrict to service tags": null,
+ "Select Adapter": null,
+ "Create adapter": null,
+ "Docs": null,
"Sites & Areas": null,
"Manage your organization's sites and production areas": null,
- "New site": null,
+ "New": null,
"Site": null,
"Areas": null,
"Geo features": null,
@@ -468,30 +456,23 @@
"Copyright notice if required by the tile server": null,
"User Accounts": null,
"Add and edit user accounts": null,
- "Existing user accounts": null,
"Service Accounts": null,
"Add and edit service accounts": null,
- "Existing service accounts": null,
+ "Groups": null,
"Manage user groups": null,
- "Existing groups": null,
"Roles": null,
"Manage roles": null,
- "Existing roles": null,
"Authentication": null,
"Auth & token settings": null,
"JWT Signature": null,
- "New User Group": null,
"Group name": null,
"Group ID": null,
"Edit user": null,
"Delete service": null,
- "New User": null,
"Full Name": null,
"Last Login": null,
"Delete user": null,
- "New Service Account": null,
"Username": null,
- "New Role": null,
"Role name": null,
"Default Role": null,
"Settings of externally-managed users cannot be changed.": null,
@@ -520,7 +501,6 @@
"Message Max Bytes": null,
"Acks": null,
"Linger MS": null,
- "Update": null,
"Protocols": null,
"Manage the priority of protocols used": null,
"Broker Configuration": null,
@@ -529,8 +509,6 @@
"Port": null,
"Labels": null,
"Configure labels which can be assigned to assets and other resources": null,
- "New label": null,
- "Available labels": null,
"Edit label": null,
"Delete label": null,
"Basic": null,
@@ -552,13 +530,10 @@
"Links": null,
"Configure application links": null,
"Documentation Link": null,
- "Documentation URL": null,
"Show documentation link on login page": null,
"Show documentation link in user menu": null,
- "API Documentation Link": null,
"Show API documentation link on login page": null,
"Support Link": null,
- "Support URL": null,
"Show support link on login page": null,
"Files": null,
"Upload and manage files that are used by adapters or pipeline elements.":
null,
@@ -577,6 +552,7 @@
"Service ID": null,
"View service details": null,
"Service Name": null,
+ "Update": null,
"Issuer": null,
"Expires": null,
"Certificate Details": null,
@@ -603,11 +579,9 @@
"Install": null,
"Uninstall": null,
"Export": null,
- "Export application data": null,
"Export assets and all linked resources": null,
"Start export process": null,
"Import": null,
- "Import application data": null,
"Import from application package": null,
"Start import process": null,
"Upload application package file": null,
@@ -653,6 +627,7 @@
"You can set various placeholder variables that will be replaced with the
actual values when sending an email:": null,
"Save changes": null,
"Choose a name for your site": null,
+ "New site": null,
"Site name is required": null,
"Available areas within the site (e.g. plants or facilities)": null,
"Location": null,
@@ -709,7 +684,6 @@
"No export providers found. Please create one first.": null,
"Data Lake Settings": null,
"Manage persisted data streams": null,
- "Existing data lake indices": null,
"Related Pipeline": null,
"# Events": null,
"Loading": null,
@@ -723,11 +697,11 @@
"(no stored measurements)": null,
"Export Providers": null,
"Add, Edit, and Delete export providers used for backing up data lakes.":
null,
- "Existing Export Providers": null,
- "New Export Provider": null,
"Provider Type": null,
"Edit Export Provider": null,
"Remove export provider configuration": null,
+ "Test": null,
+ "Test export provider configuration": null,
"no stored export providers": null,
"success": null,
"error": null,
@@ -823,13 +797,14 @@
"Location configuration updated": null,
"Ok": null,
"Edit user {{user}}": "Edit user {{user}}",
- "Add group": null,
+ "Add user": null,
"Are you sure you want to delete this account?": null,
"This action cannot be reversed!": null,
"Delete User": null,
"Are you sure you want to delete this group?": null,
"Delete Group": null,
"Edit group {{groupName}}": "Edit group {{groupName}}",
+ "Add group": null,
"Are you sure you want to delete this role?": null,
"Delete Role": null,
"Edit role {{label}}": "Edit role {{label}}",
@@ -853,14 +828,29 @@
"Email title": null,
"Email preheader": null,
"Email custom inner content (mandatory)": null,
+ "Testing the connection.": null,
+ "Connection was established and test file was successfully saved:": null,
+ "Connection could not be established.": null,
"Truncating data...": null,
"Deleting data...": null,
- "Do you really want to delete the data index {{index}}?": "Do you really
want to delete the data index {{index}}?",
- "Do you really want to truncate the data in {{index}}?": "Do you really want
to truncate the data in {{index}}?",
+ "New Export Provider": null,
"Truncate data": null,
"Delete data": null,
"Delete Export Provider": null,
+ " Test Export Provider Connection": null,
"Set Data Retention": null,
+ "Owner": null,
+ "Public Element": null,
+ "visible to registered users": null,
+ "Users": null,
+ "Authorized Users": null,
+ "User selection": null,
+ "Authorized Groups": null,
+ "Group selection": null,
+ "Public Link": null,
+ "Allow anonymous access through public link": null,
+ "URL": null,
+ "Only admins and owners can manage permissions for this resource.": null,
"Select Data": null,
"Previous": null,
"Download": null,
@@ -901,8 +891,8 @@
"No assets found - use assets to better organize resources!": null,
"Manage assets": null,
"Asset Browser": null,
- "Browse assets": null,
"Filter assets": null,
+ "All assets": null,
"Reset filters": null,
"None": null,
"Quick Selection": null,
diff --git
a/ui/projects/streampipes/platform-services/src/lib/apis/export-provider.service.ts
b/ui/projects/streampipes/platform-services/src/lib/apis/export-provider.service.ts
index a626085171..6e8b4e61d7 100644
---
a/ui/projects/streampipes/platform-services/src/lib/apis/export-provider.service.ts
+++
b/ui/projects/streampipes/platform-services/src/lib/apis/export-provider.service.ts
@@ -21,7 +21,7 @@ import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { PlatformServicesCommons } from './commons.service';
import { ExportProviderSettings } from '../model/gen/streampipes-model';
-
+import { ExportProviderResponse } from
'../model/config/export-provider-config.model';
@Injectable({
providedIn: 'root',
})
@@ -42,6 +42,14 @@ export class ExportProviderService {
);
}
+ testExportProviderById(
+ providerId: string,
+ ): Observable<ExportProviderResponse> {
+ return this.http.get<ExportProviderResponse>(
+ `${this.exportProviderBasePath}/test/${providerId}`,
+ );
+ }
+
updateExportProvider(
exportProviderSettings: ExportProviderSettings,
): Observable<ExportProviderSettings> {
diff --git
a/streampipes-data-explorer-export/src/main/java/org/apache/streampipes/dataexplorer/export/ObjectStorge/IObjectStorage.java
b/ui/projects/streampipes/platform-services/src/lib/model/config/export-provider-config.model.ts
similarity index 73%
copy from
streampipes-data-explorer-export/src/main/java/org/apache/streampipes/dataexplorer/export/ObjectStorge/IObjectStorage.java
copy to
ui/projects/streampipes/platform-services/src/lib/model/config/export-provider-config.model.ts
index c913db65d4..4f60b8a675 100644
---
a/streampipes-data-explorer-export/src/main/java/org/apache/streampipes/dataexplorer/export/ObjectStorge/IObjectStorage.java
+++
b/ui/projects/streampipes/platform-services/src/lib/model/config/export-provider-config.model.ts
@@ -1,4 +1,4 @@
-/**
+/*
* 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.
@@ -15,12 +15,9 @@
* limitations under the License.
*
*/
-package org.apache.streampipes.dataexplorer.export.ObjectStorge;
-import
org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
-
-import java.io.IOException;
-
-public interface IObjectStorage {
- void store(StreamingResponseBody datastream) throws IOException;
-}
\ No newline at end of file
+import { ExportProviderSettings } from '../gen/streampipes-model';
+export interface ExportProviderResponse {
+ filePath: string;
+ setting: ExportProviderSettings;
+}
diff --git a/ui/src/app/configuration/configuration.module.ts
b/ui/src/app/configuration/configuration.module.ts
index f4ffeaafec..dadfbcac9c 100644
--- a/ui/src/app/configuration/configuration.module.ts
+++ b/ui/src/app/configuration/configuration.module.ts
@@ -31,6 +31,7 @@ import { MessagingConfigurationComponent } from
'./messaging-configuration/messa
import { DragDropModule } from '@angular/cdk/drag-drop';
import { DatalakeConfigurationComponent } from
'./datalake-configuration/datalake-configuration.component';
import { DeleteDatalakeIndexComponent } from
'./dialog/delete-datalake-index/delete-datalake-index-dialog.component';
+import { ExportProviderConnectionTestComponent } from
'./dialog/export-provider-connection-test/export-provider-connection-test.component';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { SecurityConfigurationComponent } from
'./security-configuration/security-configuration.component';
import { CoreUiModule } from '../core-ui/core-ui.module';
@@ -224,6 +225,7 @@ import { DeleteExportProviderComponent } from
'./dialog/delete-export-provider/d
ServiceConfigsItemComponent,
ServiceConfigsNumberComponent,
DeleteDatalakeIndexComponent,
+ ExportProviderConnectionTestComponent,
EditAssetLocationComponent,
EditAssetLocationAreaComponent,
EditRoleDialogComponent,
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 a78bea7e96..3a9f98b00a 100644
---
a/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.html
+++
b/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.html
@@ -413,6 +413,44 @@
</td>
</ng-container>
+ <ng-container matColumnDef="test">
+ <th mat-header-cell *matHeaderCellDef>
+ {{ 'Test' | translate }}
+ </th>
+ <td mat-cell *matCellDef="let configurationEntry">
+ <div>
+ <div fxLayout="row">
+ <span
+ fxFlex
+ fxFlexOrder="3"
+ fxLayout="row"
+ fxLayoutAlign="start center"
+ >
+ <button
+ color="accent"
+ mat-icon-button
+ matTooltip="{{
+ 'Test export provider
configuration'
+ | translate
+ }}"
+ data-cy="exportProvider-test-btn"
+ matTooltipPosition="above"
+ (click)="
+ testExportProvider(
+
configurationEntry.providerId
+ )
+ "
+ >
+ <i class="material-icons"
+ >bug_report</i
+ >
+ </button>
+ </span>
+ </div>
+ </div>
+ </td>
+ </ng-container>
+
<tr
mat-header-row
*matHeaderRowDef="displayedColumnsExport"
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 bd64e827da..bf28431c6e 100644
---
a/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.ts
+++
b/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.ts
@@ -48,6 +48,7 @@ import { DataRetentionDialogComponent } from
'../dialog/data-retention-dialog/da
import { ExportProviderComponent } from
'../dialog/export-provider-dialog/export-provider-dialog.component';
import { DeleteExportProviderComponent } from
'../dialog/delete-export-provider/delete-export-provider-dialog.component';
import { TranslateService } from '@ngx-translate/core';
+import { ExportProviderConnectionTestComponent } from
'../dialog/export-provider-connection-test/export-provider-connection-test.component';
@Component({
selector: 'sp-datalake-configuration',
@@ -94,6 +95,7 @@ export class DatalakeConfigurationComponent implements OnInit
{
'bucket',
'editExportProvider',
'delete',
+ 'test',
];
pageSize = 15;
@@ -237,6 +239,25 @@ export class DatalakeConfigurationComponent implements
OnInit {
}
});
}
+ testExportProvider(providerId: string) {
+ const dialogRef: DialogRef<ExportProviderConnectionTestComponent> =
+ this.dialogService.open(ExportProviderConnectionTestComponent, {
+ panelType: PanelType.STANDARD_PANEL,
+ title: this.translateService.instant(
+ 'Test Export Provider Connection',
+ ),
+ width: '70vw',
+ data: {
+ providerId: providerId,
+ },
+ });
+
+ dialogRef.afterClosed().subscribe(data => {
+ if (data) {
+ this.loadAvailableExportProvider();
+ }
+ });
+ }
openDownloadDialog(measurementName: string) {
this.dialogService.open(DataDownloadDialogComponent, {
diff --git
a/ui/src/app/configuration/dialog/export-provider-connection-test/export-provider-connection-test.component.html
b/ui/src/app/configuration/dialog/export-provider-connection-test/export-provider-connection-test.component.html
new file mode 100644
index 0000000000..a753e674c9
--- /dev/null
+++
b/ui/src/app/configuration/dialog/export-provider-connection-test/export-provider-connection-test.component.html
@@ -0,0 +1,79 @@
+<!--
+ ~ 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
+ fxLayoutAlign="center center"
+ fxLayout="column"
+ data-cy="connection-testing-in-progress"
+ >
+ <div fxLayout="row" fxLayoutAlign="space-around">
+ <b
+ ><h4>{{ currentStatus }}</h4></b
+ >
+ </div>
+ </div>
+
+ <div
+ fxLayoutAlign="center center"
+ fxLayout="column"
+ data-cy="connection-testing-in-progress"
+ >
+ <div fxLayout="row" fxLayoutAlign="space-around">
+ {{ filePath }}
+ </div>
+ </div>
+
+ @if (isError) {
+ <div class="sp-dialog-content p-20">
+ <sp-exception-details [title]="title" [message]="errorMessage">
+ </sp-exception-details>
+ </div>
+ }
+
+ @if (isInProgress) {
+ <div
+ fxLayoutAlign="center center"
+ fxLayout="column"
+ data-cy="connection-testing-in-progress"
+ >
+ <div fxLayout="row" fxLayoutAlign="space-around">
+ <mat-spinner
+ [mode]="'indeterminate'"
+ color="accent"
+ diameter="25"
+ ></mat-spinner>
+ </div>
+ </div>
+ }
+ </div>
+
+ <mat-divider></mat-divider>
+
+ <div class="sp-dialog-actions actions-align-right">
+ <button
+ mat-button
+ mat-flat-button
+ class="mat-basic"
+ (click)="close(false)"
+ >
+ {{ 'Close' | translate }}
+ </button>
+ </div>
+</div>
diff --git
a/ui/src/app/configuration/dialog/export-provider-connection-test/export-provider-connection-test.component.ts
b/ui/src/app/configuration/dialog/export-provider-connection-test/export-provider-connection-test.component.ts
new file mode 100644
index 0000000000..91aa46d5be
--- /dev/null
+++
b/ui/src/app/configuration/dialog/export-provider-connection-test/export-provider-connection-test.component.ts
@@ -0,0 +1,79 @@
+/*
+ * 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, inject, Input, OnInit } from '@angular/core';
+import { DialogRef } from '@streampipes/shared-ui';
+import { ExportProviderService } from '@streampipes/platform-services';
+import { TranslateService } from '@ngx-translate/core';
+
+@Component({
+ selector: 'sp-export-provider-connection-test',
+ templateUrl: './export-provider-connection-test.component.html',
+ standalone: false,
+})
+export class ExportProviderConnectionTestComponent implements OnInit {
+ ngOnInit(): void {
+ this.testExportProvider();
+ }
+ @Input()
+ providerId: string;
+
+ private dialogRef = inject(
+ DialogRef<ExportProviderConnectionTestComponent>,
+ );
+ private exportProviderRestService = inject(ExportProviderService);
+ private translateService = inject(TranslateService);
+
+ isInProgress = false;
+ currentStatus: string;
+ errorMessage = '';
+ isError = false;
+ message = '';
+ filePath = '';
+
+ close(refreshDataLakeIndex: boolean) {
+ this.dialogRef.close(refreshDataLakeIndex);
+ }
+
+ testExportProvider() {
+ this.isInProgress = true;
+ this.currentStatus = this.translateService.instant(
+ 'Testing the connection.',
+ );
+ this.exportProviderRestService
+ .testExportProviderById(this.providerId)
+ .subscribe(
+ data => {
+ this.isInProgress = false;
+ this.isError = false;
+ this.currentStatus = this.translateService.instant(
+ 'Connection was established and test file was
successfully saved:',
+ );
+ this.filePath = data.filePath;
+ },
+ errorMessage => {
+ this.currentStatus = this.translateService.instant(
+ 'Connection could not be established.',
+ );
+ this.errorMessage = errorMessage.error;
+ this.isError = true;
+ this.isInProgress = false;
+ },
+ );
+ }
+}