aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsourabh_sourabh <sourabh.sourabh@est.tech>2022-01-18 21:57:46 +0530
committersourabh_sourabh <sourabh.sourabh@est.tech>2022-01-25 21:55:25 +0530
commit05e7b8a207b1c641468e77d754fe1a5ae9e1a51e (patch)
treeb0df8d9b8a08ca001120d6fa544f1e2c5da4f59d
parentdb1e983f40be1db7bca5acacf5a3369d74a29c95 (diff)
Replace gson mapper with jackson mapper
We introduced JsonObjectMapper (wapper) as Spring component. Issue-ID: CPS-751 Change-Id: I536b0771a3a263325e6907717baf6941d70c0d6c Signed-off-by: sourabh_sourabh <sourabh.sourabh@est.tech>
-rw-r--r--cps-ncmp-rest/pom.xml6
-rwxr-xr-xcps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java23
-rw-r--r--cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy24
-rw-r--r--cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy8
-rw-r--r--cps-ncmp-service/pom.xml6
-rwxr-xr-xcps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java40
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java12
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiModelOperations.java17
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperations.java49
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplModelSyncSpec.groovy11
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy17
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy13
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationsSpec.groovy9
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiModelOperationsSpec.groovy13
-rwxr-xr-xcps-rest/src/main/java/org/onap/cps/rest/controller/DataRestController.java31
-rw-r--r--cps-rest/src/main/java/org/onap/cps/rest/controller/QueryRestController.java13
-rwxr-xr-xcps-rest/src/test/groovy/org/onap/cps/rest/controller/DataRestControllerSpec.groovy7
-rw-r--r--cps-rest/src/test/groovy/org/onap/cps/rest/controller/QueryRestControllerSpec.groovy14
-rw-r--r--cps-rest/src/test/groovy/org/onap/cps/rest/exceptions/CpsRestExceptionHandlerSpec.groovy16
-rw-r--r--cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java61
-rw-r--r--cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentRepositoryCpsPathQueryImpl.java13
-rwxr-xr-xcps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceIntegrationSpec.groovy10
-rw-r--r--cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceSpec.groovy5
-rw-r--r--cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsPersistenceSpecBase.groovy8
-rw-r--r--cps-service/pom.xml7
-rw-r--r--cps-service/src/main/java/org/onap/cps/utils/JsonObjectMapper.java90
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/utils/JsonObjectMapperSpec.groovy87
27 files changed, 387 insertions, 223 deletions
diff --git a/cps-ncmp-rest/pom.xml b/cps-ncmp-rest/pom.xml
index 93ee680da..26b83bef8 100644
--- a/cps-ncmp-rest/pom.xml
+++ b/cps-ncmp-rest/pom.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
============LICENSE_START=======================================================
- Copyright (C) 2021 Nordix Foundation
+ Copyright (C) 2021-2022 Nordix Foundation
Modifications Copyright (C) 2021 Bell Canada
================================================================================
Licensed under the Apache License, Version 2.0 (the "License");
@@ -61,10 +61,6 @@
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
</dependency>
- <dependency>
- <groupId>org.modelmapper</groupId>
- <artifactId>modelmapper</artifactId>
- </dependency>
<!-- T E S T D E P E N D E N C I E S -->
<dependency>
<groupId>org.codehaus.groovy</groupId>
diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java
index f2f43c989..419f6e926 100755
--- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java
+++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java
@@ -27,8 +27,6 @@ import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum
import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.PATCH;
import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.UPDATE;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -36,6 +34,7 @@ import java.util.List;
import java.util.stream.Collectors;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
+import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.modelmapper.ModelMapper;
import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
@@ -48,6 +47,7 @@ import org.onap.cps.ncmp.rest.model.Conditions;
import org.onap.cps.ncmp.rest.model.ModuleNameAsJsonObject;
import org.onap.cps.ncmp.rest.model.ModuleNamesAsJsonArray;
import org.onap.cps.ncmp.rest.model.ModuleReference;
+import org.onap.cps.utils.JsonObjectMapper;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -56,21 +56,14 @@ import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
@RequestMapping("${rest.api.ncmp-base-path}")
+@RequiredArgsConstructor
public class NetworkCmProxyController implements NetworkCmProxyApi {
- private static final Gson GSON = new GsonBuilder().create();
private static final String NO_BODY = null;
- private final ModelMapper modelMapper = new ModelMapper();
+ private final ModelMapper modelMapper;
private final NetworkCmProxyDataService networkCmProxyDataService;
-
- /**
- * Constructor Injection for Dependencies.
- * @param networkCmProxyDataService Data Service Interface
- */
- public NetworkCmProxyController(final NetworkCmProxyDataService networkCmProxyDataService) {
- this.networkCmProxyDataService = networkCmProxyDataService;
- }
+ private final JsonObjectMapper jsonObjectMapper;
/**
* Get resource data from operational datastore.
@@ -119,7 +112,7 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
final String cmHandle,
final Object requestBody, final String contentType) {
final Object responseObject = networkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle(cmHandle,
- resourceIdentifier, PATCH, GSON.toJson(requestBody), contentType);
+ resourceIdentifier, PATCH, jsonObjectMapper.asJsonString(requestBody), contentType);
return ResponseEntity.ok(responseObject);
}
@@ -136,7 +129,7 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
public ResponseEntity<Void> createResourceDataRunningForCmHandle(final String resourceIdentifier,
final String cmHandle, final Object requestBody, final String contentType) {
networkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle(cmHandle,
- resourceIdentifier, CREATE, GSON.toJson(requestBody), contentType);
+ resourceIdentifier, CREATE, jsonObjectMapper.asJsonString(requestBody), contentType);
return new ResponseEntity<>(HttpStatus.CREATED);
}
@@ -155,7 +148,7 @@ public class NetworkCmProxyController implements NetworkCmProxyApi {
final Object requestBody,
final String contentType) {
networkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle(cmHandle,
- resourceIdentifier, UPDATE, GSON.toJson(requestBody), contentType);
+ resourceIdentifier, UPDATE, jsonObjectMapper.asJsonString(requestBody), contentType);
return new ResponseEntity<>(HttpStatus.OK);
}
diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy
index b5dc2eabb..0c8b2227d 100644
--- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy
+++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy
@@ -22,9 +22,6 @@
package org.onap.cps.ncmp.rest.controller
-import org.onap.cps.TestUtils
-import org.onap.cps.spi.model.ModuleReference
-
import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.PATCH
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
@@ -35,6 +32,11 @@ import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum
import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.UPDATE
import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.DELETE
+import com.fasterxml.jackson.databind.ObjectMapper
+import org.modelmapper.ModelMapper
+import org.onap.cps.TestUtils
+import org.onap.cps.spi.model.ModuleReference
+import org.onap.cps.utils.JsonObjectMapper
import org.onap.cps.ncmp.api.NetworkCmProxyDataService
import org.spockframework.spring.SpringBean
import org.springframework.beans.factory.annotation.Autowired
@@ -54,10 +56,16 @@ class NetworkCmProxyControllerSpec extends Specification {
@SpringBean
NetworkCmProxyDataService mockNetworkCmProxyDataService = Mock()
+ @SpringBean
+ ModelMapper modelMapper = new ModelMapper()
+
+ @SpringBean
+ JsonObjectMapper jsonObjectMapper = new JsonObjectMapper(new ObjectMapper())
+
@Value('${rest.api.ncmp-base-path}/v1')
def ncmpBasePathV1
- def jsonString = '{"some-key":"some-value"}'
+ def requestBody = '{"some-key":"some-value"}'
def 'Get Resource Data from pass-through operational.' () {
given: 'resource data url'
@@ -115,11 +123,11 @@ class NetworkCmProxyControllerSpec extends Specification {
def response = mvc.perform(
put(updateUrl)
.contentType(MediaType.APPLICATION_JSON_VALUE)
- .accept(MediaType.APPLICATION_JSON_VALUE).content(jsonString)
+ .accept(MediaType.APPLICATION_JSON_VALUE).content(requestBody)
).andReturn().response
then: 'ncmp service method to update resource is called'
1 * mockNetworkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle('testCmHandle',
- 'parent/child', UPDATE, jsonString, 'application/json;charset=UTF-8')
+ 'parent/child', UPDATE, requestBody, 'application/json;charset=UTF-8')
and: 'the response status is OK'
response.status == HttpStatus.OK.value()
}
@@ -192,11 +200,11 @@ class NetworkCmProxyControllerSpec extends Specification {
def response = mvc.perform(
patch(url)
.contentType(MediaType.APPLICATION_JSON)
- .accept(MediaType.APPLICATION_JSON).content(jsonString)
+ .accept(MediaType.APPLICATION_JSON).content(requestBody)
).andReturn().response
then: 'ncmp service method to update resource is called'
1 * mockNetworkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle('testCmHandle',
- 'parent/child', PATCH, jsonString, 'application/json;charset=UTF-8')
+ 'parent/child', PATCH, requestBody, 'application/json;charset=UTF-8')
and: 'the response status is OK'
response.status == HttpStatus.OK.value()
}
diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy
index f36a70693..7b3cd8914 100644
--- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy
+++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy
@@ -21,9 +21,11 @@
package org.onap.cps.ncmp.rest.exceptions
import groovy.json.JsonSlurper
+import org.modelmapper.ModelMapper
import org.onap.cps.ncmp.api.NetworkCmProxyDataService
import org.onap.cps.ncmp.api.impl.exception.NcmpException
import org.onap.cps.spi.exceptions.CpsException
+import org.onap.cps.utils.JsonObjectMapper
import org.spockframework.spring.SpringBean
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
@@ -44,6 +46,12 @@ class NetworkCmProxyRestExceptionHandlerSpec extends Specification {
@SpringBean
NetworkCmProxyDataService mockNetworkCmProxyDataService = Mock()
+ @SpringBean
+ ModelMapper modelMapper = Stub()
+
+ @SpringBean
+ JsonObjectMapper jsonObjectMapper = Stub()
+
@Value('${rest.api.ncmp-base-path}')
def basePath
diff --git a/cps-ncmp-service/pom.xml b/cps-ncmp-service/pom.xml
index b70279303..871bd14c5 100644
--- a/cps-ncmp-service/pom.xml
+++ b/cps-ncmp-service/pom.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
============LICENSE_START=======================================================
- Copyright (C) 2021 Nordix Foundation
+ Copyright (C) 2021-2022 Nordix Foundation
Modifications Copyright (C) 2021 Pantheon.tech
================================================================================
Licensed under the Apache License, Version 2.0 (the "License");
@@ -66,5 +66,9 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.modelmapper</groupId>
+ <artifactId>modelmapper</artifactId>
+ </dependency>
</dependencies>
</project>
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java
index 240d6b5ca..82145efc3 100755
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java
@@ -27,13 +27,13 @@ import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum
import static org.onap.cps.spi.CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED;
import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.onap.cps.api.CpsAdminService;
import org.onap.cps.api.CpsDataService;
@@ -50,11 +50,13 @@ import org.onap.cps.ncmp.api.models.PersistenceCmHandlesList;
import org.onap.cps.spi.exceptions.DataNodeNotFoundException;
import org.onap.cps.spi.exceptions.DataValidationException;
import org.onap.cps.spi.model.ModuleReference;
+import org.onap.cps.utils.JsonObjectMapper;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
@Slf4j
@Service
+@RequiredArgsConstructor
public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService {
private static final String NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME = "NFP-Operational";
@@ -65,37 +67,17 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
private static final OffsetDateTime NO_TIMESTAMP = null;
- private CpsDataService cpsDataService;
+ private final CpsDataService cpsDataService;
- private ObjectMapper objectMapper;
+ private final JsonObjectMapper jsonObjectMapper;
- private DmiDataOperations dmiDataOperations;
+ private final DmiDataOperations dmiDataOperations;
- private DmiModelOperations dmiModelOperations;
+ private final DmiModelOperations dmiModelOperations;
- private CpsModuleService cpsModuleService;
+ private final CpsModuleService cpsModuleService;
- private CpsAdminService cpsAdminService;
-
- /**
- * Constructor Injection for Dependencies.
- * @param dmiDataOperations DMI operation
- * @param cpsDataService Data Service Interface
- * @param objectMapper Object Mapper
- */
- public NetworkCmProxyDataServiceImpl(final DmiDataOperations dmiDataOperations,
- final DmiModelOperations dmiModelOperations,
- final CpsModuleService cpsModuleService,
- final CpsDataService cpsDataService,
- final CpsAdminService cpsAdminService,
- final ObjectMapper objectMapper) {
- this.dmiDataOperations = dmiDataOperations;
- this.dmiModelOperations = dmiModelOperations;
- this.cpsModuleService = cpsModuleService;
- this.cpsDataService = cpsDataService;
- this.cpsAdminService = cpsAdminService;
- this.objectMapper = objectMapper;
- }
+ private final CpsAdminService cpsAdminService;
@Override
public void updateDmiRegistrationAndSyncModule(final DmiPluginRegistration dmiPluginRegistration) {
@@ -198,7 +180,7 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
throws JsonProcessingException {
final PersistenceCmHandlesList updatedPersistenceCmHandlesList =
getUpdatedPersistenceCmHandlesList(dmiPluginRegistration, dmiPluginRegistration.getUpdatedCmHandles());
- final String cmHandlesAsJson = objectMapper.writeValueAsString(updatedPersistenceCmHandlesList);
+ final String cmHandlesAsJson = jsonObjectMapper.asJsonString(updatedPersistenceCmHandlesList);
cpsDataService.updateNodeLeavesAndExistingDescendantLeaves(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
"/dmi-registry", cmHandlesAsJson, NO_TIMESTAMP);
}
@@ -223,7 +205,7 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
private void registerAndSyncNewCmHandles(final PersistenceCmHandlesList persistenceCmHandlesList)
throws JsonProcessingException {
- final String cmHandleJsonData = objectMapper.writeValueAsString(persistenceCmHandlesList);
+ final String cmHandleJsonData = jsonObjectMapper.asJsonString(persistenceCmHandlesList);
cpsDataService.saveListElements(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, "/dmi-registry",
cmHandleJsonData, NO_TIMESTAMP);
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 095f677ef..3bfb424a2 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
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021 Nordix Foundation
+ * Copyright (C) 2021-2022 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,10 +25,10 @@ import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum
import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.READ;
import static org.onap.cps.ncmp.api.impl.operations.RequiredDmiService.DATA;
-import com.fasterxml.jackson.databind.ObjectMapper;
import org.onap.cps.ncmp.api.impl.client.DmiRestClient;
import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration;
import org.onap.cps.ncmp.api.models.PersistenceCmHandle;
+import org.onap.cps.utils.JsonObjectMapper;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
@@ -45,10 +45,10 @@ public class DmiDataOperations extends DmiOperations {
* @param dmiRestClient {@code DmiRestClient}
*/
public DmiDataOperations(final PersistenceCmHandleRetriever cmHandlePropertiesRetriever,
- final ObjectMapper objectMapper,
+ final JsonObjectMapper jsonObjectMapper,
final NcmpConfiguration.DmiProperties dmiProperties,
final DmiRestClient dmiRestClient) {
- super(cmHandlePropertiesRetriever, objectMapper, dmiProperties, dmiRestClient);
+ super(cmHandlePropertiesRetriever, jsonObjectMapper, dmiProperties, dmiRestClient);
}
/**
@@ -73,7 +73,7 @@ public class DmiDataOperations extends DmiOperations {
.operation(READ)
.build();
dmiRequestBody.asCmHandleProperties(persistenceCmHandle.getAdditionalProperties());
- final String jsonBody = getDmiRequestBodyAsString(dmiRequestBody);
+ final String jsonBody = jsonObjectMapper.asJsonString(dmiRequestBody);
final var dmiResourceDataUrl = getDmiDatastoreUrlWithOptions(
persistenceCmHandle.resolveDmiServiceName(DATA), cmHandle, resourceId,
@@ -106,7 +106,7 @@ public class DmiDataOperations extends DmiOperations {
.dataType(dataType)
.build();
dmiRequestBody.asCmHandleProperties(persistenceCmHandle.getAdditionalProperties());
- final String jsonBody = getDmiRequestBodyAsString(dmiRequestBody);
+ final String jsonBody = jsonObjectMapper.asJsonString(dmiRequestBody);
final String dmiUrl =
getResourceInDataStoreUrl(persistenceCmHandle.resolveDmiServiceName(DATA),
cmHandle, resourceId, PASSTHROUGH_RUNNING);
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 20a3309d0..1ce6dcfcd 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
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021 Nordix Foundation
+ * Copyright (C) 2021-2022 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,7 +22,6 @@ package org.onap.cps.ncmp.api.impl.operations;
import static org.onap.cps.ncmp.api.impl.operations.RequiredDmiService.MODEL;
-import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import java.util.ArrayList;
@@ -34,10 +33,14 @@ import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration;
import org.onap.cps.ncmp.api.models.PersistenceCmHandle;
import org.onap.cps.ncmp.api.models.YangResource;
import org.onap.cps.spi.model.ModuleReference;
+import org.onap.cps.utils.JsonObjectMapper;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
+/**
+ * Operations class for DMI Model.
+ */
@Component
public class DmiModelOperations extends DmiOperations {
@@ -47,10 +50,10 @@ public class DmiModelOperations extends DmiOperations {
* @param dmiRestClient {@code DmiRestClient}
*/
public DmiModelOperations(final PersistenceCmHandleRetriever cmHandlePropertiesRetriever,
- final ObjectMapper objectMapper,
+ final JsonObjectMapper jsonObjectMapper,
final NcmpConfiguration.DmiProperties dmiProperties,
final DmiRestClient dmiRestClient) {
- super(cmHandlePropertiesRetriever, objectMapper, dmiProperties, dmiRestClient);
+ super(cmHandlePropertiesRetriever, jsonObjectMapper, dmiProperties, dmiRestClient);
}
/**
@@ -65,7 +68,7 @@ public class DmiModelOperations extends DmiOperations {
dmiRequestBody.asCmHandleProperties(persistenceCmHandle.getAdditionalProperties());
final ResponseEntity<Object> dmiFetchModulesResponseEntity = getResourceFromDmiWithJsonData(
persistenceCmHandle.resolveDmiServiceName(MODEL),
- getDmiRequestBodyAsString(dmiRequestBody), persistenceCmHandle.getId(), "modules");
+ jsonObjectMapper.asJsonString(dmiRequestBody), persistenceCmHandle.getId(), "modules");
return toModuleReferences((Map) dmiFetchModulesResponseEntity.getBody());
}
@@ -144,7 +147,7 @@ public class DmiModelOperations extends DmiOperations {
if (moduleReferencesAsList != null) {
moduleReferencesAsList.forEach(moduleReferenceAsMap -> {
final ModuleReference moduleReference =
- objectMapper.convertValue(moduleReferenceAsMap, ModuleReference.class);
+ jsonObjectMapper.convertToValueType(moduleReferenceAsMap, ModuleReference.class);
moduleReferences.add(moduleReference);
});
}
@@ -159,7 +162,7 @@ public class DmiModelOperations extends DmiOperations {
if (yangResourcesAsList != null) {
yangResourcesAsList.forEach(yangResourceAsMap -> {
final YangResource yangResource =
- objectMapper.convertValue(yangResourceAsMap, YangResource.class);
+ jsonObjectMapper.convertToValueType(yangResourceAsMap, YangResource.class);
yangResourcesModuleNameToContentMap.put(yangResource.getModuleName(),
yangResource.getYangSource());
});
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 509728061..2f7376e87 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 Nordix Foundation
+ * Copyright (C) 2021-2022 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,17 +20,19 @@
package org.onap.cps.ncmp.api.impl.operations;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Strings;
import lombok.Getter;
+import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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.NcmpException;
+import org.onap.cps.utils.JsonObjectMapper;
import org.springframework.http.HttpHeaders;
+import org.springframework.stereotype.Service;
@Slf4j
+@RequiredArgsConstructor
+@Service
public class DmiOperations {
@Getter
@@ -44,28 +46,13 @@ public class DmiOperations {
}
}
- protected ObjectMapper objectMapper;
- protected PersistenceCmHandleRetriever cmHandlePropertiesRetriever;
- protected DmiRestClient dmiRestClient;
- protected NcmpConfiguration.DmiProperties dmiProperties;
+ protected final PersistenceCmHandleRetriever cmHandlePropertiesRetriever;
+ protected final JsonObjectMapper jsonObjectMapper;
+ protected final NcmpConfiguration.DmiProperties dmiProperties;
+ protected final DmiRestClient dmiRestClient;
static final String URL_SEPARATOR = "/";
- /**
- * Constructor for {@code DmiOperations}. This method also manipulates url properties.
- *
- * @param dmiRestClient {@code DmiRestClient}
- */
- public DmiOperations(final PersistenceCmHandleRetriever cmHandlePropertiesRetriever,
- final ObjectMapper objectMapper,
- final NcmpConfiguration.DmiProperties dmiProperties,
- final DmiRestClient dmiRestClient) {
- this.cmHandlePropertiesRetriever = cmHandlePropertiesRetriever;
- this.objectMapper = objectMapper;
- this.dmiRestClient = dmiRestClient;
- this.dmiProperties = dmiProperties;
- }
-
String getCmHandleUrl(final String dmiServiceName, final String cmHandle) {
return dmiServiceName
+ dmiProperties.getDmiBasePath()
@@ -95,20 +82,4 @@ public class DmiOperations {
return httpHeaders;
}
- /**
- * Convert DmiRequestBody to JSON.
- *
- * @param dmiRequestBody the dmi request body
- * @return DmiRequestBody as JSON
- */
- String getDmiRequestBodyAsString(final DmiRequestBody dmiRequestBody) {
- try {
- return objectMapper.writeValueAsString(dmiRequestBody);
- } catch (final JsonProcessingException e) {
- log.error("Parsing error occurred while converting Object to JSON.");
- throw new NcmpException("Parsing error occurred while converting given object to JSON.",
- e.getMessage());
- }
- }
-
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplModelSyncSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplModelSyncSpec.groovy
index b7f059a7c..464757158 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplModelSyncSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplModelSyncSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021 Nordix Foundation
+ * Copyright (C) 2021-2022 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,22 +20,25 @@
package org.onap.cps.ncmp.api.impl
-import com.fasterxml.jackson.databind.ObjectMapper
import org.onap.cps.api.CpsAdminService
import org.onap.cps.api.CpsModuleService
+import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations
import org.onap.cps.ncmp.api.impl.operations.DmiModelOperations
import org.onap.cps.ncmp.api.models.PersistenceCmHandle
import org.onap.cps.spi.model.ModuleReference
+import org.onap.cps.utils.JsonObjectMapper
import spock.lang.Specification
class NetworkCmProxyDataServiceImplModelSyncSpec extends Specification {
+ def mockJsonObjectMapper = Mock(JsonObjectMapper)
def mockCpsModuleService = Mock(CpsModuleService)
def mockCpsAdminService = Mock(CpsAdminService)
def mockDmiModelOperations = Mock(DmiModelOperations)
+ def mockDmiDataOperations = Mock(DmiDataOperations)
- def objectUnderTest = new NetworkCmProxyDataServiceImpl(null, mockDmiModelOperations,
- mockCpsModuleService, null, mockCpsAdminService, new ObjectMapper())
+ def objectUnderTest = new NetworkCmProxyDataServiceImpl(null, mockJsonObjectMapper, mockDmiDataOperations, mockDmiModelOperations,
+ mockCpsModuleService, mockCpsAdminService)
def expectedDataspaceName = 'NFP-Operational'
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy
index 90fcbfc61..b954b41ef 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021 Nordix Foundation
+ * Copyright (C) 2021-2022 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,13 +22,17 @@ package org.onap.cps.ncmp.api.impl
import com.fasterxml.jackson.core.JsonProcessingException
import com.fasterxml.jackson.databind.ObjectMapper
+import org.onap.cps.api.CpsAdminService
import org.onap.cps.api.CpsDataService
import org.onap.cps.api.CpsModuleService
import org.onap.cps.ncmp.api.impl.exception.NcmpException
+import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations
+import org.onap.cps.ncmp.api.impl.operations.DmiModelOperations
import org.onap.cps.ncmp.api.models.CmHandle
import org.onap.cps.ncmp.api.models.DmiPluginRegistration
import org.onap.cps.spi.exceptions.DataNodeNotFoundException
import org.onap.cps.spi.exceptions.DataValidationException
+import org.onap.cps.utils.JsonObjectMapper
import spock.lang.Shared
import spock.lang.Specification
@@ -44,7 +48,10 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
def mockCpsDataService = Mock(CpsDataService)
def mockCpsModuleService = Mock(CpsModuleService)
- def spyObjectMapper = Spy(ObjectMapper)
+ def spiedJsonObjectMapper = Spy(new JsonObjectMapper(new ObjectMapper()))
+ def mockCpsAdminService = Mock(CpsAdminService)
+ def mockDmiModelOperations = Mock(DmiModelOperations)
+ def mockDmiDataOperations = Mock(DmiDataOperations)
def noTimestamp = null
@@ -102,7 +109,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
dmiPluginRegistration.createdCmHandles = createdCmHandles
dmiPluginRegistration.updatedCmHandles = updatedCmHandles
and: 'an json processing exception occurs'
- spyObjectMapper.writeValueAsString(_) >> { throw (new JsonProcessingException('')) }
+ spiedJsonObjectMapper.asJsonString(_) >> { throw (new JsonProcessingException('')) }
when: 'registration is updated and modules are synced'
objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration)
then: 'a data validation exception is thrown'
@@ -182,8 +189,8 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification {
}
def getObjectUnderTestWithModelSyncDisabled() {
- def objectUnderTest = Spy(new NetworkCmProxyDataServiceImpl(null, null, mockCpsModuleService,
- mockCpsDataService, null, spyObjectMapper))
+ def objectUnderTest = Spy(new NetworkCmProxyDataServiceImpl(mockCpsDataService, spiedJsonObjectMapper, mockDmiDataOperations, mockDmiModelOperations,
+ mockCpsModuleService, mockCpsAdminService))
objectUnderTest.syncModulesAndCreateAnchor(*_) >> null
return objectUnderTest
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy
index 5753d7b67..51af0f55e 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy
@@ -28,6 +28,8 @@ import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum
import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.READ
import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.UPDATE
+import org.onap.cps.ncmp.api.impl.operations.DmiModelOperations
+import org.onap.cps.utils.JsonObjectMapper
import com.fasterxml.jackson.core.JsonProcessingException
import com.fasterxml.jackson.databind.ObjectMapper
import org.onap.cps.api.CpsAdminService
@@ -46,11 +48,12 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
def mockCpsDataService = Mock(CpsDataService)
def mockCpsModuleService = Mock(CpsModuleService)
def mockCpsAdminService = Mock(CpsAdminService)
- def spyObjectMapper = Spy(ObjectMapper)
+ def spiedJsonObjectMapper = Spy(new JsonObjectMapper(new ObjectMapper()))
+ def mockDmiModelOperations = Mock(DmiModelOperations)
def mockDmiDataOperations = Mock(DmiDataOperations)
- def objectUnderTest = new NetworkCmProxyDataServiceImpl(mockDmiDataOperations, null,
- mockCpsModuleService, mockCpsDataService, mockCpsAdminService, spyObjectMapper)
+ def objectUnderTest = new NetworkCmProxyDataServiceImpl(mockCpsDataService, spiedJsonObjectMapper, mockDmiDataOperations, mockDmiModelOperations,
+ mockCpsModuleService, mockCpsAdminService)
def cmHandleXPath = "/dmi-registry/cm-handles[@id='testCmHandle']"
@@ -126,9 +129,7 @@ class NetworkCmProxyDataServiceImplSpec extends Specification {
mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry',
cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode
and: 'objectMapper not able to parse object'
- def mockObjectMapper = Mock(ObjectMapper)
- objectUnderTest.objectMapper = mockObjectMapper
- mockObjectMapper.writeValueAsString(_) >> { throw new JsonProcessingException('testException') }
+ spiedJsonObjectMapper.asJsonString(_) >> { throw new JsonProcessingException('testException') }
and: 'dmi returns NOK response'
mockDmiDataOperations.getResourceDataFromDmi(*_)
>> new ResponseEntity<>('NOK-json', HttpStatus.NOT_FOUND)
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationsSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationsSpec.groovy
index b9704b1ea..54ae0aa6f 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationsSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationsSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021 Nordix Foundation
+ * Copyright (C) 2021-2022 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,8 +20,10 @@
package org.onap.cps.ncmp.api.impl.operations
-import org.onap.cps.ncmp.api.impl.client.DmiRestClient
+import com.fasterxml.jackson.databind.ObjectMapper
import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration
+import org.onap.cps.utils.JsonObjectMapper
+import org.spockframework.spring.SpringBean
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.ResponseEntity
@@ -37,6 +39,9 @@ import org.springframework.http.HttpStatus
@ContextConfiguration(classes = [NcmpConfiguration.DmiProperties, DmiDataOperations])
class DmiDataOperationsSpec extends DmiOperationsBaseSpec {
+ @SpringBean
+ JsonObjectMapper jsonObjectMapper = new JsonObjectMapper(new ObjectMapper())
+
@Autowired
DmiDataOperations objectUnderTest
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiModelOperationsSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiModelOperationsSpec.groovy
index 335bc062c..2efd6c2b3 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiModelOperationsSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiModelOperationsSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021 Nordix Foundation
+ * Copyright (C) 2021-2022 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,9 +21,11 @@
package org.onap.cps.ncmp.api.impl.operations
import com.fasterxml.jackson.core.JsonProcessingException
+import com.fasterxml.jackson.databind.ObjectMapper
import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration
-import org.onap.cps.ncmp.api.impl.exception.NcmpException
import org.onap.cps.spi.model.ModuleReference
+import org.onap.cps.utils.JsonObjectMapper
+import org.spockframework.spring.SpringBean
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.HttpStatus
@@ -41,6 +43,9 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec {
@Autowired
DmiModelOperations objectUnderTest
+ @SpringBean
+ JsonObjectMapper spiedJsonObjectMapper = Spy(new JsonObjectMapper(new ObjectMapper()))
+
def 'Retrieving module references.'() {
given: 'a persistence cm handle'
mockPersistenceCmHandleRetrieval([])
@@ -158,11 +163,11 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec {
given: 'a persistence cm handle'
mockPersistenceCmHandleRetrieval([])
and: 'a Json processing exception occurs'
- spyObjectMapper.writeValueAsString(_) >> {throw (new JsonProcessingException(''))}
+ spiedJsonObjectMapper.asJsonString(_) >> {throw (new JsonProcessingException('parsing error'))}
when: 'a dmi operation is executed'
objectUnderTest.getModuleReferences(persistenceCmHandle)
then: 'an ncmp exception is thrown'
- def exceptionThrown = thrown(NcmpException)
+ def exceptionThrown = thrown(JsonProcessingException)
and: 'the message indicates a parsing error'
exceptionThrown.message.toLowerCase().contains('parsing error')
}
diff --git a/cps-rest/src/main/java/org/onap/cps/rest/controller/DataRestController.java b/cps-rest/src/main/java/org/onap/cps/rest/controller/DataRestController.java
index a55b1ba7a..fc2818b6f 100755
--- a/cps-rest/src/main/java/org/onap/cps/rest/controller/DataRestController.java
+++ b/cps-rest/src/main/java/org/onap/cps/rest/controller/DataRestController.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* Copyright (C) 2020-2021 Bell Canada.
* Modifications Copyright (C) 2021 Pantheon.tech
- * Modifications Copyright (C) 2021 Nordix Foundation
+ * Modifications Copyright (C) 2021-2022 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,7 +22,6 @@
package org.onap.cps.rest.controller;
-import com.google.gson.Gson;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import javax.validation.ValidationException;
@@ -32,6 +31,7 @@ import org.onap.cps.api.CpsDataService;
import org.onap.cps.rest.api.CpsDataApi;
import org.onap.cps.spi.FetchDescendantsOption;
import org.onap.cps.utils.DataMapUtils;
+import org.onap.cps.utils.JsonObjectMapper;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -47,17 +47,18 @@ public class DataRestController implements CpsDataApi {
private static final DateTimeFormatter ISO_TIMESTAMP_FORMATTER = DateTimeFormatter.ofPattern(ISO_TIMESTAMP_FORMAT);
private final CpsDataService cpsDataService;
- private final Gson gson;
+ private final JsonObjectMapper jsonObjectMapper;
@Override
public ResponseEntity<String> createNode(final String dataspaceName, final String anchorName,
final Object jsonData, final String parentNodeXpath, final String observedTimestamp) {
+ final String jsonDataAsString = jsonObjectMapper.asJsonString(jsonData);
if (isRootXpath(parentNodeXpath)) {
- cpsDataService.saveData(dataspaceName, anchorName, gson.toJson(jsonData),
- toOffsetDateTime(observedTimestamp));
+ cpsDataService.saveData(dataspaceName, anchorName, jsonDataAsString,
+ toOffsetDateTime(observedTimestamp));
} else {
- cpsDataService.saveData(dataspaceName, anchorName, parentNodeXpath, gson.toJson(jsonData),
- toOffsetDateTime(observedTimestamp));
+ cpsDataService.saveData(dataspaceName, anchorName, parentNodeXpath,
+ jsonDataAsString, toOffsetDateTime(observedTimestamp));
}
return new ResponseEntity<>(HttpStatus.CREATED);
}
@@ -73,8 +74,8 @@ public class DataRestController implements CpsDataApi {
@Override
public ResponseEntity<String> addListElements(final String parentNodeXpath,
final String dataspaceName, final String anchorName, final Object jsonData, final String observedTimestamp) {
- cpsDataService.saveListElements(dataspaceName, anchorName, parentNodeXpath, gson.toJson(jsonData),
- toOffsetDateTime(observedTimestamp));
+ cpsDataService.saveListElements(dataspaceName, anchorName, parentNodeXpath,
+ jsonObjectMapper.asJsonString(jsonData), toOffsetDateTime(observedTimestamp));
return new ResponseEntity<>(HttpStatus.CREATED);
}
@@ -91,8 +92,8 @@ public class DataRestController implements CpsDataApi {
@Override
public ResponseEntity<Object> updateNodeLeaves(final String dataspaceName,
final String anchorName, final Object jsonData, final String parentNodeXpath, final String observedTimestamp) {
- cpsDataService.updateNodeLeaves(dataspaceName, anchorName, parentNodeXpath, gson.toJson(jsonData),
- toOffsetDateTime(observedTimestamp));
+ cpsDataService.updateNodeLeaves(dataspaceName, anchorName, parentNodeXpath,
+ jsonObjectMapper.asJsonString(jsonData), toOffsetDateTime(observedTimestamp));
return new ResponseEntity<>(HttpStatus.OK);
}
@@ -100,8 +101,8 @@ public class DataRestController implements CpsDataApi {
public ResponseEntity<Object> replaceNode(final String dataspaceName, final String anchorName,
final Object jsonData, final String parentNodeXpath, final String observedTimestamp) {
cpsDataService
- .replaceNodeTree(dataspaceName, anchorName, parentNodeXpath, gson.toJson(jsonData),
- toOffsetDateTime(observedTimestamp));
+ .replaceNodeTree(dataspaceName, anchorName, parentNodeXpath,
+ jsonObjectMapper.asJsonString(jsonData), toOffsetDateTime(observedTimestamp));
return new ResponseEntity<>(HttpStatus.OK);
}
@@ -109,8 +110,8 @@ public class DataRestController implements CpsDataApi {
public ResponseEntity<Object> replaceListContent(final String parentNodeXpath,
final String dataspaceName, final String anchorName, final Object jsonData,
final String observedTimestamp) {
- cpsDataService.replaceListContent(dataspaceName, anchorName, parentNodeXpath, gson.toJson(jsonData),
- toOffsetDateTime(observedTimestamp));
+ cpsDataService.replaceListContent(dataspaceName, anchorName, parentNodeXpath,
+ jsonObjectMapper.asJsonString(jsonData), toOffsetDateTime(observedTimestamp));
return new ResponseEntity<>(HttpStatus.OK);
}
diff --git a/cps-rest/src/main/java/org/onap/cps/rest/controller/QueryRestController.java b/cps-rest/src/main/java/org/onap/cps/rest/controller/QueryRestController.java
index 8aa65a005..eb422dc69 100644
--- a/cps-rest/src/main/java/org/onap/cps/rest/controller/QueryRestController.java
+++ b/cps-rest/src/main/java/org/onap/cps/rest/controller/QueryRestController.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021 Nordix Foundation
+ * Copyright (C) 2021-2022 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,18 +20,18 @@
package org.onap.cps.rest.controller;
-import com.google.gson.Gson;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import javax.validation.Valid;
+import lombok.RequiredArgsConstructor;
import org.onap.cps.api.CpsQueryService;
import org.onap.cps.rest.api.CpsQueryApi;
import org.onap.cps.spi.FetchDescendantsOption;
import org.onap.cps.spi.model.DataNode;
import org.onap.cps.utils.DataMapUtils;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.onap.cps.utils.JsonObjectMapper;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -39,10 +39,11 @@ import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("${rest.api.cps-base-path}")
+@RequiredArgsConstructor
public class QueryRestController implements CpsQueryApi {
- @Autowired
- private CpsQueryService cpsQueryService;
+ private final CpsQueryService cpsQueryService;
+ private final JsonObjectMapper jsonObjectMapper;
@Override
public ResponseEntity<Object> getNodesByDataspaceAndAnchorAndCpsPath(final String dataspaceName,
@@ -55,6 +56,6 @@ public class QueryRestController implements CpsQueryApi {
for (final DataNode dataNode : dataNodes) {
dataNodeList.add(DataMapUtils.toDataMap(dataNode));
}
- return new ResponseEntity<>(new Gson().toJson(dataNodeList), HttpStatus.OK);
+ return new ResponseEntity<>(jsonObjectMapper.asJsonString(dataNodeList), HttpStatus.OK);
}
}
diff --git a/cps-rest/src/test/groovy/org/onap/cps/rest/controller/DataRestControllerSpec.groovy b/cps-rest/src/test/groovy/org/onap/cps/rest/controller/DataRestControllerSpec.groovy
index fbb563656..4d75848cf 100755
--- a/cps-rest/src/test/groovy/org/onap/cps/rest/controller/DataRestControllerSpec.groovy
+++ b/cps-rest/src/test/groovy/org/onap/cps/rest/controller/DataRestControllerSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021 Nordix Foundation
+ * Copyright (C) 2021-2022 Nordix Foundation
* Modifications Copyright (C) 2021 Pantheon.tech
* Modifications Copyright (C) 2021 Bell Canada.
* ================================================================================
@@ -22,10 +22,12 @@
package org.onap.cps.rest.controller
+import com.fasterxml.jackson.databind.ObjectMapper
import org.onap.cps.api.CpsDataService
import org.onap.cps.spi.model.DataNode
import org.onap.cps.spi.model.DataNodeBuilder
import org.onap.cps.utils.DateTimeUtility
+import org.onap.cps.utils.JsonObjectMapper
import org.spockframework.spring.SpringBean
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
@@ -50,6 +52,9 @@ class DataRestControllerSpec extends Specification {
@SpringBean
CpsDataService mockCpsDataService = Mock()
+ @SpringBean
+ JsonObjectMapper jsonObjectMapper = new JsonObjectMapper(new ObjectMapper())
+
@Autowired
MockMvc mvc
diff --git a/cps-rest/src/test/groovy/org/onap/cps/rest/controller/QueryRestControllerSpec.groovy b/cps-rest/src/test/groovy/org/onap/cps/rest/controller/QueryRestControllerSpec.groovy
index 550dec972..1e42a0060 100644
--- a/cps-rest/src/test/groovy/org/onap/cps/rest/controller/QueryRestControllerSpec.groovy
+++ b/cps-rest/src/test/groovy/org/onap/cps/rest/controller/QueryRestControllerSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021 Nordix Foundation
+ * Copyright (C) 2021-2022 Nordix Foundation
* Modifications Copyright (C) 2021 Bell Canada.
* Modifications Copyright (C) 2021 Pantheon.tech
* ================================================================================
@@ -22,17 +22,12 @@
package org.onap.cps.rest.controller
-import org.onap.cps.spi.model.DataNode
-
import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS
import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
-import com.google.gson.Gson
-import org.modelmapper.ModelMapper
-import org.onap.cps.api.CpsAdminService
-import org.onap.cps.api.CpsDataService
-import org.onap.cps.api.CpsModuleService
+import com.fasterxml.jackson.databind.ObjectMapper
+import org.onap.cps.utils.JsonObjectMapper
import org.onap.cps.api.CpsQueryService
import org.onap.cps.spi.model.DataNodeBuilder
import org.spockframework.spring.SpringBean
@@ -49,6 +44,9 @@ class QueryRestControllerSpec extends Specification {
@SpringBean
CpsQueryService mockCpsQueryService = Mock()
+ @SpringBean
+ JsonObjectMapper jsonObjectMapper = new JsonObjectMapper(new ObjectMapper())
+
@Autowired
MockMvc mvc
diff --git a/cps-rest/src/test/groovy/org/onap/cps/rest/exceptions/CpsRestExceptionHandlerSpec.groovy b/cps-rest/src/test/groovy/org/onap/cps/rest/exceptions/CpsRestExceptionHandlerSpec.groovy
index 658dcaa70..a2eaa525e 100644
--- a/cps-rest/src/test/groovy/org/onap/cps/rest/exceptions/CpsRestExceptionHandlerSpec.groovy
+++ b/cps-rest/src/test/groovy/org/onap/cps/rest/exceptions/CpsRestExceptionHandlerSpec.groovy
@@ -1,7 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2020 Pantheon.tech
- * Modifications Copyright (C) 2021 Nordix Foundation
+ * Modifications Copyright (C) 2021-2022 Nordix Foundation
* Modifications Copyright (C) 2021 Bell Canada.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -38,6 +38,7 @@ import org.onap.cps.spi.exceptions.ModelValidationException
import org.onap.cps.spi.exceptions.NotFoundInDataspaceException
import org.onap.cps.spi.exceptions.SchemaSetInUseException
import org.onap.cps.spi.exceptions.DataspaceInUseException
+import org.onap.cps.utils.JsonObjectMapper
import org.spockframework.spring.SpringBean
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
@@ -58,19 +59,22 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
class CpsRestExceptionHandlerSpec extends Specification {
@SpringBean
- CpsAdminService mockCpsAdminService = Mock()
+ CpsAdminService mockCpsAdminService = Stub()
@SpringBean
- CpsModuleService mockCpsModuleService = Mock()
+ CpsModuleService mockCpsModuleService = Stub()
@SpringBean
- CpsDataService mockCpsDataService = Mock()
+ CpsDataService mockCpsDataService = Stub()
@SpringBean
- CpsQueryService mockCpsQueryService = Mock()
+ CpsQueryService mockCpsQueryService = Stub()
@SpringBean
- ModelMapper modelMapper = Mock()
+ ModelMapper modelMapper = Stub()
+
+ @SpringBean
+ JsonObjectMapper jsonObjectMapper = Stub()
@Autowired
MockMvc mvc
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java
index c616c8fac..c6e28aba9 100644
--- a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java
+++ b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021 Nordix Foundation
+ * Copyright (C) 2021-2022 Nordix Foundation
* Modifications Copyright (C) 2021 Pantheon.tech
* Modifications Copyright (C) 2020-2021 Bell Canada.
* ================================================================================
@@ -24,12 +24,8 @@ package org.onap.cps.spi.impl;
import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -41,6 +37,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import javax.transaction.Transactional;
+import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.StaleStateException;
import org.onap.cps.cpspath.parser.CpsPathQuery;
@@ -53,43 +50,29 @@ import org.onap.cps.spi.exceptions.AlreadyDefinedException;
import org.onap.cps.spi.exceptions.ConcurrencyException;
import org.onap.cps.spi.exceptions.CpsPathException;
import org.onap.cps.spi.exceptions.DataNodeNotFoundException;
-import org.onap.cps.spi.exceptions.DataValidationException;
import org.onap.cps.spi.model.DataNode;
import org.onap.cps.spi.model.DataNodeBuilder;
import org.onap.cps.spi.repository.AnchorRepository;
import org.onap.cps.spi.repository.DataspaceRepository;
import org.onap.cps.spi.repository.FragmentRepository;
+import org.onap.cps.utils.JsonObjectMapper;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
@Service
@Slf4j
+@RequiredArgsConstructor
public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService {
- private DataspaceRepository dataspaceRepository;
+ private final DataspaceRepository dataspaceRepository;
- private AnchorRepository anchorRepository;
+ private final AnchorRepository anchorRepository;
- private FragmentRepository fragmentRepository;
+ private final FragmentRepository fragmentRepository;
- private final ObjectMapper objectMapper;
+ private final JsonObjectMapper jsonObjectMapper;
- /**
- * Constructor.
- *
- * @param dataspaceRepository dataspaceRepository
- * @param anchorRepository anchorRepository
- * @param fragmentRepository fragmentRepository
- */
- public CpsDataPersistenceServiceImpl(final DataspaceRepository dataspaceRepository,
- final AnchorRepository anchorRepository, final FragmentRepository fragmentRepository) {
- this.dataspaceRepository = dataspaceRepository;
- this.anchorRepository = anchorRepository;
- this.fragmentRepository = fragmentRepository;
- objectMapper = new ObjectMapper();
- }
- private static final Gson GSON = new GsonBuilder().create();
private static final String REG_EX_FOR_OPTIONAL_LIST_INDEX = "(\\[@[\\s\\S]+?]){0,1})";
private static final Pattern REG_EX_PATTERN_FOR_LIST_ELEMENT_KEY_PREDICATE =
Pattern.compile("\\[(\\@([^\\/]{0,9999}))\\]$");
@@ -152,7 +135,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
* @param dataNodeToBeConverted dataNode
* @return a Fragment built from current DataNode
*/
- private static FragmentEntity convertToFragmentWithAllDescendants(final DataspaceEntity dataspaceEntity,
+ private FragmentEntity convertToFragmentWithAllDescendants(final DataspaceEntity dataspaceEntity,
final AnchorEntity anchorEntity, final DataNode dataNodeToBeConverted) {
final FragmentEntity parentFragment = toFragmentEntity(dataspaceEntity, anchorEntity, dataNodeToBeConverted);
final Builder<FragmentEntity> childFragmentsImmutableSetBuilder = ImmutableSet.builder();
@@ -177,13 +160,13 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
}
}
- private static FragmentEntity toFragmentEntity(final DataspaceEntity dataspaceEntity,
+ private FragmentEntity toFragmentEntity(final DataspaceEntity dataspaceEntity,
final AnchorEntity anchorEntity, final DataNode dataNode) {
return FragmentEntity.builder()
.dataspace(dataspaceEntity)
.anchor(anchorEntity)
.xpath(dataNode.getXpath())
- .attributes(GSON.toJson(dataNode.getLeaves()))
+ .attributes(jsonObjectMapper.asJsonString(dataNode.getLeaves()))
.build();
}
@@ -249,14 +232,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
final List<DataNode> childDataNodes = getChildDataNodes(fragmentEntity, fetchDescendantsOption);
Map<String, Object> leaves = new HashMap<>();
if (fragmentEntity.getAttributes() != null) {
- try {
- leaves = objectMapper.readValue(fragmentEntity.getAttributes(), Map.class);
- } catch (final JsonProcessingException jsonProcessingException) {
- final String message = "Parsing error occurred while processing fragmentEntity attributes.";
- log.error(message);
- throw new DataValidationException(message,
- jsonProcessingException.getMessage(), jsonProcessingException);
- }
+ leaves = jsonObjectMapper.convertJsonString(fragmentEntity.getAttributes(), Map.class);
}
return new DataNodeBuilder()
.withXpath(fragmentEntity.getXpath())
@@ -278,7 +254,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
public void updateDataLeaves(final String dataspaceName, final String anchorName, final String xpath,
final Map<String, Object> leaves) {
final FragmentEntity fragmentEntity = getFragmentByXpath(dataspaceName, anchorName, xpath);
- fragmentEntity.setAttributes(GSON.toJson(leaves));
+ fragmentEntity.setAttributes(jsonObjectMapper.asJsonString(leaves));
fragmentRepository.save(fragmentEntity);
}
@@ -296,10 +272,10 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
}
}
- private static void replaceDataNodeTree(final FragmentEntity existingFragmentEntity,
+ private void replaceDataNodeTree(final FragmentEntity existingFragmentEntity,
final DataNode newDataNode) {
- existingFragmentEntity.setAttributes(GSON.toJson(newDataNode.getLeaves()));
+ existingFragmentEntity.setAttributes(jsonObjectMapper.asJsonString(newDataNode.getLeaves()));
final Map<String, FragmentEntity> existingChildrenByXpath = existingFragmentEntity.getChildFragments()
.stream().collect(Collectors.toMap(FragmentEntity::getXpath, childFragmentEntity -> childFragmentEntity));
@@ -412,7 +388,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
return firstChildNodeXpath.substring(0, firstChildNodeXpath.lastIndexOf("[") + 1);
}
- private static FragmentEntity getFragmentForReplacement(final FragmentEntity parentEntity,
+ private FragmentEntity getFragmentForReplacement(final FragmentEntity parentEntity,
final DataNode newListElement,
final FragmentEntity existingListElementEntity) {
if (existingListElementEntity == null) {
@@ -433,10 +409,11 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
return !existingListElementsByXpath.containsKey(replacementDataNode.getXpath());
}
- private static void copyAttributesFromNewListElement(final FragmentEntity existingListElementEntity,
+ private void copyAttributesFromNewListElement(final FragmentEntity existingListElementEntity,
final DataNode newListElement) {
final FragmentEntity replacementFragmentEntity =
- FragmentEntity.builder().attributes(GSON.toJson(newListElement.getLeaves())).build();
+ FragmentEntity.builder().attributes(jsonObjectMapper.asJsonString(
+ newListElement.getLeaves())).build();
existingListElementEntity.setAttributes(replacementFragmentEntity.getAttributes());
}
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentRepositoryCpsPathQueryImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentRepositoryCpsPathQueryImpl.java
index fddedcad2..37202498f 100644
--- a/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentRepositoryCpsPathQueryImpl.java
+++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentRepositoryCpsPathQueryImpl.java
@@ -1,6 +1,6 @@
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2021 Nordix Foundation.
+ * Copyright (C) 2021-2022 Nordix Foundation.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,18 +20,19 @@
package org.onap.cps.spi.repository;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
+import lombok.RequiredArgsConstructor;
import org.onap.cps.cpspath.parser.CpsPathPrefixType;
import org.onap.cps.cpspath.parser.CpsPathQuery;
import org.onap.cps.spi.entities.FragmentEntity;
+import org.onap.cps.utils.JsonObjectMapper;
+@RequiredArgsConstructor
public class FragmentRepositoryCpsPathQueryImpl implements FragmentRepositoryCpsPathQuery {
public static final String SIMILAR_TO_ABSOLUTE_PATH_PREFIX = "%/";
@@ -39,8 +40,7 @@ public class FragmentRepositoryCpsPathQueryImpl implements FragmentRepositoryCps
@PersistenceContext
private EntityManager entityManager;
-
- private static final Gson GSON = new GsonBuilder().create();
+ private final JsonObjectMapper jsonObjectMapper;
@Override
public List<FragmentEntity> findByAnchorAndCpsPath(final int anchorId, final CpsPathQuery cpsPathQuery) {
@@ -52,7 +52,8 @@ public class FragmentRepositoryCpsPathQueryImpl implements FragmentRepositoryCps
queryParameters.put("xpathRegex", xpathRegex);
if (cpsPathQuery.hasLeafConditions()) {
sqlStringBuilder.append(" AND attributes @> :leafDataAsJson\\:\\:jsonb");
- queryParameters.put("leafDataAsJson", GSON.toJson(cpsPathQuery.getLeavesData()));
+ queryParameters.put("leafDataAsJson", jsonObjectMapper.asJsonString(
+ cpsPathQuery.getLeavesData()));
}
addTextFunctionCondition(cpsPathQuery, sqlStringBuilder, queryParameters);
diff --git a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceIntegrationSpec.groovy b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceIntegrationSpec.groovy
index 85e1155cf..69e6aa81c 100755
--- a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceIntegrationSpec.groovy
+++ b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceIntegrationSpec.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021 Nordix Foundation
+ * Copyright (C) 2021-2022 Nordix Foundation
* Modifications Copyright (C) 2021 Pantheon.tech
* Modifications Copyright (C) 2021 Bell Canada.
* ================================================================================
@@ -21,9 +21,8 @@
*/
package org.onap.cps.spi.impl
+import com.fasterxml.jackson.databind.ObjectMapper
import com.google.common.collect.ImmutableSet
-import com.google.gson.Gson
-import com.google.gson.GsonBuilder
import org.onap.cps.spi.CpsDataPersistenceService
import org.onap.cps.spi.entities.FragmentEntity
import org.onap.cps.spi.exceptions.AlreadyDefinedException
@@ -32,6 +31,7 @@ import org.onap.cps.spi.exceptions.DataNodeNotFoundException
import org.onap.cps.spi.exceptions.DataspaceNotFoundException
import org.onap.cps.spi.model.DataNode
import org.onap.cps.spi.model.DataNodeBuilder
+import org.onap.cps.utils.JsonObjectMapper
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.test.context.jdbc.Sql
@@ -46,7 +46,7 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase {
@Autowired
CpsDataPersistenceService objectUnderTest
- static final Gson GSON = new GsonBuilder().create()
+ static final JsonObjectMapper jsonObjectMapper = new JsonObjectMapper(new ObjectMapper())
static final String SET_DATA = '/data/fragment.sql'
static final long ID_DATA_NODE_WITH_DESCENDANTS = 4001
@@ -549,7 +549,7 @@ class CpsDataPersistenceServiceIntegrationSpec extends CpsPersistenceSpecBase {
}
static Map<String, Object> getLeavesMap(FragmentEntity fragmentEntity) {
- return GSON.fromJson(fragmentEntity.getAttributes(), Map<String, Object>.class)
+ return jsonObjectMapper.convertJsonString(fragmentEntity.getAttributes(), Map<String, Object>.class)
}
def static assertLeavesMaps(actualLeavesMap, expectedLeavesMap) {
diff --git a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceSpec.groovy b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceSpec.groovy
index 162a56682..7166008ad 100644
--- a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceSpec.groovy
+++ b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsDataPersistenceServiceSpec.groovy
@@ -18,6 +18,7 @@
package org.onap.cps.spi.impl
+import com.fasterxml.jackson.databind.ObjectMapper
import org.hibernate.StaleStateException
import org.onap.cps.spi.FetchDescendantsOption
import org.onap.cps.spi.entities.FragmentEntity
@@ -27,6 +28,7 @@ import org.onap.cps.spi.model.DataNodeBuilder
import org.onap.cps.spi.repository.AnchorRepository
import org.onap.cps.spi.repository.DataspaceRepository
import org.onap.cps.spi.repository.FragmentRepository
+import org.onap.cps.utils.JsonObjectMapper
import spock.lang.Specification
@@ -35,9 +37,10 @@ class CpsDataPersistenceServiceSpec extends Specification {
def mockDataspaceRepository = Mock(DataspaceRepository)
def mockAnchorRepository = Mock(AnchorRepository)
def mockFragmentRepository = Mock(FragmentRepository)
+ def jsonObjectMapper = new JsonObjectMapper(new ObjectMapper())
def objectUnderTest = new CpsDataPersistenceServiceImpl(
- mockDataspaceRepository, mockAnchorRepository, mockFragmentRepository)
+ mockDataspaceRepository, mockAnchorRepository, mockFragmentRepository, jsonObjectMapper)
def 'Handling of StaleStateException (caused by concurrent updates) during data node tree update.'() {
diff --git a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsPersistenceSpecBase.groovy b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsPersistenceSpecBase.groovy
index 8ec5c90e9..8e13be2ae 100644
--- a/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsPersistenceSpecBase.groovy
+++ b/cps-ri/src/test/groovy/org/onap/cps/spi/impl/CpsPersistenceSpecBase.groovy
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021 Nordix Foundation
+ * Copyright (C) 2021-2022 Nordix Foundation
* Modifications Copyright (C) 2021 Pantheon.tech
* Modifications Copyright (C) 2021 Bell Canada.
* ================================================================================
@@ -22,11 +22,14 @@
package org.onap.cps.spi.impl
+import com.fasterxml.jackson.databind.ObjectMapper
import org.onap.cps.DatabaseTestContainer
import org.onap.cps.spi.repository.AnchorRepository
import org.onap.cps.spi.repository.DataspaceRepository
import org.onap.cps.spi.repository.FragmentRepository
import org.onap.cps.spi.repository.YangResourceRepository
+import org.onap.cps.utils.JsonObjectMapper
+import org.spockframework.spring.SpringBean
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.testcontainers.spock.Testcontainers
@@ -52,6 +55,9 @@ class CpsPersistenceSpecBase extends Specification {
@Autowired
FragmentRepository fragmentRepository
+ @SpringBean
+ JsonObjectMapper jsonObjectMapper = new JsonObjectMapper(new ObjectMapper())
+
static final String CLEAR_DATA = '/data/clear-all.sql'
static final String DATASPACE_NAME = 'DATASPACE-001'
diff --git a/cps-service/pom.xml b/cps-service/pom.xml
index 6cef985f8..0c7556407 100644
--- a/cps-service/pom.xml
+++ b/cps-service/pom.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
============LICENSE_START=======================================================
- Copyright (C) 2021 Nordix Foundation
+ Copyright (C) 2021-2022 Nordix Foundation
Modifications Copyright (C) 2021 Bell Canada.
Modifications Copyright (C) 2021 Pantheon.tech
================================================================================
@@ -110,6 +110,11 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>org.codehaus.groovy</groupId>
+ <artifactId>groovy-json</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-core</artifactId>
<scope>test</scope>
diff --git a/cps-service/src/main/java/org/onap/cps/utils/JsonObjectMapper.java b/cps-service/src/main/java/org/onap/cps/utils/JsonObjectMapper.java
new file mode 100644
index 000000000..2459b51af
--- /dev/null
+++ b/cps-service/src/main/java/org/onap/cps/utils/JsonObjectMapper.java
@@ -0,0 +1,90 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 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.utils;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.spi.exceptions.DataValidationException;
+import org.springframework.stereotype.Component;
+
+@Slf4j
+@RequiredArgsConstructor
+@Component
+public class JsonObjectMapper {
+
+ private final ObjectMapper objectMapper;
+
+ /**
+ * Serializing generic java object to JSON using Jackson.
+ *
+ * @param object any java object value
+ * @return the generated JSON as a string.
+ */
+ public String asJsonString(final Object object) {
+ try {
+ return objectMapper.writeValueAsString(object);
+ } catch (final JsonProcessingException e) {
+ log.error("Parsing error occurred while converting Object to JSON string.");
+ throw new DataValidationException("Parsing error occurred while converting given object to JSON string.",
+ e.getMessage());
+ }
+ }
+
+ /**
+ * Constructing JavaType out of given type (typically java.lang.Class).
+ * Allow efficient value conversions for structurally compatible json objects,
+ * according to standard Jackson configuration.
+ *
+ * @param jsonObject structurally compatible json object
+ * @param valueType compatible Object class type
+ * @param <T> type parameter
+ * @return a class object of specific class type 'T'
+ */
+ public <T> T convertToValueType(final Object jsonObject, final Class<T> valueType) {
+ try {
+ return objectMapper.convertValue(jsonObject, valueType);
+ } catch (final IllegalArgumentException e) {
+ log.error("Found structurally incompatible object while converting into value type.");
+ throw new DataValidationException("Found structurally incompatible object while converting "
+ + "into value type.", e.getMessage());
+ }
+ }
+
+ /**
+ * Deserialize JSON content from given JSON content String.
+ *
+ * @param jsonContent JSON content
+ * @param valueType compatible Object class type
+ * @param <T> type parameter
+ * @return a class object of specific class type 'T'
+ */
+ public <T> T convertJsonString(final String jsonContent, final Class<T> valueType) {
+ try {
+ return objectMapper.readValue(jsonContent, valueType);
+ } catch (final JsonProcessingException e) {
+ log.error("Parsing error occurred while converting JSON content to specific class type.");
+ throw new DataValidationException("Parsing error occurred while converting "
+ + "JSON content to specific class type.", e.getMessage());
+ }
+ }
+}
diff --git a/cps-service/src/test/groovy/org/onap/cps/utils/JsonObjectMapperSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/utils/JsonObjectMapperSpec.groovy
new file mode 100644
index 000000000..f9b8febd4
--- /dev/null
+++ b/cps-service/src/test/groovy/org/onap/cps/utils/JsonObjectMapperSpec.groovy
@@ -0,0 +1,87 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 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.utils
+
+
+import com.fasterxml.jackson.databind.ObjectMapper
+import groovy.json.JsonSlurper
+import org.onap.cps.TestUtils
+import org.onap.cps.spi.exceptions.DataValidationException
+import spock.lang.Specification
+
+class JsonObjectMapperSpec extends Specification {
+
+ def spiedObjectMapper = Spy(ObjectMapper)
+ def jsonObjectMapper = new JsonObjectMapper(spiedObjectMapper)
+
+ def 'Map a structured object to json String.'() {
+ given: 'an object model'
+ def object = spiedObjectMapper.readValue(TestUtils.getResourceFileContent('bookstore.json'), Object)
+ when: 'the object is mapped to string'
+ def content = jsonObjectMapper.asJsonString(object);
+ then: 'the result is a valid json string (can be parsed)'
+ def contentMap = new JsonSlurper().parseText(content)
+ and: 'the parsed content is as expected'
+ assert contentMap.'test:bookstore'.'bookstore-name' == 'Chapters'
+ }
+
+ def 'Map a structurally compatible object to class object of specific class type T.'() {
+ given: 'a map object model'
+ def contentMap = new JsonSlurper().parseText(TestUtils.getResourceFileContent('bookstore.json'))
+ when: 'converted into a Map'
+ def result = jsonObjectMapper.convertToValueType(contentMap, Map);
+ then: 'the result is a mapped into class of type Map'
+ assert result instanceof Map
+ and: 'the map contains the expected key'
+ assert result.containsKey('test:bookstore')
+ assert result.'test:bookstore'.categories[0].name == 'SciFi'
+
+ }
+
+ def 'Mapping an unstructured json string to class object of specific class type T.'() {
+ given: 'Unstructured json string'
+ def content = '{ "nest": { "birds": "bird"] } }'
+ when: 'mapping json string to given class type'
+ def contentMap = jsonObjectMapper.convertJsonString(content, Map);
+ then: 'an exception is thrown'
+ thrown(DataValidationException)
+ }
+
+ def 'Map an incompatible object to class object of specific class type T.'() {
+ given: 'a map object model'
+ def contentMap = new JsonSlurper().parseText(TestUtils.getResourceFileContent('bookstore.json'))
+ and: 'Object mapper throws an exception'
+ spiedObjectMapper.convertValue(*_) >> { throw new IllegalArgumentException() }
+ when: 'converted into specific class type'
+ jsonObjectMapper.convertToValueType(contentMap, Object);
+ then: 'an exception is thrown'
+ thrown(DataValidationException)
+ }
+
+ def 'Map a unstructured object to json String.'() {
+ given: 'Unstructured object'
+ def object = new Object()
+ when: 'the object is mapped to string'
+ jsonObjectMapper.asJsonString(object);
+ then: 'an exception is thrown'
+ thrown(DataValidationException)
+ }
+}