summaryrefslogtreecommitdiffstats
path: root/cps-ri/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'cps-ri/src/main')
-rw-r--r--cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java49
-rwxr-xr-xcps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java44
-rw-r--r--cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceQuery.java34
-rw-r--r--cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceRepository.java36
-rw-r--r--cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceRepositoryImpl.java107
-rw-r--r--cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java2
6 files changed, 233 insertions, 39 deletions
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 04804726c9..f22d83b981 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
@@ -329,22 +329,34 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
}
private void deleteDataNode(final String dataspaceName, final String anchorName, final String targetXpath,
- final boolean onlySupportListNodeDeletion) {
- final String parentNodeXpath = targetXpath.substring(0, targetXpath.lastIndexOf('/'));
- final FragmentEntity parentFragmentEntity = getFragmentByXpath(dataspaceName, anchorName, parentNodeXpath);
- final String lastXpathElement = targetXpath.substring(targetXpath.lastIndexOf('/'));
- final boolean isListElement = REG_EX_PATTERN_FOR_LIST_ELEMENT_KEY_PREDICATE.matcher(lastXpathElement).find();
- boolean targetExist;
- if (isListElement) {
- targetExist = deleteDataNode(parentFragmentEntity, targetXpath);
+ final boolean onlySupportListNodeDeletion) {
+ final String parentNodeXpath;
+ FragmentEntity parentFragmentEntity = null;
+ boolean targetDeleted = false;
+ if (isRootXpath(targetXpath)) {
+ deleteDataNodes(dataspaceName, anchorName);
+ targetDeleted = true;
} else {
- targetExist = deleteAllListElements(parentFragmentEntity, targetXpath);
- final boolean tryToDeleteDataNode = !targetExist && !onlySupportListNodeDeletion;
- if (tryToDeleteDataNode) {
- targetExist = deleteDataNode(parentFragmentEntity, targetXpath);
+ if (isContainerNodeXpath(targetXpath)) {
+ parentNodeXpath = targetXpath;
+ } else {
+ parentNodeXpath = targetXpath.substring(0, targetXpath.lastIndexOf('/'));
+ }
+ parentFragmentEntity = getFragmentByXpath(dataspaceName, anchorName, parentNodeXpath);
+ final String lastXpathElement = targetXpath.substring(targetXpath.lastIndexOf('/'));
+ final boolean isListElement = REG_EX_PATTERN_FOR_LIST_ELEMENT_KEY_PREDICATE
+ .matcher(lastXpathElement).find();
+ if (isListElement) {
+ targetDeleted = deleteDataNode(parentFragmentEntity, targetXpath);
+ } else {
+ targetDeleted = deleteAllListElements(parentFragmentEntity, targetXpath);
+ final boolean tryToDeleteDataNode = !targetDeleted && !onlySupportListNodeDeletion;
+ if (tryToDeleteDataNode) {
+ targetDeleted = deleteDataNode(parentFragmentEntity, targetXpath);
+ }
}
}
- if (!targetExist) {
+ if (!targetDeleted) {
final String additionalInformation = onlySupportListNodeDeletion
? "The target is probably not a List." : "";
throw new DataNodeNotFoundException(parentFragmentEntity.getDataspace().getName(),
@@ -353,6 +365,10 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
}
private boolean deleteDataNode(final FragmentEntity parentFragmentEntity, final String targetXpath) {
+ if (parentFragmentEntity.getXpath().equals(targetXpath)) {
+ fragmentRepository.delete(parentFragmentEntity);
+ return true;
+ }
if (parentFragmentEntity.getChildFragments()
.removeIf(fragment -> fragment.getXpath().equals(targetXpath))) {
fragmentRepository.save(parentFragmentEntity);
@@ -361,7 +377,6 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
return false;
}
-
private boolean deleteAllListElements(final FragmentEntity parentFragmentEntity, final String listXpath) {
final String deleteTargetXpathPrefix = listXpath + "[";
if (parentFragmentEntity.getChildFragments()
@@ -384,7 +399,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
"Cannot replace list elements with empty collection");
}
final String firstChildNodeXpath = newListElements.iterator().next().getXpath();
- return firstChildNodeXpath.substring(0, firstChildNodeXpath.lastIndexOf("[") + 1);
+ return firstChildNodeXpath.substring(0, firstChildNodeXpath.lastIndexOf('[') + 1);
}
private FragmentEntity getFragmentForReplacement(final FragmentEntity parentEntity,
@@ -408,6 +423,10 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
return !existingListElementsByXpath.containsKey(replacementDataNode.getXpath());
}
+ private static boolean isContainerNodeXpath(final String xpath) {
+ return 0 == xpath.lastIndexOf('/');
+ }
+
private void copyAttributesFromNewListElement(final FragmentEntity existingListElementEntity,
final DataNode newListElement) {
final FragmentEntity replacementFragmentEntity =
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java
index 86d5de6d0f..ec720b8a96 100755
--- a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java
+++ b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.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
* ================================================================================
@@ -40,6 +40,7 @@ import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import javax.transaction.Transactional;
+import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
@@ -53,9 +54,8 @@ import org.onap.cps.spi.exceptions.AlreadyDefinedException;
import org.onap.cps.spi.exceptions.DuplicatedYangResourceException;
import org.onap.cps.spi.exceptions.ModelValidationException;
import org.onap.cps.spi.model.ModuleReference;
-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.ModuleReferenceRepository;
import org.onap.cps.spi.repository.SchemaSetRepository;
import org.onap.cps.spi.repository.YangResourceRepository;
import org.opendaylight.yangtools.yang.common.Revision;
@@ -63,15 +63,14 @@ import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException
import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
import org.opendaylight.yangtools.yang.parser.rfc7950.repo.YangModelDependencyInfo;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Component;
-
-@Component
@Slf4j
+@Component
+@AllArgsConstructor
public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceService {
private static final String YANG_RESOURCE_CHECKSUM_CONSTRAINT_NAME = "yang_resource_checksum_key";
@@ -79,24 +78,16 @@ public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceServ
private static final Pattern RFC6020_RECOMMENDED_FILENAME_PATTERN = Pattern
.compile("([\\w-]+)@(\\d{4}-\\d{2}-\\d{2})(?:\\.yang)?", Pattern.CASE_INSENSITIVE);
- @Autowired
private YangResourceRepository yangResourceRepository;
- @Autowired
private SchemaSetRepository schemaSetRepository;
- @Autowired
private DataspaceRepository dataspaceRepository;
- @Autowired
- private AnchorRepository anchorRepository;
-
- @Autowired
- private FragmentRepository fragmentRepository;
-
- @Autowired
private CpsAdminPersistenceService cpsAdminPersistenceService;
+ private ModuleReferenceRepository moduleReferenceRepository;
+
@Override
public Map<String, String> getYangSchemaResources(final String dataspaceName, final String schemaSetName) {
final var dataspaceEntity = dataspaceRepository.getByName(dataspaceName);
@@ -137,9 +128,9 @@ public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceServ
@Retryable(value = DuplicatedYangResourceException.class, maxAttempts = 5, backoff =
@Backoff(random = true, delay = 200, maxDelay = 2000, multiplier = 2))
public void storeSchemaSet(final String dataspaceName, final String schemaSetName,
- final Map<String, String> yangResourcesNameToContentMap) {
+ final Map<String, String> moduleReferenceNameToContentMap) {
final var dataspaceEntity = dataspaceRepository.getByName(dataspaceName);
- final var yangResourceEntities = synchronizeYangResources(yangResourcesNameToContentMap);
+ final var yangResourceEntities = synchronizeYangResources(moduleReferenceNameToContentMap);
final var schemaSetEntity = new SchemaSetEntity();
schemaSetEntity.setName(schemaSetName);
schemaSetEntity.setDataspace(dataspaceEntity);
@@ -158,9 +149,9 @@ public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceServ
@Retryable(value = DuplicatedYangResourceException.class, maxAttempts = 5, backoff =
@Backoff(random = true, delay = 200, maxDelay = 2000, multiplier = 2))
public void storeSchemaSetFromModules(final String dataspaceName, final String schemaSetName,
- final Map<String, String> newYangResourcesModuleNameToContentMap,
- final List<ModuleReference> moduleReferences) {
- storeSchemaSet(dataspaceName, schemaSetName, newYangResourcesModuleNameToContentMap);
+ final Map<String, String> newModuleNameToContentMap,
+ final Collection<ModuleReference> moduleReferences) {
+ storeSchemaSet(dataspaceName, schemaSetName, newModuleNameToContentMap);
final var dataspaceEntity = dataspaceRepository.getByName(dataspaceName);
final var schemaSetEntity =
schemaSetRepository.getByDataspaceAndName(dataspaceEntity, schemaSetName);
@@ -186,8 +177,15 @@ public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceServ
yangResourceRepository.deleteOrphans();
}
- private Set<YangResourceEntity> synchronizeYangResources(final Map<String, String> yangResourcesNameToContentMap) {
- final Map<String, YangResourceEntity> checksumToEntityMap = yangResourcesNameToContentMap.entrySet().stream()
+ @Override
+ public Collection<ModuleReference> identifyNewModuleReferences(
+ final Collection<ModuleReference> moduleReferencesToCheck) {
+ return moduleReferenceRepository.identifyNewModuleReferences(moduleReferencesToCheck);
+ }
+
+ private Set<YangResourceEntity> synchronizeYangResources(
+ final Map<String, String> moduleReferenceNameToContentMap) {
+ final Map<String, YangResourceEntity> checksumToEntityMap = moduleReferenceNameToContentMap.entrySet().stream()
.map(entry -> {
final String checksum = DigestUtils.sha256Hex(entry.getValue().getBytes(StandardCharsets.UTF_8));
final Map<String, String> moduleNameAndRevisionMap = createModuleNameAndRevisionMap(entry.getKey(),
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceQuery.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceQuery.java
new file mode 100644
index 0000000000..6551937e10
--- /dev/null
+++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceQuery.java
@@ -0,0 +1,34 @@
+/*-
+ * ============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.repository;
+
+import java.util.Collection;
+import org.onap.cps.spi.model.ModuleReference;
+
+/**
+ * This interface is used in conjunction with {@link ModuleReferenceRepository} to create native sql queries.
+ */
+public interface ModuleReferenceQuery {
+
+ Collection<ModuleReference> identifyNewModuleReferences(
+ final Collection<ModuleReference> moduleReferencesToCheck);
+
+}
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceRepository.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceRepository.java
new file mode 100644
index 0000000000..ce2bfe7847
--- /dev/null
+++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceRepository.java
@@ -0,0 +1,36 @@
+/*
+ * ============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.repository;
+
+import java.util.Collection;
+import org.onap.cps.spi.entities.YangResourceEntity;
+import org.onap.cps.spi.model.ModuleReference;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface ModuleReferenceRepository extends
+ JpaRepository<YangResourceEntity, Long>, ModuleReferenceQuery {
+
+ Collection<ModuleReference> identifyNewModuleReferences(
+ final Collection<ModuleReference> moduleReferencesToCheck);
+
+} \ No newline at end of file
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceRepositoryImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceRepositoryImpl.java
new file mode 100644
index 0000000000..f4078ffec7
--- /dev/null
+++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleReferenceRepositoryImpl.java
@@ -0,0 +1,107 @@
+/*-
+ * ============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.repository;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.spi.model.ModuleReference;
+import org.springframework.transaction.annotation.Transactional;
+
+@Slf4j
+@Transactional
+public class ModuleReferenceRepositoryImpl implements ModuleReferenceQuery {
+
+ @PersistenceContext
+ private EntityManager entityManager;
+
+ @Override
+ @SneakyThrows
+ public Collection<ModuleReference> identifyNewModuleReferences(
+ final Collection<ModuleReference> moduleReferencesToCheck) {
+
+ if (moduleReferencesToCheck == null || moduleReferencesToCheck.isEmpty()) {
+ return Collections.EMPTY_LIST;
+ }
+
+ final String tempTableName = "moduleReferencesToCheckTemp"
+ + UUID.randomUUID().toString().replaceAll("-", "");
+
+ createTemporaryTable(tempTableName);
+ insertDataIntoTable(tempTableName, moduleReferencesToCheck);
+
+ return identifyNewModuleReferencesForCmHandle(tempTableName);
+ }
+
+ private void createTemporaryTable(final String tempTableName) {
+ final StringBuilder sqlStringBuilder = new StringBuilder("CREATE TEMPORARY TABLE " + tempTableName + "(");
+ sqlStringBuilder.append(" id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,");
+ sqlStringBuilder.append(" module_name varchar NOT NULL,");
+ sqlStringBuilder.append(" revision varchar NOT NULL");
+ sqlStringBuilder.append(");");
+
+ entityManager.createNativeQuery(sqlStringBuilder.toString()).executeUpdate();
+ }
+
+ private void insertDataIntoTable(final String tempTableName, final Collection<ModuleReference> moduleReferences) {
+ final StringBuilder sqlStringBuilder = new StringBuilder("INSERT INTO " + tempTableName);
+ sqlStringBuilder.append(" (module_name, revision) ");
+ sqlStringBuilder.append(" VALUES ");
+
+ for (final ModuleReference moduleReference : moduleReferences) {
+ sqlStringBuilder.append("('");
+ sqlStringBuilder.append(moduleReference.getModuleName());
+ sqlStringBuilder.append("', '");
+ sqlStringBuilder.append(moduleReference.getRevision());
+ sqlStringBuilder.append("'),");
+ }
+
+ // replace last ',' with ';'
+ sqlStringBuilder.replace(sqlStringBuilder.length() - 1, sqlStringBuilder.length(), ";");
+
+ entityManager.createNativeQuery(sqlStringBuilder.toString()).executeUpdate();
+ }
+
+ private Collection<ModuleReference> identifyNewModuleReferencesForCmHandle(final String tempTableName) {
+ final String sql = String.format(
+ "SELECT %1$s.module_name, %1$s.revision"
+ + " FROM %1$s LEFT JOIN yang_resource"
+ + " ON yang_resource.module_name=%1$s.module_name"
+ + " AND yang_resource.revision=%1$s.revision"
+ + " WHERE yang_resource.module_name IS NULL;", tempTableName);
+
+ final List<Object[]> resultsAsObjects =
+ entityManager.createNativeQuery(sql).getResultList();
+
+ final List<ModuleReference> resultsAsModuleReferences = new ArrayList<>(resultsAsObjects.size());
+ for (final Object[] row : resultsAsObjects) {
+ resultsAsModuleReferences.add(new ModuleReference((String) row[0], (String) row[1]));
+ }
+
+ return resultsAsModuleReferences;
+ }
+}
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java
index 3f5c43decc..895937b60a 100644
--- a/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java
+++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java
@@ -1,7 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2020 Pantheon.tech
- * Modifications Copyright (C) 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.