aboutsummaryrefslogtreecommitdiffstats
path: root/cps-service
diff options
context:
space:
mode:
authorDylanB95EST <dylan.byrne@est.tech>2022-03-08 17:26:34 +0000
committerDylanB95EST <dylan.byrne@est.tech>2022-03-30 12:01:00 +0100
commit1839f38e054a958793ec40f524d911253086c74e (patch)
tree67895018797e6a1ea28f8a99ceb50547c66100c7 /cps-service
parenta0bbcfd8de94bb433e787b1a6ee400c988975850 (diff)
Additional validation for names/identifiers
Implementing additional regex validation for names/identifiers in CPS - Introduces a CpsValidator - Applies to relevent java public API's - Tests have been updated where necessary Issue-ID: CPS-322 Change-Id: I29ab8820bb1fe0eee247e425d6bb018bcd38f28e Signed-off-by: DylanB95EST <dylan.byrne@est.tech>
Diffstat (limited to 'cps-service')
-rwxr-xr-xcps-service/src/main/java/org/onap/cps/api/CpsAdminService.java2
-rw-r--r--cps-service/src/main/java/org/onap/cps/api/CpsModuleService.java15
-rw-r--r--cps-service/src/main/java/org/onap/cps/api/CpsQueryService.java7
-rwxr-xr-xcps-service/src/main/java/org/onap/cps/api/impl/CpsAdminServiceImpl.java11
-rwxr-xr-xcps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java13
-rw-r--r--cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java7
-rw-r--r--cps-service/src/main/java/org/onap/cps/api/impl/CpsQueryServiceImpl.java2
-rw-r--r--cps-service/src/main/java/org/onap/cps/api/impl/YangTextSchemaSourceSetCache.java4
-rw-r--r--cps-service/src/main/java/org/onap/cps/utils/CpsValidator.java51
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy6
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/api/impl/CpsQueryServiceImplSpec.groovy4
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/utils/CpsValidatorSpec.groovy48
12 files changed, 151 insertions, 19 deletions
diff --git a/cps-service/src/main/java/org/onap/cps/api/CpsAdminService.java b/cps-service/src/main/java/org/onap/cps/api/CpsAdminService.java
index 44f7f77152..2cb01ac1ef 100755
--- a/cps-service/src/main/java/org/onap/cps/api/CpsAdminService.java
+++ b/cps-service/src/main/java/org/onap/cps/api/CpsAdminService.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2020 Nordix Foundation
+ * Copyright (C) 2020-2021 Nordix Foundation
* Modifications Copyright (C) 2020-2022 Bell Canada.
* Modifications Copyright (C) 2021 Pantheon.tech
* ================================================================================
diff --git a/cps-service/src/main/java/org/onap/cps/api/CpsModuleService.java b/cps-service/src/main/java/org/onap/cps/api/CpsModuleService.java
index ecc9bf0986..79d6e03d4a 100644
--- a/cps-service/src/main/java/org/onap/cps/api/CpsModuleService.java
+++ b/cps-service/src/main/java/org/onap/cps/api/CpsModuleService.java
@@ -23,7 +23,6 @@ package org.onap.cps.api;
import java.util.Collection;
import java.util.Map;
-import org.checkerframework.checker.nullness.qual.NonNull;
import org.onap.cps.spi.CascadeDeleteAllowed;
import org.onap.cps.spi.exceptions.DataInUseException;
import org.onap.cps.spi.model.ModuleReference;
@@ -42,8 +41,8 @@ public interface CpsModuleService {
* @param yangResourcesNameToContentMap yang resources (files) as a mep where key is resource name
* and value is content
*/
- void createSchemaSet(@NonNull String dataspaceName, @NonNull String schemaSetName,
- @NonNull Map<String, String> yangResourcesNameToContentMap);
+ void createSchemaSet(String dataspaceName, String schemaSetName,
+ Map<String, String> yangResourcesNameToContentMap);
/**
* Create a schema set from new modules and existing modules.
@@ -52,8 +51,8 @@ public interface CpsModuleService {
* @param newModuleNameToContentMap YANG resources map where key is a module name and value is content
* @param moduleReferences List of YANG resources module references of the modules
*/
- void createSchemaSetFromModules(@NonNull String dataspaceName, @NonNull String schemaSetName,
- @NonNull Map<String, String> newModuleNameToContentMap,
+ void createSchemaSetFromModules(String dataspaceName, String schemaSetName,
+ Map<String, String> newModuleNameToContentMap,
Collection<ModuleReference> moduleReferences);
/**
@@ -63,7 +62,7 @@ public interface CpsModuleService {
* @param schemaSetName schema set name
* @return a SchemaSet
*/
- SchemaSet getSchemaSet(@NonNull String dataspaceName, @NonNull String schemaSetName);
+ SchemaSet getSchemaSet(String dataspaceName, String schemaSetName);
/**
* Deletes Schema Set.
@@ -74,8 +73,8 @@ public interface CpsModuleService {
* @throws DataInUseException if cascadeDeleteAllowed is set to CASCADE_DELETE_PROHIBITED and there
* is associated anchor record exists in database
*/
- void deleteSchemaSet(@NonNull String dataspaceName, @NonNull String schemaSetName,
- @NonNull CascadeDeleteAllowed cascadeDeleteAllowed);
+ void deleteSchemaSet(String dataspaceName, String schemaSetName,
+ CascadeDeleteAllowed cascadeDeleteAllowed);
/**
* Retrieve module references for the given dataspace name.
diff --git a/cps-service/src/main/java/org/onap/cps/api/CpsQueryService.java b/cps-service/src/main/java/org/onap/cps/api/CpsQueryService.java
index beb0a1540e..68ae1ebf0a 100644
--- a/cps-service/src/main/java/org/onap/cps/api/CpsQueryService.java
+++ b/cps-service/src/main/java/org/onap/cps/api/CpsQueryService.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2020 Nordix Foundation
+ * Copyright (C) 2020-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,7 +21,6 @@
package org.onap.cps.api;
import java.util.Collection;
-import org.checkerframework.checker.nullness.qual.NonNull;
import org.onap.cps.spi.FetchDescendantsOption;
import org.onap.cps.spi.model.DataNode;
@@ -40,7 +39,7 @@ public interface CpsQueryService {
* included in the output
* @return a collection of data nodes
*/
- Collection<DataNode> queryDataNodes(@NonNull String dataspaceName, @NonNull String anchorName,
- @NonNull String cpsPath, @NonNull FetchDescendantsOption fetchDescendantsOption);
+ Collection<DataNode> queryDataNodes(String dataspaceName, String anchorName,
+ String cpsPath, FetchDescendantsOption fetchDescendantsOption);
}
diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsAdminServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsAdminServiceImpl.java
index 1013addbe1..7bec1e39f0 100755
--- a/cps-service/src/main/java/org/onap/cps/api/impl/CpsAdminServiceImpl.java
+++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsAdminServiceImpl.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2020 Nordix Foundation
+ * Copyright (C) 2020-2022 Nordix Foundation
* Modifications Copyright (C) 2020-2022 Bell Canada.
* Modifications Copyright (C) 2021 Pantheon.tech
* ================================================================================
@@ -30,6 +30,7 @@ import org.onap.cps.api.CpsAdminService;
import org.onap.cps.api.CpsDataService;
import org.onap.cps.spi.CpsAdminPersistenceService;
import org.onap.cps.spi.model.Anchor;
+import org.onap.cps.utils.CpsValidator;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
@@ -43,42 +44,50 @@ public class CpsAdminServiceImpl implements CpsAdminService {
@Override
public void createDataspace(final String dataspaceName) {
+ CpsValidator.validateNameCharacters(dataspaceName);
cpsAdminPersistenceService.createDataspace(dataspaceName);
}
@Override
public void deleteDataspace(final String dataspaceName) {
+ CpsValidator.validateNameCharacters(dataspaceName);
cpsAdminPersistenceService.deleteDataspace(dataspaceName);
}
@Override
public void createAnchor(final String dataspaceName, final String schemaSetName, final String anchorName) {
+ CpsValidator.validateNameCharacters(dataspaceName, schemaSetName, anchorName);
cpsAdminPersistenceService.createAnchor(dataspaceName, schemaSetName, anchorName);
}
@Override
public Collection<Anchor> getAnchors(final String dataspaceName) {
+ CpsValidator.validateNameCharacters(dataspaceName);
return cpsAdminPersistenceService.getAnchors(dataspaceName);
}
@Override
public Collection<Anchor> getAnchors(final String dataspaceName, final String schemaSetName) {
+ CpsValidator.validateNameCharacters(dataspaceName, schemaSetName);
return cpsAdminPersistenceService.getAnchors(dataspaceName, schemaSetName);
}
@Override
public Anchor getAnchor(final String dataspaceName, final String anchorName) {
+ CpsValidator.validateNameCharacters(dataspaceName, anchorName);
return cpsAdminPersistenceService.getAnchor(dataspaceName, anchorName);
}
@Override
public void deleteAnchor(final String dataspaceName, final String anchorName) {
+ CpsValidator.validateNameCharacters(dataspaceName, anchorName);
cpsDataService.deleteDataNodes(dataspaceName, anchorName, OffsetDateTime.now());
cpsAdminPersistenceService.deleteAnchor(dataspaceName, anchorName);
}
@Override
public Collection<String> queryAnchorNames(final String dataspaceName, final Collection<String> moduleNames) {
+ CpsValidator.validateNameCharacters(dataspaceName);
final Collection<Anchor> anchors = cpsAdminPersistenceService.queryAnchors(dataspaceName, moduleNames);
return anchors.stream().map(Anchor::getName).collect(Collectors.toList());
}
diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java
index 643614f4fb..399457dd6d 100755
--- a/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java
+++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java
@@ -36,6 +36,7 @@ import org.onap.cps.spi.exceptions.DataValidationException;
import org.onap.cps.spi.model.Anchor;
import org.onap.cps.spi.model.DataNode;
import org.onap.cps.spi.model.DataNodeBuilder;
+import org.onap.cps.utils.CpsValidator;
import org.onap.cps.utils.YangUtils;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
@@ -56,6 +57,7 @@ public class CpsDataServiceImpl implements CpsDataService {
@Override
public void saveData(final String dataspaceName, final String anchorName, final String jsonData,
final OffsetDateTime observedTimestamp) {
+ CpsValidator.validateNameCharacters(dataspaceName, anchorName);
final var dataNode = buildDataNode(dataspaceName, anchorName, ROOT_NODE_XPATH, jsonData);
cpsDataPersistenceService.storeDataNode(dataspaceName, anchorName, dataNode);
processDataUpdatedEventAsync(dataspaceName, anchorName, observedTimestamp, ROOT_NODE_XPATH, Operation.CREATE);
@@ -64,6 +66,7 @@ public class CpsDataServiceImpl implements CpsDataService {
@Override
public void saveData(final String dataspaceName, final String anchorName, final String parentNodeXpath,
final String jsonData, final OffsetDateTime observedTimestamp) {
+ CpsValidator.validateNameCharacters(dataspaceName, anchorName);
final var dataNode = buildDataNode(dataspaceName, anchorName, parentNodeXpath, jsonData);
cpsDataPersistenceService.addChildDataNode(dataspaceName, anchorName, parentNodeXpath, dataNode);
processDataUpdatedEventAsync(dataspaceName, anchorName, observedTimestamp, parentNodeXpath, Operation.CREATE);
@@ -72,6 +75,7 @@ public class CpsDataServiceImpl implements CpsDataService {
@Override
public void saveListElements(final String dataspaceName, final String anchorName,
final String parentNodeXpath, final String jsonData, final OffsetDateTime observedTimestamp) {
+ CpsValidator.validateNameCharacters(dataspaceName, anchorName);
final Collection<DataNode> listElementDataNodeCollection =
buildDataNodes(dataspaceName, anchorName, parentNodeXpath, jsonData);
cpsDataPersistenceService.addListElements(dataspaceName, anchorName, parentNodeXpath,
@@ -82,12 +86,14 @@ public class CpsDataServiceImpl implements CpsDataService {
@Override
public DataNode getDataNode(final String dataspaceName, final String anchorName, final String xpath,
final FetchDescendantsOption fetchDescendantsOption) {
+ CpsValidator.validateNameCharacters(dataspaceName, anchorName);
return cpsDataPersistenceService.getDataNode(dataspaceName, anchorName, xpath, fetchDescendantsOption);
}
@Override
public void updateNodeLeaves(final String dataspaceName, final String anchorName, final String parentNodeXpath,
final String jsonData, final OffsetDateTime observedTimestamp) {
+ CpsValidator.validateNameCharacters(dataspaceName, anchorName);
final var dataNode = buildDataNode(dataspaceName, anchorName, parentNodeXpath, jsonData);
cpsDataPersistenceService
.updateDataLeaves(dataspaceName, anchorName, dataNode.getXpath(), dataNode.getLeaves());
@@ -102,6 +108,7 @@ public class CpsDataServiceImpl implements CpsDataService {
final Collection<DataNode> dataNodeUpdates =
buildDataNodes(dataspaceName, anchorName,
parentNodeXpath, dataNodeUpdatesAsJson);
+ CpsValidator.validateNameCharacters(dataspaceName, anchorName);
for (final DataNode dataNodeUpdate : dataNodeUpdates) {
processDataNodeUpdate(dataspaceName, anchorName, dataNodeUpdate);
}
@@ -122,6 +129,7 @@ public class CpsDataServiceImpl implements CpsDataService {
@Override
public void replaceNodeTree(final String dataspaceName, final String anchorName, final String parentNodeXpath,
final String jsonData, final OffsetDateTime observedTimestamp) {
+ CpsValidator.validateNameCharacters(dataspaceName, anchorName);
final var dataNode = buildDataNode(dataspaceName, anchorName, parentNodeXpath, jsonData);
cpsDataPersistenceService.replaceDataNodeTree(dataspaceName, anchorName, dataNode);
processDataUpdatedEventAsync(dataspaceName, anchorName, observedTimestamp, parentNodeXpath, Operation.UPDATE);
@@ -130,6 +138,7 @@ public class CpsDataServiceImpl implements CpsDataService {
@Override
public void replaceListContent(final String dataspaceName, final String anchorName, final String parentNodeXpath,
final String jsonData, final OffsetDateTime observedTimestamp) {
+ CpsValidator.validateNameCharacters(dataspaceName, anchorName);
final Collection<DataNode> newListElements =
buildDataNodes(dataspaceName, anchorName, parentNodeXpath, jsonData);
replaceListContent(dataspaceName, anchorName, parentNodeXpath, newListElements, observedTimestamp);
@@ -138,6 +147,7 @@ public class CpsDataServiceImpl implements CpsDataService {
@Override
public void replaceListContent(final String dataspaceName, final String anchorName, final String parentNodeXpath,
final Collection<DataNode> dataNodes, final OffsetDateTime observedTimestamp) {
+ CpsValidator.validateNameCharacters(dataspaceName, anchorName);
cpsDataPersistenceService.replaceListContent(dataspaceName, anchorName, parentNodeXpath, dataNodes);
processDataUpdatedEventAsync(dataspaceName, anchorName, observedTimestamp, parentNodeXpath, Operation.UPDATE);
}
@@ -145,6 +155,7 @@ public class CpsDataServiceImpl implements CpsDataService {
@Override
public void deleteDataNode(final String dataspaceName, final String anchorName, final String dataNodeXpath,
final OffsetDateTime observedTimestamp) {
+ CpsValidator.validateNameCharacters(dataspaceName, anchorName);
cpsDataPersistenceService.deleteDataNode(dataspaceName, anchorName, dataNodeXpath);
processDataUpdatedEventAsync(dataspaceName, anchorName, observedTimestamp, dataNodeXpath, Operation.DELETE);
}
@@ -152,6 +163,7 @@ public class CpsDataServiceImpl implements CpsDataService {
@Override
public void deleteDataNodes(final String dataspaceName, final String anchorName,
final OffsetDateTime observedTimestamp) {
+ CpsValidator.validateNameCharacters(dataspaceName, anchorName);
final var anchor = cpsAdminService.getAnchor(dataspaceName, anchorName);
cpsDataPersistenceService.deleteDataNodes(dataspaceName, anchorName);
processDataUpdatedEventAsync(anchor, ROOT_NODE_XPATH, Operation.DELETE, observedTimestamp);
@@ -160,6 +172,7 @@ public class CpsDataServiceImpl implements CpsDataService {
@Override
public void deleteListOrListElement(final String dataspaceName, final String anchorName, final String listNodeXpath,
final OffsetDateTime observedTimestamp) {
+ CpsValidator.validateNameCharacters(dataspaceName, anchorName);
cpsDataPersistenceService.deleteListDataNode(dataspaceName, anchorName, listNodeXpath);
processDataUpdatedEventAsync(dataspaceName, anchorName, observedTimestamp, listNodeXpath, Operation.DELETE);
}
diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java
index f0e79c60c7..8e43227f97 100644
--- a/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java
+++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java
@@ -33,6 +33,7 @@ import org.onap.cps.spi.exceptions.SchemaSetInUseException;
import org.onap.cps.spi.model.Anchor;
import org.onap.cps.spi.model.ModuleReference;
import org.onap.cps.spi.model.SchemaSet;
+import org.onap.cps.utils.CpsValidator;
import org.onap.cps.yang.YangTextSchemaSourceSetBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -48,6 +49,7 @@ public class CpsModuleServiceImpl implements CpsModuleService {
@Override
public void createSchemaSet(final String dataspaceName, final String schemaSetName,
final Map<String, String> yangResourcesNameToContentMap) {
+ CpsValidator.validateNameCharacters(dataspaceName, schemaSetName);
final var yangTextSchemaSourceSet
= YangTextSchemaSourceSetBuilder.of(yangResourcesNameToContentMap);
cpsModulePersistenceService.storeSchemaSet(dataspaceName, schemaSetName, yangResourcesNameToContentMap);
@@ -58,6 +60,7 @@ public class CpsModuleServiceImpl implements CpsModuleService {
public void createSchemaSetFromModules(final String dataspaceName, final String schemaSetName,
final Map<String, String> newModuleNameToContentMap,
final Collection<ModuleReference> moduleReferences) {
+ CpsValidator.validateNameCharacters(dataspaceName, schemaSetName);
cpsModulePersistenceService.storeSchemaSetFromModules(dataspaceName, schemaSetName,
newModuleNameToContentMap, moduleReferences);
@@ -65,6 +68,7 @@ public class CpsModuleServiceImpl implements CpsModuleService {
@Override
public SchemaSet getSchemaSet(final String dataspaceName, final String schemaSetName) {
+ CpsValidator.validateNameCharacters(dataspaceName, schemaSetName);
final var yangTextSchemaSourceSet = yangTextSchemaSourceSetCache
.get(dataspaceName, schemaSetName);
return SchemaSet.builder().name(schemaSetName).dataspaceName(dataspaceName)
@@ -75,6 +79,7 @@ public class CpsModuleServiceImpl implements CpsModuleService {
@Transactional
public void deleteSchemaSet(final String dataspaceName, final String schemaSetName,
final CascadeDeleteAllowed cascadeDeleteAllowed) {
+ CpsValidator.validateNameCharacters(dataspaceName, schemaSetName);
final Collection<Anchor> anchors = cpsAdminService.getAnchors(dataspaceName, schemaSetName);
if (!anchors.isEmpty() && isCascadeDeleteProhibited(cascadeDeleteAllowed)) {
throw new SchemaSetInUseException(dataspaceName, schemaSetName);
@@ -89,12 +94,14 @@ public class CpsModuleServiceImpl implements CpsModuleService {
@Override
public Collection<ModuleReference> getYangResourceModuleReferences(final String dataspaceName) {
+ CpsValidator.validateNameCharacters(dataspaceName);
return cpsModulePersistenceService.getYangResourceModuleReferences(dataspaceName);
}
@Override
public Collection<ModuleReference> getYangResourcesModuleReferences(final String dataspaceName,
final String anchorName) {
+ CpsValidator.validateNameCharacters(dataspaceName);
return cpsModulePersistenceService.getYangResourceModuleReferences(dataspaceName, anchorName);
}
diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsQueryServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsQueryServiceImpl.java
index dd9f160dbf..c2003d6bf7 100644
--- a/cps-service/src/main/java/org/onap/cps/api/impl/CpsQueryServiceImpl.java
+++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsQueryServiceImpl.java
@@ -25,6 +25,7 @@ import org.onap.cps.api.CpsQueryService;
import org.onap.cps.spi.CpsDataPersistenceService;
import org.onap.cps.spi.FetchDescendantsOption;
import org.onap.cps.spi.model.DataNode;
+import org.onap.cps.utils.CpsValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -37,6 +38,7 @@ public class CpsQueryServiceImpl implements CpsQueryService {
@Override
public Collection<DataNode> queryDataNodes(final String dataspaceName, final String anchorName,
final String cpsPath, final FetchDescendantsOption fetchDescendantsOption) {
+ CpsValidator.validateNameCharacters(dataspaceName, anchorName);
return cpsDataPersistenceService.queryDataNodes(dataspaceName, anchorName, cpsPath, fetchDescendantsOption);
}
}
diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/YangTextSchemaSourceSetCache.java b/cps-service/src/main/java/org/onap/cps/api/impl/YangTextSchemaSourceSetCache.java
index 03b52a3088..fb881a97b6 100644
--- a/cps-service/src/main/java/org/onap/cps/api/impl/YangTextSchemaSourceSetCache.java
+++ b/cps-service/src/main/java/org/onap/cps/api/impl/YangTextSchemaSourceSetCache.java
@@ -24,6 +24,7 @@ package org.onap.cps.api.impl;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.util.Map;
import org.onap.cps.spi.CpsModulePersistenceService;
+import org.onap.cps.utils.CpsValidator;
import org.onap.cps.yang.YangTextSchemaSourceSet;
import org.onap.cps.yang.YangTextSchemaSourceSetBuilder;
import org.springframework.beans.factory.annotation.Autowired;
@@ -52,6 +53,7 @@ public class YangTextSchemaSourceSetCache {
*/
@Cacheable(key = "#p0.concat('-').concat(#p1)")
public YangTextSchemaSourceSet get(final String dataspaceName, final String schemaSetName) {
+ CpsValidator.validateNameCharacters(dataspaceName, schemaSetName);
final Map<String, String> yangResourceNameToContent =
cpsModulePersistenceService.getYangSchemaResources(dataspaceName, schemaSetName);
return YangTextSchemaSourceSetBuilder.of(yangResourceNameToContent);
@@ -69,6 +71,7 @@ public class YangTextSchemaSourceSetCache {
@CanIgnoreReturnValue
public YangTextSchemaSourceSet updateCache(final String dataspaceName, final String schemaSetName,
final YangTextSchemaSourceSet yangTextSchemaSourceSet) {
+ CpsValidator.validateNameCharacters(dataspaceName, schemaSetName);
return yangTextSchemaSourceSet;
}
@@ -81,6 +84,7 @@ public class YangTextSchemaSourceSetCache {
*/
@CacheEvict(key = "#p0.concat('-').concat(#p1)")
public void removeFromCache(final String dataspaceName, final String schemaSetName) {
+ CpsValidator.validateNameCharacters(dataspaceName, schemaSetName);
// Spring provides implementation for removing object from cache
}
diff --git a/cps-service/src/main/java/org/onap/cps/utils/CpsValidator.java b/cps-service/src/main/java/org/onap/cps/utils/CpsValidator.java
new file mode 100644
index 0000000000..dd16495638
--- /dev/null
+++ b/cps-service/src/main/java/org/onap/cps/utils/CpsValidator.java
@@ -0,0 +1,51 @@
+/*
+ * ============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.google.common.collect.Lists;
+import java.util.Collection;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.spi.exceptions.DataValidationException;
+
+@Slf4j
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class CpsValidator {
+
+ private static final char[] UNSUPPORTED_NAME_CHARACTERS = "!\" #$%&'()*+,./\\:;<=>?@[]^`{|}~".toCharArray();
+
+ /**
+ * Validate characters in names within cps.
+ * @param names names of data to be validated
+ */
+ public static void validateNameCharacters(final String... names) {
+ for (final String name : names) {
+ final Collection<Character> charactersOfName = Lists.charactersOf(name);
+ for (final char unsupportedCharacter : UNSUPPORTED_NAME_CHARACTERS) {
+ if (charactersOfName.contains(unsupportedCharacter)) {
+ throw new DataValidationException("Name or ID Validation Error.",
+ name + " invalid token encountered at position " + (name.indexOf(unsupportedCharacter) + 1));
+ }
+ }
+ }
+ }
+}
diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy
index eb06199d1b..fc1293cb76 100644
--- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy
@@ -50,9 +50,9 @@ class CpsDataServiceImplSpec extends Specification {
mockCpsAdminService.getAnchor(dataspaceName, anchorName) >> anchor
}
- def dataspaceName = 'some dataspace'
- def anchorName = 'some anchor'
- def schemaSetName = 'some schema set'
+ def dataspaceName = 'some-dataspace'
+ def anchorName = 'some-anchor'
+ def schemaSetName = 'some-schema-set'
def anchor = Anchor.builder().name(anchorName).schemaSetName(schemaSetName).build()
def observedTimestamp = OffsetDateTime.now()
diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsQueryServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsQueryServiceImplSpec.groovy
index 4878f4c11b..aa01b44019 100644
--- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsQueryServiceImplSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsQueryServiceImplSpec.groovy
@@ -35,8 +35,8 @@ class CpsQueryServiceImplSpec extends Specification {
def 'Query data nodes by cps path with #fetchDescendantsOption.'() {
given: 'a dataspace name, an anchor name and a cps path'
- def dataspaceName = 'some dataspace'
- def anchorName = 'some anchor'
+ def dataspaceName = 'some-dataspace'
+ def anchorName = 'some-anchor'
def cpsPath = '/cps-path'
when: 'queryDataNodes is invoked'
objectUnderTest.queryDataNodes(dataspaceName, anchorName, cpsPath, fetchDescendantsOption)
diff --git a/cps-service/src/test/groovy/org/onap/cps/utils/CpsValidatorSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/utils/CpsValidatorSpec.groovy
new file mode 100644
index 0000000000..191472ceea
--- /dev/null
+++ b/cps-service/src/test/groovy/org/onap/cps/utils/CpsValidatorSpec.groovy
@@ -0,0 +1,48 @@
+/*
+ * ============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 org.onap.cps.spi.exceptions.DataValidationException
+import spock.lang.Specification
+
+class CpsValidatorSpec extends Specification {
+
+
+ def 'Validating a valid string.'() {
+ when: 'the string is validated using a valid name'
+ CpsValidator.validateNameCharacters('name-with-no-spaces')
+ then: 'no exception is thrown'
+ noExceptionThrown()
+ }
+
+ def 'Validating an invalid string.'() {
+ when: 'the string is validated using an invalid name'
+ CpsValidator.validateNameCharacters(name)
+ then: 'a data validation exception is thrown'
+ def exceptionThrown = thrown(DataValidationException)
+ and: 'the error was encountered at the following index in #scenario'
+ assert exceptionThrown.getDetails().contains(expectedErrorMessage)
+ where: 'the following names are used'
+ scenario | name || expectedErrorMessage
+ 'position 5' | 'name with spaces' || 'name with spaces invalid token encountered at position 5'
+ 'position 9' | 'nameWith Space' || 'nameWith Space invalid token encountered at position 9'
+ }
+}