Skip to content

Introduce soft deleted list option for soft deletable entities#3093

Open
strailov wants to merge 12 commits into
eclipse-hawkbit:masterfrom
boschglobal:feature/soft_deletion_mode_listing_option
Open

Introduce soft deleted list option for soft deletable entities#3093
strailov wants to merge 12 commits into
eclipse-hawkbit:masterfrom
boschglobal:feature/soft_deletion_mode_listing_option

Conversation

@strailov
Copy link
Copy Markdown
Contributor

@strailov strailov commented May 19, 2026

Add soft_deleted_mode query parameter to listing REST endpoints

Summary

Introduces a soft_deleted_mode filter parameter to all soft-deletable entity listing endpoints, allowing API consumers to query soft-deleted entities that were previously hidden from listing results.

Motivation

Soft-deleted entities (Distribution Sets, Software Modules, their Types, and Rollouts) were previously only accessible by direct ID lookup. There was no way to list or search them via the REST API, making it difficult for UI and integrations to display or manage deleted resources.

Changes

New API contract:

  • SoftDeletedMode enum (only_soft_deleted, exclude_not_soft_deleted, include_soft_deleted) with safe fromValue() parsing
  • SoftDeletableRepositoryManagement interface extending RepositoryManagement with findAll(SoftDeletedMode, Pageable) and findByRsql(String, SoftDeletedMode, Pageable)
  • count(SoftDeletedMode) added to RepositoryManagement with fallback for non-soft-deletable entities

Affected REST endpoints:

  • GET /rest/v1/distributionsets
  • GET /rest/v1/distributionsettypes
  • GET /rest/v1/softwaremodules
  • GET /rest/v1/softwaremoduletypes
  • GET /rest/v1/rollouts (compact mode only; full mode intentionally excluded)

Mutation guards:

  • update, lock, unlock, invalidate, assignTag, unassignTag now reject operations on soft-deleted entities with DeletedException

Implementations:

  • JpaDistributionSetManagement — refactored findByRsql to support deleted filter while preserving legacy complete field handling
  • JpaSoftwareModuleManagement, JpaSoftwareModuleTypeManagement, JpaDistributionSetTypeManagement — added findAll/findByRsql with soft-delete filtering and update guards
  • JpaRolloutManagement — added findAll/findByRsql with SoftDeletedFilter
  • Chosen that approach instead of introducing this logic in AbstractJpaRepositoryManagement due to that some entities are not soft-deletable by definition. So the current approach may have some duplications with findAll or findByRsql implementations but seems with more clear architecture approach and distinguish those entities.
  • Soft-delete mutation guards - Soft-deleted entities must reject mutation operations (like Rollout already does). Users can stumble into "Entity exists" errors due to unique key constraint violations on soft-deleted entities they cannot see. Here I rejected the approach with intermediate class due to AbstractJpaRepositoryManagementAbstractJpaRepositoryWithMetadataManagement - Would need two variants (with/without metadata) or force unrelated coupling. Not worth the complexity. Decided to override the updates for each entity which is easy to review, no risk for other entities and straightforward .
  • Reject all for bulk updates - to be still considered ...

strailov added 5 commits May 19, 2026 17:54
Signed-off-by: strailov <Stanislav.Trailov@bosch.io>
Signed-off-by: strailov <Stanislav.Trailov@bosch.io>
Signed-off-by: strailov <Stanislav.Trailov@bosch.io>
Signed-off-by: strailov <Stanislav.Trailov@bosch.io>
Signed-off-by: strailov <Stanislav.Trailov@bosch.io>
strailov added 5 commits June 2, 2026 14:57
Signed-off-by: strailov <Stanislav.Trailov@bosch.io>
Signed-off-by: strailov <Stanislav.Trailov@bosch.io>
Signed-off-by: strailov <Stanislav.Trailov@bosch.io>
Signed-off-by: strailov <Stanislav.Trailov@bosch.io>
Signed-off-by: strailov <Stanislav.Trailov@bosch.io>
Comment thread licenses/LICENSE_HEADER_TEMPLATE_CONTRIBUTORS_26.txt Outdated
Comment thread pom.xml Outdated
* @return number of {@link BaseEntity}s matching the given soft-deleted filter
*/
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
long count(@NotNull SoftDeletedMode softDeletedMode);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you extract soft deletable interface SoftDeletableRepositoryManagement - this count method shall go there

*/
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Page<Rollout> findByRsql(@NotNull String rsql, SoftDeletedMode softDeletedMode, @NotNull Pageable pageable);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't we want here count with soft deleted mode?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I even started to think - why we need count at all ? Previously Slice it was used - that's why count was invoked, but It seems everything is page now - meaning why do we need count at all since we have it into the page ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably would eliminate the need of count(SoftDeletedMode) at all.

}

@Override
public long count(SoftDeletedMode softDeletedMode) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

currently there is softe deleted support here, see supportSoftDelete0, isNotDeleted0 that automatically resolve if there is soft deleted support or not.
So there are two options:
A) stick to this support, and implement using that mechanism, eventually AbstractJpaSoftDeletableRepostioryManagement (or this class to extend and implement SoftDeletableRepostioryManagement)
B) remove soft deletable mechanism from here and move the support entirely into AbstractJpaSoftDeletableRepostioryManagement
Anyway I think a dedicated abstract class with impl of SoftDeletableRepostioryManagement will help to minimise boilerplate code

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not that simple I think - DS & SM extend AbstractJpaRepositoryWithMetadataManagement but other entities don't - they lay on AbstractJpaRepositoryManagement . So it again leads to not so clean separation ...
We would have to add also AbstractJpaSoftDeletableRepositoryWithMetadataManagement for DS & SM eventually ?

strailov added 2 commits June 5, 2026 14:51
Signed-off-by: strailov <Stanislav.Trailov@bosch.io>
Signed-off-by: strailov <Stanislav.Trailov@bosch.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants