[#1650] Expose externalRef via REST API (#1655)

Signed-off-by: Marinov Avgustin <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2024-02-19 16:21:18 +02:00
committed by GitHub
parent 1d981802f4
commit bf1c7df52e
5 changed files with 126 additions and 40 deletions

View File

@@ -116,4 +116,7 @@ public class MgmtAction extends MgmtBaseEntity {
@Schema(description = "(Optional) Code provided as part of the last status update that was sent by the device.", @Schema(description = "(Optional) Code provided as part of the last status update that was sent by the device.",
example = "200") example = "200")
private Integer lastStatusCode; private Integer lastStatusCode;
@JsonProperty
@Schema(description = "If created by external system this field contains the external reference for the action")
private String externalRef;
} }

View File

@@ -42,7 +42,8 @@ public final class MgmtActionMapper {
if (actions == null) { if (actions == null) {
return Collections.emptyList(); return Collections.emptyList();
} }
return new ResponseList<>(actions.stream().map(action -> MgmtActionMapper.toResponse(action, repMode)) return new ResponseList<>(actions.stream()
.map(action -> toResponse(action, repMode))
.collect(Collectors.toList())); .collect(Collectors.toList()));
} }

View File

@@ -53,6 +53,7 @@ import org.eclipse.hawkbit.rest.data.SortDirection;
import org.eclipse.hawkbit.util.IpUtil; import org.eclipse.hawkbit.util.IpUtil;
import org.eclipse.hawkbit.utils.TenantConfigHelper; import org.eclipse.hawkbit.utils.TenantConfigHelper;
import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.PageRequest;
import org.springframework.util.ObjectUtils;
/** /**
* A mapper which maps repository model to RESTful model representation and * A mapper which maps repository model to RESTful model representation and
@@ -280,6 +281,11 @@ public final class MgmtTargetMapper {
result.setMaintenanceWindow(maintenanceWindow); result.setMaintenanceWindow(maintenanceWindow);
} }
final String externalRef = action.getExternalRef();
if (!ObjectUtils.isEmpty(externalRef)) {
result.setExternalRef(externalRef);
}
MgmtRestModelMapper.mapBaseToBase(result, action); MgmtRestModelMapper.mapBaseToBase(result, action);
result.add( result.add(

View File

@@ -20,6 +20,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.time.Duration; import java.time.Duration;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@@ -43,6 +44,7 @@ import io.qameta.allure.Description;
import io.qameta.allure.Feature; import io.qameta.allure.Feature;
import io.qameta.allure.Step; import io.qameta.allure.Step;
import io.qameta.allure.Story; import io.qameta.allure.Story;
import org.springframework.test.web.servlet.ResultActions;
/** /**
* Integration test for the {@link MgmtActionRestApi}. * Integration test for the {@link MgmtActionRestApi}.
@@ -263,34 +265,62 @@ class MgmtActionResourceTest extends AbstractManagementApiIntegrationTest {
@Test @Test
@Description("Verifies that all available actions are returned if the complete collection is requested.") @Description("Verifies that all available actions are returned if the complete collection is requested.")
void getActions() throws Exception { void getActions() throws Exception {
getActions(false);
}
@Test
@Description("Verifies that all available actions (whit ext refs) are returned if the complete collection is requested.")
void getActionsExtRef() throws Exception {
getActions(true);
}
private void getActions(final boolean withExternalRef ) throws Exception {
final String knownTargetId = "targetId"; final String knownTargetId = "targetId";
final List<Action> actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId); final List<Action> actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId);
final Action action0 = actions.get(0); final Action action0 = actions.get(0);
final Action action1 = actions.get(1); final Action action1 = actions.get(1);
mvc.perform(get(MgmtRestConstants.ACTION_V1_REQUEST_MAPPING).param(MgmtRestConstants.REQUEST_PARAMETER_SORTING,
"ID:ASC")).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
// verify action 1 final List<String> externalRefs = new ArrayList<>(2);
.andExpect(jsonPath("content.[1].id", equalTo(action1.getId().intValue()))) if (withExternalRef) {
.andExpect(jsonPath("content.[1].type", equalTo("update"))) externalRefs.add("extRef#123_0");
.andExpect(jsonPath("content.[1].status", equalTo("pending"))) externalRefs.add("extRef#123_1");
.andExpect(jsonPath("content.[1].detailStatus", equalTo("running"))) controllerManagement.updateActionExternalRef(action0.getId(), externalRefs.get(0));
.andExpect(jsonPath("content.[1]._links.self.href", controllerManagement.updateActionExternalRef(action1.getId(), externalRefs.get(1));
equalTo(generateActionLink(knownTargetId, action1.getId())))) }
// verify action 0 final ResultActions resultActions =
.andExpect(jsonPath("content.[0].id", equalTo(action0.getId().intValue()))) mvc.perform(
.andExpect(jsonPath("content.[0].type", equalTo("cancel"))) get(MgmtRestConstants.ACTION_V1_REQUEST_MAPPING)
.andExpect(jsonPath("content.[0].status", equalTo("pending"))) .param(MgmtRestConstants.REQUEST_PARAMETER_SORTING,"ID:ASC"))
.andExpect(jsonPath("content.[1].detailStatus", equalTo("running"))) .andDo(MockMvcResultPrinter.print())
.andExpect(jsonPath("content.[0]._links.self.href", .andExpect(status().isOk())
equalTo(generateActionLink(knownTargetId, action0.getId())))) // verify action 1
.andExpect(jsonPath("content.[1].id", equalTo(action1.getId().intValue())))
.andExpect(jsonPath("content.[1].type", equalTo("update")))
.andExpect(jsonPath("content.[1].status", equalTo("pending")))
.andExpect(jsonPath("content.[1].detailStatus", equalTo("running")))
.andExpect(jsonPath("content.[1]._links.self.href",
equalTo(generateActionLink(knownTargetId, action1.getId()))))
// verify collection properties // verify action 0
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_TOTAL, equalTo(2))) .andExpect(jsonPath("content.[0].id", equalTo(action0.getId().intValue())))
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_SIZE, equalTo(2))) .andExpect(jsonPath("content.[0].type", equalTo("cancel")))
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_CONTENT, hasSize(2))); .andExpect(jsonPath("content.[0].status", equalTo("pending")))
.andExpect(jsonPath("content.[1].detailStatus", equalTo("running")))
.andExpect(jsonPath("content.[0]._links.self.href",
equalTo(generateActionLink(knownTargetId, action0.getId()))))
// verify collection properties
.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)));
if (withExternalRef) {
resultActions
.andExpect(jsonPath("content.[1].externalRef", equalTo(externalRefs.get(1))))
.andExpect(jsonPath("content.[0].externalRef", equalTo(externalRefs.get(0))));
}
} }
@Test @Test
@@ -345,6 +375,16 @@ class MgmtActionResourceTest extends AbstractManagementApiIntegrationTest {
@Test @Test
@Description("Handles the GET request of retrieving a specific action.") @Description("Handles the GET request of retrieving a specific action.")
public void getAction() throws Exception { public void getAction() throws Exception {
getAction(false);
}
@Test
@Description("Handles the GET request of retrieving a specific action with external reference.")
public void getActionExtRef() throws Exception {
getAction(true);
}
private void getAction(final boolean withExternalRef) throws Exception {
final String knownTargetId = "targetId"; final String knownTargetId = "targetId";
// prepare ds // prepare ds
final DistributionSet ds = testdataFactory.createDistributionSet(); final DistributionSet ds = testdataFactory.createDistributionSet();
@@ -358,10 +398,19 @@ class MgmtActionResourceTest extends AbstractManagementApiIntegrationTest {
final List<Action> actions = deploymentManagement.findActionsByTarget(target.getControllerId(), PAGE) final List<Action> actions = deploymentManagement.findActionsByTarget(target.getControllerId(), PAGE)
.getContent(); .getContent();
assertThat(actions).hasSize(1); assertThat(actions).hasSize(1);
final String externalRef = "externalRef#123";
if (withExternalRef) {
controllerManagement.updateActionExternalRef(actions.get(0).getId(), externalRef);
}
mvc.perform(get(MgmtRestConstants.ACTION_V1_REQUEST_MAPPING + "/{actionId}", actions.get(0).getId())) final ResultActions resultActions =
.andDo(MockMvcResultPrinter.print()) mvc.perform(get(MgmtRestConstants.ACTION_V1_REQUEST_MAPPING + "/{actionId}", actions.get(0).getId()))
.andExpect(status().isOk()); .andDo(MockMvcResultPrinter.print())
.andExpect(status().isOk());
if (withExternalRef) {
resultActions.andExpect(jsonPath("externalRef", equalTo(externalRef)));
}
} }
@Test @Test

View File

@@ -28,6 +28,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.time.Duration; import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
@@ -100,6 +101,7 @@ import io.qameta.allure.Description;
import io.qameta.allure.Feature; import io.qameta.allure.Feature;
import io.qameta.allure.Step; import io.qameta.allure.Step;
import io.qameta.allure.Story; import io.qameta.allure.Story;
import org.springframework.test.web.servlet.ResultActions;
/** /**
* Spring MVC Tests against the MgmtTargetResource. * Spring MVC Tests against the MgmtTargetResource.
@@ -1088,25 +1090,50 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
@Test @Test
@Description("Ensures that the expected response of getting actions of a target is returned.") @Description("Ensures that the expected response of getting actions of a target is returned.")
void getActions() throws Exception { void getActions() throws Exception {
getActions(false);
}
@Test
@Description("Ensures that the expected response of getting actions (with ext refs) of a target is returned.")
void getActionsExtRef() throws Exception {
getActions(true);
}
private void getActions(final boolean withExternalRef) throws Exception {
final String knownTargetId = "targetId"; final String knownTargetId = "targetId";
final List<Action> actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId); final List<Action> actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId);
mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" final List<String> externalRefs = new ArrayList<>(2);
+ MgmtRestConstants.TARGET_V1_ACTIONS).param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "ID:ASC")) if (withExternalRef) {
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) externalRefs.add("extRef#123_0");
.andExpect(jsonPath("content.[1].id", equalTo(actions.get(1).getId().intValue()))) externalRefs.add("extRef#123_1");
.andExpect(jsonPath("content.[1].type", equalTo("update"))) controllerManagement.updateActionExternalRef(actions.get(0).getId(), externalRefs.get(0));
.andExpect(jsonPath("content.[1].status", equalTo("pending"))) controllerManagement.updateActionExternalRef(actions.get(1).getId(), externalRefs.get(1));
.andExpect(jsonPath("content.[1]._links.self.href", }
equalTo(generateActionSelfLink(knownTargetId, actions.get(1).getId()))))
.andExpect(jsonPath("content.[0].id", equalTo(actions.get(0).getId().intValue()))) final ResultActions resultActions =
.andExpect(jsonPath("content.[0].type", equalTo("cancel"))) mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/"
.andExpect(jsonPath("content.[0].status", equalTo("pending"))) + MgmtRestConstants.TARGET_V1_ACTIONS).param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "ID:ASC"))
.andExpect(jsonPath("content.[0]._links.self.href", .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
equalTo(generateActionSelfLink(knownTargetId, actions.get(0).getId())))) .andExpect(jsonPath("content.[1].id", equalTo(actions.get(1).getId().intValue())))
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_TOTAL, equalTo(2))) .andExpect(jsonPath("content.[1].type", equalTo("update")))
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_SIZE, equalTo(2))) .andExpect(jsonPath("content.[1].status", equalTo("pending")))
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_CONTENT, hasSize(2))); .andExpect(jsonPath("content.[1]._links.self.href",
equalTo(generateActionSelfLink(knownTargetId, actions.get(1).getId()))))
.andExpect(jsonPath("content.[0].id", equalTo(actions.get(0).getId().intValue())))
.andExpect(jsonPath("content.[0].type", equalTo("cancel")))
.andExpect(jsonPath("content.[0].status", equalTo("pending")))
.andExpect(jsonPath("content.[0]._links.self.href",
equalTo(generateActionSelfLink(knownTargetId, actions.get(0).getId()))))
.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)));
if (withExternalRef) {
resultActions
.andExpect(jsonPath("content.[1].externalRef", equalTo(externalRefs.get(1))))
.andExpect(jsonPath("content.[0].externalRef", equalTo(externalRefs.get(0))));
}
} }
@Test @Test