From 404ed9ebe00cca865cf6c2cadf65086dac1ebf02 Mon Sep 17 00:00:00 2001 From: Valentin Stern Date: Wed, 26 Nov 2025 17:10:24 +0100 Subject: [PATCH 1/4] [backend] feat: reset XTM Hub registration when platform is not found --- .../java/io/openaev/xtmhub/XtmHubClient.java | 5 ++-- .../xtmhub/XtmHubConnectivityStatus.java | 3 ++- .../java/io/openaev/xtmhub/XtmHubService.java | 19 +++++++++------ .../io/openaev/xtmhub/XtmHubServiceTest.java | 24 +++++++++++++++++++ 4 files changed, 41 insertions(+), 10 deletions(-) diff --git a/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubClient.java b/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubClient.java index 79ffab1d755..74cd336fffa 100644 --- a/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubClient.java +++ b/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubClient.java @@ -57,12 +57,13 @@ mutation RefreshPlatformRegistrationConnectivityStatus($input: RefreshPlatformRe "input": { "platformId": "%s", "platformVersion": "%s", - "token": "%s" + "token": "%s", + "platformIdentifier": "%s" } } } """, - platformId, platformVersion, token); + platformId, platformVersion, token, "openaev"); JsonElement element = JsonParser.parseString(mutationBody); return new StringEntity(element.toString()); diff --git a/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubConnectivityStatus.java b/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubConnectivityStatus.java index 8ecad449760..788b89f6d82 100644 --- a/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubConnectivityStatus.java +++ b/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubConnectivityStatus.java @@ -2,7 +2,8 @@ public enum XtmHubConnectivityStatus { ACTIVE("active"), - INACTIVE("inactive"); + INACTIVE("inactive"), + NOT_FOUND("not_found"); public final String label; diff --git a/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubService.java b/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubService.java index 9620b75514e..1afb38b36e1 100644 --- a/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubService.java +++ b/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubService.java @@ -41,12 +41,15 @@ public PlatformSettings unregister() { public PlatformSettings refreshConnectivity() { PlatformSettings settings = platformSettingsService.findSettings(); - if (!isRegisteredWithXtmHub(settings)) { return settings; } ConnectivityCheckResult checkResult = checkConnectivityStatus(settings); + if (checkResult.status == XtmHubConnectivityStatus.NOT_FOUND) { + return platformSettingsService.deleteXTMHubRegistration(); + } + handleConnectivityLossNotification(settings, checkResult); return updateRegistrationStatus(settings, checkResult); @@ -61,10 +64,9 @@ private ConnectivityCheckResult checkConnectivityStatus(PlatformSettings setting xtmHubClient.refreshRegistrationStatus( settings.getPlatformId(), settings.getPlatformVersion(), settings.getXtmHubToken()); - boolean isActive = status == XtmHubConnectivityStatus.ACTIVE; LocalDateTime lastCheck = parseLastConnectivityCheck(settings); - return new ConnectivityCheckResult(isActive, lastCheck); + return new ConnectivityCheckResult(status, lastCheck); } private LocalDateTime parseLastConnectivityCheck(PlatformSettings settings) { @@ -83,7 +85,7 @@ private void handleConnectivityLossNotification( private boolean shouldSendConnectivityLossEmail( PlatformSettings settings, ConnectivityCheckResult checkResult) { - return !checkResult.isActive() + return checkResult.status() != XtmHubConnectivityStatus.ACTIVE && hasConnectivityBeenLostForTooLong(checkResult.lastCheck()) && isEmailNotificationEnabled(settings); } @@ -101,12 +103,14 @@ private PlatformSettings updateRegistrationStatus( PlatformSettings settings, ConnectivityCheckResult checkResult) { XtmHubRegistrationStatus newStatus = - checkResult.isActive() + checkResult.status() == XtmHubConnectivityStatus.ACTIVE ? XtmHubRegistrationStatus.REGISTERED : XtmHubRegistrationStatus.LOST_CONNECTIVITY; LocalDateTime updatedLastCheck = - checkResult.isActive() ? LocalDateTime.now() : checkResult.lastCheck(); + checkResult.status() == XtmHubConnectivityStatus.ACTIVE + ? LocalDateTime.now() + : checkResult.lastCheck(); boolean shouldKeepEmailNotificationEnabled = !shouldSendConnectivityLossEmail(settings, checkResult); @@ -126,5 +130,6 @@ private LocalDateTime parseRegistrationDate(PlatformSettings settings) { } /** Encapsulates the result of a connectivity check */ - private record ConnectivityCheckResult(boolean isActive, LocalDateTime lastCheck) {} + private record ConnectivityCheckResult( + XtmHubConnectivityStatus status, LocalDateTime lastCheck) {} } diff --git a/openaev-api/src/test/java/io/openaev/xtmhub/XtmHubServiceTest.java b/openaev-api/src/test/java/io/openaev/xtmhub/XtmHubServiceTest.java index 9da4823fc97..1e14472fa38 100644 --- a/openaev-api/src/test/java/io/openaev/xtmhub/XtmHubServiceTest.java +++ b/openaev-api/src/test/java/io/openaev/xtmhub/XtmHubServiceTest.java @@ -76,6 +76,30 @@ void refreshConnectivity_WhenTokenIsNull_ShouldReturnSettingsUnchanged() { verifyNoInteractions(xtmHubEmailService); } + @Test + @DisplayName("Should remove XTM Hub registration when platform is not found in the hub") + void refreshConnectivity_WhenPlatformIsNotFound_ShouldRemoveRegistration() { + // Given + String token = "valid-token"; + String platformId = "platform-123"; + String platformVersion = "1.0.0"; + + mockSettings.setXtmHubToken(token); + mockSettings.setPlatformId(platformId); + mockSettings.setPlatformVersion(platformVersion); + + when(platformSettingsService.findSettings()).thenReturn(mockSettings); + when(xtmHubClient.refreshRegistrationStatus(platformId, platformVersion, token)) + .thenReturn(XtmHubConnectivityStatus.NOT_FOUND); + + // When + xtmHubService.refreshConnectivity(); + + // Then + verify(platformSettingsService).deleteXTMHubRegistration(); + verifyNoInteractions(xtmHubEmailService); + } + @Test @DisplayName("Should update registration as REGISTERED when connectivity is ACTIVE") void refreshConnectivity_WhenConnectivityIsActive_ShouldUpdateAsRegistered() { From fa3146d712b7cee049c473c8b520c0c46bbdfb65 Mon Sep 17 00:00:00 2001 From: Valentin Stern Date: Thu, 27 Nov 2025 12:31:23 +0100 Subject: [PATCH 2/4] chore: use constant as hub platform identifier --- openaev-api/src/main/java/io/openaev/xtmhub/XtmHubClient.java | 3 ++- openaev-api/src/main/java/io/openaev/xtmhub/XtmHubService.java | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubClient.java b/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubClient.java index 74cd336fffa..0aed885de4b 100644 --- a/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubClient.java +++ b/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubClient.java @@ -22,6 +22,7 @@ public class XtmHubClient { private final XtmHubConfig config; private final HttpClientFactory httpClientFactory; + private static final String platformIdentifier = "openaev"; public XtmHubConnectivityStatus refreshRegistrationStatus( String platformId, String platformVersion, String token) { @@ -63,7 +64,7 @@ mutation RefreshPlatformRegistrationConnectivityStatus($input: RefreshPlatformRe } } """, - platformId, platformVersion, token, "openaev"); + platformId, platformVersion, token, platformIdentifier); JsonElement element = JsonParser.parseString(mutationBody); return new StringEntity(element.toString()); diff --git a/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubService.java b/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubService.java index 1afb38b36e1..1ae1efee27a 100644 --- a/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubService.java +++ b/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubService.java @@ -47,6 +47,7 @@ public PlatformSettings refreshConnectivity() { ConnectivityCheckResult checkResult = checkConnectivityStatus(settings); if (checkResult.status == XtmHubConnectivityStatus.NOT_FOUND) { + log.warn("Platform was not found on XTM Hub"); return platformSettingsService.deleteXTMHubRegistration(); } From 2cd55cf38d35d4e4e07384ad8a9bb7928a6d0aad Mon Sep 17 00:00:00 2001 From: Valentin Stern Date: Mon, 1 Dec 2025 12:15:16 +0100 Subject: [PATCH 3/4] fix: add log and fix wrong status returned --- .../main/java/io/openaev/xtmhub/XtmHubClient.java | 4 ++++ .../io/openaev/xtmhub/XtmHubConnectivityService.java | 12 ++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubClient.java b/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubClient.java index 0aed885de4b..381d3b722b0 100644 --- a/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubClient.java +++ b/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubClient.java @@ -92,6 +92,10 @@ private XtmHubConnectivityStatus parseResponseAsConnectivityStatus(ClassicHttpRe return XtmHubConnectivityStatus.ACTIVE; } + if (status.equals(XtmHubConnectivityStatus.NOT_FOUND.label)) { + return XtmHubConnectivityStatus.NOT_FOUND; + } + return XtmHubConnectivityStatus.INACTIVE; } catch (Exception e) { log.warn("Error occurred while parsing XTM Hub connectivity response: {}", e.getMessage(), e); diff --git a/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubConnectivityService.java b/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubConnectivityService.java index 89d3f123d3a..0104f54f0bd 100644 --- a/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubConnectivityService.java +++ b/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubConnectivityService.java @@ -5,9 +5,11 @@ import java.net.*; import lombok.Getter; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; +@Slf4j @Service @RequiredArgsConstructor public class XtmHubConnectivityService { @@ -23,13 +25,19 @@ void init() { boolean checkIsReachable() { HttpURLConnection connection = null; try { - URI uri = new URI(XtmHubConfig.getApiUrl()); + URI uri = new URI(XtmHubConfig.getApiUrl() + "/health"); connection = (HttpURLConnection) uri.toURL().openConnection(); connection.setRequestMethod("HEAD"); connection.setConnectTimeout(5000); connection.setReadTimeout(5000); - return HttpStatus.valueOf(connection.getResponseCode()).is2xxSuccessful(); + HttpStatus httpStatus = HttpStatus.valueOf(connection.getResponseCode()); + boolean isReachable = httpStatus.is2xxSuccessful(); + if (!isReachable){ + log.warn("XTM Hub backend is not reachable on URl {}, response status: {}", XtmHubConfig.getApiUrl(), httpStatus); + } + return isReachable; } catch (Exception e) { + log.warn("XTM Hub backend is not reachable on URL {} due to {}", XtmHubConfig.getApiUrl(), e.getMessage(), e); return false; } finally { if (connection != null) { From 2b2efc83ee3384ca9efd116485593de92c31d331 Mon Sep 17 00:00:00 2001 From: Valentin Stern Date: Mon, 1 Dec 2025 14:55:20 +0100 Subject: [PATCH 4/4] chore: apply spotless --- .../openaev/xtmhub/XtmHubConnectivityService.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubConnectivityService.java b/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubConnectivityService.java index 0104f54f0bd..347ffab83e3 100644 --- a/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubConnectivityService.java +++ b/openaev-api/src/main/java/io/openaev/xtmhub/XtmHubConnectivityService.java @@ -25,19 +25,26 @@ void init() { boolean checkIsReachable() { HttpURLConnection connection = null; try { - URI uri = new URI(XtmHubConfig.getApiUrl() + "/health"); + URI uri = new URI(XtmHubConfig.getApiUrl()); connection = (HttpURLConnection) uri.toURL().openConnection(); connection.setRequestMethod("HEAD"); connection.setConnectTimeout(5000); connection.setReadTimeout(5000); HttpStatus httpStatus = HttpStatus.valueOf(connection.getResponseCode()); boolean isReachable = httpStatus.is2xxSuccessful(); - if (!isReachable){ - log.warn("XTM Hub backend is not reachable on URl {}, response status: {}", XtmHubConfig.getApiUrl(), httpStatus); + if (!isReachable) { + log.warn( + "XTM Hub backend is not reachable on URl {}, response status: {}", + XtmHubConfig.getApiUrl(), + httpStatus); } return isReachable; } catch (Exception e) { - log.warn("XTM Hub backend is not reachable on URL {} due to {}", XtmHubConfig.getApiUrl(), e.getMessage(), e); + log.warn( + "XTM Hub backend is not reachable on URL {} due to {}", + XtmHubConfig.getApiUrl(), + e.getMessage(), + e); return false; } finally { if (connection != null) {