Add support for on not found policy in Target REST (un)assignTags (#1905)
Signed-off-by: Marinov Avgustin <Avgustin.Marinov@bosch.com>
This commit is contained in:
@@ -14,6 +14,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import jakarta.validation.ConstraintViolationException;
|
import jakarta.validation.ConstraintViolationException;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
@@ -48,16 +49,9 @@ import org.springframework.security.access.prepost.PreAuthorize;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Management service for {@link Target}s.
|
* Management service for {@link Target}s.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public interface TargetManagement {
|
public interface TargetManagement {
|
||||||
|
|
||||||
enum OnNotFoundPolicy {
|
|
||||||
FAIL, // default
|
|
||||||
TAG_AND_SUCCESS,
|
|
||||||
TAG_AND_ERROR
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Counts number of targets with the given distribution set assigned.
|
* Counts number of targets with the given distribution set assigned.
|
||||||
*
|
*
|
||||||
@@ -674,12 +668,12 @@ public interface TargetManagement {
|
|||||||
*
|
*
|
||||||
* @param controllerIds to assign for
|
* @param controllerIds to assign for
|
||||||
* @param targetTagId to assign
|
* @param targetTagId to assign
|
||||||
* @param onNotFoundPolicy what to do if there are targets that are not found
|
* @param notFoundHandler if not all targets found - if null - exception, otherwise tag what found and the handler is called with what's not found
|
||||||
* @return list of assigned targets
|
* @return list of assigned targets
|
||||||
* @throws EntityNotFoundException if given targetTagId or at least one of the targets do not exist
|
* @throws EntityNotFoundException if given targetTagId or at least one of the targets do not exist
|
||||||
*/
|
*/
|
||||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET)
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET)
|
||||||
List<Target> assignTag(@NotEmpty Collection<String> controllerIds, long targetTagId, final OnNotFoundPolicy onNotFoundPolicy);
|
List<Target> assignTag(@NotEmpty Collection<String> controllerIds, long targetTagId, final Consumer<Collection<String>> notFoundHandler);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assign a {@link TargetTag} assignment to given {@link Target}s.
|
* Assign a {@link TargetTag} assignment to given {@link Target}s.
|
||||||
@@ -691,7 +685,7 @@ public interface TargetManagement {
|
|||||||
*/
|
*/
|
||||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET)
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET)
|
||||||
default List<Target> assignTag(@NotEmpty Collection<String> controllerIds, long targetTagId) {
|
default List<Target> assignTag(@NotEmpty Collection<String> controllerIds, long targetTagId) {
|
||||||
return assignTag(controllerIds, targetTagId, OnNotFoundPolicy.FAIL);
|
return assignTag(controllerIds, targetTagId, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -699,12 +693,12 @@ public interface TargetManagement {
|
|||||||
*
|
*
|
||||||
* @param controllerIds to un-assign for
|
* @param controllerIds to un-assign for
|
||||||
* @param targetTagId to un-assign
|
* @param targetTagId to un-assign
|
||||||
* @param onNotFoundPolicy what to do if there are targets that are not found
|
* @param notFoundHandler if not all targets found - if null - exception, otherwise un-tag what found and the handler is called with what's not found
|
||||||
* @return list of unassigned targets
|
* @return list of unassigned targets
|
||||||
* @throws EntityNotFoundException if given targetTagId or at least one of the targets do not exist
|
* @throws EntityNotFoundException if given targetTagId or at least one of the targets do not exist
|
||||||
*/
|
*/
|
||||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
|
||||||
List<Target> unassignTag(@NotEmpty Collection<String> controllerIds, long targetTagId, final OnNotFoundPolicy onNotFoundPolicy);
|
List<Target> unassignTag(@NotEmpty Collection<String> controllerIds, long targetTagId, final Consumer<Collection<String>> notFoundHandler);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Un-assign a {@link TargetTag} assignment to given {@link Target}s.
|
* Un-assign a {@link TargetTag} assignment to given {@link Target}s.
|
||||||
@@ -716,7 +710,7 @@ public interface TargetManagement {
|
|||||||
*/
|
*/
|
||||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
|
||||||
default List<Target> unassignTag(@NotEmpty Collection<String> controllerIds, long targetTagId) {
|
default List<Target> unassignTag(@NotEmpty Collection<String> controllerIds, long targetTagId) {
|
||||||
return unassignTag(controllerIds, targetTagId, OnNotFoundPolicy.FAIL);
|
return unassignTag(controllerIds, targetTagId, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1012,7 +1006,7 @@ public interface TargetManagement {
|
|||||||
/**
|
/**
|
||||||
* Un-assign a {@link TargetTag} assignment to given {@link Target}.
|
* Un-assign a {@link TargetTag} assignment to given {@link Target}.
|
||||||
*
|
*
|
||||||
* @deprecated since 0.6.0 - use {@link #unassigнnTag(List, long)} instead
|
* @deprecated since 0.6.0 - use {@link #unassignTag(Collection, long)} (List, long)} instead
|
||||||
* @param controllerId to un-assign for
|
* @param controllerId to un-assign for
|
||||||
* @param targetTagId to un-assign
|
* @param targetTagId to un-assign
|
||||||
* @return the unassigned target or <null> if no target is unassigned
|
* @return the unassigned target or <null> if no target is unassigned
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import java.util.Objects;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -533,8 +534,8 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
@Transactional
|
@Transactional
|
||||||
@Retryable(include = {
|
@Retryable(include = {
|
||||||
ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY))
|
ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY))
|
||||||
public List<Target> assignTag(final Collection<String> controllerIds, final long targetTagId, final OnNotFoundPolicy onNotFoundPolicy) {
|
public List<Target> assignTag(final Collection<String> controllerIds, final long targetTagId, final Consumer<Collection<String>> notFoundHandler) {
|
||||||
return updateTag(controllerIds, targetTagId, onNotFoundPolicy, (tag, target) -> {
|
return updateTag(controllerIds, targetTagId, notFoundHandler, (tag, target) -> {
|
||||||
if (target.getTags().contains(tag)) {
|
if (target.getTags().contains(tag)) {
|
||||||
return target;
|
return target;
|
||||||
} else {
|
} else {
|
||||||
@@ -547,8 +548,8 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
@Transactional
|
@Transactional
|
||||||
@Retryable(include = {
|
@Retryable(include = {
|
||||||
ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY))
|
ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY))
|
||||||
public List<Target> unassignTag(final Collection<String> controllerIds, final long targetTagId, final OnNotFoundPolicy onNotFoundPolicy) {
|
public List<Target> unassignTag(final Collection<String> controllerIds, final long targetTagId, final Consumer<Collection<String>> notFoundHandler) {
|
||||||
return updateTag(controllerIds, targetTagId, onNotFoundPolicy, (tag, target) -> {
|
return updateTag(controllerIds, targetTagId, notFoundHandler, (tag, target) -> {
|
||||||
if (target.getTags().contains(tag)) {
|
if (target.getTags().contains(tag)) {
|
||||||
target.removeTag(tag);
|
target.removeTag(tag);
|
||||||
return targetRepository.save(target);
|
return targetRepository.save(target);
|
||||||
@@ -558,7 +559,7 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
private List<Target> updateTag(
|
private List<Target> updateTag(
|
||||||
final Collection<String> controllerIds, final long targetTagId, final OnNotFoundPolicy notFoundPolicy,
|
final Collection<String> controllerIds, final long targetTagId, final Consumer<Collection<String>> notFoundHandler,
|
||||||
final BiFunction<JpaTargetTag, JpaTarget, Target> updater) {
|
final BiFunction<JpaTargetTag, JpaTarget, Target> updater) {
|
||||||
final JpaTargetTag tag = targetTagRepository.findById(targetTagId)
|
final JpaTargetTag tag = targetTagRepository.findById(targetTagId)
|
||||||
.orElseThrow(() -> new EntityNotFoundException(TargetTag.class, targetTagId));
|
.orElseThrow(() -> new EntityNotFoundException(TargetTag.class, targetTagId));
|
||||||
@@ -568,25 +569,20 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
.orElseGet(Collections::emptyList) :
|
.orElseGet(Collections::emptyList) :
|
||||||
targetRepository
|
targetRepository
|
||||||
.findAll(TargetSpecifications.byControllerIdWithTagsInJoin(controllerIds));
|
.findAll(TargetSpecifications.byControllerIdWithTagsInJoin(controllerIds));
|
||||||
final EntityNotFoundException notFoundException;
|
if (targets.size() < controllerIds.size()) {
|
||||||
if (targets.size() < controllerIds.size() && notFoundPolicy != OnNotFoundPolicy.TAG_AND_SUCCESS) {
|
final Collection<String> notFound = notFound(controllerIds, targets);
|
||||||
notFoundException = new EntityNotFoundException(Target.class, notFound(controllerIds, targets));
|
if (notFoundHandler == null) {
|
||||||
if (notFoundPolicy == OnNotFoundPolicy.FAIL) {
|
throw new EntityNotFoundException(Target.class, notFound);
|
||||||
throw notFoundException;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
notFoundException = null;
|
notFoundHandler.accept(notFound);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
targetRepository.getAccessController()
|
targetRepository.getAccessController()
|
||||||
.ifPresent(acm -> acm.assertOperationAllowed(AccessController.Operation.UPDATE, targets));
|
.ifPresent(acm -> acm.assertOperationAllowed(AccessController.Operation.UPDATE, targets));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final List<Target> result = targets.stream().map(target -> updater.apply(tag, target)).toList();
|
return targets.stream().map(target -> updater.apply(tag, target)).toList();
|
||||||
if (notFoundException != null) { // if notFoundPolicy is NotFoundPolicy.TAG_AND_FAIL
|
|
||||||
throw notFoundException;
|
|
||||||
} else {
|
|
||||||
return result; // if all found or notFoundPolicy is NotFoundPolicy.TAG_AND_SUCCESS
|
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
// No reason to save the tag
|
// No reason to save the tag
|
||||||
entityManager.detach(tag);
|
entityManager.detach(tag);
|
||||||
|
|||||||
@@ -42,6 +42,12 @@ import org.springframework.web.bind.annotation.RequestParam;
|
|||||||
@Tag(name = "Target Tags", description = "REST API for Target Tag CRUD operations.")
|
@Tag(name = "Target Tags", description = "REST API for Target Tag CRUD operations.")
|
||||||
public interface MgmtTargetTagRestApi {
|
public interface MgmtTargetTagRestApi {
|
||||||
|
|
||||||
|
enum OnNotFoundPolicy {
|
||||||
|
FAIL, // default
|
||||||
|
ON_WHAT_FOUND_AND_FAIL,
|
||||||
|
ON_WHAT_FOUND_AND_SUCCESS
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the GET request of retrieving all target tags.
|
* Handles the GET request of retrieving all target tags.
|
||||||
*
|
*
|
||||||
@@ -351,6 +357,7 @@ public interface MgmtTargetTagRestApi {
|
|||||||
consumes = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE } )
|
consumes = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE } )
|
||||||
ResponseEntity<Void> assignTargets(
|
ResponseEntity<Void> assignTargets(
|
||||||
@PathVariable("targetTagId") Long targetTagId,
|
@PathVariable("targetTagId") Long targetTagId,
|
||||||
|
@RequestParam(value = "onNotFoundPolicy", required = false, defaultValue = "FAIL") OnNotFoundPolicy onNotFoundPolicy,
|
||||||
@Schema(description = "List of controller ids to be assigned", example = "[\"controllerId1\", \"controllerId2\"]")
|
@Schema(description = "List of controller ids to be assigned", example = "[\"controllerId1\", \"controllerId2\"]")
|
||||||
@RequestBody List<String> controllerIds);
|
@RequestBody List<String> controllerIds);
|
||||||
|
|
||||||
@@ -410,6 +417,7 @@ public interface MgmtTargetTagRestApi {
|
|||||||
consumes = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE })
|
consumes = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE })
|
||||||
ResponseEntity<Void> unassignTargets(
|
ResponseEntity<Void> unassignTargets(
|
||||||
@PathVariable("targetTagId") Long targetTagId,
|
@PathVariable("targetTagId") Long targetTagId,
|
||||||
|
@RequestParam(value = "onNotFoundPolicy", required = false, defaultValue = "FAIL") OnNotFoundPolicy onNotFoundPolicy,
|
||||||
@Schema(description = "List of controller ids to be unassigned", example = "[\"controllerId1\", \"controllerId2\"]")
|
@Schema(description = "List of controller ids to be unassigned", example = "[\"controllerId1\", \"controllerId2\"]")
|
||||||
@RequestBody List<String> controllerId);
|
@RequestBody List<String> controllerId);
|
||||||
|
|
||||||
|
|||||||
@@ -9,10 +9,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.mgmt.rest.resource;
|
package org.eclipse.hawkbit.mgmt.rest.resource;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.PagedList;
|
import org.eclipse.hawkbit.mgmt.json.model.PagedList;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.tag.MgmtAssignedTargetRequestBody;
|
import org.eclipse.hawkbit.mgmt.json.model.tag.MgmtAssignedTargetRequestBody;
|
||||||
@@ -186,14 +187,25 @@ public class MgmtTargetTagResource implements MgmtTargetTagRestApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResponseEntity<Void> assignTargets(final Long targetTagId, final List<String> controllerIds) {
|
public ResponseEntity<Void> assignTargets(final Long targetTagId, final OnNotFoundPolicy onNotFoundPolicy, final List<String> controllerIds) {
|
||||||
log.debug("Assign {} targets for target tag {}", controllerIds.size(), targetTagId);
|
log.debug("Assign {} targets for target tag {}", controllerIds.size(), targetTagId);
|
||||||
|
if (onNotFoundPolicy == OnNotFoundPolicy.FAIL) {
|
||||||
this.targetManagement.assignTag(controllerIds, targetTagId);
|
this.targetManagement.assignTag(controllerIds, targetTagId);
|
||||||
|
} else {
|
||||||
|
final AtomicReference<Collection<String>> notFound = new AtomicReference<>();
|
||||||
|
this.targetManagement.assignTag(controllerIds, targetTagId, notFound::set);
|
||||||
|
if (notFound.get() != null) {
|
||||||
|
// has not found
|
||||||
|
if (onNotFoundPolicy == OnNotFoundPolicy.ON_WHAT_FOUND_AND_FAIL) {
|
||||||
|
throw new EntityNotFoundException(Target.class, notFound.get());
|
||||||
|
} // else - success
|
||||||
|
}
|
||||||
|
}
|
||||||
return ResponseEntity.ok().build();
|
return ResponseEntity.ok().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResponseEntity<Void> unassignTarget(@PathVariable("targetTagId") final Long targetTagId,
|
public ResponseEntity<Void> unassignTarget(final Long targetTagId,
|
||||||
@PathVariable("controllerId") final String controllerId) {
|
@PathVariable("controllerId") final String controllerId) {
|
||||||
log.debug("Unassign target {} for target tag {}", controllerId, targetTagId);
|
log.debug("Unassign target {} for target tag {}", controllerId, targetTagId);
|
||||||
this.targetManagement.unassignTag(controllerId, targetTagId);
|
this.targetManagement.unassignTag(controllerId, targetTagId);
|
||||||
@@ -201,9 +213,20 @@ public class MgmtTargetTagResource implements MgmtTargetTagRestApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResponseEntity<Void> unassignTargets(final Long targetTagId, final List<String> controllerIds) {
|
public ResponseEntity<Void> unassignTargets(final Long targetTagId, final OnNotFoundPolicy onNotFoundPolicy, final List<String> controllerIds) {
|
||||||
log.debug("Unassign {} targets for target tag {}", controllerIds.size(), targetTagId);
|
log.debug("Unassign {} targets for target tag {}", controllerIds.size(), targetTagId);
|
||||||
|
if (onNotFoundPolicy == OnNotFoundPolicy.FAIL) {
|
||||||
this.targetManagement.unassignTag(controllerIds, targetTagId);
|
this.targetManagement.unassignTag(controllerIds, targetTagId);
|
||||||
|
} else {
|
||||||
|
final AtomicReference<Collection<String>> notFound = new AtomicReference<>();
|
||||||
|
this.targetManagement.unassignTag(controllerIds, targetTagId, notFound::set);
|
||||||
|
if (notFound.get() != null) {
|
||||||
|
// has not found
|
||||||
|
if (onNotFoundPolicy == OnNotFoundPolicy.ON_WHAT_FOUND_AND_FAIL) {
|
||||||
|
throw new EntityNotFoundException(Target.class, notFound.get());
|
||||||
|
} // else - success
|
||||||
|
}
|
||||||
|
}
|
||||||
return ResponseEntity.ok().build();
|
return ResponseEntity.ok().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,13 +30,13 @@ import java.util.Random;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
|
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
|
||||||
|
import org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetTagRestApi;
|
||||||
import org.eclipse.hawkbit.repository.event.remote.TargetTagDeletedEvent;
|
import org.eclipse.hawkbit.repository.event.remote.TargetTagDeletedEvent;
|
||||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetCreatedEvent;
|
import org.eclipse.hawkbit.repository.event.remote.entity.TargetCreatedEvent;
|
||||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetTagCreatedEvent;
|
import org.eclipse.hawkbit.repository.event.remote.entity.TargetTagCreatedEvent;
|
||||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetTagUpdatedEvent;
|
import org.eclipse.hawkbit.repository.event.remote.entity.TargetTagUpdatedEvent;
|
||||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent;
|
import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent;
|
||||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
|
|
||||||
import org.eclipse.hawkbit.repository.model.Tag;
|
import org.eclipse.hawkbit.repository.model.Tag;
|
||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetTag;
|
import org.eclipse.hawkbit.repository.model.TargetTag;
|
||||||
@@ -344,6 +344,82 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT
|
|||||||
Collections.sort(notFound);
|
Collections.sort(notFound);
|
||||||
assertThat(notFound).isEqualTo(missing);
|
assertThat(notFound).isEqualTo(missing);
|
||||||
});
|
});
|
||||||
|
assertThat(targetManagement.findByTag(PAGE, tag.getId()).getContent()).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Description("Verifies that tag assignments (multi targets) done through tag API command are correctly stored in the repository.")
|
||||||
|
@ExpectEvents({
|
||||||
|
@Expect(type = TargetTagCreatedEvent.class, count = 1),
|
||||||
|
@Expect(type = TargetCreatedEvent.class, count = 2),
|
||||||
|
@Expect(type = TargetUpdatedEvent.class, count = 2)})
|
||||||
|
public void assignTargetsNotFoundTagAndFail() throws Exception {
|
||||||
|
final TargetTag tag = testdataFactory.createTargetTags(1, "").get(0);
|
||||||
|
final List<String> targets = testdataFactory.createTargets(2).stream().map(Target::getControllerId).toList();
|
||||||
|
final List<String> missing = new ArrayList<>();
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
while (true) {
|
||||||
|
final String id = String.valueOf(Math.abs(RND.nextLong()));
|
||||||
|
if (!targets.contains(id)) {
|
||||||
|
missing.add(id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Collections.sort(missing);
|
||||||
|
final List<String> withMissing = new ArrayList<>(targets);
|
||||||
|
withMissing.addAll(missing);
|
||||||
|
|
||||||
|
mvc.perform(put(MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/" + tag.getId() + "/assigned")
|
||||||
|
.param("onNotFoundPolicy", MgmtTargetTagRestApi.OnNotFoundPolicy.ON_WHAT_FOUND_AND_FAIL.name())
|
||||||
|
.content(JsonBuilder.toArray(withMissing))
|
||||||
|
.contentType(MediaType.APPLICATION_JSON))
|
||||||
|
.andDo(MockMvcResultPrinter.print())
|
||||||
|
.andExpect(status().isNotFound())
|
||||||
|
.andExpect(handler -> {
|
||||||
|
final ExceptionInfo exceptionInfo = ResourceUtility.convertException(handler.getResponse().getContentAsString());
|
||||||
|
final Map<String, Object> info = exceptionInfo.getInfo();
|
||||||
|
assertThat(info).isNotNull();
|
||||||
|
assertThat(info.get(EntityNotFoundException.TYPE)).isEqualTo(Target.class.getSimpleName());
|
||||||
|
final List<String> notFound = (List<String>) info.get(EntityNotFoundException.ENTITY_ID);
|
||||||
|
Collections.sort(notFound);
|
||||||
|
assertThat(notFound).isEqualTo(missing);
|
||||||
|
});
|
||||||
|
assertThat(targetManagement.findByTag(PAGE, tag.getId()).getContent().stream().map(Target::getControllerId).sorted().toList())
|
||||||
|
.isEqualTo(targets.stream().sorted().toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Description("Verifies that tag assignments (multi targets) done through tag API command are correctly stored in the repository.")
|
||||||
|
@ExpectEvents({
|
||||||
|
@Expect(type = TargetTagCreatedEvent.class, count = 1),
|
||||||
|
@Expect(type = TargetCreatedEvent.class, count = 2),
|
||||||
|
@Expect(type = TargetUpdatedEvent.class, count = 2)})
|
||||||
|
public void assignTargetsNotFoundTagAndSuccess() throws Exception {
|
||||||
|
final TargetTag tag = testdataFactory.createTargetTags(1, "").get(0);
|
||||||
|
final List<String> targets = testdataFactory.createTargets(2).stream().map(Target::getControllerId).toList();
|
||||||
|
final List<String> missing = new ArrayList<>();
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
while (true) {
|
||||||
|
final String id = String.valueOf(Math.abs(RND.nextLong()));
|
||||||
|
if (!targets.contains(id)) {
|
||||||
|
missing.add(id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Collections.sort(missing);
|
||||||
|
final List<String> withMissing = new ArrayList<>(targets);
|
||||||
|
withMissing.addAll(missing);
|
||||||
|
|
||||||
|
mvc.perform(put(MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/" + tag.getId() + "/assigned")
|
||||||
|
.param("onNotFoundPolicy", MgmtTargetTagRestApi.OnNotFoundPolicy.ON_WHAT_FOUND_AND_SUCCESS.name())
|
||||||
|
.content(JsonBuilder.toArray(withMissing))
|
||||||
|
.contentType(MediaType.APPLICATION_JSON))
|
||||||
|
.andDo(MockMvcResultPrinter.print())
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
assertThat(targetManagement.findByTag(PAGE, tag.getId()).getContent().stream().map(Target::getControllerId).sorted().toList())
|
||||||
|
.isEqualTo(targets.stream().sorted().toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -394,6 +470,126 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT
|
|||||||
.containsOnly(assigned.getControllerId());
|
.containsOnly(assigned.getControllerId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Description("Verifies that tag assignments (multi targets) done through tag API command are correctly stored in the repository.")
|
||||||
|
@ExpectEvents({
|
||||||
|
@Expect(type = TargetTagCreatedEvent.class, count = 1),
|
||||||
|
@Expect(type = TargetCreatedEvent.class, count = 2),
|
||||||
|
@Expect(type = TargetUpdatedEvent.class, count = 2)})
|
||||||
|
public void unassignTargetsNotFound() throws Exception {
|
||||||
|
final TargetTag tag = testdataFactory.createTargetTags(1, "").get(0);
|
||||||
|
final List<String> targets = testdataFactory.createTargets(2).stream().map(Target::getControllerId).toList();
|
||||||
|
final List<String> missing = new ArrayList<>();
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
while (true) {
|
||||||
|
final String id = String.valueOf(Math.abs(RND.nextLong()));
|
||||||
|
if (!targets.contains(id)) {
|
||||||
|
missing.add(id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Collections.sort(missing);
|
||||||
|
final List<String> withMissing = new ArrayList<>(targets);
|
||||||
|
withMissing.addAll(missing);
|
||||||
|
|
||||||
|
targetManagement.assignTag(targets, tag.getId());
|
||||||
|
|
||||||
|
mvc.perform(delete(MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/" + tag.getId() + "/assigned")
|
||||||
|
.content(JsonBuilder.toArray(withMissing))
|
||||||
|
.contentType(MediaType.APPLICATION_JSON))
|
||||||
|
.andDo(MockMvcResultPrinter.print())
|
||||||
|
.andExpect(status().isNotFound())
|
||||||
|
.andExpect(handler -> {
|
||||||
|
final ExceptionInfo exceptionInfo = ResourceUtility.convertException(handler.getResponse().getContentAsString());
|
||||||
|
final Map<String, Object> info = exceptionInfo.getInfo();
|
||||||
|
assertThat(info).isNotNull();
|
||||||
|
assertThat(info.get(EntityNotFoundException.TYPE)).isEqualTo(Target.class.getSimpleName());
|
||||||
|
final List<String> notFound = (List<String>) info.get(EntityNotFoundException.ENTITY_ID);
|
||||||
|
Collections.sort(notFound);
|
||||||
|
assertThat(notFound).isEqualTo(missing);
|
||||||
|
});
|
||||||
|
assertThat(targetManagement.findByTag(PAGE, tag.getId()).getContent().stream().map(Target::getControllerId).sorted().toList())
|
||||||
|
.isEqualTo(targets.stream().sorted().toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Description("Verifies that tag assignments (multi targets) done through tag API command are correctly stored in the repository.")
|
||||||
|
@ExpectEvents({
|
||||||
|
@Expect(type = TargetTagCreatedEvent.class, count = 1),
|
||||||
|
@Expect(type = TargetCreatedEvent.class, count = 2),
|
||||||
|
@Expect(type = TargetUpdatedEvent.class, count = 4)})
|
||||||
|
public void unassignTargetsNotFoundUntagAndFail() throws Exception {
|
||||||
|
final TargetTag tag = testdataFactory.createTargetTags(1, "").get(0);
|
||||||
|
final List<String> targets = testdataFactory.createTargets(2).stream().map(Target::getControllerId).toList();
|
||||||
|
final List<String> missing = new ArrayList<>();
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
while (true) {
|
||||||
|
final String id = String.valueOf(Math.abs(RND.nextLong()));
|
||||||
|
if (!targets.contains(id)) {
|
||||||
|
missing.add(id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Collections.sort(missing);
|
||||||
|
final List<String> withMissing = new ArrayList<>(targets);
|
||||||
|
withMissing.addAll(missing);
|
||||||
|
|
||||||
|
targetManagement.assignTag(targets, tag.getId());
|
||||||
|
|
||||||
|
mvc.perform(delete(MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/" + tag.getId() + "/assigned")
|
||||||
|
.param("onNotFoundPolicy", MgmtTargetTagRestApi.OnNotFoundPolicy.ON_WHAT_FOUND_AND_FAIL.name())
|
||||||
|
.content(JsonBuilder.toArray(withMissing))
|
||||||
|
.contentType(MediaType.APPLICATION_JSON))
|
||||||
|
.andDo(MockMvcResultPrinter.print())
|
||||||
|
.andExpect(status().isNotFound())
|
||||||
|
.andExpect(handler -> {
|
||||||
|
final ExceptionInfo exceptionInfo = ResourceUtility.convertException(handler.getResponse().getContentAsString());
|
||||||
|
final Map<String, Object> info = exceptionInfo.getInfo();
|
||||||
|
assertThat(info).isNotNull();
|
||||||
|
assertThat(info.get(EntityNotFoundException.TYPE)).isEqualTo(Target.class.getSimpleName());
|
||||||
|
final List<String> notFound = (List<String>) info.get(EntityNotFoundException.ENTITY_ID);
|
||||||
|
Collections.sort(notFound);
|
||||||
|
assertThat(notFound).isEqualTo(missing);
|
||||||
|
});
|
||||||
|
assertThat(targetManagement.findByTag(PAGE, tag.getId()).getContent()).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Description("Verifies that tag assignments (multi targets) done through tag API command are correctly stored in the repository.")
|
||||||
|
@ExpectEvents({
|
||||||
|
@Expect(type = TargetTagCreatedEvent.class, count = 1),
|
||||||
|
@Expect(type = TargetCreatedEvent.class, count = 2),
|
||||||
|
@Expect(type = TargetUpdatedEvent.class, count = 4)})
|
||||||
|
public void unassignTargetsNotFoundUntagAndSuccess() throws Exception {
|
||||||
|
final TargetTag tag = testdataFactory.createTargetTags(1, "").get(0);
|
||||||
|
final List<String> targets = testdataFactory.createTargets(2).stream().map(Target::getControllerId).toList();
|
||||||
|
final List<String> missing = new ArrayList<>();
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
while (true) {
|
||||||
|
final String id = String.valueOf(Math.abs(RND.nextLong()));
|
||||||
|
if (!targets.contains(id)) {
|
||||||
|
missing.add(id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Collections.sort(missing);
|
||||||
|
final List<String> withMissing = new ArrayList<>(targets);
|
||||||
|
withMissing.addAll(missing);
|
||||||
|
|
||||||
|
targetManagement.assignTag(targets, tag.getId());
|
||||||
|
|
||||||
|
mvc.perform(delete(MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/" + tag.getId() + "/assigned")
|
||||||
|
.param("onNotFoundPolicy", MgmtTargetTagRestApi.OnNotFoundPolicy.ON_WHAT_FOUND_AND_SUCCESS.name())
|
||||||
|
.content(JsonBuilder.toArray(withMissing))
|
||||||
|
.contentType(MediaType.APPLICATION_JSON))
|
||||||
|
.andDo(MockMvcResultPrinter.print())
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
assertThat(targetManagement.findByTag(PAGE, tag.getId()).getContent()).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
// DEPRECATED scenarios
|
// DEPRECATED scenarios
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifes that tag assignments done through toggle API command are correctly assigned or unassigned.")
|
@Description("Verifes that tag assignments done through toggle API command are correctly assigned or unassigned.")
|
||||||
|
|||||||
Reference in New Issue
Block a user