Merge pull request #64 from bsinno/mgmtapi-shows-wrong-status-content
👍 ok merging
This commit is contained in:
@@ -20,7 +20,12 @@ public enum ActionStatusFields implements FieldNameProvider {
|
|||||||
/**
|
/**
|
||||||
* The id field.
|
* The id field.
|
||||||
*/
|
*/
|
||||||
ID("id");
|
ID("id"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The reportedAt field.
|
||||||
|
*/
|
||||||
|
REPORTEDAT("createdAt");
|
||||||
|
|
||||||
private final String fieldName;
|
private final String fieldName;
|
||||||
|
|
||||||
|
|||||||
@@ -21,45 +21,47 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
/**
|
/**
|
||||||
* {@link ActionStatus} repository.
|
* {@link ActionStatus} repository.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public interface ActionStatusRepository
|
public interface ActionStatusRepository
|
||||||
extends BaseEntityRepository<ActionStatus, Long>, JpaSpecificationExecutor<ActionStatus> {
|
extends BaseEntityRepository<ActionStatus, Long>, JpaSpecificationExecutor<ActionStatus> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param target
|
* Counts {@link ActionStatus} entries of given {@link Action} in
|
||||||
|
* repository.
|
||||||
|
*
|
||||||
* @param action
|
* @param action
|
||||||
* @return
|
* to count status entries
|
||||||
|
* @return number of actions in repository
|
||||||
*/
|
*/
|
||||||
Long countByAction(Action action);
|
Long countByAction(Action action);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Counts {@link ActionStatus} entries of given {@link Action} with given
|
||||||
|
* {@link Status} in repository.
|
||||||
|
*
|
||||||
* @param action
|
* @param action
|
||||||
* @param retrieved
|
* to count status entries
|
||||||
* @return
|
* @param status
|
||||||
|
* to filter for
|
||||||
|
* @return number of actions in repository
|
||||||
*/
|
*/
|
||||||
Long countByActionAndStatus(Action action, Status retrieved);
|
Long countByActionAndStatus(Action action, Status status);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Retrieves all {@link ActionStatus} entries from repository of given
|
||||||
|
* {@link Action}.
|
||||||
|
*
|
||||||
* @param pageReq
|
* @param pageReq
|
||||||
|
* parameters
|
||||||
* @param action
|
* @param action
|
||||||
* @return
|
* of the status entries
|
||||||
|
* @return pages list of {@link ActionStatus} entries
|
||||||
*/
|
*/
|
||||||
Page<ActionStatus> findByAction(Pageable pageReq, Action action);
|
Page<ActionStatus> findByAction(Pageable pageReq, Action action);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param pageReq
|
* Finds all status updates for the defined action and target including
|
||||||
* @param action
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
Page<ActionStatus> findByActionOrderByIdDesc(Pageable pageReq, Action action);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds all status updates for the defined action and target order by
|
|
||||||
* {@link ActionStatus#getId()} desc including
|
|
||||||
* {@link ActionStatus#getMessages()}.
|
* {@link ActionStatus#getMessages()}.
|
||||||
*
|
*
|
||||||
* @param pageReq
|
* @param pageReq
|
||||||
@@ -71,6 +73,6 @@ public interface ActionStatusRepository
|
|||||||
* @return Page with found targets
|
* @return Page with found targets
|
||||||
*/
|
*/
|
||||||
@EntityGraph(value = "ActionStatus.withMessages", type = EntityGraphType.LOAD)
|
@EntityGraph(value = "ActionStatus.withMessages", type = EntityGraphType.LOAD)
|
||||||
Page<ActionStatus> getByActionOrderByIdDesc(Pageable pageReq, Action action);
|
Page<ActionStatus> getByAction(Pageable pageReq, Action action);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -925,7 +925,7 @@ public class DeploymentManagement {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* retrieves all the {@link ActionStatus} entries of the given
|
* retrieves all the {@link ActionStatus} entries of the given
|
||||||
* {@link Action} and {@link Target} in the order latest first.
|
* {@link Action} and {@link Target}.
|
||||||
*
|
*
|
||||||
* @param pageReq
|
* @param pageReq
|
||||||
* pagination parameter
|
* pagination parameter
|
||||||
@@ -937,12 +937,12 @@ public class DeploymentManagement {
|
|||||||
* @return the corresponding {@link Page} of {@link ActionStatus}
|
* @return the corresponding {@link Page} of {@link ActionStatus}
|
||||||
*/
|
*/
|
||||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
||||||
public Page<ActionStatus> findActionStatusMessagesByActionInDescOrder(final Pageable pageReq, final Action action,
|
public Page<ActionStatus> findActionStatusByAction(final Pageable pageReq, final Action action,
|
||||||
final boolean withMessages) {
|
final boolean withMessages) {
|
||||||
if (withMessages) {
|
if (withMessages) {
|
||||||
return actionStatusRepository.getByActionOrderByIdDesc(pageReq, action);
|
return actionStatusRepository.getByAction(pageReq, action);
|
||||||
} else {
|
} else {
|
||||||
return actionStatusRepository.findByActionOrderByIdDesc(pageReq, action);
|
return actionStatusRepository.findByAction(pageReq, action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -70,8 +70,8 @@ public class ControllerManagementTest extends AbstractIntegrationTest {
|
|||||||
.isEqualTo(TargetUpdateStatus.IN_SYNC);
|
.isEqualTo(TargetUpdateStatus.IN_SYNC);
|
||||||
|
|
||||||
assertThat(actionStatusRepository.findAll(pageReq).getNumberOfElements()).isEqualTo(3);
|
assertThat(actionStatusRepository.findAll(pageReq).getNumberOfElements()).isEqualTo(3);
|
||||||
assertThat(deploymentManagement.findActionStatusMessagesByActionInDescOrder(pageReq, savedAction, false)
|
assertThat(deploymentManagement.findActionStatusByAction(pageReq, savedAction, false).getNumberOfElements())
|
||||||
.getNumberOfElements()).isEqualTo(3);
|
.isEqualTo(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -23,11 +23,6 @@ import org.springframework.data.domain.Sort.Direction;
|
|||||||
/**
|
/**
|
||||||
* Utility class for for paged body generation.
|
* Utility class for for paged body generation.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public final class PagingUtility {
|
public final class PagingUtility {
|
||||||
/*
|
/*
|
||||||
@@ -90,8 +85,9 @@ public final class PagingUtility {
|
|||||||
if (sortParam != null) {
|
if (sortParam != null) {
|
||||||
sorting = new Sort(SortUtility.parse(ActionFields.class, sortParam));
|
sorting = new Sort(SortUtility.parse(ActionFields.class, sortParam));
|
||||||
} else {
|
} else {
|
||||||
// default sort
|
// default sort is DESC in case of action to match behavior
|
||||||
sorting = new Sort(Direction.ASC, ActionFields.ID.getFieldName());
|
// of management UI (last entry on top)
|
||||||
|
sorting = new Sort(Direction.DESC, ActionFields.ID.getFieldName());
|
||||||
}
|
}
|
||||||
return sorting;
|
return sorting;
|
||||||
}
|
}
|
||||||
@@ -101,8 +97,9 @@ public final class PagingUtility {
|
|||||||
if (sortParam != null) {
|
if (sortParam != null) {
|
||||||
sorting = new Sort(SortUtility.parse(ActionStatusFields.class, sortParam));
|
sorting = new Sort(SortUtility.parse(ActionStatusFields.class, sortParam));
|
||||||
} else {
|
} else {
|
||||||
// default sort
|
// default sort is DESC in case of action status to match behavior
|
||||||
sorting = new Sort(Direction.ASC, ActionStatusFields.ID.getFieldName());
|
// of management UI (last entry on top)
|
||||||
|
sorting = new Sort(Direction.DESC, ActionStatusFields.ID.getFieldName());
|
||||||
}
|
}
|
||||||
return sorting;
|
return sorting;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -297,8 +297,8 @@ final public class TargetMapper {
|
|||||||
final ActionStatusRest result = new ActionStatusRest();
|
final ActionStatusRest result = new ActionStatusRest();
|
||||||
|
|
||||||
result.setMessages(actionStatus.getMessages());
|
result.setMessages(actionStatus.getMessages());
|
||||||
result.setReportedAt(action.getCreatedAt());
|
result.setReportedAt(actionStatus.getCreatedAt());
|
||||||
result.setStatusId(action.getId());
|
result.setStatusId(actionStatus.getId());
|
||||||
result.setType(getNameOfActionStatusType(actionStatus.getStatus()));
|
result.setType(getNameOfActionStatusType(actionStatus.getStatus()));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -235,7 +235,7 @@ public class TargetResource implements TargetRestApi {
|
|||||||
final int sanitizedLimitParam = PagingUtility.sanitizePageLimitParam(pagingLimitParam);
|
final int sanitizedLimitParam = PagingUtility.sanitizePageLimitParam(pagingLimitParam);
|
||||||
final Sort sorting = PagingUtility.sanitizeActionStatusSortParam(sortParam);
|
final Sort sorting = PagingUtility.sanitizeActionStatusSortParam(sortParam);
|
||||||
|
|
||||||
final Page<ActionStatus> statusList = this.deploymentManagement.findActionStatusMessagesByActionInDescOrder(
|
final Page<ActionStatus> statusList = this.deploymentManagement.findActionStatusByAction(
|
||||||
new OffsetBasedPageRequest(sanitizedOffsetParam, sanitizedLimitParam, sorting), action, true);
|
new OffsetBasedPageRequest(sanitizedOffsetParam, sanitizedLimitParam, sorting), action, true);
|
||||||
|
|
||||||
return new ResponseEntity<>(
|
return new ResponseEntity<>(
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ package org.eclipse.hawkbit.rest.resource;
|
|||||||
import static org.fest.assertions.api.Assertions.assertThat;
|
import static org.fest.assertions.api.Assertions.assertThat;
|
||||||
import static org.hamcrest.CoreMatchers.equalTo;
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
import static org.hamcrest.CoreMatchers.not;
|
import static org.hamcrest.CoreMatchers.not;
|
||||||
|
import static org.hamcrest.Matchers.hasItem;
|
||||||
import static org.hamcrest.Matchers.hasKey;
|
import static org.hamcrest.Matchers.hasKey;
|
||||||
import static org.hamcrest.Matchers.hasSize;
|
import static org.hamcrest.Matchers.hasSize;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
|
||||||
@@ -34,6 +35,7 @@ import org.eclipse.hawkbit.TestDataUtil;
|
|||||||
import org.eclipse.hawkbit.WithUser;
|
import org.eclipse.hawkbit.WithUser;
|
||||||
import org.eclipse.hawkbit.exception.SpServerError;
|
import org.eclipse.hawkbit.exception.SpServerError;
|
||||||
import org.eclipse.hawkbit.im.authentication.SpPermission;
|
import org.eclipse.hawkbit.im.authentication.SpPermission;
|
||||||
|
import org.eclipse.hawkbit.repository.ActionFields;
|
||||||
import org.eclipse.hawkbit.repository.ActionStatusFields;
|
import org.eclipse.hawkbit.repository.ActionStatusFields;
|
||||||
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
||||||
import org.eclipse.hawkbit.repository.model.Action;
|
import org.eclipse.hawkbit.repository.model.Action;
|
||||||
@@ -116,27 +118,24 @@ public class TargetResourceTest extends AbstractIntegrationTest {
|
|||||||
new ActionStatus(actions.get(0), Status.FINISHED, System.currentTimeMillis(), "testmessage"),
|
new ActionStatus(actions.get(0), Status.FINISHED, System.currentTimeMillis(), "testmessage"),
|
||||||
actions.get(0));
|
actions.get(0));
|
||||||
|
|
||||||
final PageRequest pageRequest = new PageRequest(0, 1000, Direction.ASC, ActionStatusFields.ID.getFieldName());
|
final PageRequest pageRequest = new PageRequest(0, 1000, Direction.ASC, ActionFields.ID.getFieldName());
|
||||||
|
final ActionStatus status = deploymentManagement
|
||||||
|
.findActionsByTarget(pageRequest, targetManagement.findTargetByControllerID(knownTargetId)).getContent()
|
||||||
|
.get(0).getActionStatus().stream().sorted((e1, e2) -> Long.compare(e2.getId(), e1.getId()))
|
||||||
|
.collect(Collectors.toList()).get(0);
|
||||||
|
|
||||||
// limit to 1 - first page -> standard cancel message
|
|
||||||
final Long reportAt = deploymentManagement
|
|
||||||
.findActionsByTarget(pageRequest, targetManagement.findTargetByControllerID(knownTargetId)).getContent()
|
|
||||||
.get(0).getCreatedAt();
|
|
||||||
final Long id = deploymentManagement
|
|
||||||
.findActionsByTarget(pageRequest, targetManagement.findTargetByControllerID(knownTargetId)).getContent()
|
|
||||||
.get(0).getId();
|
|
||||||
mvc.perform(get(RestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/"
|
mvc.perform(get(RestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/"
|
||||||
+ RestConstants.TARGET_V1_ACTIONS + "/" + actions.get(0).getId() + "/status")
|
+ RestConstants.TARGET_V1_ACTIONS + "/" + actions.get(0).getId() + "/status")
|
||||||
.param(RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(limitSize))
|
.param(RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(limitSize))
|
||||||
.param(RestConstants.REQUEST_PARAMETER_SORTING, "ID:ASC"))
|
.param(RestConstants.REQUEST_PARAMETER_SORTING, "ID:DESC"))
|
||||||
.andExpect(status().isOk()).andDo(MockMvcResultPrinter.print())
|
.andExpect(status().isOk()).andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_TOTAL, equalTo(3)))
|
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_TOTAL, equalTo(3)))
|
||||||
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_SIZE, equalTo(limitSize)))
|
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_SIZE, equalTo(limitSize)))
|
||||||
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_CONTENT, hasSize(limitSize)))
|
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_CONTENT, hasSize(limitSize)))
|
||||||
.andExpect(jsonPath("content.[0].id", equalTo(id.intValue())))
|
.andExpect(jsonPath("content.[0].id", equalTo(status.getId().intValue())))
|
||||||
.andExpect(jsonPath("content.[0].type", equalTo("finished")))
|
.andExpect(jsonPath("content.[0].type", equalTo("finished")))
|
||||||
.andExpect(jsonPath("content.[0].messages", hasSize(1)))
|
.andExpect(jsonPath("content.[0].messages", hasSize(1)))
|
||||||
.andExpect(jsonPath("content.[0].reportedAt", equalTo(reportAt)))
|
.andExpect(jsonPath("content.[0].reportedAt", equalTo(status.getCreatedAt().longValue())))
|
||||||
.andExpect(jsonPath("content.[1].type", equalTo("canceling")));
|
.andExpect(jsonPath("content.[1].type", equalTo("canceling")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,7 +228,7 @@ public class TargetResourceTest extends AbstractIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
public void cancelActionOK() throws Exception {
|
public void cancelActionOK() throws Exception {
|
||||||
// prepare test
|
// prepare test
|
||||||
Target tA = createTargetAndStartAction();
|
final Target tA = createTargetAndStartAction();
|
||||||
|
|
||||||
// test - cancel the active action
|
// test - cancel the active action
|
||||||
mvc.perform(delete(RestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/actions/{actionId}",
|
mvc.perform(delete(RestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/actions/{actionId}",
|
||||||
@@ -252,7 +251,7 @@ public class TargetResourceTest extends AbstractIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
public void cancelAnCancelActionIsNotAllowed() throws Exception {
|
public void cancelAnCancelActionIsNotAllowed() throws Exception {
|
||||||
// prepare test
|
// prepare test
|
||||||
Target tA = createTargetAndStartAction();
|
final Target tA = createTargetAndStartAction();
|
||||||
|
|
||||||
// cancel the active action
|
// cancel the active action
|
||||||
deploymentManagement.cancelAction(tA.getActions().get(0), tA);
|
deploymentManagement.cancelAction(tA.getActions().get(0), tA);
|
||||||
@@ -272,7 +271,7 @@ public class TargetResourceTest extends AbstractIntegrationTest {
|
|||||||
@Description("Force Quit an Action, which is already canceled. Expected Result is an HTTP response code 204.")
|
@Description("Force Quit an Action, which is already canceled. Expected Result is an HTTP response code 204.")
|
||||||
public void forceQuitAnCanceledActionReturnsOk() throws Exception {
|
public void forceQuitAnCanceledActionReturnsOk() throws Exception {
|
||||||
|
|
||||||
Target tA = createTargetAndStartAction();
|
final Target tA = createTargetAndStartAction();
|
||||||
|
|
||||||
// cancel the active action
|
// cancel the active action
|
||||||
deploymentManagement.cancelAction(tA.getActions().get(0), tA);
|
deploymentManagement.cancelAction(tA.getActions().get(0), tA);
|
||||||
@@ -293,7 +292,7 @@ public class TargetResourceTest extends AbstractIntegrationTest {
|
|||||||
@Description("Force Quit an Action, which is not canceled. Expected Result is an HTTP response code 405.")
|
@Description("Force Quit an Action, which is not canceled. Expected Result is an HTTP response code 405.")
|
||||||
public void forceQuitAnNotCanceledActionReturnsMethodNotAllowed() throws Exception {
|
public void forceQuitAnNotCanceledActionReturnsMethodNotAllowed() throws Exception {
|
||||||
|
|
||||||
Target tA = createTargetAndStartAction();
|
final Target tA = createTargetAndStartAction();
|
||||||
|
|
||||||
// test - cancel an cancel action returns forbidden
|
// test - cancel an cancel action returns forbidden
|
||||||
mvc.perform(delete(RestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/actions/{actionId}?force=true",
|
mvc.perform(delete(RestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/actions/{actionId}?force=true",
|
||||||
@@ -834,7 +833,8 @@ public class TargetResourceTest extends AbstractIntegrationTest {
|
|||||||
final List<Action> actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId);
|
final List<Action> actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId);
|
||||||
|
|
||||||
mvc.perform(get(
|
mvc.perform(get(
|
||||||
RestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" + RestConstants.TARGET_V1_ACTIONS))
|
RestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" + RestConstants.TARGET_V1_ACTIONS)
|
||||||
|
.param(RestConstants.REQUEST_PARAMETER_SORTING, "ID:ASC"))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("content.[1].id", equalTo(actions.get(1).getId().intValue())))
|
.andExpect(jsonPath("content.[1].id", equalTo(actions.get(1).getId().intValue())))
|
||||||
.andExpect(jsonPath("content.[1].type", equalTo("update")))
|
.andExpect(jsonPath("content.[1].type", equalTo("update")))
|
||||||
@@ -851,6 +851,108 @@ public class TargetResourceTest extends AbstractIntegrationTest {
|
|||||||
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_CONTENT, hasSize(2)));
|
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_CONTENT, hasSize(2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Description("Verfies that the API returns the status list with expected content.")
|
||||||
|
public void getMultipleActionStatus() throws Exception {
|
||||||
|
final String knownTargetId = "targetId";
|
||||||
|
final Action action = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId).get(0);
|
||||||
|
// retrieve list in default descending order for actionstaus entries
|
||||||
|
final List<ActionStatus> actionStatus = action.getActionStatus().stream()
|
||||||
|
.sorted((e1, e2) -> Long.compare(e2.getId(), e1.getId())).collect(Collectors.toList());
|
||||||
|
|
||||||
|
// sort is default descending order, latest status first
|
||||||
|
mvc.perform(get(RestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/"
|
||||||
|
+ RestConstants.TARGET_V1_ACTIONS + "/" + action.getId() + "/" + RestConstants.TARGET_V1_ACTION_STATUS))
|
||||||
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("content.[0].id", equalTo(actionStatus.get(0).getId().intValue())))
|
||||||
|
.andExpect(jsonPath("content.[0].type", equalTo("canceling")))
|
||||||
|
.andExpect(jsonPath("content.[0].messages", hasItem("manual cancelation requested")))
|
||||||
|
.andExpect(jsonPath("content.[0].reportedAt", equalTo(actionStatus.get(0).getCreatedAt())))
|
||||||
|
.andExpect(jsonPath("content.[1].id", equalTo(actionStatus.get(1).getId().intValue())))
|
||||||
|
.andExpect(jsonPath("content.[1].type", equalTo("running")))
|
||||||
|
.andExpect(jsonPath("content.[1].reportedAt", equalTo(actionStatus.get(1).getCreatedAt())))
|
||||||
|
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_TOTAL, equalTo(2)))
|
||||||
|
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_SIZE, equalTo(2)))
|
||||||
|
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_CONTENT, hasSize(2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Description("Verfies that the API returns the status list with expected content sorted by reportedAt field.")
|
||||||
|
public void getMultipleActionStatusSortedByReportedAt() throws Exception {
|
||||||
|
final String knownTargetId = "targetId";
|
||||||
|
final Action action = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId).get(0);
|
||||||
|
final List<ActionStatus> actionStatus = action.getActionStatus().stream()
|
||||||
|
.sorted((e1, e2) -> Long.compare(e1.getId(), e2.getId())).collect(Collectors.toList());
|
||||||
|
|
||||||
|
// descending order
|
||||||
|
mvc.perform(get(RestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/"
|
||||||
|
+ RestConstants.TARGET_V1_ACTIONS + "/" + action.getId() + "/" + RestConstants.TARGET_V1_ACTION_STATUS)
|
||||||
|
.param(RestConstants.REQUEST_PARAMETER_SORTING, "REPORTEDAT:DESC"))
|
||||||
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("content.[0].id", equalTo(actionStatus.get(1).getId().intValue())))
|
||||||
|
.andExpect(jsonPath("content.[0].type", equalTo("canceling")))
|
||||||
|
.andExpect(jsonPath("content.[0].messages", hasItem("manual cancelation requested")))
|
||||||
|
.andExpect(jsonPath("content.[0].reportedAt", equalTo(actionStatus.get(1).getCreatedAt())))
|
||||||
|
.andExpect(jsonPath("content.[1].id", equalTo(actionStatus.get(0).getId().intValue())))
|
||||||
|
.andExpect(jsonPath("content.[1].type", equalTo("running")))
|
||||||
|
.andExpect(jsonPath("content.[1].reportedAt", equalTo(actionStatus.get(0).getCreatedAt())))
|
||||||
|
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_TOTAL, equalTo(2)))
|
||||||
|
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_SIZE, equalTo(2)))
|
||||||
|
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_CONTENT, hasSize(2)));
|
||||||
|
|
||||||
|
// ascending order
|
||||||
|
mvc.perform(get(RestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/"
|
||||||
|
+ RestConstants.TARGET_V1_ACTIONS + "/" + action.getId() + "/" + RestConstants.TARGET_V1_ACTION_STATUS)
|
||||||
|
.param(RestConstants.REQUEST_PARAMETER_SORTING, "REPORTEDAT:ASC"))
|
||||||
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("content.[1].id", equalTo(actionStatus.get(1).getId().intValue())))
|
||||||
|
.andExpect(jsonPath("content.[1].type", equalTo("canceling")))
|
||||||
|
.andExpect(jsonPath("content.[1].messages", hasItem("manual cancelation requested")))
|
||||||
|
.andExpect(jsonPath("content.[1].reportedAt", equalTo(actionStatus.get(1).getCreatedAt())))
|
||||||
|
.andExpect(jsonPath("content.[0].id", equalTo(actionStatus.get(0).getId().intValue())))
|
||||||
|
.andExpect(jsonPath("content.[0].type", equalTo("running")))
|
||||||
|
.andExpect(jsonPath("content.[0].reportedAt", equalTo(actionStatus.get(0).getCreatedAt())))
|
||||||
|
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_TOTAL, equalTo(2)))
|
||||||
|
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_SIZE, equalTo(2)))
|
||||||
|
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_CONTENT, hasSize(2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Description("Verfies that the API returns the status list with expected content split into two pages.")
|
||||||
|
public void getMultipleActionStatusWithPagingLimitRequestParameter() throws Exception {
|
||||||
|
final String knownTargetId = "targetId";
|
||||||
|
|
||||||
|
final Action action = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId).get(0);
|
||||||
|
final List<ActionStatus> actionStatus = action.getActionStatus().stream()
|
||||||
|
.sorted((e1, e2) -> Long.compare(e1.getId(), e2.getId())).collect(Collectors.toList());
|
||||||
|
|
||||||
|
// Page 1
|
||||||
|
mvc.perform(get(RestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/"
|
||||||
|
+ RestConstants.TARGET_V1_ACTIONS + "/" + action.getId() + "/" + RestConstants.TARGET_V1_ACTION_STATUS)
|
||||||
|
.param(RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(1)))
|
||||||
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("content.[0].id", equalTo(actionStatus.get(1).getId().intValue())))
|
||||||
|
.andExpect(jsonPath("content.[0].type", equalTo("canceling")))
|
||||||
|
.andExpect(jsonPath("content.[0].messages", hasItem("manual cancelation requested")))
|
||||||
|
.andExpect(jsonPath("content.[0].reportedAt", equalTo(actionStatus.get(1).getCreatedAt())))
|
||||||
|
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_TOTAL, equalTo(2)))
|
||||||
|
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_SIZE, equalTo(1)))
|
||||||
|
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_CONTENT, hasSize(1)));
|
||||||
|
|
||||||
|
// Page 2
|
||||||
|
mvc.perform(get(RestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/"
|
||||||
|
+ RestConstants.TARGET_V1_ACTIONS + "/" + action.getId() + "/" + RestConstants.TARGET_V1_ACTION_STATUS)
|
||||||
|
.param(RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(1))
|
||||||
|
.param(RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(1)))
|
||||||
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("content.[0].id", equalTo(actionStatus.get(0).getId().intValue())))
|
||||||
|
.andExpect(jsonPath("content.[0].type", equalTo("running")))
|
||||||
|
.andExpect(jsonPath("content.[0].reportedAt", equalTo(actionStatus.get(0).getCreatedAt())))
|
||||||
|
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_TOTAL, equalTo(2)))
|
||||||
|
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_SIZE, equalTo(1)))
|
||||||
|
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_CONTENT, hasSize(1)));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getMultipleActionsWithPagingLimitRequestParameter() throws Exception {
|
public void getMultipleActionsWithPagingLimitRequestParameter() throws Exception {
|
||||||
final String knownTargetId = "targetId";
|
final String knownTargetId = "targetId";
|
||||||
@@ -859,7 +961,8 @@ public class TargetResourceTest extends AbstractIntegrationTest {
|
|||||||
// page 1: one entry
|
// page 1: one entry
|
||||||
mvc.perform(get(
|
mvc.perform(get(
|
||||||
RestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" + RestConstants.TARGET_V1_ACTIONS)
|
RestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" + RestConstants.TARGET_V1_ACTIONS)
|
||||||
.param(RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(1)))
|
.param(RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(1))
|
||||||
|
.param(RestConstants.REQUEST_PARAMETER_SORTING, "ID:ASC"))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("content.[0].id", equalTo(actions.get(0).getId().intValue())))
|
.andExpect(jsonPath("content.[0].id", equalTo(actions.get(0).getId().intValue())))
|
||||||
.andExpect(jsonPath("content.[0].type", equalTo("cancel")))
|
.andExpect(jsonPath("content.[0].type", equalTo("cancel")))
|
||||||
@@ -874,7 +977,9 @@ public class TargetResourceTest extends AbstractIntegrationTest {
|
|||||||
mvc.perform(get(
|
mvc.perform(get(
|
||||||
RestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" + RestConstants.TARGET_V1_ACTIONS)
|
RestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" + RestConstants.TARGET_V1_ACTIONS)
|
||||||
.param(RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(1))
|
.param(RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(1))
|
||||||
.param(RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(1)))
|
.param(RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(1))
|
||||||
|
.param(RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(1))
|
||||||
|
.param(RestConstants.REQUEST_PARAMETER_SORTING, "ID:ASC"))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("content.[0].id", equalTo(actions.get(1).getId().intValue())))
|
.andExpect(jsonPath("content.[0].id", equalTo(actions.get(1).getId().intValue())))
|
||||||
.andExpect(jsonPath("content.[0].type", equalTo("update")))
|
.andExpect(jsonPath("content.[0].type", equalTo("update")))
|
||||||
@@ -902,7 +1007,8 @@ public class TargetResourceTest extends AbstractIntegrationTest {
|
|||||||
+ "?offset=0&limit=50&sort=id:DESC";
|
+ "?offset=0&limit=50&sort=id:DESC";
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Action> generateTargetWithTwoUpdatesWithOneOverride(final String knownTargetId) {
|
private List<Action> generateTargetWithTwoUpdatesWithOneOverride(final String knownTargetId)
|
||||||
|
throws InterruptedException {
|
||||||
|
|
||||||
final PageRequest pageRequest = new PageRequest(0, 100, Direction.ASC, ActionStatusFields.ID.getFieldName());
|
final PageRequest pageRequest = new PageRequest(0, 100, Direction.ASC, ActionStatusFields.ID.getFieldName());
|
||||||
|
|
||||||
@@ -920,6 +1026,8 @@ public class TargetResourceTest extends AbstractIntegrationTest {
|
|||||||
final List<Target> updatedTargets = deploymentManagement.assignDistributionSet(one, targets)
|
final List<Target> updatedTargets = deploymentManagement.assignDistributionSet(one, targets)
|
||||||
.getAssignedTargets();
|
.getAssignedTargets();
|
||||||
// 2nd update
|
// 2nd update
|
||||||
|
// sleep 10ms to ensure that we can sort by reportedAt
|
||||||
|
Thread.sleep(10);
|
||||||
deploymentManagement.assignDistributionSet(two, updatedTargets);
|
deploymentManagement.assignDistributionSet(two, updatedTargets);
|
||||||
|
|
||||||
// two updates, one cancelation
|
// two updates, one cancelation
|
||||||
@@ -946,54 +1054,6 @@ public class TargetResourceTest extends AbstractIntegrationTest {
|
|||||||
equalTo(generateStatusreferenceLink(knownTargetId, actions.get(1)))));
|
equalTo(generateStatusreferenceLink(knownTargetId, actions.get(1)))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getActionStatusWithMultipleResultsWithPagingLimitRequestParameter() throws Exception {
|
|
||||||
final int limitSize = 1;
|
|
||||||
final String knownTargetId = "targetId";
|
|
||||||
final List<Action> actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId);
|
|
||||||
actions.get(0).setStatus(Status.RUNNING);
|
|
||||||
controllerManagament.addUpdateActionStatus(
|
|
||||||
new ActionStatus(actions.get(0), Status.RUNNING, System.currentTimeMillis(), "testmessage"),
|
|
||||||
actions.get(0));
|
|
||||||
|
|
||||||
final PageRequest pageRequest = new PageRequest(0, 1000, Direction.ASC, ActionStatusFields.ID.getFieldName());
|
|
||||||
|
|
||||||
// limit to 1 - first page -> standard cancel message
|
|
||||||
Long reportAt = deploymentManagement
|
|
||||||
.findActionsByTarget(pageRequest, targetManagement.findTargetByControllerID(knownTargetId)).getContent()
|
|
||||||
.get(0).getCreatedAt();
|
|
||||||
Long id = deploymentManagement
|
|
||||||
.findActionsByTarget(pageRequest, targetManagement.findTargetByControllerID(knownTargetId)).getContent()
|
|
||||||
.get(0).getId();
|
|
||||||
mvc.perform(get(RestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/"
|
|
||||||
+ RestConstants.TARGET_V1_ACTIONS + "/" + actions.get(0).getId() + "/status")
|
|
||||||
.param(RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(limitSize)))
|
|
||||||
.andExpect(status().isOk()).andDo(MockMvcResultPrinter.print())
|
|
||||||
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_TOTAL, equalTo(3)))
|
|
||||||
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_SIZE, equalTo(limitSize)))
|
|
||||||
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_CONTENT, hasSize(limitSize)))
|
|
||||||
.andExpect(jsonPath("content.[0].id", equalTo(id.intValue())))
|
|
||||||
.andExpect(jsonPath("content.[0].type", equalTo("running")))
|
|
||||||
.andExpect(jsonPath("content.[0].messages", hasSize(1)))
|
|
||||||
.andExpect(jsonPath("content.[0].reportedAt", equalTo(reportAt)));
|
|
||||||
|
|
||||||
// limit to 1 - first page -> added custom message
|
|
||||||
reportAt = deploymentManagement
|
|
||||||
.findActionsByTarget(pageRequest, targetManagement.findTargetByControllerID(knownTargetId)).getContent()
|
|
||||||
.get(1).getCreatedAt();
|
|
||||||
id = deploymentManagement
|
|
||||||
.findActionsByTarget(pageRequest, targetManagement.findTargetByControllerID(knownTargetId)).getContent()
|
|
||||||
.get(1).getCreatedAt();
|
|
||||||
|
|
||||||
mvc.perform(get(RestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/"
|
|
||||||
+ RestConstants.TARGET_V1_ACTIONS + "/" + actions.get(0).getId() + "/status")
|
|
||||||
.param(RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(limitSize))
|
|
||||||
.param(RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(1)))
|
|
||||||
.andExpect(status().isOk()).andDo(MockMvcResultPrinter.print())
|
|
||||||
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_TOTAL, equalTo(3)))
|
|
||||||
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_SIZE, equalTo(1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void assignDistributionSetToTarget() throws Exception {
|
public void assignDistributionSetToTarget() throws Exception {
|
||||||
|
|
||||||
@@ -1232,7 +1292,8 @@ public class TargetResourceTest extends AbstractIntegrationTest {
|
|||||||
// prepare test
|
// prepare test
|
||||||
final DistributionSet dsA = TestDataUtil.generateDistributionSet("", softwareManagement,
|
final DistributionSet dsA = TestDataUtil.generateDistributionSet("", softwareManagement,
|
||||||
distributionSetManagement);
|
distributionSetManagement);
|
||||||
Target tA = targetManagement.createTarget(TestDataUtil.buildTargetFixture("target-id-A", "first description"));
|
final Target tA = targetManagement
|
||||||
|
.createTarget(TestDataUtil.buildTargetFixture("target-id-A", "first description"));
|
||||||
// assign a distribution set so we get an active update action
|
// assign a distribution set so we get an active update action
|
||||||
deploymentManagement.assignDistributionSet(dsA, Lists.newArrayList(tA));
|
deploymentManagement.assignDistributionSet(dsA, Lists.newArrayList(tA));
|
||||||
// verify active action
|
// verify active action
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
</Console>
|
</Console>
|
||||||
</Appenders>
|
</Appenders>
|
||||||
<Loggers>
|
<Loggers>
|
||||||
<Logger name="org.eclipse.hawkbit.MockMvcResultPrinter" level="debug" />
|
<Logger name="org.eclipse.hawkbit.MockMvcResultPrinter" level="error" />
|
||||||
|
|
||||||
<Root level="error">
|
<Root level="error">
|
||||||
<AppenderRef ref="Console"/>
|
<AppenderRef ref="Console"/>
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import java.util.StringJoiner;
|
|||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import javax.annotation.PreDestroy;
|
import javax.annotation.PreDestroy;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.repository.ActionStatusFields;
|
||||||
import org.eclipse.hawkbit.repository.DeploymentManagement;
|
import org.eclipse.hawkbit.repository.DeploymentManagement;
|
||||||
import org.eclipse.hawkbit.repository.exception.CancelActionNotAllowedException;
|
import org.eclipse.hawkbit.repository.exception.CancelActionNotAllowedException;
|
||||||
import org.eclipse.hawkbit.repository.model.Action;
|
import org.eclipse.hawkbit.repository.model.Action;
|
||||||
@@ -43,6 +44,8 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.data.domain.Sort;
|
||||||
|
import org.springframework.data.domain.Sort.Direction;
|
||||||
import org.vaadin.spring.events.EventBus;
|
import org.vaadin.spring.events.EventBus;
|
||||||
import org.vaadin.spring.events.EventScope;
|
import org.vaadin.spring.events.EventScope;
|
||||||
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
|
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
|
||||||
@@ -417,10 +420,10 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
|||||||
|
|
||||||
final org.eclipse.hawkbit.repository.model.Action action = deploymentManagement
|
final org.eclipse.hawkbit.repository.model.Action action = deploymentManagement
|
||||||
.findActionWithDetails(actionId);
|
.findActionWithDetails(actionId);
|
||||||
final Pageable pageReq = new PageRequest(0, 1000);
|
final Pageable pageReq = new PageRequest(0, 1000,
|
||||||
final Page<ActionStatus> actionStatusList = deploymentManagement
|
new Sort(Direction.DESC, ActionStatusFields.ID.getFieldName()));
|
||||||
.findActionStatusMessagesByActionInDescOrder(pageReq, action,
|
final Page<ActionStatus> actionStatusList = deploymentManagement.findActionStatusByAction(pageReq, action,
|
||||||
managementUIState.isActionHistoryMaximized());
|
managementUIState.isActionHistoryMaximized());
|
||||||
final List<ActionStatus> content = actionStatusList.getContent();
|
final List<ActionStatus> content = actionStatusList.getContent();
|
||||||
/*
|
/*
|
||||||
* Since the recent action status and messages are already
|
* Since the recent action status and messages are already
|
||||||
|
|||||||
Reference in New Issue
Block a user