1. Erste Schritte
Diese Anleitung führt Sie durch die Schritte bis zum ersten Aufruf unter Verwendung des V5 Java API Clients.
Schnellstart (60 Sekunden)
3 erforderliche Dinge
| Element | Wert | Quelle |
|---|---|---|
| Serveradresse | http://<server-ip>:80 (TLS ist https://<server-ip>:443) | REST API Endpunkt. Gleiche Adresse wie die Web-Konsole |
| Account-ID | Bsp.: api | Benutzerkonto für API-Aufrufe |
| Token | UUID-Format | In der Konsole unter Sicherheitsverwaltung → API-Authentifizierungstoken (/token/index) für dieses Konto ausgestellt → Sicherheitseinstellungen · Sicherheitsverwaltung |
Mit diesen drei Werten ist der erste Aufruf mit einem einzigen Block möglich.
import java.util.List;
import plantpulse.api.v5.APIClient_V5;
import plantpulse.api.v5.dto.response.SiteResponseV5;
try (APIClient_V5 client = new APIClient_V5(
"HTTP", "100.68.69.41", 80, "api", "<issued-token>", false)) {
client.connect(); // 인증
System.out.println(client.system().ping().isPing()); // → true
for (SiteResponseV5 s : client.site().list()) // 사이트 목록
System.out.println(s.getSite_id() + " — " + s.getSite_name());
}
Wenn dieser Block true und die Standortliste ausgibt, ist alles bereit. Die Abschnitte 1.1 bis 1.7 erläutern die einzelnen Schritte im Detail.
1.1 Abhängigkeiten hinzufügen
Fügen Sie die JAR-Datei zum Classpath hinzu.
# 빌드 (Gradle + Java 21)
cd plantpulse-api
./gradlew build
Das Build-Artefakt wird in target/ erstellt.
| Datei | Verwendungszweck |
|---|---|
target/plantpulse-api.jar | Zur Integration in bestehende Projekte zusammen mit den Abhängigkeiten |
1.2 Client erstellen
Übergeben Sie die Optionen direkt an den Konstruktor von APIClient_V5.
import plantpulse.api.v5.APIClient_V5;
APIClient_V5 client = new APIClient_V5(
"HTTPS", // 프로토콜: "HTTP" 또는 "HTTPS"
"100.68.69.41", // host
443, // port (REST API: 80=HTTP, 443=HTTPS)
"api", // user_id
"19ba7a54-1132-49f2-967e-3c6f5cd989a0", // token (api_key 발급용)
false); // debug
client.connect(); // 인증 + HTTP 클라이언트 초기화
// ... API 호출 ...
client.close(); // 종료
Konstruktor-Parameter
| Parameter | Typ | Beschreibung |
|---|---|---|
protocol | String | "HTTP" oder "HTTPS" |
host | String | Server-Host oder IP |
port | int | Server-Port |
user_id | String | Authentifizierungs-Account-ID |
token | String | Ausgestelltes Token (UUID-Format) |
debug | boolean | Debug-Logs für HTTP-Anfragen und -Antworten |
Authentifizierungsfluss: Beim Aufruf von
connect()wird intern überuser_id+tokenein api_key ausgestellt. Dieser Schlüssel wird anschließend bei jedem weiteren Aufruf automatisch im Header mitgesendet. Der Benutzer muss diesen Schlüssel nicht manuell verwalten.
1.3 Erster API-Aufruf — Ping & Standortliste
import java.util.List;
import plantpulse.api.v5.APIClient_V5;
import plantpulse.api.v5.dto.response.SiteResponseV5;
import plantpulse.api.v5.dto.response.SystemPingResponseV5;
public class FirstCall {
public static void main(String[] args) throws Exception {
try (APIClient_V5 client = new APIClient_V5(
"HTTP", "100.68.69.41", 80, "api",
"19ba7a54-1132-49f2-967e-3c6f5cd989a0", false)) {
client.connect();
// 1) 서버 헬스체크
SystemPingResponseV5 ping = client.system().ping();
System.out.println("Server alive: " + ping.isPing()
+ " (v" + ping.getVersion() + ")");
// 2) 사이트 목록 (typed DTO 리스트)
List<SiteResponseV5> sites = client.site().list();
for (SiteResponseV5 s : sites) {
System.out.println(s.getSite_id() + " — " + s.getSite_name());
}
}
}
}
Ausführungsergebnis:
Server alive: true (v5.0)
SITE_000001 — 대전 1공장
SITE_000002 — 천안 2공장
1.4 Try-with-Resources Muster
APIClient_V5 implementiert AutoCloseable. Die Verwendung von try-with-resources wird empfohlen.
try (APIClient_V5 client = new APIClient_V5(proto, host, port, user, token, false)) {
client.connect();
// ... API 호출 ...
}
// close() 자동 호출 — HTTP 커넥션 정리
1.5 Alle 13 Dienste im Überblick
Unmittelbar nach connect() können Sie über die folgenden Servicemethoden auf alle Domänen zugreifen (Lazy Initialization).
client.system() // 헬스체크
client.site() // 사이트(공장)
client.customer() // 고객
client.employee() // 직원
client.product() // 제품
client.asset() // 자산 계층 (Area → Line → Equipment)
client.opc() // OPC 데이터 채널
client.tag() // 태그(데이터 포인트)
client.alarm() // 알람
client.order() // 작업지시
client.calendar() // 일정
client.path() // 자산 경로
client.flow() // Flow / Flow Node
1.6 V5 Methodensignatur Standardmuster
Alle Domänendienste folgen einem konsistenten Methodenmuster. Die Verwendung ist identisch, lediglich der Domänenname unterscheidet sich.
| Muster | Rückgabetyp | Rückgabewert bei Fehler | Beschreibung |
|---|---|---|---|
create(req) | *ResponseV5 | null | Registrierung |
update(id, req) | *ResponseV5 | null | Gesamte Änderung |
delete(id) | boolean | false | Löschung |
get(id) | *ResponseV5 | null | Einzelabfrage |
list() | List<*ResponseV5> | Leere Liste | Gesamte Liste |
exists(id) | boolean | false | Existenzprüfung |
count() | long | 0 | Zählung |
⚠️ Es werden keine Exceptions geworfen. Kommunikationsfehler oder Server-ERROR-Antworten werden als sichere Standardwerte gemäß der obigen Tabelle zurückgegeben. Die Fehlerursache kann über die Logs oder
BaseServiceV5.getErrorCode(env)ermittelt werden. Weitere Details finden Sie unter Antwortformate und Fehlerbehandlung.
1.7 Debug-Modus
Wenn das letzte Argument des Konstruktors auf true gesetzt wird, werden die HTTP-Anfragen und -Antworten in der Konsole ausgegeben.
APIClient_V5 client = new APIClient_V5(
"HTTP", "100.68.69.41", 80, "api", TOKEN, true); // debug=true
Ausgabebeispiel:
[V5] GET https://server/api/v5/site headers={api_key=ab****cd}
[V5] response: 200 {"_status":"OK","data":[{"site_id":"SITE_000001",...}]}
1.8 Bei Authentifizierungsfehlern — 503 bedeutet nicht «Falscher Schlüssel»
connect() tauscht das Token über POST /api/v5/auth gegen api_key aus. Ein Erfolg wird nicht allein durch HTTP 200 definiert — der Erfolg liegt vor, wenn meta.status gleich "OK" ist und data.api_key nicht leer ist. Dass es eine zweite Bedingung gibt, liegt daran, dass es Pfade gibt, bei denen die Token-Prüfung bestanden wurde, aber die Schlüsselausstellung fehlgeschlagen ist (in diesem Fall gibt der Server einen Fehler 500 zurück).
curl -s -X POST "http://<server>/api/v5/auth" \
-H "Content-Type: application/json; charset=UTF-8" \
-d '{"token":"<issued-token>"}'
# 200: {"data":{"api_key":"..."},"meta":{"status":"OK"},"errors":null}
| Antwort | Code | Bedeutung | Was ist zu korrigieren? |
|---|---|---|---|
| 400 | E1001 | token fehlt oder ist leer | Request Body |
| 422 | E1002 | Body ist kein JSON | Request Body |
| 401 | E1100 | Token ist falsch | Anmeldedaten |
| 401 | E1102 | Token abgelaufen | Wiederherstellung durch Neuausstellung |
| 401 | E1103 | Token widerrufen | Gleiches Token nicht wiederherstellbar — Bitte neues Token anfordern |
| 429 | E1101 | Zu viele Fehler von derselben IP | Wartezeit von Retry-After abwarten, dann mit korrigierten Werten erneut versuchen |
| 500 | E5000 | Token ist korrekt, aber api_key Ausstellung fehlgeschlagen | Serverseitig — keine Anmeldedaten |
| 503 | E5500 | Token-Speicher nicht erreichbar «keine Entscheidung möglich» | Serverseitig — keine Anmeldedaten |
Der Server gibt keinen 401 zurück, wenn der Token-Speicher (PostgreSQL) nicht erreichbar ist. Ein 401 ist eine Behauptung, dass «Ihre Anmeldedaten falsch sind». Wenn der Speicher nicht erreichbar ist, weiß der Server jedoch nicht, ob das Token gültig ist oder nicht. Das Problem besteht darin, dass der Aufrufer diese beiden Fälle sonst nicht unterscheiden könnte.
Tatsächlich gab es einen solchen Vorfall am 07.09.2026, bei dem nächtliche E2E-Tests über acht Tage lang «22/22 fehlgeschlagen, E1100 Token authentication failed» meldeten, während die tatsächliche Ursache in den Plattform-Logs Connection to plantpulse-datalake:5432 refused war. Ein PostgreSQL-Ausfall tarnte sich acht Tage lang als Anmeldedatenfehler. Mittlerweile werden Speicher-Exceptions (SQLException · Socket-Klasse) bis zur Ursachenkette verfolgt und als 503 E5500 beantwortet.
Aus demselben Grund wird 503 nicht als fehlgeschlagener Authentifizierungsversuch gezählt. Würde man dies tun, würde ein DB-Ausfall korrekte Aufrufer durch einen 429-Fehler sperren — eine Sperre würde sich auf einen bestehenden Ausfall legen.
Der Java-Client gibt diese Unterscheidung direkt in der Exception-Message zurück. Entscheiden Sie anhand der Nachricht, was korrigiert werden muss.
| Nachricht | Bedeutung |
|---|---|
V5 connect: /api/v5/auth call failed — … | Anfrage hat den Server nicht erreicht (Adresse, Port, Firewall) |
V5 connect: auth endpoint unavailable (http=503) — server reached no verdict about the token | Server konnte keine Entscheidung treffen — Token nicht infrage stellen |
V5 connect: authentication failed — … | 401/400-Serie — Anmeldedaten oder Anfrage korrigieren |
V5 connect: api_key issuance failed — response=… | meta.status ist OK, aber Schlüssel ist leer — serverseitig |
Wenn von derselben IP engine.api.v5.auth.bruteforce.ip_limit (Standard: 30) Fehlversuche gesammelt werden, erfolgt eine Sperre per 429 für engine.api.v5.auth.bruteforce.window.minutes (Standard: 15 Minuten). Dies kann über engine.api.v5.auth.bruteforce.enabled=false deaktiviert werden, macht das System jedoch anfällig für Token-Brute-Force-Angriffe. Anfragen, deren Body kein JSON ist, gelten nicht als Authentifizierungsversuch und werden nicht mitgezählt.
Nächste Schritte
- Domänen-ID-Regeln — Bitte unbedingt als Nächstes lesen. Die Validierung von ID-Präfixen ist zwingend erforderlich.
- Antwortformate und Fehlerbehandlung — Fehlercode-Mapping und sichere Verarbeitungsmuster
- Site-Service — Erstellung der ersten Stammdaten