Skip to content

Commit

Permalink
fix integrity meta initializer (#391)
Browse files Browse the repository at this point in the history
Signed-off-by: vithikashukla <[email protected]>
Co-authored-by: vithikashukla <[email protected]>
  • Loading branch information
VithikaS and vithikashukla authored Oct 24, 2023
1 parent 0d4c70d commit b362975
Show file tree
Hide file tree
Showing 20 changed files with 329 additions and 277 deletions.
5 changes: 3 additions & 2 deletions src/main/java/org/dependencytrack/common/ConfigKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public enum ConfigKey implements Config.Key {
CRON_EXPRESSION_FOR_DEFECT_DOJO_SYNC("task.cron.defectdojo.sync", "0 2 * * *"),
CRON_EXPRESSION_FOR_KENNA_SYNC("task.cron.kenna.sync", "0 2 * * *"),
CRON_EXPRESSION_FOR_WORKFLOW_STATE_CLEANUP_TASK("task.cron.workflow.state.cleanup", "*/15 * * * *"),
CRON_EXPRESSION_FOR_INTEGRITY_META_INITIALIZER_TASK("task.cron.integrityInitializer", "0 */12 * * *"),
TASK_SCHEDULER_INITIAL_DELAY("task.scheduler.initial.delay", "180000"),
TASK_SCHEDULER_POLLING_INTERVAL("task.scheduler.polling.interval", "60000"),
TASK_PORTFOLIO_LOCK_AT_MOST_FOR("task.metrics.portfolio.lockAtMostForInMillis", "900000"),
Expand All @@ -72,8 +73,8 @@ public enum ConfigKey implements Config.Key {
WORKFLOW_STEP_TIMEOUT_DURATION("workflow.step.timeout.duration", "PT1H"),
TMP_DELAY_BOM_PROCESSED_NOTIFICATION("tmp.delay.bom.processed.notification", "false"),
CEL_POLICY_ENGINE_ENABLED("cel.policy.engine.enabled", "false"),
TASK_INTEGRITY_META_INITIALIZER_LOCK_AT_MOST_FOR("task.integrity.integrityMetaInitializer.lockAtMostForInMillis", String.valueOf(Duration.ofMinutes(15).toMillis())),
TASK_INTEGRITY_META_INITIALIZER_LOCK_AT_LEAST_FOR("task.integrity.integrityMetaInitializer.lockAtLeastForInMillis", String.valueOf(Duration.ofMinutes(5).toMillis())),
INTEGRITY_META_INITIALIZER_LOCK_AT_MOST_FOR("integrityMetaInitializer.lockAtMostForInMillis", String.valueOf(Duration.ofMinutes(15).toMillis())),
INTEGRITY_META_INITIALIZER_LOCK_AT_LEAST_FOR("integrityMetaInitializer.lockAtLeastForInMillis", String.valueOf(Duration.ofMinutes(5).toMillis())),
INTEGRITY_INITIALIZER_ENABLED("integrity.initializer.enabled", "false"),
INTEGRITY_CHECK_ENABLED("integrity.check.enabled", "false");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.dependencytrack.tasks.EpssMirrorTask;
import org.dependencytrack.tasks.FortifySscUploadTask;
import org.dependencytrack.tasks.GitHubAdvisoryMirrorTask;
import org.dependencytrack.tasks.IntegrityMetaInitializerTask;
import org.dependencytrack.tasks.InternalComponentIdentificationTask;
import org.dependencytrack.tasks.KennaSecurityUploadTask;
import org.dependencytrack.tasks.LdapSyncTaskWrapper;
Expand Down Expand Up @@ -98,6 +99,7 @@ public void contextInitialized(final ServletContextEvent event) {
EVENT_SERVICE.subscribe(ComponentPolicyEvaluationEvent.class, PolicyEvaluationTask.class);
EVENT_SERVICE.subscribe(ProjectPolicyEvaluationEvent.class, PolicyEvaluationTask.class);
EVENT_SERVICE.subscribe(WorkflowStateCleanupEvent.class, WorkflowStateCleanupTask.class);
EVENT_SERVICE.subscribe(IntegrityMetaInitializerEvent.class, IntegrityMetaInitializerTask.class);

TaskScheduler.getInstance();
}
Expand Down Expand Up @@ -132,6 +134,7 @@ public void contextDestroyed(final ServletContextEvent event) {
EVENT_SERVICE.unsubscribe(EpssMirrorTask.class);
EVENT_SERVICE.unsubscribe(PolicyEvaluationTask.class);
EVENT_SERVICE.unsubscribe(WorkflowStateCleanupTask.class);
EVENT_SERVICE.unsubscribe(IntegrityMetaInitializerTask.class);
EVENT_SERVICE.shutdown(DRAIN_TIMEOUT_DURATION);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package org.dependencytrack.event;

import alpine.event.framework.Event;

public class IntegrityMetaInitializerEvent implements Event {
}
48 changes: 48 additions & 0 deletions src/main/java/org/dependencytrack/event/PurlMigrator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.dependencytrack.event;

import alpine.Config;
import alpine.common.logging.Logger;
import net.javacrumbs.shedlock.core.LockingTaskExecutor;
import org.dependencytrack.common.ConfigKey;
import org.dependencytrack.persistence.QueryManager;
import org.dependencytrack.util.LockProvider;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import static org.dependencytrack.tasks.LockName.INTEGRITY_META_INITIALIZER_LOCK;

public class PurlMigrator implements ServletContextListener {

private static final Logger LOGGER = Logger.getLogger(PurlMigrator.class);
private final boolean integrityInitializerEnabled;

public PurlMigrator() {
this(Config.getInstance().getPropertyAsBoolean(ConfigKey.INTEGRITY_INITIALIZER_ENABLED));
}

PurlMigrator(final boolean integrityInitializerEnabled) {
this.integrityInitializerEnabled = integrityInitializerEnabled;
}


@Override
public void contextInitialized(final ServletContextEvent event) {
if (integrityInitializerEnabled) {
try {
LockProvider.executeWithLock(INTEGRITY_META_INITIALIZER_LOCK, (LockingTaskExecutor.Task) () -> process());
} catch (Throwable e) {
throw new RuntimeException("An unexpected error occurred while running Initializer for integrity meta", e);
}
} else {
LOGGER.info("Component integrity initializer is disabled.");
}
}

private void process() {
LOGGER.info("Initializing integrity meta component sync");
try (final var qm = new QueryManager()) {
qm.synchronizeIntegrityMetaComponent();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ private RepositoryMetaComponent createRepositoryMetaResult(Record<String, Analys
private IntegrityMetaComponent synchronizeIntegrityMetaResult(final Record<String, AnalysisResult> incomingAnalysisResultRecord, QueryManager queryManager, PackageURL purl) {
final AnalysisResult result = incomingAnalysisResultRecord.value();
IntegrityMetaComponent persistentIntegrityMetaComponent = queryManager.getIntegrityMetaComponent(purl.toString());
if (persistentIntegrityMetaComponent != null && persistentIntegrityMetaComponent.getStatus().equals(FetchStatus.PROCESSED)) {
if (persistentIntegrityMetaComponent != null && persistentIntegrityMetaComponent.getStatus() != null && persistentIntegrityMetaComponent.getStatus().equals(FetchStatus.PROCESSED)) {
LOGGER.warn("""
Received hash information for %s that has already been processed; Discarding
""".formatted(purl));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@
import alpine.resources.AlpineRequest;
import com.github.packageurl.MalformedPackageURLException;
import com.github.packageurl.PackageURL;
import org.dependencytrack.event.IntegrityMetaInitializer;
import org.dependencytrack.model.Component;
import org.dependencytrack.model.ComponentIdentity;
import org.dependencytrack.model.ConfigPropertyConstants;
import org.dependencytrack.model.Project;
import org.dependencytrack.model.RepositoryMetaComponent;
import org.dependencytrack.model.RepositoryType;
import org.dependencytrack.resources.v1.vo.DependencyGraphResponse;
import org.dependencytrack.tasks.IntegrityMetaInitializerTask;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;
Expand Down Expand Up @@ -240,14 +240,14 @@ public PaginatedResult getComponentByHash(String hash) {
* @param purl the purl of the component to retrieve
* @return associated ComponentProjection
*/
public IntegrityMetaInitializer.ComponentProjection getComponentByPurl(String purl) {
public IntegrityMetaInitializerTask.ComponentProjection getComponentByPurl(String purl) {
if (purl == null) {
return null;
}
final Query<Component> query = pm.newQuery(Component.class, "purl == :purl");
query.setParameters(purl);
query.setResult("DISTINCT purlCoordinates, internal");
return query.executeResultUnique(IntegrityMetaInitializer.ComponentProjection.class);
return query.executeResultUnique(IntegrityMetaInitializerTask.ComponentProjection.class);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ public synchronized void synchronizeIntegrityMetaComponent() {
SELECT DISTINCT "PURL"
FROM "COMPONENT"
WHERE "PURL" IS NOT NULL
ON CONFLICT DO NOTHING
""";
Connection connection = null;
PreparedStatement preparedStatement = null;
Expand Down Expand Up @@ -147,13 +148,13 @@ public long getIntegrityMetaComponentCount() {
*
* @return the list of purls
*/
public List<String> fetchNextPurlsPage(long offset) {
public List<IntegrityMetaComponent> fetchNextPurlsPage(long offset) {
try (final Query<IntegrityMetaComponent> query =
pm.newQuery(IntegrityMetaComponent.class, "status == null || (status == :inProgress && lastFetch < :latest)")) {
query.setParameters(FetchStatus.IN_PROGRESS, Date.from(Instant.now().minus(1, ChronoUnit.HOURS)));
query.setRange(offset, offset + 5000);
query.setResult("purl");
return List.copyOf(query.executeResultList(String.class));
query.setResult("id, purl");
return List.copyOf(query.executeResultList(IntegrityMetaComponent.class));
} catch (Exception e) {
LOGGER.error("Error in getting purls from integrity meta.", e);
throw new RuntimeException(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
import org.apache.commons.lang3.ClassUtils;
import org.datanucleus.PropertyNames;
import org.datanucleus.api.jdo.JDOQuery;
import org.dependencytrack.event.IntegrityMetaInitializer;
import org.dependencytrack.model.AffectedVersionAttribution;
import org.dependencytrack.model.Analysis;
import org.dependencytrack.model.AnalysisComment;
Expand Down Expand Up @@ -87,6 +86,7 @@
import org.dependencytrack.notification.NotificationScope;
import org.dependencytrack.notification.publisher.PublisherClass;
import org.dependencytrack.resources.v1.vo.DependencyGraphResponse;
import org.dependencytrack.tasks.IntegrityMetaInitializerTask;
import org.hyades.proto.vulnanalysis.v1.ScanResult;
import org.hyades.proto.vulnanalysis.v1.ScanStatus;
import org.hyades.proto.vulnanalysis.v1.ScannerResult;
Expand Down Expand Up @@ -597,7 +597,7 @@ public PaginatedResult getComponentByHash(String hash) {
return getComponentQueryManager().getComponentByHash(hash);
}

public IntegrityMetaInitializer.ComponentProjection getComponentByPurl(String purl) {
public IntegrityMetaInitializerTask.ComponentProjection getComponentByPurl(String purl) {
return getComponentQueryManager().getComponentByPurl(purl);
}

Expand Down Expand Up @@ -1823,7 +1823,7 @@ public long getIntegrityMetaComponentCount() {
return getIntegrityMetaQueryManager().getIntegrityMetaComponentCount();
}

public List<String> fetchNextPurlsPage(long offset) {
public List<IntegrityMetaComponent> fetchNextPurlsPage(long offset) {
return getIntegrityMetaQueryManager().fetchNextPurlsPage(offset);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package org.dependencytrack.tasks;

import alpine.Config;
import alpine.common.logging.Logger;
import alpine.event.framework.Event;
import alpine.event.framework.Subscriber;
import org.dependencytrack.common.ConfigKey;
import org.dependencytrack.event.ComponentRepositoryMetaAnalysisEvent;
import org.dependencytrack.event.IntegrityMetaInitializerEvent;
import org.dependencytrack.event.kafka.KafkaEventDispatcher;
import org.dependencytrack.model.IntegrityMetaComponent;
import org.dependencytrack.persistence.QueryManager;

import java.util.List;

import static org.hyades.proto.repometaanalysis.v1.FetchMeta.FETCH_META_INTEGRITY_DATA;

public class IntegrityMetaInitializerTask implements Subscriber {

private static final Logger LOGGER = Logger.getLogger(IntegrityMetaInitializerTask.class);

private final KafkaEventDispatcher kafkaEventDispatcher = new KafkaEventDispatcher();

public void inform(final Event e) {
if (e instanceof IntegrityMetaInitializerEvent) {
if (!Config.getInstance().getPropertyAsBoolean(ConfigKey.INTEGRITY_INITIALIZER_ENABLED)) {
LOGGER.debug("Integrity initializer is disabled");
return;
}
try (final var qm = new QueryManager()) {
batchProcessPurls(qm);
}
}
}

private void batchProcessPurls(QueryManager qm) {
long offset = 0;
List<IntegrityMetaComponent> integrityMetaPurls = qm.fetchNextPurlsPage(offset);
while (!integrityMetaPurls.isEmpty()) {
dispatchPurls(qm, integrityMetaPurls);
qm.batchUpdateIntegrityMetaComponent(integrityMetaPurls);
offset += integrityMetaPurls.size();
integrityMetaPurls = qm.fetchNextPurlsPage(offset);
}
}

private void dispatchPurls(QueryManager qm, List<IntegrityMetaComponent> integrityMetaPurls) {
for (final var integrityMetaPurl : integrityMetaPurls) {
IntegrityMetaInitializerTask.ComponentProjection componentProjection = qm.getComponentByPurl(integrityMetaPurl.getPurl());
LOGGER.debug("Dispatching purl for integrity metadata: " + integrityMetaPurl.getPurl());
//Initializer will not trigger Integrity Check on component so component uuid is not required
kafkaEventDispatcher.dispatchAsync(new ComponentRepositoryMetaAnalysisEvent(null, integrityMetaPurl.getPurl(), componentProjection.internal(), FETCH_META_INTEGRITY_DATA));
}
}

public record ComponentProjection(String purlCoordinates, Boolean internal) {
}
}
2 changes: 1 addition & 1 deletion src/main/java/org/dependencytrack/tasks/LockName.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ public enum LockName {
WORKFLOW_STEP_CLEANUP_TASK_LOCK,
PORTFOLIO_REPO_META_ANALYSIS_TASK_LOCK,
PORTFOLIO_VULN_ANALYSIS_TASK_LOCK,
INTEGRITY_META_INITIALIZER_TASK_LOCK
INTEGRITY_META_INITIALIZER_LOCK
}
5 changes: 4 additions & 1 deletion src/main/java/org/dependencytrack/tasks/TaskScheduler.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.dependencytrack.event.DefectDojoUploadEventAbstract;
import org.dependencytrack.event.FortifySscUploadEventAbstract;
import org.dependencytrack.event.GitHubAdvisoryMirrorEvent;
import org.dependencytrack.event.IntegrityMetaInitializerEvent;
import org.dependencytrack.event.InternalComponentIdentificationEvent;
import org.dependencytrack.event.KennaSecurityUploadEventAbstract;
import org.dependencytrack.event.NistMirrorEvent;
Expand All @@ -51,6 +52,7 @@

import static org.dependencytrack.common.ConfigKey.CRON_EXPRESSION_FOR_COMPONENT_IDENTIFICATION_TASK;
import static org.dependencytrack.common.ConfigKey.CRON_EXPRESSION_FOR_GITHUB_MIRRORING_TASK;
import static org.dependencytrack.common.ConfigKey.CRON_EXPRESSION_FOR_INTEGRITY_META_INITIALIZER_TASK;
import static org.dependencytrack.common.ConfigKey.CRON_EXPRESSION_FOR_LDAP_SYNC_TASK;
import static org.dependencytrack.common.ConfigKey.CRON_EXPRESSION_FOR_NIST_MIRRORING_TASK;
import static org.dependencytrack.common.ConfigKey.CRON_EXPRESSION_FOR_OSV_MIRRORING_TASK;
Expand Down Expand Up @@ -94,7 +96,8 @@ private TaskScheduler() {
Map.entry(new PortfolioVulnerabilityAnalysisEvent(), Schedule.create(configInstance.getProperty(CRON_EXPRESSION_FOR_VULN_ANALYSIS_TASK))),
Map.entry(new VulnerabilityScanCleanupEvent(), Schedule.create(configInstance.getProperty(CRON_EXPRESSION_FOR_VULN_SCAN_CLEANUP_TASK))),
Map.entry(new PortfolioRepositoryMetaAnalysisEvent(), Schedule.create(configInstance.getProperty(CRON_EXPRESSION_FOR_REPO_META_ANALYSIS_TASK))),
Map.entry(new WorkflowStateCleanupEvent(), Schedule.create(configInstance.getProperty(CRON_EXPRESSION_FOR_WORKFLOW_STATE_CLEANUP_TASK)))
Map.entry(new WorkflowStateCleanupEvent(), Schedule.create(configInstance.getProperty(CRON_EXPRESSION_FOR_WORKFLOW_STATE_CLEANUP_TASK))),
Map.entry(new IntegrityMetaInitializerEvent(), Schedule.create(configInstance.getProperty(CRON_EXPRESSION_FOR_INTEGRITY_META_INITIALIZER_TASK)))
);

if (isTaskEnabled(FORTIFY_SSC_ENABLED)) {
Expand Down
Loading

0 comments on commit b362975

Please sign in to comment.