Performance Improvement: Retreive Yang Resources 56/130356/7
authorToineSiebelink <toine.siebelink@est.tech>
Thu, 18 Aug 2022 14:03:16 +0000 (15:03 +0100)
committerToineSiebelink <toine.siebelink@est.tech>
Mon, 22 Aug 2022 12:12:49 +0000 (13:12 +0100)
Native query to more efficiently get all yangResourceIds
Combined Hibernate Fragment Repository with Native impl.

Issue-ID: CPS-1206
Issue-ID: CPS-1126
Signed-off-by: ToineSiebelink <toine.siebelink@est.tech>
Change-Id: I93fbd5347dd8f9fc48d44e69e47e8aed2d7ac030

cps-ri/src/main/java/org/onap/cps/spi/impl/CpsModulePersistenceServiceImpl.java
cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceNativeRepository.java [new file with mode: 0644]
cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceNativeRepositoryImpl.java [new file with mode: 0644]
cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceRepository.java

index 647d6cd..e9e945a 100755 (executable)
@@ -30,7 +30,6 @@ import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
@@ -40,13 +39,14 @@ import java.util.Set;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 import javax.transaction.Transactional;
-import lombok.AllArgsConstructor;
+import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.codec.digest.DigestUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.hibernate.exception.ConstraintViolationException;
 import org.onap.cps.spi.CpsAdminPersistenceService;
 import org.onap.cps.spi.CpsModulePersistenceService;
+import org.onap.cps.spi.entities.DataspaceEntity;
 import org.onap.cps.spi.entities.SchemaSetEntity;
 import org.onap.cps.spi.entities.YangResourceEntity;
 import org.onap.cps.spi.entities.YangResourceModuleReference;
@@ -72,7 +72,7 @@ import org.springframework.stereotype.Component;
 
 @Slf4j
 @Component
-@AllArgsConstructor
+@RequiredArgsConstructor
 public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceService {
 
     private static final String YANG_RESOURCE_CHECKSUM_CONSTRAINT_NAME = "yang_resource_checksum_key";
@@ -80,15 +80,15 @@ 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);
 
-    private YangResourceRepository yangResourceRepository;
+    private final YangResourceRepository yangResourceRepository;
 
-    private SchemaSetRepository schemaSetRepository;
+    private final SchemaSetRepository schemaSetRepository;
 
-    private DataspaceRepository dataspaceRepository;
+    private final DataspaceRepository dataspaceRepository;
 
-    private CpsAdminPersistenceService cpsAdminPersistenceService;
+    private final CpsAdminPersistenceService cpsAdminPersistenceService;
 
-    private ModuleReferenceRepository moduleReferenceRepository;
+    private final ModuleReferenceRepository moduleReferenceRepository;
 
     @Override
     public Map<String, String> getYangSchemaResources(final String dataspaceName, final String schemaSetName) {
@@ -164,13 +164,11 @@ public class CpsModulePersistenceServiceImpl implements CpsModulePersistenceServ
                                           final Map<String, String> newModuleNameToContentMap,
                                           final Collection<ModuleReference> moduleReferences) {
         storeSchemaSet(dataspaceName, schemaSetName, newModuleNameToContentMap);
-        final var dataspaceEntity = dataspaceRepository.getByName(dataspaceName);
-        final var schemaSetEntity =
+        final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName);
+        final SchemaSetEntity schemaSetEntity =
                 schemaSetRepository.getByDataspaceAndName(dataspaceEntity, schemaSetName);
-        final List<Long> listOfYangResourceIds = new ArrayList<>();
-        moduleReferences.forEach(moduleReference ->
-                listOfYangResourceIds.add(yangResourceRepository.getIdByModuleNameAndRevision(
-                        moduleReference.getModuleName(), moduleReference.getRevision())));
+        final List<Long> listOfYangResourceIds =
+            yangResourceRepository.getResourceIdsByModuleReferences(moduleReferences);
         yangResourceRepository.insertSchemaSetIdYangResourceId(schemaSetEntity.getId(), listOfYangResourceIds);
     }
 
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceNativeRepository.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceNativeRepository.java
new file mode 100644 (file)
index 0000000..335c971
--- /dev/null
@@ -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.repository;
+
+import java.util.Collection;
+import java.util.List;
+import org.onap.cps.spi.model.ModuleReference;
+
+public interface YangResourceNativeRepository {
+
+    List<Long> getResourceIdsByModuleReferences(Collection<ModuleReference> moduleReferences);
+
+}
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceNativeRepositoryImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/YangResourceNativeRepositoryImpl.java
new file mode 100644 (file)
index 0000000..e21fecb
--- /dev/null
@@ -0,0 +1,58 @@
+/*-
+ * ============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 java.util.List;
+import java.util.StringJoiner;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.Query;
+import org.hibernate.type.StandardBasicTypes;
+import org.onap.cps.spi.model.ModuleReference;
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
+
+@Repository
+public class YangResourceNativeRepositoryImpl implements YangResourceNativeRepository {
+
+    @PersistenceContext
+    private EntityManager entityManager;
+
+    @Override
+    @Transactional
+    public List<Long> getResourceIdsByModuleReferences(final Collection<ModuleReference> moduleReferences) {
+        final Query query = entityManager.createNativeQuery(getCombinedSelectSqlQuery(moduleReferences))
+            .unwrap(org.hibernate.query.NativeQuery.class)
+            .addScalar("id", StandardBasicTypes.LONG);
+        return query.getResultList();
+    }
+
+    private String getCombinedSelectSqlQuery(final Collection<ModuleReference> moduleReferences) {
+        final StringJoiner sqlQueryJoiner = new StringJoiner(" UNION ALL ");
+        moduleReferences.stream().forEach(moduleReference -> {
+            sqlQueryJoiner.add(String.format("SELECT id FROM yang_resource WHERE module_name='%s' and revision='%s'",
+                moduleReference.getModuleName(),
+                moduleReference.getRevision()));
+        });
+        return sqlQueryJoiner.toString();
+    }
+}
index 98306d8..6ca4fff 100644 (file)
@@ -34,7 +34,7 @@ import org.springframework.stereotype.Repository;
 
 @Repository
 public interface YangResourceRepository extends JpaRepository<YangResourceEntity, Long>,
-        SchemaSetYangResourceRepository {
+    YangResourceNativeRepository, SchemaSetYangResourceRepository {
 
     List<YangResourceEntity> findAllByChecksumIn(@NotNull Set<String> checksum);
 
@@ -91,10 +91,6 @@ public interface YangResourceRepository extends JpaRepository<YangResourceEntity
     Set<YangResourceModuleReference> findAllModuleReferencesByDataspaceAndModuleNames(
             @Param("dataspaceName") String dataspaceName, @Param("moduleNames") Collection<String> moduleNames);
 
-
-    @Query(value = "SELECT id FROM yang_resource WHERE module_name=:name and revision=:revision", nativeQuery = true)
-    Long getIdByModuleNameAndRevision(@Param("name") String moduleName, @Param("revision") String revision);
-
     @Modifying
     @Query(value = "DELETE FROM yang_resource yr WHERE NOT EXISTS "
         + "(SELECT 1 FROM schema_set_yang_resources ssyr WHERE ssyr.yang_resource_id = yr.id)", nativeQuery = true)