Commit 4838dbb7 authored by Labros Papadopoulos's avatar Labros Papadopoulos
Browse files

fix: retry mechanism in case of small connect timeout in rest client

parent 036ff1f0
Loading
Loading
Loading
Loading
Loading
+27 −7
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@ import io.quarkus.rest.client.reactive.QuarkusRestClientBuilder;
import io.smallrye.mutiny.Uni;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.Response;
import java.io.Closeable;
import java.io.IOException;
@@ -73,7 +74,8 @@ public class OssRestClientImpl {
            String username,
            String password,
            String organizationId,
            String authUrl) {
            String authUrl)
            throws Exception {

        return executeWithRetry(
                baseUrl,
@@ -85,8 +87,14 @@ public class OssRestClientImpl {
                password,
                authUrl,
                (client, token) -> {
                    logger.debugf(
                            "Trying to fetch specifications from organization with id: %s", organizationId);
                    Response response = client.getServiceSpecifications("Bearer " + token.getAccessToken());
                    String jsonResponse = response.readEntity(String.class);
                    if (jsonResponse == null || jsonResponse.isBlank()) {
                        throw new WebApplicationException(
                                "Empty response body from OSS  " + organizationId, response.getStatus());
                    }
                    return objectMapper.readValue(
                            jsonResponse, new TypeReference<List<ServiceSpecificationEntity>>() {});
                });
@@ -101,7 +109,8 @@ public class OssRestClientImpl {
            String password,
            String serviceSpecificationId,
            String organizationId,
            String authUrl) {
            String authUrl)
            throws Exception {

        return executeWithRetry(
                baseUrl,
@@ -113,10 +122,19 @@ public class OssRestClientImpl {
                password,
                authUrl,
                (client, token) -> {
                    logger.debugf("Trying to fetch spec with id: %s ", serviceSpecificationId);
                    Response response =
                            client.getServiceSpecificationById(
                                    "Bearer " + token.getAccessToken(), serviceSpecificationId);
                    String jsonResponse = response.readEntity(String.class);
                    if (jsonResponse == null || jsonResponse.isBlank()) {
                        logger.warnf(
                                "Empty body from OSS for spec %s. status=%d headers=%s",
                                serviceSpecificationId, response.getStatus(), response.getHeaders());
                        throw new WebApplicationException(
                                "Empty response body from OSS for spec " + serviceSpecificationId,
                                response.getStatus());
                    }
                    ServiceSpecification spec =
                            objectMapper.readValue(jsonResponse, ServiceSpecification.class);
                    return serviceSpecificationMapper.mapToServiceSpecificationEntity(
@@ -148,7 +166,8 @@ public class OssRestClientImpl {
            String user,
            String pass,
            String authUrl,
            BiFunctionWithException<OssRestClient, Tokens, T> action) {
            BiFunctionWithException<OssRestClient, Tokens, T> action)
            throws Exception {
        OssRestClient client = getCachedRestClient(baseUrl);

        // Compute token if missing
@@ -159,12 +178,13 @@ public class OssRestClientImpl {
            logger.debugf(
                    "Request failed for %s, attempting to refresh token and retry: " + e.getMessage(), name);

            // Force refresh token
            tokens = createToken(name, authUrl, clientId, secret, user, pass);
            tokenCache.put(orgId, tokens); // Update cache
            clientCache.invalidate(baseUrl);
            OssRestClient freshClient = getCachedRestClient(baseUrl);

            tokens = createToken(name, authUrl, clientId, secret, user, pass);
            tokenCache.put(orgId, tokens);
            try {
                return action.apply(client, tokens);
                return action.apply(freshClient, tokens);
            } catch (Exception retryEx) {
                throw new RuntimeException("Failed to execute request after token refresh", retryEx);
            }
+1 −1
Original line number Diff line number Diff line
@@ -89,7 +89,7 @@ public class HealthCheckService {
    }

    public void checkPeeredOrganizationStatus(
            OssClientData ossClientData, PeeringInfoSecret peeringInfoSecret) {
            OssClientData ossClientData, PeeringInfoSecret peeringInfoSecret) throws Exception {

        List<ServiceSpecificationEntity> serviceSpecificationEntities =
                ossRestClientImpl.callOssToGetServiceSpecifications(
+3 −4
Original line number Diff line number Diff line
@@ -12,7 +12,6 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import com.fasterxml.jackson.core.JsonProcessingException;
import io.quarkus.oidc.client.Tokens;
import io.quarkus.test.InjectMock;
import io.quarkus.test.junit.QuarkusTest;
@@ -54,7 +53,7 @@ class OssRestClientImplTest {
    }

    @Test
    void testCallOssToGetServiceSpecifications_Success() throws JsonProcessingException {
    void testCallOssToGetServiceSpecifications_Success() throws Exception {

        doReturn(mockOpenSliceRestClient).when(ossRestClient).getCachedRestClient(anyString());

@@ -78,7 +77,7 @@ class OssRestClientImplTest {
    }

    @Test
    void testCallOssToGetServiceSpecifications_RetryOnFailure() throws JsonProcessingException {
    void testCallOssToGetServiceSpecifications_RetryOnFailure() throws Exception {
        doReturn(mockOpenSliceRestClient).when(ossRestClient).getCachedRestClient(anyString());

        // Define two tokens: Old one and New one
@@ -114,7 +113,7 @@ class OssRestClientImplTest {
    }

    @Test
    void testRetrieveServiceSpecification_Mapping() throws JsonProcessingException {
    void testRetrieveServiceSpecification_Mapping() throws Exception {
        doReturn(mockOpenSliceRestClient).when(ossRestClient).getCachedRestClient(anyString());

        Tokens mockTokens = new Tokens(ACCESS_TOKEN, 1000L, null, null, null, null, null);
+3 −6
Original line number Diff line number Diff line
@@ -4,7 +4,6 @@ import static com.github.tomakehurst.wiremock.common.Json.getObjectMapper;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
@@ -13,7 +12,6 @@ import io.quarkus.test.junit.QuarkusMock;
import io.quarkus.test.junit.QuarkusTest;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.microprofile.rest.client.inject.RestClient;
@@ -60,7 +58,7 @@ class HealthCheckServiceTest {
    }

    @Test
    void peeredOrganizationsHealthCheckTest() throws MalformedURLException, JsonProcessingException {
    void peeredOrganizationsHealthCheckTest() throws Exception {
        when(registryClient.getSecretWithVaultToken(any(), any()))
                .thenReturn(preparePeeringInfoSecret());
        persistOssClientData(prepareOssClientData());
@@ -82,7 +80,7 @@ class HealthCheckServiceTest {
    }

    @Test
    void checkPeeredOrganizationStatusTest() throws MalformedURLException, JsonProcessingException {
    void checkPeeredOrganizationStatusTest() throws Exception {
        when(ossRestClientImpl.callOssToGetServiceSpecifications(
                        "testName", null, null, null, null, null, null, null))
                .thenThrow();
@@ -94,8 +92,7 @@ class HealthCheckServiceTest {
    }

    @Test
    void checkPeeredOrganizationStatusPerIdTest()
            throws MalformedURLException, JsonProcessingException {
    void checkPeeredOrganizationStatusPerIdTest() throws Exception {
        when(ossRestClientImpl.retrieveServiceSpecification(
                        "testName",
                        null,
+5 −5
Original line number Diff line number Diff line
@@ -108,7 +108,7 @@ class PeeringServiceTest {
    }

    @Test
    void peerNewOssTest() throws JsonProcessingException, FileNotFoundException {
    void peerNewOssTest() throws Exception {
        com.google.gson.JsonArray jsonArray =
                FileReader.getJsonArrayFromFileReader("Util", "ServiceSpecificationList.json");

@@ -126,7 +126,7 @@ class PeeringServiceTest {
    }

    @Test
    void addPeeredOssTest() throws JsonProcessingException, FileNotFoundException {
    void addPeeredOssTest() throws Exception {
        com.google.gson.JsonArray jsonArray =
                FileReader.getJsonArrayFromFileReader("Util", "ServiceSpecificationList.json");

@@ -145,7 +145,7 @@ class PeeringServiceTest {
    }

    @Test
    void sendPeeredSpecsToTmfApi_testBatches() throws JsonProcessingException, FileNotFoundException {
    void sendPeeredSpecsToTmfApi_testBatches() throws Exception {
        com.google.gson.JsonArray jsonArray =
                FileReader.getJsonArrayFromFileReader("Util", "ServiceSpecificationList.json");

@@ -194,7 +194,7 @@ class PeeringServiceTest {
    }

    @Test
    void updatePeeredOssTest() throws JsonProcessingException, FileNotFoundException {
    void updatePeeredOssTest() throws Exception {
        com.google.gson.JsonArray jsonArray =
                FileReader.getJsonArrayFromFileReader("Util", "ServiceSpecificationList.json");

@@ -217,7 +217,7 @@ class PeeringServiceTest {
    }

    @Test
    void updatePeeredOssTest_testBatches() throws JsonProcessingException, FileNotFoundException {
    void updatePeeredOssTest_testBatches() throws Exception {
        com.google.gson.JsonArray jsonArray =
                FileReader.getJsonArrayFromFileReader("Util", "ServiceSpecificationList.json");