Feature offline deployments (#563)

* Repository support offline deployments.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>

* Add offline assignment to Management API.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>

* DsAssignmentStrategy introduced.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>

* Fixed JavaDoc.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>

* Readibility improved.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>
This commit is contained in:
Kai Zimmermann
2017-07-27 17:28:56 +02:00
committed by GitHub
parent 09b24fa97d
commit e2ca4cf840
15 changed files with 693 additions and 190 deletions

View File

@@ -35,7 +35,6 @@ import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetAssignmentResult;
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.Target;
@@ -229,16 +228,22 @@ public class MgmtDistributionSetResource implements MgmtDistributionSetRestApi {
@Override
public ResponseEntity<MgmtTargetAssignmentResponseBody> createAssignedTarget(
@PathVariable("distributionSetId") final Long distributionSetId,
@RequestBody final List<MgmtTargetAssignmentRequestBody> targetIds) {
@RequestBody final List<MgmtTargetAssignmentRequestBody> assignments,
@RequestParam(value = "offline", required = false) final boolean offline) {
final DistributionSetAssignmentResult assignDistributionSet = this.deployManagament.assignDistributionSet(
if (offline) {
return ResponseEntity.ok(MgmtDistributionSetMapper
.toResponse(this.deployManagament.offlineAssignedDistributionSet(distributionSetId, assignments
.stream().map(MgmtTargetAssignmentRequestBody::getId).collect(Collectors.toList()))));
}
return ResponseEntity.ok(MgmtDistributionSetMapper.toResponse(this.deployManagament.assignDistributionSet(
distributionSetId,
targetIds.stream()
.map(t -> new TargetWithActionType(t.getId(),
MgmtRestModelMapper.convertActionType(t.getType()), t.getForcetime()))
.collect(Collectors.toList()));
assignments.stream()
.map(assignment -> new TargetWithActionType(assignment.getId(),
MgmtRestModelMapper.convertActionType(assignment.getType()), assignment.getForcetime()))
.collect(Collectors.toList()))));
return ResponseEntity.ok(MgmtDistributionSetMapper.toResponse(assignDistributionSet));
}
@Override

View File

@@ -21,6 +21,7 @@ import org.eclipse.hawkbit.mgmt.json.model.action.MgmtActionRequestBodyPut;
import org.eclipse.hawkbit.mgmt.json.model.action.MgmtActionStatus;
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtActionType;
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSet;
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtTargetAssignmentResponseBody;
import org.eclipse.hawkbit.mgmt.json.model.target.MgmtDistributionSetAssigment;
import org.eclipse.hawkbit.mgmt.json.model.target.MgmtTarget;
import org.eclipse.hawkbit.mgmt.json.model.target.MgmtTargetAttributes;
@@ -253,16 +254,21 @@ public class MgmtTargetResource implements MgmtTargetRestApi {
}
@Override
public ResponseEntity<Void> postAssignedDistributionSet(@PathVariable("controllerId") final String controllerId,
@RequestBody final MgmtDistributionSetAssigment dsId) {
public ResponseEntity<MgmtTargetAssignmentResponseBody> postAssignedDistributionSet(
@PathVariable("controllerId") final String controllerId,
@RequestBody final MgmtDistributionSetAssigment dsId,
@RequestParam(value = "offline", required = false) final boolean offline) {
if (offline) {
return ResponseEntity.ok(MgmtDistributionSetMapper.toResponse(
deploymentManagement.offlineAssignedDistributionSet(dsId.getId(), Arrays.asList(controllerId))));
}
findTargetWithExceptionIfNotFound(controllerId);
final ActionType type = (dsId.getType() != null) ? MgmtRestModelMapper.convertActionType(dsId.getType())
: ActionType.FORCED;
this.deploymentManagement.assignDistributionSet(dsId.getId(), type, dsId.getForcetime(),
Arrays.asList(controllerId));
return ResponseEntity.ok().build();
return ResponseEntity.ok(MgmtDistributionSetMapper.toResponse(deploymentManagement
.assignDistributionSet(dsId.getId(), type, dsId.getForcetime(), Arrays.asList(controllerId))));
}
@Override

View File

@@ -205,30 +205,49 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
@Test
@Description("Ensures that multi target assignment through API is reflected by the repository.")
public void assignMultipleTargetsToDistributionSet() throws Exception {
// prepare distribution set
final Set<DistributionSet> createDistributionSetsAlphabetical = createDistributionSetsAlphabetical(1);
final DistributionSet createdDs = createDistributionSetsAlphabetical.iterator().next();
// prepare targets
final String[] knownTargetIds = new String[] { "1", "2", "3", "4", "5" };
final DistributionSet createdDs = testdataFactory.createDistributionSet();
final List<Target> targets = testdataFactory.createTargets(5);
final JSONArray list = new JSONArray();
for (final String targetId : knownTargetIds) {
testdataFactory.createTarget(targetId);
list.put(new JSONObject().put("id", Long.valueOf(targetId)));
}
targets.forEach(target -> list.put(new JSONObject().put("id", target.getControllerId())));
// assign already one target to DS
assignDistributionSet(createdDs.getId(), knownTargetIds[0]);
assignDistributionSet(createdDs.getId(), targets.get(0).getControllerId());
mvc.perform(post(
MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + createdDs.getId() + "/assignedTargets")
.contentType(MediaType.APPLICATION_JSON).content(list.toString()))
.andExpect(status().isOk()).andExpect(jsonPath("$.assigned", equalTo(knownTargetIds.length - 1)))
.andExpect(status().isOk()).andExpect(jsonPath("$.assigned", equalTo(targets.size() - 1)))
.andExpect(jsonPath("$.alreadyAssigned", equalTo(1)))
.andExpect(jsonPath("$.total", equalTo(knownTargetIds.length)));
.andExpect(jsonPath("$.total", equalTo(targets.size())));
assertThat(targetManagement.findTargetByAssignedDistributionSet(createdDs.getId(), PAGE).getContent())
.as("Five targets in repository have DS assigned").hasSize(5);
}
@Test
@Description("Ensures that offline reported multi target assignment through API is reflected by the repository.")
public void offlineAssignmentOfMultipleTargetsToDistributionSet() throws Exception {
final DistributionSet createdDs = testdataFactory.createDistributionSet();
final List<Target> targets = testdataFactory.createTargets(5);
final JSONArray list = new JSONArray();
targets.forEach(target -> list.put(new JSONObject().put("id", target.getControllerId())));
// assign already one target to DS
assignDistributionSet(createdDs.getId(), targets.get(0).getControllerId());
mvc.perform(post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + createdDs.getId()
+ "/assignedTargets?offline=true").contentType(MediaType.APPLICATION_JSON).content(list.toString()))
.andExpect(status().isOk()).andExpect(jsonPath("$.assigned", equalTo(targets.size() - 1)))
.andExpect(jsonPath("$.alreadyAssigned", equalTo(1)))
.andExpect(jsonPath("$.total", equalTo(targets.size())));
assertThat(targetManagement.findTargetByAssignedDistributionSet(createdDs.getId(), PAGE).getContent())
.as("Five targets in repository have DS assigned").hasSize(5);
assertThat(targetManagement.findTargetByInstalledDistributionSet(createdDs.getId(), PAGE).getContent())
.hasSize(4);
}
@Test
@Description("Ensures that assigned targets of DS are returned as reflected by the repository.")
public void getAssignedTargetsOfDistributionSet() throws Exception {

View File

@@ -47,6 +47,7 @@ import org.eclipse.hawkbit.repository.model.ActionStatus;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.repository.test.util.WithUser;
import org.eclipse.hawkbit.rest.exception.MessageNotReadableException;
import org.eclipse.hawkbit.rest.json.model.ExceptionInfo;
@@ -1145,7 +1146,9 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + target.getControllerId() + "/assignedDS")
.content("{\"id\":" + set.getId() + "}").contentType(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
.andExpect(jsonPath("assigned", equalTo(1))).andExpect(jsonPath("alreadyAssigned", equalTo(0)))
.andExpect(jsonPath("total", equalTo(1)));
assertThat(deploymentManagement.getAssignedDistributionSet(target.getControllerId()).get()).isEqualTo(set);
target = targetManagement.findTargetByControllerID(target.getControllerId()).get();
@@ -1153,7 +1156,41 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
// repeating DS assignment leads again to OK
mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + target.getControllerId() + "/assignedDS")
.content("{\"id\":" + set.getId() + "}").contentType(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
.andExpect(jsonPath("assigned", equalTo(0))).andExpect(jsonPath("alreadyAssigned", equalTo(1)))
.andExpect(jsonPath("total", equalTo(1)));
// ...but does not change the target
assertThat(targetManagement.findTargetByControllerID(target.getControllerId()).get()).isEqualTo(target);
}
@Test
@Description("Verfies that an offline DS to target assignment is reflected by the repository and that repeating "
+ "the assignment does not change the target.")
public void offlineAssignDistributionSetToTarget() throws Exception {
Target target = testdataFactory.createTarget();
final DistributionSet set = testdataFactory.createDistributionSet("one");
mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + target.getControllerId()
+ "/assignedDS?offline=true").content("{\"id\":" + set.getId() + "}")
.contentType(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
.andExpect(jsonPath("assigned", equalTo(1))).andExpect(jsonPath("alreadyAssigned", equalTo(0)))
.andExpect(jsonPath("total", equalTo(1)));
assertThat(deploymentManagement.getAssignedDistributionSet(target.getControllerId()).get()).isEqualTo(set);
assertThat(deploymentManagement.getInstalledDistributionSet(target.getControllerId()).get()).isEqualTo(set);
target = targetManagement.findTargetByControllerID(target.getControllerId()).get();
assertThat(target.getUpdateStatus()).isEqualTo(TargetUpdateStatus.IN_SYNC);
// repeating DS assignment leads again to OK
mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + target.getControllerId()
+ "/assignedDS?offline=true").content("{\"id\":" + set.getId() + "}")
.contentType(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
.andExpect(jsonPath("assigned", equalTo(0))).andExpect(jsonPath("alreadyAssigned", equalTo(1)))
.andExpect(jsonPath("total", equalTo(1)));
// ...but does not change the target
assertThat(targetManagement.findTargetByControllerID(target.getControllerId()).get()).isEqualTo(target);