diff --git a/java/code/src/com/redhat/rhn/common/db/datasource/xml/oval_queries.xml b/java/code/src/com/redhat/rhn/common/db/datasource/xml/oval_queries.xml index a72e6e98e9ba..29eccb64c4f0 100755 --- a/java/code/src/com/redhat/rhn/common/db/datasource/xml/oval_queries.xml +++ b/java/code/src/com/redhat/rhn/common/db/datasource/xml/oval_queries.xml @@ -45,4 +45,11 @@ AND server_id = :server_id + + + + DELETE FROM suseOVALPlatformVulnerablePackage pvp WHERE pvp.platform_id = (SELECT id FROM suseOVALPlatform plat WHERE plat.cpe = :cpe); + DELETE FROM suseOVALPlatform plat where plat.cpe = :cpe; + + diff --git a/java/code/src/com/suse/oval/OVALCachingFactory.java b/java/code/src/com/suse/oval/OVALCachingFactory.java index 2d99374e93c4..9e395733a600 100644 --- a/java/code/src/com/suse/oval/OVALCachingFactory.java +++ b/java/code/src/com/suse/oval/OVALCachingFactory.java @@ -15,11 +15,14 @@ package com.suse.oval; +import static java.util.stream.Collectors.groupingBy; + import com.redhat.rhn.common.db.datasource.CallableMode; import com.redhat.rhn.common.db.datasource.DataResult; import com.redhat.rhn.common.db.datasource.ModeFactory; import com.redhat.rhn.common.db.datasource.Row; import com.redhat.rhn.common.db.datasource.SelectMode; +import com.redhat.rhn.common.db.datasource.WriteMode; import com.redhat.rhn.common.hibernate.HibernateFactory; import com.suse.oval.manager.OVALLookupHelper; @@ -47,6 +50,11 @@ private OVALCachingFactory() { // Left empty on purpose } + private static void clearOVALMetadataByPlatform(String platformCpe) { + WriteMode mode = ModeFactory.getWriteMode("oval_queries", "clear_oval_metadata_by_platform"); + mode.executeUpdate(Map.of("cpe", platformCpe)); + } + /** * Extracts and save the list of vulnerable packages from {@code rootType} * @@ -57,33 +65,40 @@ public static void savePlatformsVulnerablePackages(OvalRootType rootType) { OVALLookupHelper ovalLookupHelper = new OVALLookupHelper(rootType); - DataResult> batch = new DataResult<>(new ArrayList<>(1000)); - + List productVulnerablePackages = new ArrayList<>(); for (DefinitionType definition : rootType.getDefinitions()) { VulnerablePackagesExtractor vulnerablePackagesExtractor = VulnerablePackagesExtractors.create(definition, rootType.getOsFamily(), ovalLookupHelper); - List extractionResult = vulnerablePackagesExtractor.extract(); - for (ProductVulnerablePackages productVulnerablePackages : extractionResult) { - for (String cve : productVulnerablePackages.getCves()) { - for (VulnerablePackage vulnerablePackage : productVulnerablePackages.getVulnerablePackages()) { - Map params = new HashMap<>(); - params.put("product_name", productVulnerablePackages.getProductCpe()); - params.put("cve_name", cve); - params.put("package_name", vulnerablePackage.getName()); - params.put("fix_version", vulnerablePackage.getFixVersion().orElse(null)); - - batch.add(params); - - if (batch.size() % 1000 == 0) { - mode.getQuery().executeBatchUpdates(batch); - batch.clear(); - commitTransaction(); - - Session session = getSession(); - if (!inTransaction()) { - session.beginTransaction(); - } + productVulnerablePackages.addAll(vulnerablePackagesExtractor.extract()); + } + + // Clear previous OVAL metadata + productVulnerablePackages.stream() + .collect(groupingBy(ProductVulnerablePackages::getProductCpe)) + .keySet().forEach(OVALCachingFactory::clearOVALMetadataByPlatform); + + // Write OVAL metadata in batches + DataResult> batch = new DataResult<>(new ArrayList<>(1000)); + for (ProductVulnerablePackages pvp : productVulnerablePackages) { + for (String cve : pvp.getCves()) { + for (VulnerablePackage vulnerablePackage : pvp.getVulnerablePackages()) { + Map params = new HashMap<>(); + params.put("product_name", pvp.getProductCpe()); + params.put("cve_name", cve); + params.put("package_name", vulnerablePackage.getName()); + params.put("fix_version", vulnerablePackage.getFixVersion().orElse(null)); + + batch.add(params); + + if (batch.size() % 1000 == 0) { + mode.getQuery().executeBatchUpdates(batch); + batch.clear(); + commitTransaction(); + + Session session = getSession(); + if (!inTransaction()) { + session.beginTransaction(); } } }