Skip to content

Commit 0df1ad7

Browse files
committed
feat: delete orphaned components
1 parent 33dd400 commit 0df1ad7

5 files changed

Lines changed: 42 additions & 12 deletions

File tree

‎backend/application/background_tasks/periodic_tasks/core_tasks.py‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from application.background_tasks.services.task_base import so_periodic_task
55
from application.commons import settings_static
66
from application.core.services.housekeeping import (
7-
delete_inactive_branches_and_set_flags,
7+
housekeeping,
88
)
99
from application.core.services.risk_acceptance_expiry_task import (
1010
expire_risk_acceptances,
@@ -17,9 +17,9 @@
1717
hour=settings_static.branch_housekeeping_crontab_hour,
1818
)
1919
)
20-
@so_periodic_task("Branch housekeeping")
21-
def task_branch_housekeeping() -> str:
22-
message = delete_inactive_branches_and_set_flags()
20+
@so_periodic_task("Housekeeping")
21+
def task_housekeeping() -> str:
22+
message = housekeeping()
2323
return message
2424

2525

‎backend/application/background_tasks/services/registry.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
),
1111
"Import EPSS and cvss-bt": "application.background_tasks.periodic_tasks.epss_tasks.task_import_epss",
1212
"Import SPDX licenses": "application.background_tasks.periodic_tasks.license_tasks.task_spdx_license_import",
13-
"Branch housekeeping": "application.background_tasks.periodic_tasks.core_tasks.task_branch_housekeeping",
13+
"Housekeeping": "application.background_tasks.periodic_tasks.core_tasks.task_housekeeping",
1414
"Expire risk acceptances": "application.background_tasks.periodic_tasks.core_tasks.task_expire_risk_acceptances",
1515
"Calculate product metrics": (
1616
"application.background_tasks.periodic_tasks.metrics_tasks.task_calculate_product_metrics"

‎backend/application/core/services/housekeeping.py‎

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
import logging
22
import re
33
from datetime import timedelta
4+
from itertools import batched
45

6+
from django.db.models import Exists, OuterRef
57
from django.utils import timezone
68

79
from application.commons.models import Settings
8-
from application.core.models import Branch, Observation, Product
10+
from application.core.models import Branch, Component, Observation, Product
11+
from application.licenses.models import License_Component
912

1013
logger = logging.getLogger("secobserve.core")
1114

15+
BULK_BATCH_SIZE = 1000
1216

13-
def delete_inactive_branches_and_set_flags() -> str:
17+
18+
def housekeeping() -> str:
1419
num_products = 0
1520
num_deleted_branches = 0
1621
products = Product.objects.filter(is_product_group=False)
@@ -21,7 +26,12 @@ def delete_inactive_branches_and_set_flags() -> str:
2126
num_products += 1
2227
set_product_flags(product)
2328

24-
return f"Deleted {num_deleted_branches} inactive branches in {num_products} products."
29+
num_deleted_components = delete_orphaned_components()
30+
31+
return (
32+
f"Deleted {num_deleted_branches} inactive branches in {num_products} products."
33+
f"\nDeleted {num_deleted_components} orphaned components."
34+
)
2535

2636

2737
def delete_inactive_branches_for_product(product: Product) -> int:
@@ -129,3 +139,23 @@ def set_product_flags(product: Product) -> None:
129139
or has_potential_duplicates_before != product.has_potential_duplicates
130140
):
131141
product.save()
142+
143+
144+
def delete_orphaned_components() -> int:
145+
orphaned_components = Component.objects.filter(
146+
~Exists(Observation.objects.filter(origin_component=OuterRef("pk"))),
147+
~Exists(License_Component.objects.filter(component=OuterRef("pk"))),
148+
)
149+
orphaned_component_ids = list(orphaned_components.values_list("pk", flat=True))
150+
151+
num_deleted_components = 0
152+
for component_ids_batch in batched(orphaned_component_ids, BULK_BATCH_SIZE):
153+
deleted_objects = orphaned_components.filter(pk__in=component_ids_batch).delete()
154+
num_deleted_components += deleted_objects[1].get("core.Component", 0)
155+
156+
if num_deleted_components:
157+
logger.info( # pylint: disable=logging-fstring-interpolation
158+
f"Deleted {num_deleted_components} orphaned components"
159+
)
160+
161+
return num_deleted_components

‎frontend/src/commons/settings/SettingsEdit.tsx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,7 @@ const SettingsEdit = () => {
559559
</FormDataConsumer>
560560
<NumberInput
561561
source="branch_housekeeping_crontab_hour"
562-
label="Branch housekeeping crontab (hour)"
562+
label="Housekeeping crontab (hour)"
563563
min={0}
564564
step={1}
565565
validate={validate_0_23}
@@ -625,7 +625,7 @@ const SettingsEdit = () => {
625625
</FormDataConsumer>
626626
<NumberInput
627627
source="branch_housekeeping_crontab_minute"
628-
label="Branch housekeeping crontab (minute)"
628+
label="Housekeeping crontab (minute)"
629629
min={0}
630630
step={1}
631631
validate={validate_0_59}

‎frontend/src/commons/settings/SettingsShow.tsx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ const SettingsShowComponent = () => {
359359
<NumberField source="license_import_crontab_hour" />
360360
</Labeled>
361361
)}
362-
<Labeled label="Branch housekeeping crontab (hour/UTC)">
362+
<Labeled label="Housekeeping crontab (hour/UTC)">
363363
<NumberField source="branch_housekeeping_crontab_hour" />
364364
</Labeled>
365365
<Labeled label="EPSS and exploit import crontab (hour/UTC)">
@@ -386,7 +386,7 @@ const SettingsShowComponent = () => {
386386
<NumberField source="license_import_crontab_minute" />
387387
</Labeled>
388388
)}
389-
<Labeled label="Branch housekeeping crontab (minute)">
389+
<Labeled label="Housekeeping crontab (minute)">
390390
<NumberField source="branch_housekeeping_crontab_minute" />
391391
</Labeled>
392392
<Labeled label="EPSS and exploit import crontab (minutes)">

0 commit comments

Comments
 (0)