X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=cps-ncmp-service%2Fsrc%2Fmain%2Fjava%2Forg%2Fonap%2Fcps%2Fncmp%2Fapi%2Fimpl%2Foperations%2FDmiDataOperations.java;h=fa18767dbe7fed7737de1893123e32f317eff45b;hb=d8580ac133935b6a8ac38bbed2452072510a0b67;hp=1a3952306ffc88727307bbd0bd57096e55ce9718;hpb=e626c9661fd88a585b50dafab5f5542784690143;p=cps.git 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 1a3952306..fa18767db 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,26 +21,36 @@ 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.OperationEnum.READ; +import static org.onap.cps.ncmp.api.impl.operations.OperationType.READ; +import io.micrometer.core.annotation.Timed; import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.Set; +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.executor.TaskExecutor; -import org.onap.cps.ncmp.api.impl.utils.DmiServiceNameOrganizer; +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; +import org.onap.cps.ncmp.api.impl.utils.data.operation.ResourceDataOperationRequestUtils; import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle; -import org.onap.cps.ncmp.api.inventory.CmHandleState; -import org.onap.cps.ncmp.api.inventory.InventoryPersistence; +import org.onap.cps.ncmp.api.models.DataOperationRequest; import org.onap.cps.spi.exceptions.CpsException; import org.onap.cps.utils.JsonObjectMapper; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.util.UriComponentsBuilder; /** * Operations class for DMI data. @@ -50,7 +60,6 @@ import org.springframework.stereotype.Component; public class DmiDataOperations extends DmiOperations { private static final long DEFAULT_ASYNC_TASK_EXECUTOR_TIMEOUT_IN_MILLISECONDS = 30000L; - private static final String NO_CM_HANDLE_ID = ""; public DmiDataOperations(final InventoryPersistence inventoryPersistence, final JsonObjectMapper jsonObjectMapper, @@ -72,6 +81,9 @@ public class DmiDataOperations extends DmiOperations { * @param requestId requestId for async responses * @return {@code ResponseEntity} response entity */ + @Timed(value = "cps.ncmp.dmi.get", + description = "Time taken to fetch the resource data from operational data store for given cm handle " + + "identifier on given resource using dmi client") public ResponseEntity getResourceDataFromDmi(final String dataStoreName, final String cmHandleId, final String resourceId, @@ -88,40 +100,13 @@ public class DmiDataOperations extends DmiOperations { return dmiRestClient.postOperationWithJsonData(dmiResourceDataUrl, jsonRequestBody, READ); } - /** - * This method fetches the resource data by data store for given list of cm handles using dmi client. - * - * @param dataStoreName data store name - * @param cmHandleIds list of cm handles - * @param resourceId resource identifier - * @param optionsParamInQuery options query - * @param topicParamInQuery topic name for (triggering) async responses - * @param requestId requestId for async responses - * @return {@code ResponseEntity} response entity - */ - public ResponseEntity getResourceDataFromDmi(final String dataStoreName, - final List cmHandleIds, - final String resourceId, - final String optionsParamInQuery, - final String topicParamInQuery, - final String requestId) { - final Collection yangModelCmHandles - = inventoryPersistence.getYangModelCmHandles(cmHandleIds); - final Map>> dmiServiceNameCmHandlePropertiesMap = - DmiServiceNameOrganizer.getDmiPropertiesPerCmHandleIdPerServiceName(yangModelCmHandles); - - buildBulkResourceDataRequestAndSend(dataStoreName, resourceId, optionsParamInQuery, - topicParamInQuery, requestId, dmiServiceNameCmHandlePropertiesMap); - return new ResponseEntity<>(HttpStatus.ACCEPTED); - } - /** * This method fetches all the resource data from operational data store for given cm handle * identifier using dmi client. * - * @param dataStoreName data store name - * @param cmHandleId network resource identifier - * @param requestId requestId for async responses + * @param dataStoreName data store name + * @param cmHandleId network resource identifier + * @param requestId requestId for async responses * @return {@code ResponseEntity} response entity */ public ResponseEntity getResourceDataFromDmi(final String dataStoreName, @@ -130,12 +115,37 @@ public class DmiDataOperations extends DmiOperations { final YangModelCmHandle yangModelCmHandle = getYangModelCmHandle(cmHandleId); final String jsonRequestBody = getDmiRequestBody(READ, requestId, null, null, yangModelCmHandle); - final String dmiResourceDataUrl = getDmiRequestUrl(dataStoreName, cmHandleId, "/", null, - null, yangModelCmHandle.resolveDmiServiceName(RequiredDmiService.DATA)); + final String dmiResourceDataUrl = getDmiRequestUrl(dataStoreName, cmHandleId, "/", + null, null, + yangModelCmHandle.resolveDmiServiceName(RequiredDmiService.DATA)); final CmHandleState cmHandleState = yangModelCmHandle.getCompositeState().getCmHandleState(); validateIfCmHandleStateReady(yangModelCmHandle, cmHandleState); - return dmiRestClient.postOperationWithJsonData(dmiResourceDataUrl, jsonRequestBody, - READ); + return dmiRestClient.postOperationWithJsonData(dmiResourceDataUrl, jsonRequestBody, READ); + } + + /** + * This method requests the resource data by data store for given list of cm handles using dmi client. + * The data wil be returned as message on the topic specified. + * + * @param topicParamInQuery topic name for (triggering) async responses + * @param dataOperationRequest data operation request to execute operations + * @param requestId requestId for as a response + */ + public void requestResourceDataFromDmi(final String topicParamInQuery, + final DataOperationRequest dataOperationRequest, + final String requestId) { + + final Set cmHandlesIds + = getDistinctCmHandleIdsFromDataOperationRequest(dataOperationRequest); + + final Collection yangModelCmHandles + = inventoryPersistence.getYangModelCmHandles(cmHandlesIds); + + final Map> operationsOutPerDmiServiceName + = ResourceDataOperationRequestUtils.processPerDefinitionInDataOperationsRequest(topicParamInQuery, + requestId, dataOperationRequest, yangModelCmHandles); + + buildDataOperationRequestUrlAndSendToDmiService(topicParamInQuery, requestId, operationsOutPerDmiServiceName); } /** @@ -143,36 +153,39 @@ public class DmiDataOperations extends DmiOperations { * identifier on given resource using dmi client. * * @param cmHandleId network resource identifier - * @param resourceId resource identifier - * @param operation operation enum - * @param requestData the request data - * @param dataType data type + * @param resourceId resource identifier + * @param operationType operation enum + * @param requestData the request data + * @param dataType data type * @return {@code ResponseEntity} response entity */ public ResponseEntity writeResourceDataPassThroughRunningFromDmi(final String cmHandleId, final String resourceId, - final OperationEnum operation, + final OperationType operationType, final String requestData, final String dataType) { final YangModelCmHandle yangModelCmHandle = getYangModelCmHandle(cmHandleId); - final String jsonRequestBody = getDmiRequestBody(operation, null, requestData, dataType, + final String jsonRequestBody = getDmiRequestBody(operationType, null, requestData, dataType, yangModelCmHandle); final String dmiUrl = getDmiRequestUrl(PASSTHROUGH_RUNNING.getDatastoreName(), cmHandleId, resourceId, null, null, yangModelCmHandle.resolveDmiServiceName(RequiredDmiService.DATA)); final CmHandleState cmHandleState = yangModelCmHandle.getCompositeState().getCmHandleState(); validateIfCmHandleStateReady(yangModelCmHandle, cmHandleState); - return dmiRestClient.postOperationWithJsonData(dmiUrl, jsonRequestBody, operation); + return dmiRestClient.postOperationWithJsonData(dmiUrl, jsonRequestBody, operationType); } private YangModelCmHandle getYangModelCmHandle(final String cmHandleId) { return inventoryPersistence.getYangModelCmHandle(cmHandleId); } - private String getDmiRequestBody(final OperationEnum operation, final String requestId, final String requestData, - final String dataType, final YangModelCmHandle yangModelCmHandle) { + private String getDmiRequestBody(final OperationType operationType, + final String requestId, + final String requestData, + final String dataType, + final YangModelCmHandle yangModelCmHandle) { final DmiRequestBody dmiRequestBody = DmiRequestBody.builder() - .operation(operation) + .operationType(operationType) .requestId(requestId) .data(requestData) .dataType(dataType) @@ -181,17 +194,6 @@ public class DmiDataOperations extends DmiOperations { return jsonObjectMapper.asJsonString(dmiRequestBody); } - private String getDmiBulkRequestBody(final OperationEnum operation, - final String requestId, - final String requestData) { - final DmiRequestBody dmiBulkRequestBody = DmiRequestBody.builder() - .operation(operation) - .requestId(requestId) - .data(requestData) - .build(); - return jsonObjectMapper.asJsonString(dmiBulkRequestBody); - } - private String getDmiRequestUrl(final String dataStoreName, final String cmHandleId, final String resourceId, @@ -204,15 +206,13 @@ public class DmiDataOperations extends DmiOperations { cmHandleId)); } - private String getDmiServiceBulkRequestUrl(final String dataStoreName, - final String resourceId, - final String optionsParamInQuery, - final String topicParamInQuery, - final String dmiServiceName) { - return dmiServiceUrlBuilder.getBulkRequestUrl( - dmiServiceUrlBuilder.populateQueryParams(resourceId, optionsParamInQuery, - topicParamInQuery), dmiServiceUrlBuilder.populateUriVariables(dataStoreName, dmiServiceName, - NO_CM_HANDLE_ID)); + private String getDmiServiceDataOperationRequestUrl(final String dmiServiceName, + final String topicParamInQuery, + final String requestId) { + final MultiValueMap dataOperationRequestQueryParams = dmiServiceUrlBuilder + .getDataOperationRequestQueryParams(topicParamInQuery, requestId); + return dmiServiceUrlBuilder.getDataOperationRequestUrl(dataOperationRequestQueryParams, + dmiServiceUrlBuilder.populateDataOperationRequestUriVariables(dmiServiceName)); } private void validateIfCmHandleStateReady(final YangModelCmHandle yangModelCmHandle, @@ -224,37 +224,63 @@ public class DmiDataOperations extends DmiOperations { } } - private void buildBulkResourceDataRequestAndSend(final String dataStoreName, - final String resourceId, - final String optionsParamInQuery, - final String topicParamInQuery, - final String requestId, - final Map>> - dmiServiceNameCmHandlePropertiesMap) { - dmiServiceNameCmHandlePropertiesMap.entrySet().parallelStream().forEach( - dmiServiceNameCmHandlePropertiesEntry -> { - final String dmiBulkResourceDataUrl = getDmiServiceBulkRequestUrl(dataStoreName, resourceId, - optionsParamInQuery, topicParamInQuery, dmiServiceNameCmHandlePropertiesEntry.getKey()); - final String jsonRequestBodyAsJsonString = - jsonObjectMapper.asJsonString(dmiServiceNameCmHandlePropertiesEntry.getValue()); - final String jsonRequestBody - = getDmiBulkRequestBody(READ, requestId, jsonRequestBodyAsJsonString); - sendDmiResourceDataRequestToDmiService(dmiBulkResourceDataUrl, jsonRequestBody); - }); + private static Set getDistinctCmHandleIdsFromDataOperationRequest(final DataOperationRequest + dataOperationRequest) { + return dataOperationRequest.getDataOperationDefinitions().stream() + .flatMap(dataOperationDefinition -> + dataOperationDefinition.getCmHandleIds().stream()).collect(Collectors.toSet()); } - private void sendDmiResourceDataRequestToDmiService(final String dmiBulkResourceDataUrl, - final String dmiResourceDataRequestAsJsonString) { - TaskExecutor.executeTask(() -> - dmiRestClient.postOperationWithJsonData(dmiBulkResourceDataUrl, - dmiResourceDataRequestAsJsonString, READ), + private void buildDataOperationRequestUrlAndSendToDmiService(final String topicParamInQuery, + final String requestId, + final Map> + groupsOutPerDmiServiceName) { + + groupsOutPerDmiServiceName.forEach((dmiServiceName, dmiDataOperationRequestBodies) -> { + final String dmiDataOperationResourceUrl = + getDmiServiceDataOperationRequestUrl(dmiServiceName, topicParamInQuery, requestId); + sendDataOperationRequestToDmiService(dmiDataOperationResourceUrl, dmiDataOperationRequestBodies); + }); + } + + private void sendDataOperationRequestToDmiService(final String dataOperationResourceUrl, + final List dmiDataOperationRequestBodies) { + final DmiDataOperationRequest dmiDataOperationRequest = DmiDataOperationRequest.builder() + .operations(dmiDataOperationRequestBodies).build(); + final String dmiDataOperationRequestAsJsonString = + jsonObjectMapper.asJsonString(dmiDataOperationRequest); + TaskExecutor.executeTask(() -> dmiRestClient.postOperationWithJsonData(dataOperationResourceUrl, + dmiDataOperationRequestAsJsonString, READ), DEFAULT_ASYNC_TASK_EXECUTOR_TIMEOUT_IN_MILLISECONDS) - .whenCompleteAsync(this::handleTaskCompletion); + .whenCompleteAsync((response, throwable) -> handleTaskCompletionException(throwable, + dataOperationResourceUrl, dmiDataOperationRequestBodies)); } - private void handleTaskCompletion(final Object response, final Throwable throwable) { - // TODO Need to publish an error response to client given topic. - // Code should be implemented into https://jira.onap.org/browse/CPS-1558 ( - // NCMP : Handle non responding DMI-Plugin) + private void handleTaskCompletionException(final Throwable throwable, + final String dataOperationResourceUrl, + final List dmiDataOperationRequestBodies) { + if (throwable != null) { + final MultiValueMap dataOperationResourceUrlParameters = + UriComponentsBuilder.fromUriString(dataOperationResourceUrl).build().getQueryParams(); + final String topicName = dataOperationResourceUrlParameters.get("topic").get(0); + final String requestId = dataOperationResourceUrlParameters.get("requestId").get(0); + + final MultiValueMap>> + cmHandleIdsPerResponseCodesPerOperation = new LinkedMultiValueMap<>(); + + dmiDataOperationRequestBodies.forEach(dmiDataOperationRequestBody -> { + final List 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); + } } }