Fix target group assignment with RSQL negation filters (e.g. tag!=tag… (#3116)

* Fix target group assignment with RSQL negation filters (e.g. tag!=tag1) failing on EclipseLink/MySQL

Signed-off-by: strailov <Stanislav.Trailov@bosch.io>

* address comments

Signed-off-by: strailov <Stanislav.Trailov@bosch.io>

* Fix test for chunked calls to use also negate operator

Signed-off-by: strailov <Stanislav.Trailov@bosch.io>

* address comments

Signed-off-by: strailov <Stanislav.Trailov@bosch.io>

---------

Signed-off-by: strailov <Stanislav.Trailov@bosch.io>
This commit is contained in:
Stanislav Trailov
2026-06-08 15:15:50 +03:00
committed by GitHub
parent 6a85a43dde
commit 95680962cc
2 changed files with 95 additions and 22 deletions

View File

@@ -27,6 +27,7 @@ import org.eclipse.hawkbit.repository.model.TargetTag;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import org.springframework.test.util.ReflectionTestUtils;
public class MgmtTargetGroupResourceTest extends AbstractManagementApiIntegrationTest {
@@ -257,4 +258,40 @@ public class MgmtTargetGroupResourceTest extends AbstractManagementApiIntegratio
.andExpect(jsonPath("content", Matchers.hasSize(1)))
.andExpect(jsonPath("content.[0].controllerId", Matchers.equalTo("target3")));
}
@Test
void shouldAssignGroupInChunksWhenTargetCountExceedsChunkSize() throws Exception {
// create 5 targets with tag "exclude", 2 without — chunk size 2 forces multiple batches
final TargetTag excludeTag = targetTagManagement.create(TargetTagManagement.Create.builder().name("exclude").build());
for (int i = 1; i <= 5; i++) {
targetManagement.create(builder().controllerId("chunked-" + i).build());
}
targetManagement.create(builder().controllerId("excluded-1").build());
targetManagement.create(builder().controllerId("excluded-2").build());
targetManagement.assignTag(List.of("excluded-1", "excluded-2"), excludeTag.getId());
// override chunk size to 2 for this test
ReflectionTestUtils.setField(targetManagement, "assignTargetGroupChunkSize", 2);
try {
// tag!=exclude triggers chunked path and should assign only non-tagged targets
mvc.perform(put(MgmtTargetGroupRestApi.TARGETGROUPS_V1 + "/ChunkedGroup")
.contentType(MediaType.APPLICATION_JSON)
.param("q", "tag!=exclude"))
.andExpect(status().isNoContent());
mvc.perform(get(MgmtTargetGroupRestApi.TARGETGROUPS_V1 + "/ChunkedGroup/assigned")
.param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "ID:ASC")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("content", Matchers.hasSize(5)))
.andExpect(jsonPath("content.[0].controllerId", Matchers.equalTo("chunked-1")))
.andExpect(jsonPath("content.[1].controllerId", Matchers.equalTo("chunked-2")))
.andExpect(jsonPath("content.[2].controllerId", Matchers.equalTo("chunked-3")))
.andExpect(jsonPath("content.[3].controllerId", Matchers.equalTo("chunked-4")))
.andExpect(jsonPath("content.[4].controllerId", Matchers.equalTo("chunked-5")));
} finally {
// restore default
ReflectionTestUtils.setField(targetManagement, "assignTargetGroupChunkSize", 1000);
}
}
}