Software Design Description: Device Deletion Filtering

This document describes the filtering mechanism that controls which devices are eligible for automatic deletion during the periodic data-store cleanup job, governed by two ACS settings: doNotDeletePreprovisionedDevices and dataStoreExclusionModels.

1. Overview

ACS periodically deletes devices whose last connection time is older than a configured threshold (dataStoreDaysAmount days). This job runs on the schedule defined by autoDeleteCron (default: daily at 02:00) inside FTCpeDeleteTaskJob.

Two independent filters narrow the set of devices eligible for deletion:

Setting Type Effect

doNotDeletePreprovisionedDevices

Boolean (default: 0)

Excludes devices that have pre-provisioned tasks/methods (entries in cpe_method).

dataStoreExclusionModels

JSON String (default: "")

Excludes devices belonging to specific product-class groups or manufacturer names.

The two filters are independent and are evaluated together before each deletion batch.

2. Auto-Deletion Job

The entry point is FTCpeDeleteTaskJob#execute. On each iteration the job:

  1. Reads dataStoreDaysAmount, concurrentDataStoreCleanThreads, doNotDeletePreprovisionedDevices, and dataStoreExclusionModels from the live ACS configuration.

  2. Computes the cutoff timestamp: now − dataStoreDaysAmount × 24h.

  3. Selects up to limit (1000 for MySQL, 4000 for Oracle) eligible device IDs by calling the appropriate DAO method (see DAO Method Selection).

  4. Deletes the selected devices concurrently in groups of concurrentDataStoreCleanThreads.

  5. Repeats until no eligible devices remain.

3. doNotDeletePreprovisionedDevices

3.1. Meaning

A device is considered pre-provisioned when it has at least one row in the cpe_method table. This indicates that tasks or provisioning profiles have been assigned to the device before it ever connected.

3.2. Behaviour

Value DAO method called

0 (disabled, default)

cpeDao.getCpeIdsUpdatedOlderThan(ts, limit) — selects all stale devices

1 (enabled)

cpeDao.getCpeIdsWithMethodsAndUpdatedOlderThan(ts, limit) — excludes pre-provisioned devices

When exclusion models are also configured, the *Excluding variants are used instead (see DAO Method Selection).

3.3. SQL

Base query (MySQL example):

-- doNotDeletePreprovisionedDevices = 0
SELECT id, serial FROM cpe WHERE updated < ? LIMIT <N>

-- doNotDeletePreprovisionedDevices = 1
SELECT id, serial FROM cpe c
WHERE updated < ?
  AND EXISTS (SELECT 1 FROM cpe_method WHERE cpe_id = c.id)
LIMIT <N>

4. dataStoreExclusionModels

4.1. Value Format

The setting stores a JSON string with two optional arrays:

{
  "models": [42, 87],
  "manufacturers": ["Cisco", "Huawei"]
}
Key Element type Semantics

models

Integer

product_class_group.id values — excludes all product_class rows whose group_id matches.

manufacturers

String

Manufacturer names as stored in manufacturer.name — excludes all product_class rows whose manuf_id resolves to one of these names.

An empty string or a missing key means no exclusion for that dimension.

4.2. UI

ui 1
ui 2

4.3. Parsing

FTCpeDeleteTaskJob#parseExclusionModels deserialises the JSON value at the start of every job cycle:

JsonNode root = OBJECT_MAPPER.readTree(dataStoreExclusionModels);

// models → List<Integer> productClassGroupIds
JsonNode models = root.get("models");
if (models != null && models.isArray()) { ... }

// manufacturers → List<String> manufacturerNames
JsonNode manufacturers = root.get("manufacturers");
if (manufacturers != null && manufacturers.isArray()) { ... }

A parse error is logged and treated as an empty exclusion list (safe fallback — no devices are skipped).

5. DAO Method Selection

The combination of doNotDeletePreprovisionedDevices and whether the exclusion list is non-empty determines which DAO method is called:

doNotDeletePreprovisionedDevices Exclusions non-empty DAO method

false

No

getCpeIdsUpdatedOlderThan

false

Yes

getCpeIdsUpdatedOlderThanExcluding

true

No

getCpeIdsWithMethodsAndUpdatedOlderThan

true

Yes

getCpeIdsWithMethodsAndUpdatedOlderThanExcluding

5.1. Generated SQL (Excluding Variants)

CpeDaoJdbcImpl#getCpeIdsOlderThanExcludingInternal builds the query dynamically. Only the clauses for non-empty lists are appended:

SELECT id, serial FROM cpe c
WHERE updated < ?
  -- only when doNotDeletePreprovisionedDevices = true:
  [AND EXISTS (SELECT 1 FROM cpe_method WHERE cpe_id = c.id)]
  -- only when at least one exclusion list is non-empty:
  AND c.product_class_id NOT IN (
    SELECT id FROM product_class WHERE
      -- only when models list is non-empty:
      [group_id IN (?, ?, ...)]
      -- OR (only when manufacturers list is non-empty):
      [OR manuf_id IN (SELECT id FROM manufacturer WHERE name IN (?, ?, ...))]
  )
LIMIT <N>                                  -- MySQL
[AND rownum <= ?]                          -- Oracle

The two exclusion criteria inside the subquery are combined with OR: a device is kept if its product_class row matches either a group ID or a manufacturer name.

6. Automatic Exclusion Cleanup on Model Deletion

When a product-class group or a manufacturer is deleted via FTCpeProductService#deleteManufacturerAndModel, the corresponding entries are removed from the dataStoreExclusionModels JSON so that the setting never references non-existent entities.

7. ACS Settings Reference

Setting name Type Default Description

dataStoreDaysAmount

Int

0 (disabled)

Devices last seen more than N days ago become candidates for deletion. 0 disables the job entirely.

autoDeleteCron

Str

0 0 2 * * ?

Quartz cron expression defining when the deletion job runs.

concurrentDataStoreCleanThreads

Int

Number of devices deleted in parallel per batch iteration.

doNotDeletePreprovisionedDevices

Bool

0

When 1, devices with pre-provisioned tasks (cpe_method rows) are never auto-deleted.

dataStoreExclusionModels

Str

""

JSON value listing product-class group IDs and/or manufacturer names to exclude from auto-deletion.

8. Component Map

Class Responsibility

FTCpeDeleteTaskJob

Quartz job: reads settings, calls parseExclusionModels, selects and deletes device batches.

FTCpeDeleteTask

Spring component: registers the Quartz trigger on startup using autoDeleteCron.

CpeDao / CpeDaoJdbcImpl

DAO: getCpeIdsUpdatedOlderThan[Excluding], getCpeIdsWithMethodsAndUpdatedOlderThan[Excluding] — builds dynamic SQL.

FTCpeProductService

Service: orchestrates model/manufacturer deletion and calls removeFromExclusionModels to keep the JSON setting consistent.

ManufacturerDaoJdbcImpl

DAO: getNamesByIds — resolves manufacturer IDs to names before deletion.

DMConfigurationParameter

Enum: declares dataStoreExclusionModels as Type.Str with empty-string default.