aboutsummaryrefslogtreecommitdiffstats
path: root/cps-ncmp-service/src/main/java/org/onap/cps/ncmp
diff options
context:
space:
mode:
authorsourabh_sourabh <sourabh.sourabh@est.tech>2024-05-07 12:31:44 +0100
committersourabh_sourabh <sourabh.sourabh@est.tech>2024-05-17 12:23:36 +0100
commit3ad3931017bafabbb78c43e82beb8f462e3796ac (patch)
tree76e1c2bd3ca93e4cca7bb27df574d8eab1e77b6b /cps-ncmp-service/src/main/java/org/onap/cps/ncmp
parent01d2f8e3cdb59ce11856b6e6e8ad4e3e4ec91804 (diff)
Replaced RestTemplate with WebClient in synchronous DMI calls
- added DmiWebClientConfiguration - use WebClient in DmiRestClient - fixed unit tests - encode query params for DMI request - added configurable buffer size - Re-used ncmp.dmi.httpclient.maximumConnectionsTotal parameter (as documented in RTD) to control webclient connection poolsize Issue-ID: CPS-2173 Change-Id: I21584563034d58e8ae3ff3cbcf172e0d14b408fb Signed-off-by: sourabh_sourabh <sourabh.sourabh@est.tech>
Diffstat (limited to 'cps-ncmp-service/src/main/java/org/onap/cps/ncmp')
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/client/DmiRestClient.java84
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/DmiWebClientConfiguration.java94
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/NcmpConfiguration.java114
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/DmiClientRequestException.java54
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/InvalidDmiResourceUrlException.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/HttpClientRequestException.java)22
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java53
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiModelOperations.java4
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperations.java8
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/DmiServiceUrlBuilder.java12
9 files changed, 251 insertions, 194 deletions
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/client/DmiRestClient.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/client/DmiRestClient.java
index 798a280c8..97ae677c5 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/client/DmiRestClient.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/client/DmiRestClient.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021-2023 Nordix Foundation
+ * Copyright (C) 2021-2024 Nordix Foundation
* Modifications Copyright (C) 2022 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,20 +21,31 @@
package org.onap.cps.ncmp.api.impl.client;
+import static org.onap.cps.ncmp.api.NcmpResponseStatus.DMI_SERVICE_NOT_RESPONDING;
+import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNABLE_TO_READ_RESOURCE_DATA;
+import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNKNOWN_ERROR;
+import static org.springframework.http.HttpStatus.BAD_REQUEST;
+import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
+
import com.fasterxml.jackson.databind.JsonNode;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.util.Locale;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration.DmiProperties;
-import org.onap.cps.ncmp.api.impl.exception.HttpClientRequestException;
+import org.onap.cps.ncmp.api.impl.config.DmiWebClientConfiguration.DmiProperties;
+import org.onap.cps.ncmp.api.impl.exception.DmiClientRequestException;
+import org.onap.cps.ncmp.api.impl.exception.InvalidDmiResourceUrlException;
import org.onap.cps.ncmp.api.impl.operations.OperationType;
-import org.springframework.http.HttpEntity;
+import org.onap.cps.utils.JsonObjectMapper;
import org.springframework.http.HttpHeaders;
-import org.springframework.http.MediaType;
+import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
-import org.springframework.web.client.HttpStatusCodeException;
-import org.springframework.web.client.RestTemplate;
+import org.springframework.web.client.HttpServerErrorException;
+import org.springframework.web.reactive.function.BodyInserters;
+import org.springframework.web.reactive.function.client.WebClient;
+import org.springframework.web.reactive.function.client.WebClientResponseException;
@Component
@RequiredArgsConstructor
@@ -43,8 +54,10 @@ public class DmiRestClient {
private static final String HEALTH_CHECK_URL_EXTENSION = "/actuator/health";
private static final String NOT_SPECIFIED = "";
- private final RestTemplate restTemplate;
+ private static final String NO_AUTHORIZATION = null;
+ private final WebClient webClient;
private final DmiProperties dmiProperties;
+ private final JsonObjectMapper jsonObjectMapper;
/**
* Sends POST operation to DMI with json body containing module references.
@@ -59,14 +72,16 @@ public class DmiRestClient {
final String requestBodyAsJsonString,
final OperationType operationType,
final String authorization) {
- final var httpEntity = new HttpEntity<>(requestBodyAsJsonString, configureHttpHeaders(new HttpHeaders(),
- authorization));
try {
- return restTemplate.postForEntity(dmiResourceUrl, httpEntity, Object.class);
- } catch (final HttpStatusCodeException httpStatusCodeException) {
- final String exceptionMessage = "Unable to " + operationType.toString() + " resource data.";
- throw new HttpClientRequestException(exceptionMessage, httpStatusCodeException.getResponseBodyAsString(),
- httpStatusCodeException.getStatusCode().value());
+ return ResponseEntity.ok(webClient.post().uri(toUri(dmiResourceUrl))
+ .headers(httpHeaders -> configureHttpHeaders(httpHeaders, authorization))
+ .body(BodyInserters.fromValue(requestBodyAsJsonString))
+ .retrieve()
+ .bodyToMono(Object.class)
+ .onErrorMap(httpError -> handleDmiClientException(httpError, operationType.getOperationName()))
+ .block());
+ } catch (final HttpServerErrorException e) {
+ throw handleDmiClientException(e, operationType.getOperationName());
}
}
@@ -77,13 +92,14 @@ public class DmiRestClient {
* @return plugin health status ("UP" is all OK, "" (not-specified) in case of any exception)
*/
public String getDmiHealthStatus(final String dmiPluginBaseUrl) {
- final HttpEntity<Object> httpHeaders = new HttpEntity<>(configureHttpHeaders(new HttpHeaders(), null));
try {
- final JsonNode responseHealthStatus =
- restTemplate.getForObject(dmiPluginBaseUrl + HEALTH_CHECK_URL_EXTENSION,
- JsonNode.class, httpHeaders);
+ final JsonNode responseHealthStatus = webClient.get()
+ .uri(toUri(dmiPluginBaseUrl + HEALTH_CHECK_URL_EXTENSION))
+ .headers(httpHeaders -> configureHttpHeaders(httpHeaders, NO_AUTHORIZATION))
+ .retrieve()
+ .bodyToMono(JsonNode.class).block();
return responseHealthStatus == null ? NOT_SPECIFIED :
- responseHealthStatus.get("status").asText();
+ responseHealthStatus.get("status").asText();
} catch (final Exception e) {
log.warn("Failed to retrieve health status from {}. Error Message: {}", dmiPluginBaseUrl, e.getMessage());
return NOT_SPECIFIED;
@@ -96,7 +112,33 @@ public class DmiRestClient {
} else if (authorization != null && authorization.toLowerCase(Locale.getDefault()).startsWith("bearer ")) {
httpHeaders.add(HttpHeaders.AUTHORIZATION, authorization);
}
- httpHeaders.setContentType(MediaType.APPLICATION_JSON);
return httpHeaders;
}
+
+ private static URI toUri(final String dmiResourceUrl) {
+ try {
+ return new URI(dmiResourceUrl);
+ } catch (final URISyntaxException e) {
+ throw new InvalidDmiResourceUrlException(dmiResourceUrl, BAD_REQUEST.value());
+ }
+ }
+
+ private DmiClientRequestException handleDmiClientException(final Throwable e, final String operationType) {
+ final String exceptionMessage = "Unable to " + operationType + " resource data.";
+ if (e instanceof WebClientResponseException wcre) {
+ if (wcre.getStatusCode().isSameCodeAs(HttpStatus.REQUEST_TIMEOUT)) {
+ throw new DmiClientRequestException(wcre.getStatusCode().value(), wcre.getMessage(),
+ jsonObjectMapper.asJsonString(wcre.getResponseBodyAsString()), DMI_SERVICE_NOT_RESPONDING);
+ }
+ throw new DmiClientRequestException(wcre.getStatusCode().value(), wcre.getMessage(),
+ jsonObjectMapper.asJsonString(wcre.getResponseBodyAsString()), UNABLE_TO_READ_RESOURCE_DATA);
+
+ }
+ if (e instanceof HttpServerErrorException httpServerErrorException) {
+ throw new DmiClientRequestException(httpServerErrorException.getStatusCode().value(), exceptionMessage,
+ httpServerErrorException.getResponseBodyAsString(), DMI_SERVICE_NOT_RESPONDING);
+ }
+ throw new DmiClientRequestException(INTERNAL_SERVER_ERROR.value(), exceptionMessage, e.getMessage(),
+ UNKNOWN_ERROR);
+ }
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/DmiWebClientConfiguration.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/DmiWebClientConfiguration.java
new file mode 100644
index 000000000..21271665f
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/DmiWebClientConfiguration.java
@@ -0,0 +1,94 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.api.impl.config;
+
+import io.netty.channel.ChannelOption;
+import io.netty.handler.timeout.ReadTimeoutHandler;
+import io.netty.handler.timeout.WriteTimeoutHandler;
+import java.util.concurrent.TimeUnit;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.client.reactive.ReactorClientHttpConnector;
+import org.springframework.stereotype.Component;
+import org.springframework.web.reactive.function.client.WebClient;
+import reactor.netty.http.client.HttpClient;
+import reactor.netty.resources.ConnectionProvider;
+
+@Configuration
+@RequiredArgsConstructor
+public class DmiWebClientConfiguration {
+
+ @Value("${ncmp.dmi.httpclient.connectionTimeoutInSeconds:20000}")
+ private Integer connectionTimeoutInSeconds;
+
+ @Value("${ncmp.dmi.httpclient.maximumInMemorySizeInMegabytes:1}")
+ private Integer maximumInMemorySizeInMegabytes;
+
+ @Value("${ncmp.dmi.httpclient.maximumConnectionsTotal:100}")
+ private Integer maximumConnectionsTotal;
+
+ @Getter
+ @Component
+ public static class DmiProperties {
+ @Value("${ncmp.dmi.auth.username}")
+ private String authUsername;
+ @Value("${ncmp.dmi.auth.password}")
+ private String authPassword;
+ @Value("${ncmp.dmi.api.base-path}")
+ private String dmiBasePath;
+ @Value("${ncmp.dmi.auth.enabled}")
+ private boolean dmiBasicAuthEnabled;
+ }
+
+ /**
+ * Configures and create a WebClient bean that triggers an initialization (warmup) of the host name resolver and
+ * loads the necessary native libraries to avoid the extra time needed to load resources for first request.
+ *
+ * @return a WebClient instance.
+ */
+ @Bean
+ public WebClient webClient() {
+
+ final ConnectionProvider dmiWebClientConnectionProvider
+ = ConnectionProvider.create("dmiWebClientConnectionPool", maximumConnectionsTotal);
+
+ final HttpClient httpClient = HttpClient.create(dmiWebClientConnectionProvider)
+ .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectionTimeoutInSeconds * 1000)
+ .doOnConnected(connection ->
+ connection
+ .addHandlerLast(new ReadTimeoutHandler(connectionTimeoutInSeconds, TimeUnit.SECONDS))
+ .addHandlerLast(new WriteTimeoutHandler(connectionTimeoutInSeconds, TimeUnit.SECONDS)));
+ httpClient.warmup().block();
+ return WebClient.builder()
+ .defaultHeaders(header -> header.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE))
+ .defaultHeaders(header -> header.set(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE))
+ .clientConnector(new ReactorClientHttpConnector(httpClient))
+ .codecs(configurer -> configurer
+ .defaultCodecs()
+ .maxInMemorySize(maximumInMemorySizeInMegabytes * 1024 * 1024))
+ .build();
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/NcmpConfiguration.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/NcmpConfiguration.java
deleted file mode 100644
index c6ff116a7..000000000
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/NcmpConfiguration.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2021-2023 Nordix Foundation
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * SPDX-License-Identifier: Apache-2.0
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.cps.ncmp.api.impl.config;
-
-import java.util.Arrays;
-import lombok.AccessLevel;
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-import org.apache.hc.client5.http.config.ConnectionConfig;
-import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
-import org.apache.hc.client5.http.impl.classic.HttpClients;
-import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
-import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
-import org.apache.hc.core5.util.TimeValue;
-import org.apache.hc.core5.util.Timeout;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.beans.factory.config.ConfigurableBeanFactory;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.boot.web.client.RestTemplateBuilder;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Scope;
-import org.springframework.http.MediaType;
-import org.springframework.http.client.ClientHttpRequestFactory;
-import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
-import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
-import org.springframework.stereotype.Component;
-import org.springframework.web.client.RestTemplate;
-
-@Configuration
-@EnableConfigurationProperties(HttpClientConfiguration.class)
-@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
-public class NcmpConfiguration {
-
- @Getter
- @Component
- public static class DmiProperties {
- @Value("${ncmp.dmi.auth.username}")
- private String authUsername;
- @Value("${ncmp.dmi.auth.password}")
- private String authPassword;
- @Value("${ncmp.dmi.api.base-path}")
- private String dmiBasePath;
- @Value("${ncmp.dmi.auth.enabled}")
- private boolean dmiBasicAuthEnabled;
- }
-
- /**
- * Rest template bean.
- *
- * @param restTemplateBuilder the rest template builder
- * @param httpClientConfiguration the http client configuration
- * @return rest template instance
- */
- @Bean
- @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
- public static RestTemplate restTemplate(final RestTemplateBuilder restTemplateBuilder,
- final HttpClientConfiguration httpClientConfiguration) {
-
- final ConnectionConfig connectionConfig = ConnectionConfig.copy(ConnectionConfig.DEFAULT)
- .setConnectTimeout(Timeout.of(httpClientConfiguration.getConnectionTimeoutInSeconds()))
- .build();
-
- final PoolingHttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder.create()
- .setDefaultConnectionConfig(connectionConfig)
- .setMaxConnTotal(httpClientConfiguration.getMaximumConnectionsTotal())
- .setMaxConnPerRoute(httpClientConfiguration.getMaximumConnectionsPerRoute())
- .build();
-
- final CloseableHttpClient httpClient = HttpClients.custom()
- .setConnectionManager(connectionManager)
- .evictExpiredConnections()
- .evictIdleConnections(
- TimeValue.of(httpClientConfiguration.getIdleConnectionEvictionThresholdInSeconds()))
- .build();
-
- final ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
-
- final RestTemplate restTemplate = restTemplateBuilder
- .requestFactory(() -> requestFactory)
- .setConnectTimeout(httpClientConfiguration.getConnectionTimeoutInSeconds())
- .build();
-
- setRestTemplateMessageConverters(restTemplate);
- return restTemplate;
- }
-
- private static void setRestTemplateMessageConverters(final RestTemplate restTemplate) {
- final MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter =
- new MappingJackson2HttpMessageConverter();
- mappingJackson2HttpMessageConverter.setSupportedMediaTypes(
- Arrays.asList(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN));
- restTemplate.getMessageConverters().add(mappingJackson2HttpMessageConverter);
- }
-
-}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/DmiClientRequestException.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/DmiClientRequestException.java
new file mode 100644
index 000000000..ab0fa6893
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/DmiClientRequestException.java
@@ -0,0 +1,54 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022-2024 Nordix Foundation
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.api.impl.exception;
+
+import lombok.Getter;
+import org.onap.cps.ncmp.api.NcmpResponseStatus;
+
+/**
+ * Http Client Request exception from dmi service.
+ */
+@Getter
+public class DmiClientRequestException extends NcmpException {
+
+ private static final long serialVersionUID = 6659897770659834797L;
+ final NcmpResponseStatus ncmpResponseStatus;
+ final String message;
+ final String responseBodyAsString;
+ final int httpStatusCode;
+
+ /**
+ * Constructor to form exception for dmi service response.
+ *
+ * @param httpStatusCode http response code from the client
+ * @param message response message from the client
+ * @param responseBodyAsString response body from the client
+ * @param ncmpResponseStatus ncmp status message and code
+ */
+ public DmiClientRequestException(final int httpStatusCode, final String message, final String responseBodyAsString,
+ final NcmpResponseStatus ncmpResponseStatus) {
+ super(message, responseBodyAsString);
+ this.httpStatusCode = httpStatusCode;
+ this.message = message;
+ this.responseBodyAsString = responseBodyAsString;
+ this.ncmpResponseStatus = ncmpResponseStatus;
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/HttpClientRequestException.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/InvalidDmiResourceUrlException.java
index 9d307e5d2..270988b63 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/HttpClientRequestException.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/exception/InvalidDmiResourceUrlException.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2022 Nordix Foundation
+ * Copyright (C) 2024 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,24 +22,16 @@ package org.onap.cps.ncmp.api.impl.exception;
import lombok.Getter;
-/**
- * Http Client Request exception for passthrough scenarios.
- */
@Getter
-public class HttpClientRequestException extends NcmpException {
+public class InvalidDmiResourceUrlException extends RuntimeException {
+
+ private static final long serialVersionUID = 2928476384584894968L;
- private static final long serialVersionUID = 6659897770659834797L;
+ private static final String INVALID_DMI_URL = "Invalid dmi resource url";
final Integer httpStatus;
- /**
- * Constructor to form exception for passthrough scenarios.
- *
- * @param message message details from NCMP
- * @param details response body from the client available as details
- * @param httpStatus http status code from the client
- */
- public HttpClientRequestException(final String message, final String details, final Integer httpStatus) {
- super(message, details);
+ public InvalidDmiResourceUrlException(final String details, final Integer httpStatus) {
+ super(String.format(INVALID_DMI_URL + ": %s", details));
this.httpStatus = httpStatus;
}
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java
index a9ec1241b..20b891616 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java
@@ -21,8 +21,6 @@
package org.onap.cps.ncmp.api.impl.operations;
-import static org.onap.cps.ncmp.api.NcmpResponseStatus.DMI_SERVICE_NOT_RESPONDING;
-import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNABLE_TO_READ_RESOURCE_DATA;
import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.PASSTHROUGH_RUNNING;
import static org.onap.cps.ncmp.api.impl.operations.OperationType.READ;
@@ -35,8 +33,8 @@ import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.onap.cps.ncmp.api.NcmpResponseStatus;
import org.onap.cps.ncmp.api.impl.client.DmiRestClient;
-import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration;
-import org.onap.cps.ncmp.api.impl.exception.HttpClientRequestException;
+import org.onap.cps.ncmp.api.impl.config.DmiWebClientConfiguration.DmiProperties;
+import org.onap.cps.ncmp.api.impl.exception.DmiClientRequestException;
import org.onap.cps.ncmp.api.impl.inventory.CmHandleState;
import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence;
import org.onap.cps.ncmp.api.impl.utils.DmiServiceUrlBuilder;
@@ -61,7 +59,7 @@ public class DmiDataOperations extends DmiOperations {
public DmiDataOperations(final InventoryPersistence inventoryPersistence,
final JsonObjectMapper jsonObjectMapper,
- final NcmpConfiguration.DmiProperties dmiProperties,
+ final DmiProperties dmiProperties,
final DmiRestClient dmiRestClient,
final DmiServiceUrlBuilder dmiServiceUrlBuilder) {
super(inventoryPersistence, jsonObjectMapper, dmiProperties, dmiRestClient, dmiServiceUrlBuilder);
@@ -226,7 +224,7 @@ public class DmiDataOperations extends DmiOperations {
}
private static Set<String> getDistinctCmHandleIdsFromDataOperationRequest(final DataOperationRequest
- dataOperationRequest) {
+ dataOperationRequest) {
return dataOperationRequest.getDataOperationDefinitions().stream()
.flatMap(dataOperationDefinition ->
dataOperationDefinition.getCmHandleIds().stream()).collect(Collectors.toSet());
@@ -235,7 +233,7 @@ public class DmiDataOperations extends DmiOperations {
private void buildDataOperationRequestUrlAndSendToDmiService(final String topicParamInQuery,
final String requestId,
final Map<String, List<DmiDataOperation>>
- groupsOutPerDmiServiceName,
+ groupsOutPerDmiServiceName,
final String authorization) {
groupsOutPerDmiServiceName.forEach((dmiServiceName, dmiDataOperationRequestBodies) -> {
@@ -256,36 +254,29 @@ public class DmiDataOperations extends DmiOperations {
try {
dmiRestClient.postOperationWithJsonData(dataOperationResourceUrl, dmiDataOperationRequestAsJsonString, READ,
authorization);
- } catch (final Exception exception) {
- handleTaskCompletionException(exception, dataOperationResourceUrl, dmiDataOperationRequestBodies);
+ } catch (final DmiClientRequestException e) {
+ handleTaskCompletionException(e, dataOperationResourceUrl, dmiDataOperationRequestBodies);
}
}
- private void handleTaskCompletionException(final Throwable throwable,
+ private void handleTaskCompletionException(final DmiClientRequestException dmiClientRequestException,
final String dataOperationResourceUrl,
final List<DmiDataOperation> dmiDataOperationRequestBodies) {
- if (throwable != null) {
- final MultiValueMap<String, String> dataOperationResourceUrlParameters =
- UriComponentsBuilder.fromUriString(dataOperationResourceUrl).build().getQueryParams();
- final String topicName = dataOperationResourceUrlParameters.get("topic").get(0);
- final String requestId = dataOperationResourceUrlParameters.get("requestId").get(0);
+ final MultiValueMap<String, String> dataOperationResourceUrlParameters =
+ UriComponentsBuilder.fromUriString(dataOperationResourceUrl).build().getQueryParams();
+ final String topicName = dataOperationResourceUrlParameters.get("topic").get(0);
+ final String requestId = dataOperationResourceUrlParameters.get("requestId").get(0);
- final MultiValueMap<DmiDataOperation, Map<NcmpResponseStatus, List<String>>>
- cmHandleIdsPerResponseCodesPerOperation = new LinkedMultiValueMap<>();
+ final MultiValueMap<DmiDataOperation, Map<NcmpResponseStatus, List<String>>>
+ cmHandleIdsPerResponseCodesPerOperation = new LinkedMultiValueMap<>();
- dmiDataOperationRequestBodies.forEach(dmiDataOperationRequestBody -> {
- final List<String> cmHandleIds = dmiDataOperationRequestBody.getCmHandles().stream()
- .map(CmHandle::getId).toList();
- if (throwable.getCause() instanceof HttpClientRequestException) {
- cmHandleIdsPerResponseCodesPerOperation.add(dmiDataOperationRequestBody,
- Map.of(UNABLE_TO_READ_RESOURCE_DATA, cmHandleIds));
- } else {
- cmHandleIdsPerResponseCodesPerOperation.add(dmiDataOperationRequestBody,
- Map.of(DMI_SERVICE_NOT_RESPONDING, cmHandleIds));
- }
- });
- ResourceDataOperationRequestUtils.publishErrorMessageToClientTopic(topicName, requestId,
- cmHandleIdsPerResponseCodesPerOperation);
- }
+ dmiDataOperationRequestBodies.forEach(dmiDataOperationRequestBody -> {
+ final List<String> cmHandleIds = dmiDataOperationRequestBody.getCmHandles().stream()
+ .map(CmHandle::getId).toList();
+ cmHandleIdsPerResponseCodesPerOperation.add(dmiDataOperationRequestBody,
+ Map.of(dmiClientRequestException.getNcmpResponseStatus(), cmHandleIds));
+ });
+ ResourceDataOperationRequestUtils.publishErrorMessageToClientTopic(topicName, requestId,
+ cmHandleIdsPerResponseCodesPerOperation);
}
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiModelOperations.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiModelOperations.java
index 798f6de81..2a9248a16 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiModelOperations.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiModelOperations.java
@@ -34,7 +34,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.onap.cps.ncmp.api.impl.client.DmiRestClient;
-import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration;
+import org.onap.cps.ncmp.api.impl.config.DmiWebClientConfiguration.DmiProperties;
import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence;
import org.onap.cps.ncmp.api.impl.utils.DmiServiceUrlBuilder;
import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
@@ -57,7 +57,7 @@ public class DmiModelOperations extends DmiOperations {
*/
public DmiModelOperations(final InventoryPersistence inventoryPersistence,
final JsonObjectMapper jsonObjectMapper,
- final NcmpConfiguration.DmiProperties dmiProperties,
+ final DmiProperties dmiProperties,
final DmiRestClient dmiRestClient, final DmiServiceUrlBuilder dmiServiceUrlBuilder) {
super(inventoryPersistence, jsonObjectMapper, dmiProperties, dmiRestClient, dmiServiceUrlBuilder);
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperations.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperations.java
index c8d73eac6..f4166d41b 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperations.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperations.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021-2023 Nordix Foundation
+ * Copyright (C) 2021-2024 Nordix Foundation
* Modifications Copyright (C) 2022 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,7 +23,7 @@ package org.onap.cps.ncmp.api.impl.operations;
import lombok.RequiredArgsConstructor;
import org.onap.cps.ncmp.api.impl.client.DmiRestClient;
-import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration;
+import org.onap.cps.ncmp.api.impl.config.DmiWebClientConfiguration.DmiProperties;
import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence;
import org.onap.cps.ncmp.api.impl.utils.DmiServiceUrlBuilder;
import org.onap.cps.utils.JsonObjectMapper;
@@ -35,7 +35,7 @@ public class DmiOperations {
protected final InventoryPersistence inventoryPersistence;
protected final JsonObjectMapper jsonObjectMapper;
- protected final NcmpConfiguration.DmiProperties dmiProperties;
+ protected final DmiProperties dmiProperties;
protected final DmiRestClient dmiRestClient;
protected final DmiServiceUrlBuilder dmiServiceUrlBuilder;
@@ -44,6 +44,4 @@ public class DmiOperations {
.pathSegment("{resourceName}")
.buildAndExpand(dmiServiceName, dmiProperties.getDmiBasePath(), cmHandle, resourceName).toUriString();
}
-
-
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/DmiServiceUrlBuilder.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/DmiServiceUrlBuilder.java
index 04acaa5e9..e0c956803 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/DmiServiceUrlBuilder.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/DmiServiceUrlBuilder.java
@@ -20,12 +20,14 @@
package org.onap.cps.ncmp.api.impl.utils;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import org.apache.logging.log4j.util.Strings;
import org.apache.logging.log4j.util.TriConsumer;
-import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration;
+import org.onap.cps.ncmp.api.impl.config.DmiWebClientConfiguration.DmiProperties;
import org.onap.cps.spi.utils.CpsValidator;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
@@ -35,8 +37,7 @@ import org.springframework.web.util.UriComponentsBuilder;
@Component
@RequiredArgsConstructor
public class DmiServiceUrlBuilder {
-
- private final NcmpConfiguration.DmiProperties dmiProperties;
+ private final DmiProperties dmiProperties;
private final CpsValidator cpsValidator;
/**
@@ -141,8 +142,7 @@ public class DmiServiceUrlBuilder {
final String optionsParamInQuery,
final String topicParamInQuery) {
final MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
- getQueryParamConsumer().accept("resourceIdentifier",
- resourceId, queryParams);
+ getQueryParamConsumer().accept("resourceIdentifier", resourceId, queryParams);
getQueryParamConsumer().accept("options", optionsParamInQuery, queryParams);
if (Strings.isNotEmpty(topicParamInQuery)) {
getQueryParamConsumer().accept("topic", topicParamInQuery, queryParams);
@@ -168,7 +168,7 @@ public class DmiServiceUrlBuilder {
private TriConsumer<String, String, MultiValueMap<String, String>> getQueryParamConsumer() {
return (paramName, paramValue, paramMap) -> {
if (Strings.isNotEmpty(paramValue)) {
- paramMap.add(paramName, paramValue);
+ paramMap.add(paramName, URLEncoder.encode(paramValue, StandardCharsets.UTF_8));
}
};
}