Skip to content

Commit

Permalink
Merge pull request #840 from DependencyTrack/merge-housekeeping-tasks
Browse files Browse the repository at this point in the history
Introduce maintenance tasks; Unify cron and lock duration configs for tasks
  • Loading branch information
nscuro authored Sep 9, 2024
2 parents 40293f8 + 9bfe302 commit eca7ab7
Show file tree
Hide file tree
Showing 53 changed files with 2,229 additions and 872 deletions.
42 changes: 0 additions & 42 deletions src/main/java/org/dependencytrack/common/ConfigKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@

import alpine.Config;

import java.time.Duration;

public enum ConfigKey implements Config.Key {

ALPINE_WORKER_POOL_DRAIN_TIMEOUT_DURATION("alpine.worker.pool.drain.timeout.duration", "PT30S"),
Expand All @@ -38,49 +36,9 @@ public enum ConfigKey implements Config.Key {
KAFKA_TRUST_STORE_PASSWORD("kafka.truststore.password", ""),
KAFKA_TRUST_STORE_PATH("kafka.truststore.path", ""),

CRON_EXPRESSION_FOR_PORTFOLIO_METRICS_TASK("task.cron.metrics.portfolio", "10 * * * *"),
CRON_EXPRESSION_FOR_VULNERABILITY_METRICS_TASK("task.cron.metrics.vulnerability", "40 * * * *"),
CRON_EXPRESSION_FOR_COMPONENT_IDENTIFICATION_TASK("task.cron.componentIdentification", "25 */6 * * *"),
CRON_EXPRESSION_FOR_EPSS_MIRRORING_TASK("task.cron.mirror.epss", "0 1 * * *"),
CRON_EXPRESSION_FOR_GITHUB_MIRRORING_TASK("task.cron.mirror.github", "0 2 * * *"),
CRON_EXPRESSION_FOR_OSV_MIRRORING_TASK("task.cron.mirror.osv", "0 3 * * *"),
CRON_EXPRESSION_FOR_NIST_MIRRORING_TASK("task.cron.mirror.nist", "0 4 * * *"),
CRON_EXPRESSION_FOR_VULNERABILITY_POLICY_BUNDLE_FETCH_TASK("task.cron.vulnerability.policy.bundle.fetch", "*/5 * * * *"),
CRON_EXPRESSION_FOR_LDAP_SYNC_TASK("task.cron.ldapSync", "0 */6 * * *"),
CRON_EXPRESSION_FOR_REPO_META_ANALYSIS_TASK("task.cron.repoMetaAnalysis", "0 1 * * *"),
CRON_EXPRESSION_FOR_VULN_ANALYSIS_TASK("task.cron.vulnAnalysis", "0 6 * * *"),
CRON_EXPRESSION_FOR_VULN_SCAN_CLEANUP_TASK("task.cron.vulnScanCleanUp", "5 8 * * 4"),
CRON_EXPRESSION_FOR_FORTIFY_SSC_SYNC("task.cron.fortify.ssc.sync", "0 2 * * *"),
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"),
TASK_PORTFOLIO_LOCK_AT_LEAST_FOR("task.metrics.portfolio.lockAtLeastForInMillis", "90000"),
TASK_METRICS_VULNERABILITY_LOCK_AT_MOST_FOR("task.metrics.vulnerability.lockAtMostForInMillis", "900000"),
TASK_METRICS_VULNERABILITY_LOCK_AT_LEAST_FOR("task.metrics.vulnerability.lockAtLeastForInMillis", "90000"),
TASK_MIRROR_EPSS_LOCK_AT_MOST_FOR("task.mirror.epss.lockAtMostForInMillis", "900000"),
TASK_MIRROR_EPSS_LOCK_AT_LEAST_FOR("task.mirror.epss.lockAtLeastForInMillis", "90000"),
TASK_COMPONENT_IDENTIFICATION_LOCK_AT_MOST_FOR("task.componentIdentification.lockAtMostForInMillis", "900000"),
TASK_COMPONENT_IDENTIFICATION_LOCK_AT_LEAST_FOR("task.componentIdentification.lockAtLeastForInMillis", "90000"),
TASK_LDAP_SYNC_LOCK_AT_MOST_FOR("task.ldapSync.lockAtMostForInMillis", "900000"),
TASK_LDAP_SYNC_LOCK_AT_LEAST_FOR("task.ldapSync.lockAtLeastForInMillis", "90000"),
TASK_WORKFLOW_STEP_CLEANUP_LOCK_AT_MOST_FOR("task.workflow.state.cleanup.lockAtMostForInMillis", String.valueOf(Duration.ofMinutes(15).toMillis())),
TASK_WORKFLOW_STEP_CLEANUP_LOCK_AT_LEAST_FOR("task.workflow.state.cleanup.lockAtLeastForInMillis", String.valueOf(Duration.ofMinutes(15).toMillis())),
TASK_PORTFOLIO_REPO_META_ANALYSIS_LOCK_AT_MOST_FOR("task.portfolio.repoMetaAnalysis.lockAtMostForInMillis", String.valueOf(Duration.ofMinutes(15).toMillis())),
TASK_PORTFOLIO_REPO_META_ANALYSIS_LOCK_AT_LEAST_FOR("task.portfolio.repoMetaAnalysis.lockAtLeastForInMillis", String.valueOf(Duration.ofMinutes(5).toMillis())),
TASK_PORTFOLIO_VULN_ANALYSIS_LOCK_AT_MOST_FOR("task.portfolio.vulnAnalysis.lockAtMostForInMillis", String.valueOf(Duration.ofMinutes(15).toMillis())),
TASK_PORTFOLIO_VULN_ANALYSIS_LOCK_AT_LEAST_FOR("task.portfolio.vulnAnalysis.lockAtLeastForInMillis", String.valueOf(Duration.ofMinutes(5).toMillis())),
TASK_VULNERABILITY_POLICY_BUNDLE_FETCH_LOCK_AT_MOST_FOR("task.vulnerability.policy.bundle.fetch.lockAtMostForInMillis", String.valueOf(Duration.ofMinutes(5).toMillis())),
TASK_VULNERABILITY_POLICY_BUNDLE_FETCH_LOCK_AT_LEAST_FOR("task.vulnerability.policy.bundle.fetch.lockAtLeastForInMillis", String.valueOf(Duration.ofSeconds(5).toMillis())),
BOM_UPLOAD_PROCESSING_TRX_FLUSH_THRESHOLD("bom.upload.processing.trx.flush.threshold", "10000"),
WORKFLOW_RETENTION_DURATION("workflow.retention.duration", "P3D"),
WORKFLOW_STEP_TIMEOUT_DURATION("workflow.step.timeout.duration", "PT1H"),
TMP_DELAY_BOM_PROCESSED_NOTIFICATION("tmp.delay.bom.processed.notification", "false"),
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"),
VULNERABILITY_POLICY_ANALYSIS_ENABLED("vulnerability.policy.analysis.enabled", false),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,16 @@
import alpine.common.logging.Logger;
import alpine.event.LdapSyncEvent;
import alpine.event.framework.EventService;
import alpine.event.framework.SingleThreadedEventService;
import jakarta.servlet.ServletContextEvent;
import jakarta.servlet.ServletContextListener;
import org.dependencytrack.common.ConfigKey;
import org.dependencytrack.event.maintenance.ComponentMetadataMaintenanceEvent;
import org.dependencytrack.event.maintenance.MetricsMaintenanceEvent;
import org.dependencytrack.event.maintenance.TagMaintenanceEvent;
import org.dependencytrack.event.maintenance.VulnerabilityDatabaseMaintenanceEvent;
import org.dependencytrack.event.maintenance.VulnerabilityScanMaintenanceEvent;
import org.dependencytrack.event.maintenance.WorkflowMaintenanceEvent;
import org.dependencytrack.tasks.BomUploadProcessingTask;
import org.dependencytrack.tasks.CallbackTask;
import org.dependencytrack.tasks.CloneProjectTask;
Expand All @@ -36,21 +45,23 @@
import org.dependencytrack.tasks.KennaSecurityUploadTask;
import org.dependencytrack.tasks.LdapSyncTaskWrapper;
import org.dependencytrack.tasks.NistMirrorTask;
import org.dependencytrack.tasks.OsvDownloadTask;
import org.dependencytrack.tasks.OsvMirrorTask;
import org.dependencytrack.tasks.PolicyEvaluationTask;
import org.dependencytrack.tasks.RepositoryMetaAnalyzerTask;
import org.dependencytrack.tasks.RepositoryMetaAnalysisTask;
import org.dependencytrack.tasks.TaskScheduler;
import org.dependencytrack.tasks.VexUploadProcessingTask;
import org.dependencytrack.tasks.VulnerabilityAnalysisTask;
import org.dependencytrack.tasks.vulnerabilitypolicy.VulnerabilityPolicyFetchTask;
import org.dependencytrack.tasks.VulnerabilityScanCleanupTask;
import org.dependencytrack.tasks.WorkflowStateCleanupTask;
import org.dependencytrack.tasks.maintenance.ComponentMetadataMaintenanceTask;
import org.dependencytrack.tasks.maintenance.MetricsMaintenanceTask;
import org.dependencytrack.tasks.maintenance.TagMaintenanceTask;
import org.dependencytrack.tasks.maintenance.VulnerabilityDatabaseMaintenanceTask;
import org.dependencytrack.tasks.maintenance.VulnerabilityScanMaintenanceTask;
import org.dependencytrack.tasks.maintenance.WorkflowMaintenanceTask;
import org.dependencytrack.tasks.metrics.PortfolioMetricsUpdateTask;
import org.dependencytrack.tasks.metrics.ProjectMetricsUpdateTask;
import org.dependencytrack.tasks.metrics.VulnerabilityMetricsUpdateTask;
import org.dependencytrack.tasks.vulnerabilitypolicy.VulnerabilityPolicyFetchTask;

import jakarta.servlet.ServletContextEvent;
import jakarta.servlet.ServletContextListener;
import java.time.Duration;

/**
Expand All @@ -65,6 +76,10 @@ public class EventSubsystemInitializer implements ServletContextListener {

// Starts the EventService
private static final EventService EVENT_SERVICE = EventService.getInstance();

// Starts the SingleThreadedEventService
private static final SingleThreadedEventService EVENT_SERVICE_ST = SingleThreadedEventService.getInstance();

private static final Duration DRAIN_TIMEOUT_DURATION =
Duration.parse(Config.getInstance().getProperty(ConfigKey.ALPINE_WORKER_POOL_DRAIN_TIMEOUT_DURATION));

Expand All @@ -79,11 +94,11 @@ public void contextInitialized(final ServletContextEvent event) {
EVENT_SERVICE.subscribe(VexUploadEvent.class, VexUploadProcessingTask.class);
EVENT_SERVICE.subscribe(LdapSyncEvent.class, LdapSyncTaskWrapper.class);
EVENT_SERVICE.subscribe(GitHubAdvisoryMirrorEvent.class, GitHubAdvisoryMirrorTask.class);
EVENT_SERVICE.subscribe(OsvMirrorEvent.class, OsvDownloadTask.class);
EVENT_SERVICE.subscribe(OsvMirrorEvent.class, OsvMirrorTask.class);
EVENT_SERVICE.subscribe(ProjectVulnerabilityAnalysisEvent.class, VulnerabilityAnalysisTask.class);
EVENT_SERVICE.subscribe(PortfolioVulnerabilityAnalysisEvent.class, VulnerabilityAnalysisTask.class);
EVENT_SERVICE.subscribe(ProjectRepositoryMetaAnalysisEvent.class, RepositoryMetaAnalyzerTask.class);
EVENT_SERVICE.subscribe(PortfolioRepositoryMetaAnalysisEvent.class, RepositoryMetaAnalyzerTask.class);
EVENT_SERVICE.subscribe(ProjectRepositoryMetaAnalysisEvent.class, RepositoryMetaAnalysisTask.class);
EVENT_SERVICE.subscribe(PortfolioRepositoryMetaAnalysisEvent.class, RepositoryMetaAnalysisTask.class);
EVENT_SERVICE.subscribe(ProjectMetricsUpdateEvent.class, ProjectMetricsUpdateTask.class);
EVENT_SERVICE.subscribe(PortfolioMetricsUpdateEvent.class, PortfolioMetricsUpdateTask.class);
EVENT_SERVICE.subscribe(VulnerabilityMetricsUpdateEvent.class, VulnerabilityMetricsUpdateTask.class);
Expand All @@ -93,16 +108,23 @@ public void contextInitialized(final ServletContextEvent event) {
EVENT_SERVICE.subscribe(KennaSecurityUploadEventAbstract.class, KennaSecurityUploadTask.class);
EVENT_SERVICE.subscribe(InternalComponentIdentificationEvent.class, InternalComponentIdentificationTask.class);
EVENT_SERVICE.subscribe(CallbackEvent.class, CallbackTask.class);
EVENT_SERVICE.subscribe(VulnerabilityScanCleanupEvent.class, VulnerabilityScanCleanupTask.class);
EVENT_SERVICE.subscribe(NistMirrorEvent.class, NistMirrorTask.class);
EVENT_SERVICE.subscribe(VulnerabilityPolicyFetchEvent.class, VulnerabilityPolicyFetchTask.class);
EVENT_SERVICE.subscribe(EpssMirrorEvent.class, EpssMirrorTask.class);
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);
EVENT_SERVICE.subscribe(IntegrityAnalysisEvent.class, IntegrityAnalysisTask.class);

// Execute maintenance tasks on the single-threaded event service.
// This way, they are not blocked by, and don't block, actual processing tasks on the main event service.
EVENT_SERVICE_ST.subscribe(ComponentMetadataMaintenanceEvent.class, ComponentMetadataMaintenanceTask.class);
EVENT_SERVICE_ST.subscribe(MetricsMaintenanceEvent.class, MetricsMaintenanceTask.class);
EVENT_SERVICE_ST.subscribe(TagMaintenanceEvent.class, TagMaintenanceTask.class);
EVENT_SERVICE_ST.subscribe(VulnerabilityDatabaseMaintenanceEvent.class, VulnerabilityDatabaseMaintenanceTask.class);
EVENT_SERVICE_ST.subscribe(VulnerabilityScanMaintenanceEvent.class, VulnerabilityScanMaintenanceTask.class);
EVENT_SERVICE_ST.subscribe(WorkflowMaintenanceEvent.class, WorkflowMaintenanceTask.class);

TaskScheduler.getInstance();
}

Expand All @@ -118,9 +140,9 @@ public void contextDestroyed(final ServletContextEvent event) {
EVENT_SERVICE.unsubscribe(VexUploadProcessingTask.class);
EVENT_SERVICE.unsubscribe(LdapSyncTaskWrapper.class);
EVENT_SERVICE.unsubscribe(GitHubAdvisoryMirrorTask.class);
EVENT_SERVICE.unsubscribe(OsvDownloadTask.class);
EVENT_SERVICE.unsubscribe(OsvMirrorTask.class);
EVENT_SERVICE.unsubscribe(VulnerabilityAnalysisTask.class);
EVENT_SERVICE.unsubscribe(RepositoryMetaAnalyzerTask.class);
EVENT_SERVICE.unsubscribe(RepositoryMetaAnalysisTask.class);
EVENT_SERVICE.unsubscribe(ProjectMetricsUpdateTask.class);
EVENT_SERVICE.unsubscribe(PortfolioMetricsUpdateTask.class);
EVENT_SERVICE.unsubscribe(VulnerabilityMetricsUpdateTask.class);
Expand All @@ -130,14 +152,20 @@ public void contextDestroyed(final ServletContextEvent event) {
EVENT_SERVICE.unsubscribe(KennaSecurityUploadTask.class);
EVENT_SERVICE.unsubscribe(InternalComponentIdentificationTask.class);
EVENT_SERVICE.unsubscribe(CallbackTask.class);
EVENT_SERVICE.unsubscribe(VulnerabilityScanCleanupTask.class);
EVENT_SERVICE.unsubscribe(NistMirrorTask.class);
EVENT_SERVICE.unsubscribe(EpssMirrorTask.class);
EVENT_SERVICE.unsubscribe(PolicyEvaluationTask.class);
EVENT_SERVICE.unsubscribe(WorkflowStateCleanupTask.class);
EVENT_SERVICE.unsubscribe(IntegrityMetaInitializerTask.class);
EVENT_SERVICE.unsubscribe(IntegrityAnalysisTask.class);
EVENT_SERVICE.unsubscribe(VulnerabilityPolicyFetchTask.class);
EVENT_SERVICE.shutdown(DRAIN_TIMEOUT_DURATION);

EVENT_SERVICE_ST.unsubscribe(ComponentMetadataMaintenanceTask.class);
EVENT_SERVICE_ST.unsubscribe(MetricsMaintenanceTask.class);
EVENT_SERVICE_ST.unsubscribe(TagMaintenanceTask.class);
EVENT_SERVICE_ST.unsubscribe(VulnerabilityDatabaseMaintenanceTask.class);
EVENT_SERVICE_ST.unsubscribe(VulnerabilityScanMaintenanceTask.class);
EVENT_SERVICE_ST.unsubscribe(WorkflowMaintenanceTask.class);
EVENT_SERVICE_ST.shutdown(DRAIN_TIMEOUT_DURATION);
}
}
14 changes: 8 additions & 6 deletions src/main/java/org/dependencytrack/event/PurlMigrator.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@

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

import jakarta.servlet.ServletContextEvent;
import jakarta.servlet.ServletContextListener;
import org.dependencytrack.tasks.IntegrityMetaInitializerTask;

import static org.dependencytrack.tasks.LockName.INTEGRITY_META_INITIALIZER_LOCK;
import static org.dependencytrack.util.LockProvider.executeWithLock;
import static org.dependencytrack.util.TaskUtil.getLockConfigForTask;

public class PurlMigrator implements ServletContextListener {

Expand All @@ -48,7 +48,9 @@ public PurlMigrator() {
public void contextInitialized(final ServletContextEvent event) {
if (integrityInitializerEnabled) {
try {
LockProvider.executeWithLock(INTEGRITY_META_INITIALIZER_LOCK, (LockingTaskExecutor.Task) () -> process());
executeWithLock(
getLockConfigForTask(IntegrityMetaInitializerTask.class),
(LockingTaskExecutor.Task) this::process);
} catch (Throwable e) {
throw new RuntimeException("An unexpected error occurred while running Initializer for integrity meta", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,12 @@
* SPDX-License-Identifier: Apache-2.0
* Copyright (c) OWASP Foundation. All Rights Reserved.
*/
package org.dependencytrack.event;
package org.dependencytrack.event.maintenance;

import alpine.event.framework.Event;
import org.dependencytrack.model.VulnerabilityScan;

/**
* Defines an {@link Event} that is triggered to clean up {@link VulnerabilityScan}s
* that have not been updated for a certain amount of time.
*
* @since 5.0.0
* @since 5.6.0
*/
public record VulnerabilityScanCleanupEvent() implements Event {
public class ComponentMetadataMaintenanceEvent implements Event {
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,12 @@
* SPDX-License-Identifier: Apache-2.0
* Copyright (c) OWASP Foundation. All Rights Reserved.
*/
package org.dependencytrack.tasks;
package org.dependencytrack.event.maintenance;

public enum LockName {
PORTFOLIO_METRICS_TASK_LOCK,
LDAP_SYNC_TASK_LOCK,
EPSS_MIRROR_TASK_LOCK,
VULNERABILITY_METRICS_TASK_LOCK,
INTERNAL_COMPONENT_IDENTIFICATION_TASK_LOCK,
WORKFLOW_STEP_CLEANUP_TASK_LOCK,
PORTFOLIO_REPO_META_ANALYSIS_TASK_LOCK,
PORTFOLIO_VULN_ANALYSIS_TASK_LOCK,
INTEGRITY_META_INITIALIZER_LOCK,
VULNERABILITY_POLICY_BUNDLE_FETCH_TASK_LOCK
import alpine.event.framework.Event;

/**
* @since 5.6.0
*/
public class MetricsMaintenanceEvent implements Event {
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@
* SPDX-License-Identifier: Apache-2.0
* Copyright (c) OWASP Foundation. All Rights Reserved.
*/
package org.dependencytrack.event;
package org.dependencytrack.event.maintenance;

import alpine.event.framework.Event;

public class WorkflowStateCleanupEvent implements Event {
/**
* @since 5.6.0
*/
public class TagMaintenanceEvent implements Event {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* This file is part of Dependency-Track.
*
* 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
* Copyright (c) OWASP Foundation. All Rights Reserved.
*/
package org.dependencytrack.event.maintenance;

import alpine.event.framework.Event;

/**
* @since 5.6.0
*/
public class VulnerabilityDatabaseMaintenanceEvent implements Event {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* This file is part of Dependency-Track.
*
* 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
* Copyright (c) OWASP Foundation. All Rights Reserved.
*/
package org.dependencytrack.event.maintenance;

import alpine.event.framework.Event;

/**
* @since 5.6.0
*/
public class VulnerabilityScanMaintenanceEvent implements Event {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* This file is part of Dependency-Track.
*
* 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
* Copyright (c) OWASP Foundation. All Rights Reserved.
*/
package org.dependencytrack.event.maintenance;

import alpine.event.framework.Event;

/**
* @since 5.6.0
*/
public class WorkflowMaintenanceEvent implements Event {
}
Loading

0 comments on commit eca7ab7

Please sign in to comment.