com.metaeffekt.artifact.analysis.vulnerability.enrichment.warnings.InventoryWarnings Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2021-2024 the original author or authors.
*
* 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.
*/
package com.metaeffekt.artifact.analysis.vulnerability.enrichment.warnings;
import com.metaeffekt.artifact.analysis.utils.StringUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.metaeffekt.core.inventory.processor.model.Artifact;
import org.metaeffekt.core.inventory.processor.model.Inventory;
import org.metaeffekt.core.inventory.processor.model.InventoryInfo;
import org.metaeffekt.core.inventory.processor.model.VulnerabilityMetaData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
public class InventoryWarnings {
private final static Logger LOG = LoggerFactory.getLogger(InventoryWarnings.class);
public final static String CORRELATION_WARNINGS_INVENTORY_INFO_ROW_KEY = "correlation-warnings";
public final static String CORRELATION_WARNINGS_INVENTORY_INFO_COL_WARNINGS_KEY = "Warnings";
private final Inventory inventory;
private final InventoryInfo inventoryInfo;
private final List sourcelessWarnings = new ArrayList<>();
private final List> artifactWarnings = new ArrayList<>();
private final List> vulnerabilityWarnings = new ArrayList<>();
private final static Map CACHE = new WeakHashMap<>();
public static InventoryWarnings fromInventory(Inventory inventory) {
if (CACHE.containsKey(inventory)) {
return CACHE.get(inventory);
}
final InventoryWarnings warnings = new InventoryWarnings(inventory);
CACHE.put(inventory, warnings);
return warnings;
}
public InventoryWarnings(Inventory inventory) {
if (CACHE.containsKey(inventory)) {
LOG.warn("InventoryWarnings already initialized on inventory [{}]. Consider using fromInventory(Inventory) instead.", inventory);
}
this.inventory = inventory;
this.inventoryInfo = inventory.findOrCreateInventoryInfo(CORRELATION_WARNINGS_INVENTORY_INFO_ROW_KEY);
parse();
applyChanges();
}
public boolean hasData() {
return !artifactWarnings.isEmpty() || !vulnerabilityWarnings.isEmpty() || !sourcelessWarnings.isEmpty();
}
private void parse() {
if (StringUtils.isEmpty(inventoryInfo.get(CORRELATION_WARNINGS_INVENTORY_INFO_COL_WARNINGS_KEY))) {
applyChanges();
return;
}
try {
final JSONObject json = new JSONObject(inventoryInfo.get(CORRELATION_WARNINGS_INVENTORY_INFO_COL_WARNINGS_KEY));
if (json.optJSONArray("artifactWarnings") != null) {
final JSONArray artifactWarnings = json.getJSONArray("artifactWarnings");
for (int i = 0; i < artifactWarnings.length(); i++) {
final JSONObject artifactWarning = artifactWarnings.getJSONObject(i);
final InventoryWarningEntry entry = InventoryWarningEntry.fromToJson(artifactWarning, inventory, InventoryWarningEntry.ARTIFACT_FINDABLE);
this.artifactWarnings.add(entry);
}
} else if (json.optJSONObject("artifactWarnings") != null) {
LOG.warn("Artifact warnings are not an array. You cannot parse the legacy format. Please re-run enrichment pipeline for this inventory.");
}
if (json.optJSONArray("vulnerabilityWarnings") != null) {
final JSONArray vulnerabilityWarnings = json.optJSONArray("vulnerabilityWarnings");
for (int i = 0; i < vulnerabilityWarnings.length(); i++) {
final JSONObject vulnerabilityWarning = vulnerabilityWarnings.getJSONObject(i);
final InventoryWarningEntry entry = InventoryWarningEntry.fromToJson(vulnerabilityWarning, inventory, InventoryWarningEntry.VULNERABILITY_META_DATA_FINDABLE);
this.vulnerabilityWarnings.add(entry);
}
} else if (json.optJSONObject("vulnerabilityWarnings") != null) {
LOG.warn("Vulnerability warnings are not an array. You cannot parse the legacy format. Please re-run enrichment pipeline for this inventory.");
}
if (json.optJSONArray("sourcelessWarnings") != null) {
final JSONArray sourcelessWarnings = json.getJSONArray("sourcelessWarnings");
for (int i = 0; i < sourcelessWarnings.length(); i++) {
final String warning = sourcelessWarnings.getString(i);
this.sourcelessWarnings.add(warning);
}
}
} catch (Exception e) {
LOG.error("Failed to parse correlation warnings.", e);
throw new RuntimeException("Failed to parse correlation warnings from inventory: " + e.getMessage() + "\n" + inventoryInfo.get(CORRELATION_WARNINGS_INVENTORY_INFO_COL_WARNINGS_KEY), e);
}
}
private void applyChanges() {
if (!hasData()) {
inventory.getInventoryInfo().remove(inventoryInfo);
inventory.getInventoryInfo().removeIf(i -> i.get(InventoryInfo.Attribute.ID).equals(CORRELATION_WARNINGS_INVENTORY_INFO_ROW_KEY));
return;
} else if (!inventory.getInventoryInfo().contains(inventoryInfo)) {
inventory.getInventoryInfo().add(inventoryInfo);
}
final JSONObject json = new JSONObject();
final JSONArray artifactWarnings = new JSONArray();
for (final InventoryWarningEntry entry : this.artifactWarnings) {
artifactWarnings.put(entry.toJson());
}
json.put("artifactWarnings", artifactWarnings);
final JSONArray vulnerabilityWarnings = new JSONArray();
for (final InventoryWarningEntry entry : this.vulnerabilityWarnings) {
vulnerabilityWarnings.put(entry.toJson());
}
json.put("vulnerabilityWarnings", vulnerabilityWarnings);
json.put("sourcelessWarnings", sourcelessWarnings);
inventoryInfo.set(CORRELATION_WARNINGS_INVENTORY_INFO_COL_WARNINGS_KEY, json.toString());
}
public void addSourcelessWarning(String warning) {
sourcelessWarnings.add(warning);
applyChanges();
}
public void addArtifactWarning(InventoryWarningEntry warning) {
this.artifactWarnings.add(warning);
applyChanges();
}
public void addVulnerabilityWarning(InventoryWarningEntry warning) {
this.vulnerabilityWarnings.add(warning);
applyChanges();
}
public List> getArtifactWarnings() {
return artifactWarnings;
}
public List> getVulnerabilityWarnings() {
return vulnerabilityWarnings;
}
public List getSourcelessWarnings() {
return sourcelessWarnings;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy