From 9b5b24ec9e29ce6d4a95744a554595cfbf6c8aac Mon Sep 17 00:00:00 2001 From: baixinsui Date: Fri, 9 Aug 2024 22:54:58 +0800 Subject: [PATCH] avoid retries for auth errors in cloud API requests (#1862) --- .../handler/CommonExceptionHandler.java | 24 ++++++ .../ServiceMetricsExceptionHandler.java | 12 --- .../ServiceMetricsExceptionHandlerTest.java | 15 ---- .../ClientApiCallFailedException.java | 2 +- .../ClientAuthenticationFailedException.java | 16 ++++ .../ClientApiCallFailedExceptionTest.java | 1 + .../price/ServicePricesManager.java | 3 +- .../common/FlexibleEngineClient.java | 23 ++--- .../common/FlexibleEngineRetryStrategy.java | 39 +++++++++ .../manage/FlexibleEngineResourceManager.java | 84 ++++++------------- .../manage/FlexibleEngineVmStateManager.java | 24 ++---- .../monitor/FlexibleEngineMetricsService.java | 21 ++--- .../common/FlexibleEngineClientTest.java | 3 +- .../huaweicloud/common/HuaweiCloudClient.java | 34 ++++---- .../common/HuaweiCloudRetryStrategy.java | 40 +++++++++ .../manage/HuaweiCloudResourceManager.java | 84 ++++++------------- .../manage/HuaweiCloudVmStateManager.java | 24 ++---- .../monitor/HuaweiCloudMetricsService.java | 21 ++--- .../HuaweiCloudChinesePriceCalculator.java | 29 ++++--- .../price/HuaweiCloudPriceCalculator.java | 15 +--- .../common/auth/ProviderAuthInfoResolver.java | 43 +++++++++- .../manage/OpenstackResourceManager.java | 68 ++++----------- .../manage/OpenstackServersManager.java | 25 ++---- .../OpenstackServiceMetricsManager.java | 12 +-- .../ExistingCloudResourcesApiTest.java | 23 ----- .../flexibleEngine-compute-terraform-dev.yml | 2 - samples/flexibleEngine-K8S.yml | 2 - samples/flexibleEngine-Kafka.yml | 2 - 28 files changed, 322 insertions(+), 369 deletions(-) rename modules/models/src/main/java/org/eclipse/xpanse/modules/models/{monitor => common}/exceptions/ClientApiCallFailedException.java (83%) create mode 100644 modules/models/src/main/java/org/eclipse/xpanse/modules/models/common/exceptions/ClientAuthenticationFailedException.java diff --git a/modules/api/src/main/java/org/eclipse/xpanse/api/exceptions/handler/CommonExceptionHandler.java b/modules/api/src/main/java/org/eclipse/xpanse/api/exceptions/handler/CommonExceptionHandler.java index e3877c077..35b3865b5 100644 --- a/modules/api/src/main/java/org/eclipse/xpanse/api/exceptions/handler/CommonExceptionHandler.java +++ b/modules/api/src/main/java/org/eclipse/xpanse/api/exceptions/handler/CommonExceptionHandler.java @@ -21,6 +21,8 @@ import java.util.Set; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import org.eclipse.xpanse.modules.models.common.exceptions.ClientApiCallFailedException; +import org.eclipse.xpanse.modules.models.common.exceptions.ClientAuthenticationFailedException; import org.eclipse.xpanse.modules.models.common.exceptions.GitRepoCloneException; import org.eclipse.xpanse.modules.models.common.exceptions.ResponseInvalidException; import org.eclipse.xpanse.modules.models.common.exceptions.SensitiveFieldEncryptionOrDecryptionFailedException; @@ -245,6 +247,28 @@ public Response handleGitRepoCloneException(GitRepoCloneException ex) { Collections.singletonList(failMessage)); } + /** + * Exception handler for ClientApiCallFailedException. + */ + @ExceptionHandler({ClientApiCallFailedException.class}) + @ResponseStatus(HttpStatus.BAD_GATEWAY) + @ResponseBody + public Response handleClientApiCalledException(ClientApiCallFailedException ex) { + return getErrorResponse(ResultType.BACKEND_FAILURE, + Collections.singletonList(ex.getMessage())); + } + + /** + * Exception handler for ClientAuthenticationFailedException. + */ + @ExceptionHandler({ClientAuthenticationFailedException.class}) + @ResponseStatus(HttpStatus.BAD_GATEWAY) + @ResponseBody + public Response handleClientAuthException(ClientAuthenticationFailedException ex) { + return getErrorResponse(ResultType.BACKEND_FAILURE, + Collections.singletonList(ex.getMessage())); + } + private String findDuplicatesItemsString(List list) { if (!CollectionUtils.isEmpty(list)) { List duplicates = new ArrayList<>(); diff --git a/modules/api/src/main/java/org/eclipse/xpanse/api/exceptions/handler/ServiceMetricsExceptionHandler.java b/modules/api/src/main/java/org/eclipse/xpanse/api/exceptions/handler/ServiceMetricsExceptionHandler.java index a7d5b437a..c47671b5f 100644 --- a/modules/api/src/main/java/org/eclipse/xpanse/api/exceptions/handler/ServiceMetricsExceptionHandler.java +++ b/modules/api/src/main/java/org/eclipse/xpanse/api/exceptions/handler/ServiceMetricsExceptionHandler.java @@ -10,7 +10,6 @@ import java.util.Collections; import lombok.extern.slf4j.Slf4j; -import org.eclipse.xpanse.modules.models.monitor.exceptions.ClientApiCallFailedException; import org.eclipse.xpanse.modules.models.monitor.exceptions.MetricsDataNotYetAvailableException; import org.eclipse.xpanse.modules.models.monitor.exceptions.ResourceNotFoundException; import org.eclipse.xpanse.modules.models.monitor.exceptions.ResourceNotSupportedForMonitoringException; @@ -32,17 +31,6 @@ @RestControllerAdvice public class ServiceMetricsExceptionHandler { - /** - * Exception handler for ClientApiCallFailedException. - */ - @ExceptionHandler({ClientApiCallFailedException.class}) - @ResponseStatus(HttpStatus.BAD_GATEWAY) - @ResponseBody - public Response handleClientApiCalledException(ClientApiCallFailedException ex) { - return getErrorResponse(ResultType.BACKEND_FAILURE, - Collections.singletonList(ex.getMessage())); - } - /** * Exception handler for ResourceNotSupportedForMonitoringException. */ diff --git a/modules/api/src/test/java/org/eclipse/xpanse/api/exceptions/handler/ServiceMetricsExceptionHandlerTest.java b/modules/api/src/test/java/org/eclipse/xpanse/api/exceptions/handler/ServiceMetricsExceptionHandlerTest.java index e4e31ff65..69694d9c9 100644 --- a/modules/api/src/test/java/org/eclipse/xpanse/api/exceptions/handler/ServiceMetricsExceptionHandlerTest.java +++ b/modules/api/src/test/java/org/eclipse/xpanse/api/exceptions/handler/ServiceMetricsExceptionHandlerTest.java @@ -12,7 +12,6 @@ import org.eclipse.xpanse.api.config.CspPluginValidator; import org.eclipse.xpanse.api.controllers.ServiceMetricsApi; -import org.eclipse.xpanse.modules.models.monitor.exceptions.ClientApiCallFailedException; import org.eclipse.xpanse.modules.models.monitor.exceptions.MetricsDataNotYetAvailableException; import org.eclipse.xpanse.modules.models.monitor.exceptions.ResourceNotFoundException; import org.eclipse.xpanse.modules.models.monitor.exceptions.ResourceNotSupportedForMonitoringException; @@ -60,20 +59,6 @@ public void setup() { mockMvc = MockMvcBuilders.webAppContextSetup(context).build(); } - @Test - void testClientApiCallFailedException() throws Exception { - when(serviceMetricsAdapter - .getMetricsByServiceId(serviceId, null, null, null, null, true)) - .thenThrow(new ClientApiCallFailedException("test error")); - - this.mockMvc.perform(get("/xpanse/metrics") - .param("serviceId", serviceId) - .param("onlyLastKnownMetric", "true")) - .andExpect(status().is(502)) - .andExpect(jsonPath("$.resultType").value("Failure while connecting to backend")) - .andExpect(jsonPath("$.details[0]").value("test error")); - } - @Test void testResourceNotSupportedForMonitoringException() throws Exception { when(serviceMetricsAdapter diff --git a/modules/models/src/main/java/org/eclipse/xpanse/modules/models/monitor/exceptions/ClientApiCallFailedException.java b/modules/models/src/main/java/org/eclipse/xpanse/modules/models/common/exceptions/ClientApiCallFailedException.java similarity index 83% rename from modules/models/src/main/java/org/eclipse/xpanse/modules/models/monitor/exceptions/ClientApiCallFailedException.java rename to modules/models/src/main/java/org/eclipse/xpanse/modules/models/common/exceptions/ClientApiCallFailedException.java index 7164f11d0..dd1c889db 100644 --- a/modules/models/src/main/java/org/eclipse/xpanse/modules/models/monitor/exceptions/ClientApiCallFailedException.java +++ b/modules/models/src/main/java/org/eclipse/xpanse/modules/models/common/exceptions/ClientApiCallFailedException.java @@ -3,7 +3,7 @@ * SPDX-FileCopyrightText: Huawei Inc. */ -package org.eclipse.xpanse.modules.models.monitor.exceptions; +package org.eclipse.xpanse.modules.models.common.exceptions; /** * Exception thrown when calling API by the client. diff --git a/modules/models/src/main/java/org/eclipse/xpanse/modules/models/common/exceptions/ClientAuthenticationFailedException.java b/modules/models/src/main/java/org/eclipse/xpanse/modules/models/common/exceptions/ClientAuthenticationFailedException.java new file mode 100644 index 000000000..09ca8b77e --- /dev/null +++ b/modules/models/src/main/java/org/eclipse/xpanse/modules/models/common/exceptions/ClientAuthenticationFailedException.java @@ -0,0 +1,16 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * SPDX-FileCopyrightText: Huawei Inc. + */ + +package org.eclipse.xpanse.modules.models.common.exceptions; + +/** + * Exception thrown when the api client authentication failed. + */ +public class ClientAuthenticationFailedException extends RuntimeException { + public ClientAuthenticationFailedException(String message) { + super(message); + } +} + diff --git a/modules/models/src/test/java/org/eclipse/xpanse/modules/models/monitor/exceptions/ClientApiCallFailedExceptionTest.java b/modules/models/src/test/java/org/eclipse/xpanse/modules/models/monitor/exceptions/ClientApiCallFailedExceptionTest.java index 0ebb51ded..2b7e12632 100644 --- a/modules/models/src/test/java/org/eclipse/xpanse/modules/models/monitor/exceptions/ClientApiCallFailedExceptionTest.java +++ b/modules/models/src/test/java/org/eclipse/xpanse/modules/models/monitor/exceptions/ClientApiCallFailedExceptionTest.java @@ -8,6 +8,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; +import org.eclipse.xpanse.modules.models.common.exceptions.ClientApiCallFailedException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/modules/servicetemplate/src/main/java/org/eclipse/xpanse/modules/servicetemplate/price/ServicePricesManager.java b/modules/servicetemplate/src/main/java/org/eclipse/xpanse/modules/servicetemplate/price/ServicePricesManager.java index 02f695903..9a3e4005a 100644 --- a/modules/servicetemplate/src/main/java/org/eclipse/xpanse/modules/servicetemplate/price/ServicePricesManager.java +++ b/modules/servicetemplate/src/main/java/org/eclipse/xpanse/modules/servicetemplate/price/ServicePricesManager.java @@ -110,7 +110,8 @@ public List getPricesByService(String templateId, flavorPriceResult.setRecurringPrice(flavorPrice.getRecurringPrice()); flavorPriceResult.setOneTimePaymentPrice(flavorPrice.getOneTimePaymentPrice()); } catch (Exception e) { - log.error("Failed to get price of service flavor: {}", flavor.getName(), e); + log.error("Get price of service flavor {} failed. {}", flavor.getName(), + e.getMessage()); flavorPriceResult.setSuccessful(false); flavorPriceResult.setErrorMessage(e.getMessage()); } diff --git a/plugins/flexibleengine/src/main/java/org/eclipse/xpanse/plugins/flexibleengine/common/FlexibleEngineClient.java b/plugins/flexibleengine/src/main/java/org/eclipse/xpanse/plugins/flexibleengine/common/FlexibleEngineClient.java index 89f9a3b1a..79ebf6bf8 100644 --- a/plugins/flexibleengine/src/main/java/org/eclipse/xpanse/plugins/flexibleengine/common/FlexibleEngineClient.java +++ b/plugins/flexibleengine/src/main/java/org/eclipse/xpanse/plugins/flexibleengine/common/FlexibleEngineClient.java @@ -35,7 +35,7 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; -import org.eclipse.xpanse.modules.models.monitor.exceptions.ClientApiCallFailedException; +import org.eclipse.xpanse.modules.models.common.exceptions.ClientApiCallFailedException; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @@ -50,7 +50,7 @@ public class FlexibleEngineClient extends FlexibleEngineCredentials { private boolean sdkHttpDebugLogsEnabled; @Resource - private FlexibleEngineRetryStrategy retryStrategy; + private FlexibleEngineRetryStrategy flexibleEngineRetryStrategy; /** * Get client for service ECS. @@ -144,24 +144,19 @@ private String getProjectId(ICredential credential, String regionName) { listProjectsRequest.setName(regionName); KeystoneListProjectsResponse response = iamClient.keystoneListProjectsInvoker(listProjectsRequest) - .retryTimes(retryStrategy.getRetryMaxAttempts()) - .retryCondition(retryStrategy::matchRetryCondition) - .backoffStrategy(retryStrategy) + .retryTimes(flexibleEngineRetryStrategy.getRetryMaxAttempts()) + .retryCondition(flexibleEngineRetryStrategy::matchRetryCondition) + .backoffStrategy(flexibleEngineRetryStrategy) .invoke(); if (Objects.nonNull(response) && CollectionUtils.isNotEmpty(response.getProjects())) { projectId = response.getProjects().getFirst().getId(); } - } catch (RuntimeException e) { - String errorMsg = - String.format("Query project id by region name %s failed.", regionName); - throw new ClientApiCallFailedException(errorMsg); - } - if (StringUtils.isNotBlank(projectId)) { - log.info("Query project id {} by region name {} success.", projectId, regionName); return projectId; + } catch (Exception e) { + log.error("Get project id with region {} failed.", regionName); + flexibleEngineRetryStrategy.handleAuthExceptionForSpringRetry(e); + throw new ClientApiCallFailedException(e.getMessage()); } - String errorMsg = String.format("Query project id by region name %s failed.", regionName); - throw new ClientApiCallFailedException(errorMsg); } private HttpConfig getHttpConfig() { diff --git a/plugins/flexibleengine/src/main/java/org/eclipse/xpanse/plugins/flexibleengine/common/FlexibleEngineRetryStrategy.java b/plugins/flexibleengine/src/main/java/org/eclipse/xpanse/plugins/flexibleengine/common/FlexibleEngineRetryStrategy.java index 389e7cc1a..aad843172 100644 --- a/plugins/flexibleengine/src/main/java/org/eclipse/xpanse/plugins/flexibleengine/common/FlexibleEngineRetryStrategy.java +++ b/plugins/flexibleengine/src/main/java/org/eclipse/xpanse/plugins/flexibleengine/common/FlexibleEngineRetryStrategy.java @@ -7,12 +7,16 @@ package org.eclipse.xpanse.plugins.flexibleengine.common; import com.huaweicloud.sdk.core.SdkResponse; +import com.huaweicloud.sdk.core.exception.ClientRequestException; import com.huaweicloud.sdk.core.exception.ServiceResponseException; import com.huaweicloud.sdk.core.retry.RetryContext; import com.huaweicloud.sdk.core.retry.backoff.BackoffStrategy; import java.util.Objects; import lombok.extern.slf4j.Slf4j; +import org.eclipse.xpanse.modules.models.common.exceptions.ClientAuthenticationFailedException; import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatus; +import org.springframework.retry.support.RetrySynchronizationManager; import org.springframework.stereotype.Component; /** @@ -93,4 +97,39 @@ public boolean matchRetryCondition(SdkResponse response, Exception ex) { return statusCode == ERROR_CODE_TOO_MANY_REQUESTS || statusCode == ERROR_CODE_INTERNAL_SERVER_ERROR; } + + /** + * Handle auth exception for spring retry. + * + * @param ex Exception + */ + public void handleAuthExceptionForSpringRetry(Exception ex) { + int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) + ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); + log.error(ex.getMessage() + System.lineSeparator() + "Retry count:" + retryCount); + if (ex instanceof ClientAuthenticationFailedException) { + throw new ClientAuthenticationFailedException(ex.getMessage()); + } + ClientRequestException clientRequestException = getClientRequestException(ex); + if (Objects.nonNull(clientRequestException)) { + int statusCode = clientRequestException.getHttpStatusCode(); + if (statusCode == HttpStatus.UNAUTHORIZED.value() + || statusCode == HttpStatus.FORBIDDEN.value()) { + throw new ClientAuthenticationFailedException(ex.getMessage()); + } + } + } + + private ClientRequestException getClientRequestException(Throwable ex) { + if (Objects.isNull(ex)) { + return null; + } + if (ex instanceof ClientRequestException requestException) { + return requestException; + } + if (Objects.nonNull(ex.getCause())) { + return getClientRequestException(ex.getCause()); + } + return null; + } } diff --git a/plugins/flexibleengine/src/main/java/org/eclipse/xpanse/plugins/flexibleengine/manage/FlexibleEngineResourceManager.java b/plugins/flexibleengine/src/main/java/org/eclipse/xpanse/plugins/flexibleengine/manage/FlexibleEngineResourceManager.java index b1acb27cd..70d87b55a 100644 --- a/plugins/flexibleengine/src/main/java/org/eclipse/xpanse/plugins/flexibleengine/manage/FlexibleEngineResourceManager.java +++ b/plugins/flexibleengine/src/main/java/org/eclipse/xpanse/plugins/flexibleengine/manage/FlexibleEngineResourceManager.java @@ -38,19 +38,17 @@ import jakarta.annotation.Resource; import java.util.ArrayList; import java.util.List; -import java.util.Objects; import lombok.extern.slf4j.Slf4j; import org.eclipse.xpanse.modules.credential.CredentialCenter; import org.eclipse.xpanse.modules.models.common.enums.Csp; +import org.eclipse.xpanse.modules.models.common.exceptions.ClientApiCallFailedException; import org.eclipse.xpanse.modules.models.credential.AbstractCredentialInfo; import org.eclipse.xpanse.modules.models.credential.enums.CredentialType; -import org.eclipse.xpanse.modules.models.monitor.exceptions.ClientApiCallFailedException; import org.eclipse.xpanse.modules.models.service.enums.DeployResourceKind; import org.eclipse.xpanse.plugins.flexibleengine.common.FlexibleEngineClient; import org.eclipse.xpanse.plugins.flexibleengine.common.FlexibleEngineRetryStrategy; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Retryable; -import org.springframework.retry.support.RetrySynchronizationManager; import org.springframework.stereotype.Component; /** @@ -121,13 +119,9 @@ public List getAvailabilityZonesOfRegion(String userId, String region) { .stream().map(NovaAvailabilityZone::getZoneName).toList(); } } catch (Exception e) { - String errorMsg = String.format( - "FlexibleEngineClient listAvailabilityZones with region %s failed. %s", - region, e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); - throw new ClientApiCallFailedException(errorMsg); + log.error("FlexibleEngineClient listAvailabilityZones with region {} failed.", region); + flexibleEngineRetryStrategy.handleAuthExceptionForSpringRetry(e); + throw new ClientApiCallFailedException(e.getMessage()); } return availabilityZoneNames; } @@ -146,13 +140,9 @@ private List getVpcList(String userId, String region) { vpcNames = response.getVpcs().stream().map(Vpc::getName).toList(); } } catch (Exception e) { - String errorMsg = String.format( - "FlexibleEngineClient listVpcs with region %s failed. %s", - region, e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); - throw new ClientApiCallFailedException(errorMsg); + log.error("FlexibleEngineClient listVpcs with region {} failed.", region); + flexibleEngineRetryStrategy.handleAuthExceptionForSpringRetry(e); + throw new ClientApiCallFailedException(e.getMessage()); } return vpcNames; } @@ -171,13 +161,9 @@ private List getSubnetList(String userId, String region) { subnetNames = response.getSubnets().stream().map(Subnet::getName).toList(); } } catch (Exception e) { - String errorMsg = String.format( - "FlexibleEngineClient listSubnets with region %s failed. %s", - region, e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); - throw new ClientApiCallFailedException(errorMsg); + log.error("FlexibleEngineClient listSubnets with region {} failed.", region); + flexibleEngineRetryStrategy.handleAuthExceptionForSpringRetry(e); + throw new ClientApiCallFailedException(e.getMessage()); } return subnetNames; } @@ -197,13 +183,9 @@ private List getSecurityGroupsList(String userId, String region) { .stream().map(SecurityGroup::getName).toList(); } } catch (Exception e) { - String errorMsg = String.format( - "FlexibleEngineClient listSecurityGroups with region %s failed. %s", - region, e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); - throw new ClientApiCallFailedException(errorMsg); + log.error("FlexibleEngineClient listSecurityGroups with region {} failed.", region); + flexibleEngineRetryStrategy.handleAuthExceptionForSpringRetry(e); + throw new ClientApiCallFailedException(e.getMessage()); } return securityGroupNames; } @@ -224,13 +206,9 @@ private List getSecurityGroupRuleList(String userId, String region) { .stream().map(SecurityGroupRule::getId).toList(); } } catch (Exception e) { - String errorMsg = String.format( - "FlexibleEngineClient listSecurityGroupRules with region %s failed. %s", - region, e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); - throw new ClientApiCallFailedException(errorMsg); + log.error("FlexibleEngineClient listSecurityGroupRules with region {} failed.", region); + flexibleEngineRetryStrategy.handleAuthExceptionForSpringRetry(e); + throw new ClientApiCallFailedException(e.getMessage()); } return securityGroupRuleIds; } @@ -250,13 +228,9 @@ private List getPublicIpList(String userId, String region) { .stream().map(PublicipShowResp::getPublicIpAddress).toList(); } } catch (Exception e) { - String errorMsg = String.format( - "FlexibleEngineClient listPublicIps with region %s failed. %s", - region, e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); - throw new ClientApiCallFailedException(errorMsg); + log.error("FlexibleEngineClient listPublicIps with region {} failed.", region); + flexibleEngineRetryStrategy.handleAuthExceptionForSpringRetry(e); + throw new ClientApiCallFailedException(e.getMessage()); } return publicIpAddresses; } @@ -275,13 +249,9 @@ private List getVolumeList(String userId, String region) { volumeNames = response.getVolumes().stream().map(VolumeDetail::getName).toList(); } } catch (Exception e) { - String errorMsg = String.format( - "FlexibleEngineClient listVolumes with region %s failed. %s", - region, e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); - throw new ClientApiCallFailedException(errorMsg); + log.error("FlexibleEngineClient listVolumes with region {} failed.", region); + flexibleEngineRetryStrategy.handleAuthExceptionForSpringRetry(e); + throw new ClientApiCallFailedException(e.getMessage()); } return volumeNames; } @@ -302,13 +272,9 @@ private List getKeyPairsList(String userId, String region) { .map(NovaSimpleKeypair::getName).toList(); } } catch (Exception e) { - String errorMsg = String.format( - "FlexibleEngineClient listKeyPairs with region %s failed. %s", - region, e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); - throw new ClientApiCallFailedException(errorMsg); + log.error("FlexibleEngineClient listKeyPairs with region {} failed.", region); + flexibleEngineRetryStrategy.handleAuthExceptionForSpringRetry(e); + throw new ClientApiCallFailedException(e.getMessage()); } return keyPairNames; } diff --git a/plugins/flexibleengine/src/main/java/org/eclipse/xpanse/plugins/flexibleengine/manage/FlexibleEngineVmStateManager.java b/plugins/flexibleengine/src/main/java/org/eclipse/xpanse/plugins/flexibleengine/manage/FlexibleEngineVmStateManager.java index 49a533df9..c3332def6 100644 --- a/plugins/flexibleengine/src/main/java/org/eclipse/xpanse/plugins/flexibleengine/manage/FlexibleEngineVmStateManager.java +++ b/plugins/flexibleengine/src/main/java/org/eclipse/xpanse/plugins/flexibleengine/manage/FlexibleEngineVmStateManager.java @@ -24,15 +24,14 @@ import lombok.extern.slf4j.Slf4j; import org.eclipse.xpanse.modules.credential.CredentialCenter; import org.eclipse.xpanse.modules.models.common.enums.Csp; +import org.eclipse.xpanse.modules.models.common.exceptions.ClientApiCallFailedException; import org.eclipse.xpanse.modules.models.credential.AbstractCredentialInfo; import org.eclipse.xpanse.modules.models.credential.enums.CredentialType; -import org.eclipse.xpanse.modules.models.monitor.exceptions.ClientApiCallFailedException; import org.eclipse.xpanse.modules.orchestrator.servicestate.ServiceStateManageRequest; import org.eclipse.xpanse.plugins.flexibleengine.common.FlexibleEngineClient; import org.eclipse.xpanse.plugins.flexibleengine.common.FlexibleEngineRetryStrategy; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Retryable; -import org.springframework.retry.support.RetrySynchronizationManager; import org.springframework.stereotype.Component; /** @@ -70,11 +69,8 @@ public boolean startService(ServiceStateManageRequest serviceStateManageRequest) .invoke(); return checkEcsExecResultByJobId(ecsClient, response.getJobId()); } catch (Exception e) { - String errorMsg = String.format("Start service %s error. %s", - serviceStateManageRequest.getServiceId(), e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); + log.error("Start service {} failed.", serviceStateManageRequest.getServiceId()); + flexibleEngineRetryStrategy.handleAuthExceptionForSpringRetry(e); throw new ClientApiCallFailedException(e.getMessage()); } } @@ -99,11 +95,8 @@ public boolean stopService(ServiceStateManageRequest serviceStateManageRequest) .invoke(); return checkEcsExecResultByJobId(ecsClient, response.getJobId()); } catch (Exception e) { - String errorMsg = String.format("Stop service %s error. %s", - serviceStateManageRequest.getServiceId(), e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); + log.error("Stop service {} failed.", serviceStateManageRequest.getServiceId()); + flexibleEngineRetryStrategy.handleAuthExceptionForSpringRetry(e); throw new ClientApiCallFailedException(e.getMessage()); } } @@ -128,11 +121,8 @@ public boolean restartService(ServiceStateManageRequest serviceStateManageReques .invoke(); return checkEcsExecResultByJobId(ecsClient, response.getJobId()); } catch (Exception e) { - String errorMsg = String.format("Restart service %s error. %s", - serviceStateManageRequest.getServiceId(), e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); + log.error("Restart service {} failed.", serviceStateManageRequest.getServiceId()); + flexibleEngineRetryStrategy.handleAuthExceptionForSpringRetry(e); throw new ClientApiCallFailedException(e.getMessage()); } } diff --git a/plugins/flexibleengine/src/main/java/org/eclipse/xpanse/plugins/flexibleengine/monitor/FlexibleEngineMetricsService.java b/plugins/flexibleengine/src/main/java/org/eclipse/xpanse/plugins/flexibleengine/monitor/FlexibleEngineMetricsService.java index cf7c601f1..d70bfe273 100644 --- a/plugins/flexibleengine/src/main/java/org/eclipse/xpanse/plugins/flexibleengine/monitor/FlexibleEngineMetricsService.java +++ b/plugins/flexibleengine/src/main/java/org/eclipse/xpanse/plugins/flexibleengine/monitor/FlexibleEngineMetricsService.java @@ -27,11 +27,11 @@ import org.eclipse.xpanse.modules.cache.monitor.MonitorMetricsStore; import org.eclipse.xpanse.modules.credential.CredentialCenter; import org.eclipse.xpanse.modules.models.common.enums.Csp; +import org.eclipse.xpanse.modules.models.common.exceptions.ClientApiCallFailedException; import org.eclipse.xpanse.modules.models.credential.AbstractCredentialInfo; import org.eclipse.xpanse.modules.models.credential.enums.CredentialType; import org.eclipse.xpanse.modules.models.monitor.Metric; import org.eclipse.xpanse.modules.models.monitor.enums.MonitorResourceType; -import org.eclipse.xpanse.modules.models.monitor.exceptions.ClientApiCallFailedException; import org.eclipse.xpanse.modules.models.monitor.exceptions.MetricsDataNotYetAvailableException; import org.eclipse.xpanse.modules.models.service.deploy.DeployResource; import org.eclipse.xpanse.modules.orchestrator.monitor.ResourceMetricsRequest; @@ -40,7 +40,6 @@ import org.eclipse.xpanse.plugins.flexibleengine.common.FlexibleEngineRetryStrategy; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Retryable; -import org.springframework.retry.support.RetrySynchronizationManager; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; @@ -106,12 +105,9 @@ public List getMetricsByResource(ResourceMetricsRequest resourceMetricRe } return metrics; } catch (Exception e) { - String errorMsg = String.format("Get metrics of resource %s error. %s", - deployResource.getResourceId(), e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); - throw new ClientApiCallFailedException(errorMsg); + log.error("Get metrics of resource {} failed.", deployResource.getResourceId()); + flexibleEngineRetryStrategy.handleAuthExceptionForSpringRetry(e); + throw new ClientApiCallFailedException(e.getMessage()); } } @@ -160,12 +156,9 @@ public List getMetricsByService(ServiceMetricsRequest serviceMetricReque metrics); return metrics; } catch (Exception e) { - String errorMsg = String.format("Get metrics of service %s error. %s", - serviceMetricRequest.getServiceId(), e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); - throw new ClientApiCallFailedException(errorMsg); + log.error("Get metrics of service {} failed.", serviceMetricRequest.getServiceId()); + flexibleEngineRetryStrategy.handleAuthExceptionForSpringRetry(e); + throw new ClientApiCallFailedException(e.getMessage()); } } diff --git a/plugins/flexibleengine/src/test/java/org/eclipse/xpanse/plugins/flexibleengine/common/FlexibleEngineClientTest.java b/plugins/flexibleengine/src/test/java/org/eclipse/xpanse/plugins/flexibleengine/common/FlexibleEngineClientTest.java index d9bef8429..8a34e0d00 100644 --- a/plugins/flexibleengine/src/test/java/org/eclipse/xpanse/plugins/flexibleengine/common/FlexibleEngineClientTest.java +++ b/plugins/flexibleengine/src/test/java/org/eclipse/xpanse/plugins/flexibleengine/common/FlexibleEngineClientTest.java @@ -10,7 +10,6 @@ import org.eclipse.xpanse.modules.models.credential.CredentialVariables; import org.eclipse.xpanse.modules.models.credential.enums.CredentialType; import org.eclipse.xpanse.modules.models.credential.exceptions.CredentialsNotFoundException; -import org.eclipse.xpanse.modules.models.monitor.exceptions.ClientApiCallFailedException; import org.eclipse.xpanse.plugins.flexibleengine.monitor.constant.FlexibleEngineMonitorConstants; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; @@ -53,7 +52,7 @@ void testGetCesClient() { testClient.getCredential(getCredentialDefinition("ak", "sk")); // Verify the results - Assertions.assertThrows(ClientApiCallFailedException.class, + Assertions.assertThrows(Exception.class, () -> testClient.getCesClient(iCredential, "eu-west-0")); } diff --git a/plugins/huaweicloud/src/main/java/org/eclipse/xpanse/plugins/huaweicloud/common/HuaweiCloudClient.java b/plugins/huaweicloud/src/main/java/org/eclipse/xpanse/plugins/huaweicloud/common/HuaweiCloudClient.java index f353b547a..6d5453960 100644 --- a/plugins/huaweicloud/src/main/java/org/eclipse/xpanse/plugins/huaweicloud/common/HuaweiCloudClient.java +++ b/plugins/huaweicloud/src/main/java/org/eclipse/xpanse/plugins/huaweicloud/common/HuaweiCloudClient.java @@ -30,6 +30,7 @@ import jakarta.annotation.Resource; import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; +import org.eclipse.xpanse.modules.models.common.exceptions.ClientApiCallFailedException; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; @@ -166,22 +167,27 @@ public BssintlClient getBssintlClient(ICredential globalCredential) { * @param regionName region name. * @return projectId. */ - public String getProjectId(ICredential globalCredential, - String regionName) { + public String getProjectId(ICredential globalCredential, String regionName) { String projectId = null; - IamClient iamClient = getIamClient(globalCredential, regionName); - KeystoneListProjectsRequest listProjectsRequest = - new KeystoneListProjectsRequest().withName(regionName); - KeystoneListProjectsResponse listProjectsResponse = - iamClient.keystoneListProjectsInvoker(listProjectsRequest) - .retryTimes(huaweiCloudRetryStrategy.getRetryMaxAttempts()) - .retryCondition(huaweiCloudRetryStrategy::matchRetryCondition) - .backoffStrategy(huaweiCloudRetryStrategy) - .invoke(); - if (!CollectionUtils.isEmpty(listProjectsResponse.getProjects())) { - projectId = listProjectsResponse.getProjects().getFirst().getId(); + try { + IamClient iamClient = getIamClient(globalCredential, regionName); + KeystoneListProjectsRequest listProjectsRequest = + new KeystoneListProjectsRequest().withName(regionName); + KeystoneListProjectsResponse listProjectsResponse = + iamClient.keystoneListProjectsInvoker(listProjectsRequest) + .retryTimes(huaweiCloudRetryStrategy.getRetryMaxAttempts()) + .retryCondition(huaweiCloudRetryStrategy::matchRetryCondition) + .backoffStrategy(huaweiCloudRetryStrategy) + .invoke(); + if (!CollectionUtils.isEmpty(listProjectsResponse.getProjects())) { + projectId = listProjectsResponse.getProjects().getFirst().getId(); + } + return projectId; + } catch (Exception e) { + log.error("Get project id with region {} failed.", regionName); + huaweiCloudRetryStrategy.handleAuthExceptionForSpringRetry(e); + throw new ClientApiCallFailedException(e.getMessage()); } - return projectId; } private HttpConfig getHttpConfig() { diff --git a/plugins/huaweicloud/src/main/java/org/eclipse/xpanse/plugins/huaweicloud/common/HuaweiCloudRetryStrategy.java b/plugins/huaweicloud/src/main/java/org/eclipse/xpanse/plugins/huaweicloud/common/HuaweiCloudRetryStrategy.java index 0d3d5be14..7522c07bb 100644 --- a/plugins/huaweicloud/src/main/java/org/eclipse/xpanse/plugins/huaweicloud/common/HuaweiCloudRetryStrategy.java +++ b/plugins/huaweicloud/src/main/java/org/eclipse/xpanse/plugins/huaweicloud/common/HuaweiCloudRetryStrategy.java @@ -7,12 +7,16 @@ package org.eclipse.xpanse.plugins.huaweicloud.common; import com.huaweicloud.sdk.core.SdkResponse; +import com.huaweicloud.sdk.core.exception.ClientRequestException; import com.huaweicloud.sdk.core.exception.ServiceResponseException; import com.huaweicloud.sdk.core.retry.RetryContext; import com.huaweicloud.sdk.core.retry.backoff.BackoffStrategy; import java.util.Objects; import lombok.extern.slf4j.Slf4j; +import org.eclipse.xpanse.modules.models.common.exceptions.ClientAuthenticationFailedException; import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatus; +import org.springframework.retry.support.RetrySynchronizationManager; import org.springframework.stereotype.Component; /** @@ -93,4 +97,40 @@ public boolean matchRetryCondition(SdkResponse response, Exception ex) { return statusCode == ERROR_CODE_TOO_MANY_REQUESTS || statusCode == ERROR_CODE_INTERNAL_SERVER_ERROR; } + + + /** + * Handle auth exception for spring retry. + * + * @param ex Exception + */ + public void handleAuthExceptionForSpringRetry(Exception ex) { + int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) + ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); + log.error(ex.getMessage() + System.lineSeparator() + "Retry count:" + retryCount); + if (ex instanceof ClientAuthenticationFailedException) { + throw new ClientAuthenticationFailedException(ex.getMessage()); + } + ClientRequestException clientRequestException = getClientRequestException(ex); + if (Objects.nonNull(clientRequestException)) { + int statusCode = clientRequestException.getHttpStatusCode(); + if (statusCode == HttpStatus.UNAUTHORIZED.value() + || statusCode == HttpStatus.FORBIDDEN.value()) { + throw new ClientAuthenticationFailedException(ex.getMessage()); + } + } + } + + private ClientRequestException getClientRequestException(Throwable ex) { + if (Objects.isNull(ex)) { + return null; + } + if (ex instanceof ClientRequestException requestException) { + return requestException; + } + if (Objects.nonNull(ex.getCause())) { + return getClientRequestException(ex.getCause()); + } + return null; + } } diff --git a/plugins/huaweicloud/src/main/java/org/eclipse/xpanse/plugins/huaweicloud/manage/HuaweiCloudResourceManager.java b/plugins/huaweicloud/src/main/java/org/eclipse/xpanse/plugins/huaweicloud/manage/HuaweiCloudResourceManager.java index 1b221be16..dd9384293 100644 --- a/plugins/huaweicloud/src/main/java/org/eclipse/xpanse/plugins/huaweicloud/manage/HuaweiCloudResourceManager.java +++ b/plugins/huaweicloud/src/main/java/org/eclipse/xpanse/plugins/huaweicloud/manage/HuaweiCloudResourceManager.java @@ -38,19 +38,17 @@ import jakarta.annotation.Resource; import java.util.ArrayList; import java.util.List; -import java.util.Objects; import lombok.extern.slf4j.Slf4j; import org.eclipse.xpanse.modules.credential.CredentialCenter; import org.eclipse.xpanse.modules.models.common.enums.Csp; +import org.eclipse.xpanse.modules.models.common.exceptions.ClientApiCallFailedException; import org.eclipse.xpanse.modules.models.credential.AbstractCredentialInfo; import org.eclipse.xpanse.modules.models.credential.enums.CredentialType; -import org.eclipse.xpanse.modules.models.monitor.exceptions.ClientApiCallFailedException; import org.eclipse.xpanse.modules.models.service.enums.DeployResourceKind; import org.eclipse.xpanse.plugins.huaweicloud.common.HuaweiCloudClient; import org.eclipse.xpanse.plugins.huaweicloud.common.HuaweiCloudRetryStrategy; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Retryable; -import org.springframework.retry.support.RetrySynchronizationManager; import org.springframework.stereotype.Component; /** @@ -120,13 +118,9 @@ public List getAvailabilityZonesOfRegion(String userId, String region) { .stream().map(NovaAvailabilityZone::getZoneName).toList(); } } catch (Exception e) { - String errorMsg = String.format( - "HuaweiCloudClient listAvailabilityZones with region %s failed. %s", - region, e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); - throw new ClientApiCallFailedException(errorMsg); + log.error("HuaweiCloudClient listAvailabilityZones with region {} failed.", region); + huaweiCloudRetryStrategy.handleAuthExceptionForSpringRetry(e); + throw new ClientApiCallFailedException(e.getMessage()); } return availabilityZoneNames; } @@ -145,13 +139,9 @@ private List getVpcList(String userId, String region) { vpcNames = response.getVpcs().stream().map(Vpc::getName).toList(); } } catch (Exception e) { - String errorMsg = String.format( - "HuaweiCloudClient listVpcs with region %s failed. %s", - region, e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); - throw new ClientApiCallFailedException(errorMsg); + log.error("HuaweiCloudClient listVpcs with region {} failed.", region); + huaweiCloudRetryStrategy.handleAuthExceptionForSpringRetry(e); + throw new ClientApiCallFailedException(e.getMessage()); } return vpcNames; } @@ -170,13 +160,9 @@ private List getSubnetList(String userId, String region) { subnetNames = response.getSubnets().stream().map(Subnet::getName).toList(); } } catch (Exception e) { - String errorMsg = String.format( - "HuaweiCloudClient listSubnets with region %s failed. %s", - region, e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); - throw new ClientApiCallFailedException(errorMsg); + log.error("HuaweiCloudClient listSubnets with region {} failed.", region); + huaweiCloudRetryStrategy.handleAuthExceptionForSpringRetry(e); + throw new ClientApiCallFailedException(e.getMessage()); } return subnetNames; } @@ -196,13 +182,9 @@ private List getSecurityGroupsList(String userId, String region) { .stream().map(SecurityGroup::getName).toList(); } } catch (Exception e) { - String errorMsg = String.format( - "HuaweiCloudClient listSecurityGroups with region %s failed. %s", - region, e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); - throw new ClientApiCallFailedException(errorMsg); + log.error("HuaweiCloudClient listSecurityGroups with region {} failed.", region); + huaweiCloudRetryStrategy.handleAuthExceptionForSpringRetry(e); + throw new ClientApiCallFailedException(e.getMessage()); } return securityGroupNames; } @@ -223,13 +205,9 @@ private List getSecurityGroupRuleList(String userId, String region) { .stream().map(SecurityGroupRule::getId).toList(); } } catch (Exception e) { - String errorMsg = String.format( - "HuaweiCloudClient listSecurityGroupRules with region %s failed. %s", - region, e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); - throw new ClientApiCallFailedException(errorMsg); + log.error("HuaweiCloudClient listSecurityGroupRules with region {} failed.", region); + huaweiCloudRetryStrategy.handleAuthExceptionForSpringRetry(e); + throw new ClientApiCallFailedException(e.getMessage()); } return securityGroupRuleIds; } @@ -249,13 +227,9 @@ private List getPublicIpList(String userId, String region) { .stream().map(PublicipShowResp::getPublicIpAddress).toList(); } } catch (Exception e) { - String errorMsg = String.format( - "HuaweiCloudClient listPublicIps with region %s failed. %s", - region, e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); - throw new ClientApiCallFailedException(errorMsg); + log.error("HuaweiCloudClient listPublicIps with region {} failed.", region); + huaweiCloudRetryStrategy.handleAuthExceptionForSpringRetry(e); + throw new ClientApiCallFailedException(e.getMessage()); } return publicIpAddresses; } @@ -274,13 +248,9 @@ private List getVolumeList(String userId, String region) { volumeNames = response.getVolumes().stream().map(VolumeDetail::getName).toList(); } } catch (Exception e) { - String errorMsg = String.format( - "HuaweiCloudClient listVolumes with region %s failed. %s", - region, e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); - throw new ClientApiCallFailedException(errorMsg); + log.error("HuaweiCloudClient listVolumes with region {} failed.", region); + huaweiCloudRetryStrategy.handleAuthExceptionForSpringRetry(e); + throw new ClientApiCallFailedException(e.getMessage()); } return volumeNames; } @@ -301,13 +271,9 @@ private List getKeyPairsList(String userId, String region) { .map(NovaSimpleKeypair::getName).toList(); } } catch (Exception e) { - String errorMsg = String.format( - "HuaweiCloudClient listKeyPairs with region %s failed. %s", - region, e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); - throw new ClientApiCallFailedException(errorMsg); + log.error("HuaweiCloudClient listKeyPairs with region {} failed.", region); + huaweiCloudRetryStrategy.handleAuthExceptionForSpringRetry(e); + throw new ClientApiCallFailedException(e.getMessage()); } return keyPairNames; } diff --git a/plugins/huaweicloud/src/main/java/org/eclipse/xpanse/plugins/huaweicloud/manage/HuaweiCloudVmStateManager.java b/plugins/huaweicloud/src/main/java/org/eclipse/xpanse/plugins/huaweicloud/manage/HuaweiCloudVmStateManager.java index 8b040b097..e6dfc198a 100644 --- a/plugins/huaweicloud/src/main/java/org/eclipse/xpanse/plugins/huaweicloud/manage/HuaweiCloudVmStateManager.java +++ b/plugins/huaweicloud/src/main/java/org/eclipse/xpanse/plugins/huaweicloud/manage/HuaweiCloudVmStateManager.java @@ -25,15 +25,14 @@ import lombok.extern.slf4j.Slf4j; import org.eclipse.xpanse.modules.credential.CredentialCenter; import org.eclipse.xpanse.modules.models.common.enums.Csp; +import org.eclipse.xpanse.modules.models.common.exceptions.ClientApiCallFailedException; import org.eclipse.xpanse.modules.models.credential.AbstractCredentialInfo; import org.eclipse.xpanse.modules.models.credential.enums.CredentialType; -import org.eclipse.xpanse.modules.models.monitor.exceptions.ClientApiCallFailedException; import org.eclipse.xpanse.modules.orchestrator.servicestate.ServiceStateManageRequest; import org.eclipse.xpanse.plugins.huaweicloud.common.HuaweiCloudClient; import org.eclipse.xpanse.plugins.huaweicloud.common.HuaweiCloudRetryStrategy; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Retryable; -import org.springframework.retry.support.RetrySynchronizationManager; import org.springframework.stereotype.Component; /** @@ -69,11 +68,8 @@ public boolean startService(ServiceStateManageRequest serviceStateManageRequest) .invoke(); return checkEcsExecResultByJobId(ecsClient, response.getJobId()); } catch (Exception e) { - String errorMsg = String.format("Start service %s error. %s", - serviceStateManageRequest.getServiceId(), e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); + log.error("Start service {} failed", serviceStateManageRequest.getServiceId()); + huaweiCloudRetryStrategy.handleAuthExceptionForSpringRetry(e); throw new ClientApiCallFailedException(e.getMessage()); } } @@ -98,11 +94,8 @@ public boolean stopService(ServiceStateManageRequest serviceStateManageRequest) .invoke(); return checkEcsExecResultByJobId(ecsClient, response.getJobId()); } catch (Exception e) { - String errorMsg = String.format("Stop service %s error. %s", - serviceStateManageRequest.getServiceId(), e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); + log.error("Stop service {} failed", serviceStateManageRequest.getServiceId()); + huaweiCloudRetryStrategy.handleAuthExceptionForSpringRetry(e); throw new ClientApiCallFailedException(e.getMessage()); } } @@ -125,11 +118,8 @@ public boolean restartService(ServiceStateManageRequest serviceStateManageReques .invoke(); return checkEcsExecResultByJobId(ecsClient, response.getJobId()); } catch (Exception e) { - String errorMsg = String.format("Restart service %s error. %s", - serviceStateManageRequest.getServiceId(), e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); + log.error("Restart service {} failed", serviceStateManageRequest.getServiceId()); + huaweiCloudRetryStrategy.handleAuthExceptionForSpringRetry(e); throw new ClientApiCallFailedException(e.getMessage()); } } diff --git a/plugins/huaweicloud/src/main/java/org/eclipse/xpanse/plugins/huaweicloud/monitor/HuaweiCloudMetricsService.java b/plugins/huaweicloud/src/main/java/org/eclipse/xpanse/plugins/huaweicloud/monitor/HuaweiCloudMetricsService.java index f29ff6d52..3b6b0a9e9 100644 --- a/plugins/huaweicloud/src/main/java/org/eclipse/xpanse/plugins/huaweicloud/monitor/HuaweiCloudMetricsService.java +++ b/plugins/huaweicloud/src/main/java/org/eclipse/xpanse/plugins/huaweicloud/monitor/HuaweiCloudMetricsService.java @@ -27,11 +27,11 @@ import org.eclipse.xpanse.modules.cache.monitor.MonitorMetricsStore; import org.eclipse.xpanse.modules.credential.CredentialCenter; import org.eclipse.xpanse.modules.models.common.enums.Csp; +import org.eclipse.xpanse.modules.models.common.exceptions.ClientApiCallFailedException; import org.eclipse.xpanse.modules.models.credential.AbstractCredentialInfo; import org.eclipse.xpanse.modules.models.credential.enums.CredentialType; import org.eclipse.xpanse.modules.models.monitor.Metric; import org.eclipse.xpanse.modules.models.monitor.enums.MonitorResourceType; -import org.eclipse.xpanse.modules.models.monitor.exceptions.ClientApiCallFailedException; import org.eclipse.xpanse.modules.models.monitor.exceptions.MetricsDataNotYetAvailableException; import org.eclipse.xpanse.modules.models.service.deploy.DeployResource; import org.eclipse.xpanse.modules.orchestrator.monitor.ResourceMetricsRequest; @@ -40,7 +40,6 @@ import org.eclipse.xpanse.plugins.huaweicloud.common.HuaweiCloudRetryStrategy; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Retryable; -import org.springframework.retry.support.RetrySynchronizationManager; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; @@ -104,12 +103,9 @@ public List getMetricsByResource(ResourceMetricsRequest resourceMetricRe } return metrics; } catch (Exception e) { - String errorMsg = String.format("Get metrics of resource %s error. %s", - deployResource.getResourceId(), e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); - throw new ClientApiCallFailedException(errorMsg); + log.error("Get metrics of resource {} failed.", deployResource.getResourceId()); + huaweiCloudRetryStrategy.handleAuthExceptionForSpringRetry(e); + throw new ClientApiCallFailedException(e.getMessage()); } } @@ -159,12 +155,9 @@ public List getMetricsByService(ServiceMetricsRequest serviceMetricReque metrics); return metrics; } catch (Exception e) { - String errorMsg = String.format("Get metrics of service %s error. %s", - serviceMetricRequest.getServiceId(), e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); - throw new ClientApiCallFailedException(errorMsg); + log.error("Get metrics of service {} failed.", serviceMetricRequest.getServiceId()); + huaweiCloudRetryStrategy.handleAuthExceptionForSpringRetry(e); + throw new ClientApiCallFailedException(e.getMessage()); } } diff --git a/plugins/huaweicloud/src/main/java/org/eclipse/xpanse/plugins/huaweicloud/price/HuaweiCloudChinesePriceCalculator.java b/plugins/huaweicloud/src/main/java/org/eclipse/xpanse/plugins/huaweicloud/price/HuaweiCloudChinesePriceCalculator.java index bcff23388..5a132600a 100644 --- a/plugins/huaweicloud/src/main/java/org/eclipse/xpanse/plugins/huaweicloud/price/HuaweiCloudChinesePriceCalculator.java +++ b/plugins/huaweicloud/src/main/java/org/eclipse/xpanse/plugins/huaweicloud/price/HuaweiCloudChinesePriceCalculator.java @@ -21,6 +21,7 @@ import org.eclipse.xpanse.modules.models.billing.Resource; import org.eclipse.xpanse.modules.models.billing.enums.Currency; import org.eclipse.xpanse.modules.models.billing.enums.PricingPeriod; +import org.eclipse.xpanse.modules.models.common.exceptions.ClientApiCallFailedException; import org.eclipse.xpanse.modules.orchestrator.price.ServiceFlavorPriceRequest; import org.eclipse.xpanse.plugins.huaweicloud.common.HuaweiCloudClient; import org.eclipse.xpanse.plugins.huaweicloud.common.HuaweiCloudRetryStrategy; @@ -50,17 +51,23 @@ public class HuaweiCloudChinesePriceCalculator { public Price getPriceWithResourcesUsageInChineseWebsite(ServiceFlavorPriceRequest request, ICredential globalCredential, String projectId) { - log.info("Calling the API of the Chinese website to calculate the price."); - BssClient bssClient = huaweiCloudClient.getBssClient(globalCredential); - ListOnDemandResourceRatingsRequest payPerUseRequest = - convertToPayPerUseRequest(request, projectId); - ListOnDemandResourceRatingsResponse response = - bssClient.listOnDemandResourceRatingsInvoker(payPerUseRequest) - .retryTimes(huaweiCloudRetryStrategy.getRetryMaxAttempts()) - .retryCondition(huaweiCloudRetryStrategy::matchRetryCondition) - .backoffStrategy(huaweiCloudRetryStrategy) - .invoke(); - return convertResourceRatingsResponseToRecurringPrice(response); + try { + log.info("Calling the API of the Chinese website to calculate the price."); + BssClient bssClient = huaweiCloudClient.getBssClient(globalCredential); + ListOnDemandResourceRatingsRequest payPerUseRequest = + convertToPayPerUseRequest(request, projectId); + ListOnDemandResourceRatingsResponse response = + bssClient.listOnDemandResourceRatingsInvoker(payPerUseRequest) + .retryTimes(huaweiCloudRetryStrategy.getRetryMaxAttempts()) + .retryCondition(huaweiCloudRetryStrategy::matchRetryCondition) + .backoffStrategy(huaweiCloudRetryStrategy) + .invoke(); + return convertResourceRatingsResponseToRecurringPrice(response); + } catch (Exception e) { + log.error("Call the API of the Chinese website to calculate the price failed."); + huaweiCloudRetryStrategy.handleAuthExceptionForSpringRetry(e); + throw new ClientApiCallFailedException(e.getMessage()); + } } private ListOnDemandResourceRatingsRequest convertToPayPerUseRequest( diff --git a/plugins/huaweicloud/src/main/java/org/eclipse/xpanse/plugins/huaweicloud/price/HuaweiCloudPriceCalculator.java b/plugins/huaweicloud/src/main/java/org/eclipse/xpanse/plugins/huaweicloud/price/HuaweiCloudPriceCalculator.java index 57601c8ee..11057498b 100644 --- a/plugins/huaweicloud/src/main/java/org/eclipse/xpanse/plugins/huaweicloud/price/HuaweiCloudPriceCalculator.java +++ b/plugins/huaweicloud/src/main/java/org/eclipse/xpanse/plugins/huaweicloud/price/HuaweiCloudPriceCalculator.java @@ -30,16 +30,15 @@ import org.eclipse.xpanse.modules.models.billing.enums.Currency; import org.eclipse.xpanse.modules.models.billing.enums.PricingPeriod; import org.eclipse.xpanse.modules.models.common.enums.Csp; +import org.eclipse.xpanse.modules.models.common.exceptions.ClientApiCallFailedException; import org.eclipse.xpanse.modules.models.credential.AbstractCredentialInfo; import org.eclipse.xpanse.modules.models.credential.CredentialVariables; import org.eclipse.xpanse.modules.models.credential.enums.CredentialType; -import org.eclipse.xpanse.modules.models.monitor.exceptions.ClientApiCallFailedException; import org.eclipse.xpanse.modules.orchestrator.price.ServiceFlavorPriceRequest; import org.eclipse.xpanse.plugins.huaweicloud.common.HuaweiCloudClient; import org.eclipse.xpanse.plugins.huaweicloud.common.HuaweiCloudRetryStrategy; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Retryable; -import org.springframework.retry.support.RetrySynchronizationManager; import org.springframework.stereotype.Component; /** @@ -74,16 +73,7 @@ public class HuaweiCloudPriceCalculator { backoff = @Backoff(delayExpression = "${http.request.retry.delay.milliseconds}")) public FlavorPriceResult getServiceFlavorPrice(ServiceFlavorPriceRequest request) { if (request.getBillingMode() == BillingMode.PAY_PER_USE) { - try { - return getServiceFlavorPriceWithPayPerUse(request); - } catch (Exception e) { - String errorMsg = "Get service price with billingModel Pay per Use error." - + e.getMessage(); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); - throw new ClientApiCallFailedException(errorMsg); - } + return getServiceFlavorPriceWithPayPerUse(request); } else { return getServiceFlavorPriceWithFixed(request); } @@ -107,6 +97,7 @@ private FlavorPriceResult getServiceFlavorPriceWithPayPerUse( recurringPrice = getPriceWithResourcesUsageInInternationalWebsite( request, globalCredential, projectId); } catch (ClientRequestException e) { + log.error("Call the API of the international website to calculate the price failed."); if (e.getHttpStatusCode() != 200 && e.getErrorCode().startsWith("CBC.")) { log.error("Calling the API of the international website to calculate the price " + "failed, because the user does not belong to the website. Retrying the " diff --git a/plugins/openstack-common/src/main/java/org/eclipse/xpanse/plugins/openstack/common/auth/ProviderAuthInfoResolver.java b/plugins/openstack-common/src/main/java/org/eclipse/xpanse/plugins/openstack/common/auth/ProviderAuthInfoResolver.java index 87ac75254..a565b2bcf 100644 --- a/plugins/openstack-common/src/main/java/org/eclipse/xpanse/plugins/openstack/common/auth/ProviderAuthInfoResolver.java +++ b/plugins/openstack-common/src/main/java/org/eclipse/xpanse/plugins/openstack/common/auth/ProviderAuthInfoResolver.java @@ -20,13 +20,17 @@ import org.eclipse.xpanse.modules.database.servicetemplate.ServiceTemplateStorage; import org.eclipse.xpanse.modules.deployment.utils.DeployEnvironments; import org.eclipse.xpanse.modules.models.common.enums.Csp; +import org.eclipse.xpanse.modules.models.common.exceptions.ClientAuthenticationFailedException; import org.eclipse.xpanse.modules.models.credential.AbstractCredentialInfo; import org.eclipse.xpanse.modules.models.credential.enums.CredentialType; import org.eclipse.xpanse.plugins.openstack.common.auth.constants.OpenstackCommonEnvironmentConstants; import org.eclipse.xpanse.plugins.openstack.common.auth.keystone.OpenstackKeystoneManager; import org.eclipse.xpanse.plugins.openstack.common.auth.keystone.ScsKeystoneManager; import org.openstack4j.api.OSClient; +import org.openstack4j.api.exceptions.AuthenticationException; import org.springframework.core.env.Environment; +import org.springframework.http.HttpStatus; +import org.springframework.retry.support.RetrySynchronizationManager; import org.springframework.stereotype.Component; /** @@ -92,7 +96,7 @@ public OSClient.OSClientV3 getAuthenticatedClientForCsp( * @return auth url */ public String getProviderAuthUrl(Csp csp, UUID serviceId) { - String authUrl = ""; + String authUrl; if (Objects.isNull(serviceId)) { authUrl = this.environment.getProperty(getAuthUrlKeyByCsp(csp)); log.info("Get auth url {} of provider {} from environment", authUrl, csp); @@ -156,4 +160,41 @@ private String getAuthUrlFromDeploymentVariables(Csp csp, UUID serviceId) { return (String) defaultAuthUrl; } } + + + /** + * Handle auth exception for spring retry. + * + * @param ex Exception + */ + public void handleAuthExceptionForSpringRetry(Exception ex) { + int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) + ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); + log.error(ex.getMessage() + System.lineSeparator() + "Retry count:" + retryCount); + if (ex instanceof ClientAuthenticationFailedException) { + throw new ClientAuthenticationFailedException(ex.getMessage()); + } + AuthenticationException authenticationException = getAuthenticationException(ex); + if (Objects.nonNull(authenticationException)) { + int statusCode = authenticationException.getStatus(); + if (statusCode == HttpStatus.UNAUTHORIZED.value() + || statusCode == HttpStatus.FORBIDDEN.value()) { + throw new ClientAuthenticationFailedException(ex.getMessage()); + } + } + } + + + private AuthenticationException getAuthenticationException(Throwable ex) { + if (Objects.isNull(ex)) { + return null; + } + if (ex instanceof AuthenticationException authException) { + return authException; + } + if (Objects.nonNull(ex.getCause())) { + return getAuthenticationException(ex.getCause()); + } + return null; + } } diff --git a/plugins/openstack-common/src/main/java/org/eclipse/xpanse/plugins/openstack/common/manage/OpenstackResourceManager.java b/plugins/openstack-common/src/main/java/org/eclipse/xpanse/plugins/openstack/common/manage/OpenstackResourceManager.java index ddce7272f..bbb4217c3 100644 --- a/plugins/openstack-common/src/main/java/org/eclipse/xpanse/plugins/openstack/common/manage/OpenstackResourceManager.java +++ b/plugins/openstack-common/src/main/java/org/eclipse/xpanse/plugins/openstack/common/manage/OpenstackResourceManager.java @@ -8,18 +8,16 @@ import jakarta.annotation.Resource; import java.util.ArrayList; import java.util.List; -import java.util.Objects; import java.util.UUID; import lombok.extern.slf4j.Slf4j; import org.eclipse.xpanse.modules.models.common.enums.Csp; -import org.eclipse.xpanse.modules.models.monitor.exceptions.ClientApiCallFailedException; +import org.eclipse.xpanse.modules.models.common.exceptions.ClientApiCallFailedException; import org.eclipse.xpanse.modules.models.service.enums.DeployResourceKind; import org.eclipse.xpanse.plugins.openstack.common.auth.ProviderAuthInfoResolver; import org.openstack4j.api.OSClient; import org.openstack4j.api.OSClient.OSClientV3; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Retryable; -import org.springframework.retry.support.RetrySynchronizationManager; import org.springframework.stereotype.Component; /** @@ -77,12 +75,8 @@ public List getAvailabilityZonesOfRegion(Csp csp, String userId, UUID se osClient.networking().availabilityzone().list().forEach( availabilityZone -> availabilityZoneNames.add(availabilityZone.getName())); } catch (Exception e) { - String errorMsg = String.format( - "OpenstackClient listAvailabilityZones with region %s failed. %s", - region, e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); + log.error("OpenstackClient listAvailabilityZones with region {} failed.", region); + providerAuthInfoResolver.handleAuthExceptionForSpringRetry(e); throw new ClientApiCallFailedException(e.getMessage()); } return availabilityZoneNames; @@ -96,12 +90,8 @@ private List getVpcList(Csp csp, String userId, UUID serviceId, String r osClient.networking().network().list() .forEach(network -> vpcNames.add(network.getName())); } catch (Exception e) { - String errorMsg = String.format( - "OpenstackClient listVpcs with region %s failed. %s", - region, e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); + log.error("OpenstackClient listVpcs with region {} failed.", region); + providerAuthInfoResolver.handleAuthExceptionForSpringRetry(e); throw new ClientApiCallFailedException(e.getMessage()); } return vpcNames; @@ -114,12 +104,8 @@ private List getSubnetList(Csp csp, String userId, UUID serviceId, Strin osClient.networking().subnet().list() .forEach(subnet -> subnetNames.add(subnet.getName())); } catch (Exception e) { - String errorMsg = String.format( - "OpenstackClient listSubnets with region %s failed. %s", - region, e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); + log.error("OpenstackClient listSubnets with region {} failed.", region); + providerAuthInfoResolver.handleAuthExceptionForSpringRetry(e); throw new ClientApiCallFailedException(e.getMessage()); } return subnetNames; @@ -133,12 +119,8 @@ private List getSecurityGroupsList(Csp csp, String userId, UUID serviceI osClient.networking().securitygroup().list() .forEach(securityGroup -> securityGroupNames.add(securityGroup.getName())); } catch (Exception e) { - String errorMsg = String.format( - "OpenstackClient listSecurityGroups with region %s failed. %s", - region, e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); + log.error("OpenstackClient listSecurityGroups with region {} failed.", region); + providerAuthInfoResolver.handleAuthExceptionForSpringRetry(e); throw new ClientApiCallFailedException(e.getMessage()); } return securityGroupNames; @@ -152,12 +134,8 @@ private List getSecurityGroupRuleList(Csp csp, String userId, UUID servi osClient.networking().securityrule().list().forEach( securityGroupRule -> securityGroupRuleIds.add(securityGroupRule.getId())); } catch (Exception e) { - String errorMsg = String.format( - "OpenstackClient listSecurityGroupRules with region %s failed. %s", - region, e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); + log.error("OpenstackClient listSecurityGroupRules with region {} failed.", region); + providerAuthInfoResolver.handleAuthExceptionForSpringRetry(e); throw new ClientApiCallFailedException(e.getMessage()); } return securityGroupRuleIds; @@ -171,12 +149,8 @@ private List getPublicIpList(Csp csp, String userId, UUID serviceId, osClient.networking().floatingip().list().forEach( floatingIp -> publicIpAddresses.add(floatingIp.getFloatingIpAddress())); } catch (Exception e) { - String errorMsg = String.format( - "OpenstackClient listPublicIps with region %s failed. %s", - region, e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); + log.error("OpenstackClient listPublicIps with region {} failed.", region); + providerAuthInfoResolver.handleAuthExceptionForSpringRetry(e); throw new ClientApiCallFailedException(e.getMessage()); } return publicIpAddresses; @@ -190,12 +164,8 @@ private List getVolumeList(Csp csp, String userId, UUID serviceId, osClient.blockStorage().volumes().list() .forEach(volume -> volumeNames.add(volume.getName())); } catch (Exception e) { - String errorMsg = String.format( - "OpenstackClient listVolumes with region %s failed. %s", - region, e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); + log.error("OpenstackClient listVolumes with region {} failed.", region); + providerAuthInfoResolver.handleAuthExceptionForSpringRetry(e); throw new ClientApiCallFailedException(e.getMessage()); } return volumeNames; @@ -208,12 +178,8 @@ private List getKeyPairsList(Csp csp, String userId, UUID serviceId, Str osClient.compute().keypairs().list() .forEach(keyPair -> keyPairNames.add(keyPair.getName())); } catch (Exception e) { - String errorMsg = String.format( - "OpenstackClient listKeyPairs with region %s failed. %s", - region, e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); + log.error("OpenstackClient listKeyPairs with region {} failed.", region); + providerAuthInfoResolver.handleAuthExceptionForSpringRetry(e); throw new ClientApiCallFailedException(e.getMessage()); } return keyPairNames; diff --git a/plugins/openstack-common/src/main/java/org/eclipse/xpanse/plugins/openstack/common/manage/OpenstackServersManager.java b/plugins/openstack-common/src/main/java/org/eclipse/xpanse/plugins/openstack/common/manage/OpenstackServersManager.java index 3650f8ee3..8bb89f0de 100644 --- a/plugins/openstack-common/src/main/java/org/eclipse/xpanse/plugins/openstack/common/manage/OpenstackServersManager.java +++ b/plugins/openstack-common/src/main/java/org/eclipse/xpanse/plugins/openstack/common/manage/OpenstackServersManager.java @@ -8,12 +8,11 @@ import jakarta.annotation.Resource; import java.util.ArrayList; import java.util.List; -import java.util.Objects; import java.util.UUID; import lombok.extern.slf4j.Slf4j; import org.eclipse.xpanse.modules.database.resource.DeployResourceEntity; import org.eclipse.xpanse.modules.models.common.enums.Csp; -import org.eclipse.xpanse.modules.models.monitor.exceptions.ClientApiCallFailedException; +import org.eclipse.xpanse.modules.models.common.exceptions.ClientApiCallFailedException; import org.eclipse.xpanse.modules.orchestrator.servicestate.ServiceStateManageRequest; import org.eclipse.xpanse.plugins.openstack.common.auth.ProviderAuthInfoResolver; import org.openstack4j.api.OSClient; @@ -23,7 +22,6 @@ import org.openstack4j.model.compute.Server; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Retryable; -import org.springframework.retry.support.RetrySynchronizationManager; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; @@ -72,11 +70,8 @@ public boolean startService(Csp csp, ServiceStateManageRequest request) { throw new ClientApiCallFailedException(String.join("\n", errorMessages)); } } catch (Exception e) { - String errorMsg = String.format("Start service %s error. %s", - request.getServiceId(), e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); + log.error("Start service {} failed.", request.getServiceId()); + providerAuthInfoResolver.handleAuthExceptionForSpringRetry(e); throw new ClientApiCallFailedException(e.getMessage()); } return true; @@ -118,11 +113,8 @@ public boolean stopService(Csp csp, ServiceStateManageRequest request) { } return true; } catch (Exception e) { - String errorMsg = String.format("Stop service %s error. %s", - request.getServiceId(), e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); + log.error("Stop service {} failed.", request.getServiceId()); + providerAuthInfoResolver.handleAuthExceptionForSpringRetry(e); throw new ClientApiCallFailedException(e.getMessage()); } } @@ -163,11 +155,8 @@ public boolean restartService(Csp csp, ServiceStateManageRequest request) { } return true; } catch (Exception e) { - String errorMsg = String.format("Restart service %s error. %s", - request.getServiceId(), e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); + log.error("Restart service {} failed.", request.getServiceId()); + providerAuthInfoResolver.handleAuthExceptionForSpringRetry(e); throw new ClientApiCallFailedException(e.getMessage()); } } diff --git a/plugins/openstack-common/src/main/java/org/eclipse/xpanse/plugins/openstack/common/monitor/OpenstackServiceMetricsManager.java b/plugins/openstack-common/src/main/java/org/eclipse/xpanse/plugins/openstack/common/monitor/OpenstackServiceMetricsManager.java index 32335e1cd..3640dee90 100644 --- a/plugins/openstack-common/src/main/java/org/eclipse/xpanse/plugins/openstack/common/monitor/OpenstackServiceMetricsManager.java +++ b/plugins/openstack-common/src/main/java/org/eclipse/xpanse/plugins/openstack/common/monitor/OpenstackServiceMetricsManager.java @@ -15,10 +15,10 @@ import org.eclipse.xpanse.modules.cache.monitor.MonitorMetricsCacheKey; import org.eclipse.xpanse.modules.cache.monitor.MonitorMetricsStore; import org.eclipse.xpanse.modules.models.common.enums.Csp; +import org.eclipse.xpanse.modules.models.common.exceptions.ClientApiCallFailedException; import org.eclipse.xpanse.modules.models.monitor.Metric; import org.eclipse.xpanse.modules.models.monitor.enums.MetricUnit; import org.eclipse.xpanse.modules.models.monitor.enums.MonitorResourceType; -import org.eclipse.xpanse.modules.models.monitor.exceptions.ClientApiCallFailedException; import org.eclipse.xpanse.modules.orchestrator.monitor.ResourceMetricsRequest; import org.eclipse.xpanse.modules.orchestrator.monitor.ServiceMetricsExporter; import org.eclipse.xpanse.plugins.openstack.common.auth.ProviderAuthInfoResolver; @@ -31,7 +31,6 @@ import org.eclipse.xpanse.plugins.openstack.common.monitor.gnocchi.models.resources.InstanceNetworkResource; import org.eclipse.xpanse.plugins.openstack.common.monitor.gnocchi.models.resources.InstanceResource; import org.eclipse.xpanse.plugins.openstack.common.monitor.gnocchi.utils.GnocchiToXpanseModelConverter; -import org.springframework.retry.support.RetrySynchronizationManager; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; @@ -116,12 +115,9 @@ public List getMetrics(Csp csp, ResourceMetricsRequest request) { } return metrics; } catch (Exception e) { - String errorMsg = String.format("Get metrics of resource %s error. %s", - resourceId, e.getMessage()); - int retryCount = Objects.isNull(RetrySynchronizationManager.getContext()) - ? 0 : RetrySynchronizationManager.getContext().getRetryCount(); - log.error(errorMsg + " Retry count:" + retryCount); - throw new ClientApiCallFailedException(errorMsg); + log.error("Get metrics of resource {} failed.", resourceId); + providerAuthInfoResolver.handleAuthExceptionForSpringRetry(e); + throw new ClientApiCallFailedException(e.getMessage()); } } diff --git a/runtime/src/test/java/org/eclipse/xpanse/runtime/ExistingCloudResourcesApiTest.java b/runtime/src/test/java/org/eclipse/xpanse/runtime/ExistingCloudResourcesApiTest.java index 77cafd501..74b593f5f 100644 --- a/runtime/src/test/java/org/eclipse/xpanse/runtime/ExistingCloudResourcesApiTest.java +++ b/runtime/src/test/java/org/eclipse/xpanse/runtime/ExistingCloudResourcesApiTest.java @@ -496,29 +496,6 @@ void getExistingResourceNamesWithKindThrowsClientApiCallFailedException(Csp csp, Assertions.assertEquals(keypairResponse.getResultType(), ResultType.BACKEND_FAILURE); } - - @Test - @WithJwt(file = "jwt_user.json") - void test() throws Exception{ - Csp csp = Csp.PLUS_SERVER; - OSClient.OSClientV3 mockOsClient = getMockOsClientWithMockServices(); - addCredentialForOpenstack(csp); - String openstackRegion = "RegionOne"; - List networksResult = List.of("network_test"); - File networksjonFile = new File("src/test/resources/openstack/network/networks.json"); - NeutronNetwork.Networks networksResponse = - objectMapper.readValue(networksjonFile, NeutronNetwork.Networks.class); - when((List) mockOsClient.networking().network().list()).thenReturn( - networksResponse.getList()); - // Run the test - final MockHttpServletResponse openstackVpcResponse = - getExistingResourceNamesWithKind(DeployResourceKind.VPC, csp, openstackRegion); - // Verify the results - assertThat(openstackVpcResponse.getStatus()).isEqualTo(HttpStatus.OK.value()); - assertThat(openstackVpcResponse.getContentAsString()).isEqualTo( - objectMapper.writeValueAsString(networksResult)); - } - void testGetExistingResourceNamesWithKindForCspWithOsClient(Csp csp) throws Exception { // Setup OSClient.OSClientV3 mockOsClient = getMockOsClientWithMockServices(); diff --git a/samples/develop/flexibleEngine-compute-terraform-dev.yml b/samples/develop/flexibleEngine-compute-terraform-dev.yml index c4bc54e95..dc1ac8b12 100644 --- a/samples/develop/flexibleEngine-compute-terraform-dev.yml +++ b/samples/develop/flexibleEngine-compute-terraform-dev.yml @@ -18,8 +18,6 @@ cloudServiceProvider: regions: - name: eu-west-0 area: Western Europe - - name: eu-west-1 - area: Western Europe billing: # The supported mode of billing (`Fixed`, `Pay per Use`) billingModes: diff --git a/samples/flexibleEngine-K8S.yml b/samples/flexibleEngine-K8S.yml index 9aeb329ea..8c55fe9a9 100644 --- a/samples/flexibleEngine-K8S.yml +++ b/samples/flexibleEngine-K8S.yml @@ -18,8 +18,6 @@ cloudServiceProvider: regions: - name: eu-west-0 area: Western Europe - - name: eu-west-1 - area: Western Europe billing: # The supported mode of billing (`Fixed`, `Pay per Use`) billingModes: diff --git a/samples/flexibleEngine-Kafka.yml b/samples/flexibleEngine-Kafka.yml index 03b866ab7..49f8a71c1 100644 --- a/samples/flexibleEngine-Kafka.yml +++ b/samples/flexibleEngine-Kafka.yml @@ -18,8 +18,6 @@ cloudServiceProvider: regions: - name: eu-west-0 area: Western Europe - - name: eu-west-1 - area: Western Europe billing: # The supported mode of billing (`Fixed`, `Pay per Use`) billingModes: