aboutsummaryrefslogtreecommitdiffstats
path: root/cps-service/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'cps-service/src/main/java')
-rwxr-xr-xcps-service/src/main/java/org/onap/cps/api/CpsAdminService.java12
-rw-r--r--cps-service/src/main/java/org/onap/cps/api/CpsDataService.java37
-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.java18
-rwxr-xr-xcps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java55
-rw-r--r--cps-service/src/main/java/org/onap/cps/api/impl/CpsModuleServiceImpl.java15
-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
-rwxr-xr-xcps-service/src/main/java/org/onap/cps/spi/CpsAdminPersistenceService.java12
-rw-r--r--cps-service/src/main/java/org/onap/cps/spi/CpsDataPersistenceService.java27
-rw-r--r--cps-service/src/main/java/org/onap/cps/spi/exceptions/SessionManagerException.java48
-rw-r--r--cps-service/src/main/java/org/onap/cps/spi/exceptions/SessionTimeoutException.java31
-rw-r--r--cps-service/src/main/java/org/onap/cps/spi/model/CmHandleQueryParameters.java41
-rw-r--r--cps-service/src/main/java/org/onap/cps/spi/model/DataNode.java2
-rw-r--r--cps-service/src/main/java/org/onap/cps/utils/CpsValidator.java62
16 files changed, 358 insertions, 30 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..2106f1584e 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-2022 Nordix Foundation
* Modifications Copyright (C) 2020-2022 Bell Canada.
* Modifications Copyright (C) 2021 Pantheon.tech
* ================================================================================
@@ -23,9 +23,11 @@
package org.onap.cps.api;
import java.util.Collection;
+import java.util.Set;
import org.onap.cps.spi.exceptions.AlreadyDefinedException;
import org.onap.cps.spi.exceptions.CpsException;
import org.onap.cps.spi.model.Anchor;
+import org.onap.cps.spi.model.CmHandleQueryParameters;
/**
* CPS Admin Service.
@@ -100,4 +102,12 @@ public interface CpsAdminService {
* given module names
*/
Collection<String> queryAnchorNames(String dataspaceName, Collection<String> moduleNames);
+
+ /**
+ * Query and return cm handles that match the given query parameters.
+ *
+ * @param cmHandleQueryParameters the cm handle query parameters
+ * @return collection of cm handle ids
+ */
+ Set<String> queryCmHandles(CmHandleQueryParameters cmHandleQueryParameters);
}
diff --git a/cps-service/src/main/java/org/onap/cps/api/CpsDataService.java b/cps-service/src/main/java/org/onap/cps/api/CpsDataService.java
index cdd417bd8d..93c96ec650 100644
--- a/cps-service/src/main/java/org/onap/cps/api/CpsDataService.java
+++ b/cps-service/src/main/java/org/onap/cps/api/CpsDataService.java
@@ -174,4 +174,41 @@ public interface CpsDataService {
*/
void updateNodeLeavesAndExistingDescendantLeaves(String dataspaceName, String anchorName, String parentNodeXpath,
String dataNodeUpdatesAsJson, OffsetDateTime observedTimestamp);
+
+ /**
+ * Starts a session which allows use of locks and batch interaction with the persistence service.
+ *
+ * @return Session ID string
+ */
+ String startSession();
+
+ /**
+ * Close session.
+ *
+ * @param sessionId session ID
+ *
+ */
+ void closeSession(String sessionId);
+
+ /**
+ * Lock anchor with default timeout.
+ * To release locks(s), the session holding the lock(s) must be closed.
+ *
+ * @param sessionID session ID
+ * @param dataspaceName dataspace name
+ * @param anchorName anchor name
+ */
+ void lockAnchor(String sessionID, String dataspaceName, String anchorName);
+
+ /**
+ * Lock anchor with custom timeout.
+ * To release locks(s), the session holding the lock(s) must be closed.
+ *
+ * @param sessionID session ID
+ * @param dataspaceName dataspace name
+ * @param anchorName anchor name
+ * @param timeoutInMilliseconds lock attempt timeout in milliseconds
+ */
+ void lockAnchor(String sessionID, String dataspaceName, String anchorName, Long timeoutInMilliseconds);
+
}
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..762754f9a8 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
* ================================================================================
@@ -24,12 +24,15 @@ package org.onap.cps.api.impl;
import java.time.OffsetDateTime;
import java.util.Collection;
+import java.util.Set;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;
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.spi.model.CmHandleQueryParameters;
+import org.onap.cps.utils.CpsValidator;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
@@ -43,43 +46,56 @@ 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());
}
+
+ @Override
+ public Set<String> queryCmHandles(final CmHandleQueryParameters cmHandleQueryParameters) {
+ return cpsAdminPersistenceService.queryCmHandles(cmHandleQueryParameters);
+ }
}
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 aae355d507..2f1067aafe 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;
@@ -47,6 +48,7 @@ import org.springframework.stereotype.Service;
public class CpsDataServiceImpl implements CpsDataService {
private static final String ROOT_NODE_XPATH = "/";
+ private static final long DEFAULT_LOCK_TIMEOUT_IN_MILLISECONDS = 300L;
private final CpsDataPersistenceService cpsDataPersistenceService;
private final CpsAdminService cpsAdminService;
@@ -56,7 +58,8 @@ public class CpsDataServiceImpl implements CpsDataService {
@Override
public void saveData(final String dataspaceName, final String anchorName, final String jsonData,
final OffsetDateTime observedTimestamp) {
- final var dataNode = buildDataNode(dataspaceName, anchorName, ROOT_NODE_XPATH, jsonData);
+ CpsValidator.validateNameCharacters(dataspaceName, anchorName);
+ final DataNode dataNode = buildDataNode(dataspaceName, anchorName, ROOT_NODE_XPATH, jsonData);
cpsDataPersistenceService.storeDataNode(dataspaceName, anchorName, dataNode);
processDataUpdatedEventAsync(dataspaceName, anchorName, observedTimestamp, ROOT_NODE_XPATH, Operation.CREATE);
}
@@ -64,7 +67,8 @@ public class CpsDataServiceImpl implements CpsDataService {
@Override
public void saveData(final String dataspaceName, final String anchorName, final String parentNodeXpath,
final String jsonData, final OffsetDateTime observedTimestamp) {
- final var dataNode = buildDataNode(dataspaceName, anchorName, parentNodeXpath, jsonData);
+ CpsValidator.validateNameCharacters(dataspaceName, anchorName);
+ final DataNode dataNode = buildDataNode(dataspaceName, anchorName, parentNodeXpath, jsonData);
cpsDataPersistenceService.addChildDataNode(dataspaceName, anchorName, parentNodeXpath, dataNode);
processDataUpdatedEventAsync(dataspaceName, anchorName, observedTimestamp, parentNodeXpath, Operation.CREATE);
}
@@ -72,6 +76,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,13 +87,15 @@ 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) {
- final var dataNode = buildDataNode(dataspaceName, anchorName, parentNodeXpath, jsonData);
+ CpsValidator.validateNameCharacters(dataspaceName, anchorName);
+ final DataNode dataNode = buildDataNode(dataspaceName, anchorName, parentNodeXpath, jsonData);
cpsDataPersistenceService
.updateDataLeaves(dataspaceName, anchorName, dataNode.getXpath(), dataNode.getLeaves());
processDataUpdatedEventAsync(dataspaceName, anchorName, observedTimestamp, parentNodeXpath, Operation.UPDATE);
@@ -99,6 +106,7 @@ public class CpsDataServiceImpl implements CpsDataService {
final String parentNodeXpath,
final String dataNodeUpdatesAsJson,
final OffsetDateTime observedTimestamp) {
+ CpsValidator.validateNameCharacters(dataspaceName, anchorName);
final Collection<DataNode> dataNodeUpdates =
buildDataNodes(dataspaceName, anchorName,
parentNodeXpath, dataNodeUpdatesAsJson);
@@ -109,9 +117,31 @@ public class CpsDataServiceImpl implements CpsDataService {
}
@Override
+ public String startSession() {
+ return cpsDataPersistenceService.startSession();
+ }
+
+ @Override
+ public void closeSession(final String sessionId) {
+ cpsDataPersistenceService.closeSession(sessionId);
+ }
+
+ @Override
+ public void lockAnchor(final String sessionID, final String dataspaceName, final String anchorName) {
+ lockAnchor(sessionID, dataspaceName, anchorName, DEFAULT_LOCK_TIMEOUT_IN_MILLISECONDS);
+ }
+
+ @Override
+ public void lockAnchor(final String sessionID, final String dataspaceName,
+ final String anchorName, final Long timeoutInMilliseconds) {
+ cpsDataPersistenceService.lockAnchor(sessionID, dataspaceName, anchorName, timeoutInMilliseconds);
+ }
+
+ @Override
public void replaceNodeTree(final String dataspaceName, final String anchorName, final String parentNodeXpath,
final String jsonData, final OffsetDateTime observedTimestamp) {
- final var dataNode = buildDataNode(dataspaceName, anchorName, parentNodeXpath, jsonData);
+ CpsValidator.validateNameCharacters(dataspaceName, anchorName);
+ final DataNode dataNode = buildDataNode(dataspaceName, anchorName, parentNodeXpath, jsonData);
cpsDataPersistenceService.replaceDataNodeTree(dataspaceName, anchorName, dataNode);
processDataUpdatedEventAsync(dataspaceName, anchorName, observedTimestamp, parentNodeXpath, Operation.UPDATE);
}
@@ -119,6 +149,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);
@@ -127,6 +158,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);
}
@@ -134,6 +166,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);
}
@@ -141,7 +174,8 @@ public class CpsDataServiceImpl implements CpsDataService {
@Override
public void deleteDataNodes(final String dataspaceName, final String anchorName,
final OffsetDateTime observedTimestamp) {
- final var anchor = cpsAdminService.getAnchor(dataspaceName, anchorName);
+ CpsValidator.validateNameCharacters(dataspaceName, anchorName);
+ final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName);
cpsDataPersistenceService.deleteDataNodes(dataspaceName, anchorName);
processDataUpdatedEventAsync(anchor, ROOT_NODE_XPATH, Operation.DELETE, observedTimestamp);
}
@@ -149,6 +183,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);
}
@@ -156,8 +191,8 @@ public class CpsDataServiceImpl implements CpsDataService {
private DataNode buildDataNode(final String dataspaceName, final String anchorName,
final String parentNodeXpath, final String jsonData) {
- final var anchor = cpsAdminService.getAnchor(dataspaceName, anchorName);
- final var schemaContext = getSchemaContext(dataspaceName, anchor.getSchemaSetName());
+ final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName);
+ final SchemaContext schemaContext = getSchemaContext(dataspaceName, anchor.getSchemaSetName());
if (ROOT_NODE_XPATH.equals(parentNodeXpath)) {
final NormalizedNode<?, ?> normalizedNode = YangUtils.parseJsonData(jsonData, schemaContext);
@@ -176,8 +211,8 @@ public class CpsDataServiceImpl implements CpsDataService {
final String parentNodeXpath,
final String jsonData) {
- final var anchor = cpsAdminService.getAnchor(dataspaceName, anchorName);
- final var schemaContext = getSchemaContext(dataspaceName, anchor.getSchemaSetName());
+ final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName);
+ final SchemaContext schemaContext = getSchemaContext(dataspaceName, anchor.getSchemaSetName());
final NormalizedNode<?, ?> normalizedNode = YangUtils.parseJsonData(jsonData, schemaContext, parentNodeXpath);
final Collection<DataNode> dataNodes = new DataNodeBuilder()
@@ -194,7 +229,7 @@ public class CpsDataServiceImpl implements CpsDataService {
private void processDataUpdatedEventAsync(final String dataspaceName, final String anchorName,
final OffsetDateTime observedTimestamp, final String xpath,
final Operation operation) {
- final var anchor = cpsAdminService.getAnchor(dataspaceName, anchorName);
+ final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName);
this.processDataUpdatedEventAsync(anchor, xpath, operation, observedTimestamp);
}
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..db8a81f276 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,23 +94,25 @@ 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, anchorName);
return cpsModulePersistenceService.getYangResourceModuleReferences(dataspaceName, anchorName);
}
- private boolean isCascadeDeleteProhibited(final CascadeDeleteAllowed cascadeDeleteAllowed) {
- return CascadeDeleteAllowed.CASCADE_DELETE_PROHIBITED == cascadeDeleteAllowed;
- }
-
@Override
public Collection<ModuleReference> identifyNewModuleReferences(
final Collection<ModuleReference> moduleReferencesToCheck) {
return cpsModulePersistenceService.identifyNewModuleReferences(moduleReferencesToCheck);
}
+ private boolean isCascadeDeleteProhibited(final CascadeDeleteAllowed cascadeDeleteAllowed) {
+ return CascadeDeleteAllowed.CASCADE_DELETE_PROHIBITED == cascadeDeleteAllowed;
+ }
+
}
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/spi/CpsAdminPersistenceService.java b/cps-service/src/main/java/org/onap/cps/spi/CpsAdminPersistenceService.java
index dd4059d88c..25167e844a 100755
--- a/cps-service/src/main/java/org/onap/cps/spi/CpsAdminPersistenceService.java
+++ b/cps-service/src/main/java/org/onap/cps/spi/CpsAdminPersistenceService.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
* ================================================================================
@@ -23,8 +23,10 @@
package org.onap.cps.spi;
import java.util.Collection;
+import java.util.Set;
import org.onap.cps.spi.exceptions.AlreadyDefinedException;
import org.onap.cps.spi.model.Anchor;
+import org.onap.cps.spi.model.CmHandleQueryParameters;
/*
Service for handling CPS admin data.
@@ -99,4 +101,12 @@ public interface CpsAdminPersistenceService {
* @param anchorName anchor name
*/
void deleteAnchor(String dataspaceName, String anchorName);
+
+ /**
+ * Query and return cm handles that match the given query parameters.
+ *
+ * @param cmHandleQueryParameters the cm handle query parameters
+ * @return collection of cm handle ids
+ */
+ Set<String> queryCmHandles(CmHandleQueryParameters cmHandleQueryParameters);
}
diff --git a/cps-service/src/main/java/org/onap/cps/spi/CpsDataPersistenceService.java b/cps-service/src/main/java/org/onap/cps/spi/CpsDataPersistenceService.java
index fd658861c2..43cfffee70 100644
--- a/cps-service/src/main/java/org/onap/cps/spi/CpsDataPersistenceService.java
+++ b/cps-service/src/main/java/org/onap/cps/spi/CpsDataPersistenceService.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2020 Nordix Foundation.
+ * Copyright (C) 2020-2022 Nordix Foundation.
* Modifications Copyright (C) 2021 Pantheon.tech
* Modifications Copyright (C) 2022 Bell Canada
* ================================================================================
@@ -148,4 +148,29 @@ public interface CpsDataPersistenceService {
Collection<DataNode> queryDataNodes(String dataspaceName, String anchorName,
String cpsPath, FetchDescendantsOption fetchDescendantsOption);
+ /**
+ * Starts a session which allows use of locks and batch interaction with the persistence service.
+ *
+ * @return Session ID string
+ */
+ String startSession();
+
+ /**
+ * Close session.
+ *
+ * @param sessionId session ID
+ */
+ void closeSession(String sessionId);
+
+ /**
+ * Lock anchor.
+ * To release locks(s), the session holding the lock(s) must be closed.
+ *
+ * @param sessionID session ID
+ * @param dataspaceName dataspace name
+ * @param anchorName anchor name
+ * @param timeoutInMilliseconds lock attempt timeout in milliseconds
+ */
+ void lockAnchor(String sessionID, String dataspaceName, String anchorName, Long timeoutInMilliseconds);
+
}
diff --git a/cps-service/src/main/java/org/onap/cps/spi/exceptions/SessionManagerException.java b/cps-service/src/main/java/org/onap/cps/spi/exceptions/SessionManagerException.java
new file mode 100644
index 0000000000..4000bfc51d
--- /dev/null
+++ b/cps-service/src/main/java/org/onap/cps/spi/exceptions/SessionManagerException.java
@@ -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.spi.exceptions;
+
+
+public class SessionManagerException extends CpsException {
+
+ private static final long serialVersionUID = 7957090904519019500L;
+
+ /**
+ * Constructor.
+ *
+ * @param message the error message
+ * @param details the error details
+ * @param cause the cause of the exception
+ */
+ public SessionManagerException(final String message, final String details, final Throwable cause) {
+ super(message, details, cause);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param message the error message
+ * @param details the error details
+ */
+ public SessionManagerException(final String message, final String details) {
+ super(message, details);
+ }
+}
diff --git a/cps-service/src/main/java/org/onap/cps/spi/exceptions/SessionTimeoutException.java b/cps-service/src/main/java/org/onap/cps/spi/exceptions/SessionTimeoutException.java
new file mode 100644
index 0000000000..92b4aa7a8b
--- /dev/null
+++ b/cps-service/src/main/java/org/onap/cps/spi/exceptions/SessionTimeoutException.java
@@ -0,0 +1,31 @@
+/*
+ * ============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.spi.exceptions;
+
+@SuppressWarnings("squid:S110") // Team agreed to accept 6 levels of inheritance for CPS Exceptions
+public class SessionTimeoutException extends SessionManagerException {
+
+ private static final long serialVersionUID = -8809577494038691360L;
+
+ public SessionTimeoutException(final String message, final String details, final Throwable cause) {
+ super(message, details, cause);
+ }
+}
diff --git a/cps-service/src/main/java/org/onap/cps/spi/model/CmHandleQueryParameters.java b/cps-service/src/main/java/org/onap/cps/spi/model/CmHandleQueryParameters.java
new file mode 100644
index 0000000000..ff4e627636
--- /dev/null
+++ b/cps-service/src/main/java/org/onap/cps/spi/model/CmHandleQueryParameters.java
@@ -0,0 +1,41 @@
+/*
+ * ============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.spi.model;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.Collections;
+import java.util.Map;
+import javax.validation.Valid;
+import lombok.Getter;
+import lombok.Setter;
+
+@Setter
+@Getter
+@JsonInclude(Include.NON_NULL)
+public class CmHandleQueryParameters {
+
+ @JsonProperty("publicCmHandleProperties")
+ @Valid
+ private Map<String, String> publicProperties = Collections.emptyMap();
+
+}
diff --git a/cps-service/src/main/java/org/onap/cps/spi/model/DataNode.java b/cps-service/src/main/java/org/onap/cps/spi/model/DataNode.java
index 55e7b9970b..43aa06b81b 100644
--- a/cps-service/src/main/java/org/onap/cps/spi/model/DataNode.java
+++ b/cps-service/src/main/java/org/onap/cps/spi/model/DataNode.java
@@ -26,11 +26,13 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import lombok.AccessLevel;
+import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
@Setter(AccessLevel.PROTECTED)
@Getter
+@EqualsAndHashCode
public class DataNode {
DataNode() { }
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..28b49c9666
--- /dev/null
+++ b/cps-service/src/main/java/org/onap/cps/utils/CpsValidator.java
@@ -0,0 +1,62 @@
+/*
+ * ============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 java.util.regex.Pattern;
+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();
+ private static final Pattern TOPIC_NAME_PATTERN = Pattern.compile("^[a-zA-Z0-9]([._-](?![._-])|"
+ + "[a-zA-Z0-9]){0,120}[a-zA-Z0-9]$");
+
+ /**
+ * 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));
+ }
+ }
+ }
+ }
+
+ /**
+ * Validate kafka topic name pattern.
+ * @param topicName name of the topic to be validated
+ */
+ public static boolean validateTopicName(final String topicName) {
+ return topicName != null && TOPIC_NAME_PATTERN.matcher(topicName).matches();
+ }
+}