DDI API: /controller/v1/{controllerid}/installedBase/{actionId} (#1220)
* installedBase DDI: initial impl + rest docs Signed-off-by: Natalia Kislicyn <natalia.kislicyn@bosch.io> * refactor installedBase implementation Signed-off-by: Natalia Kislicyn <natalia.kislicyn@bosch.io> * ddi installed base tests Signed-off-by: Natalia Kislicyn <natalia.kislicyn@bosch.io> * restructure root controller rest docs Signed-off-by: Natalia Kislicyn <natalia.kislicyn@bosch.io> * fix some java docs and formatting Signed-off-by: Natalia Kislicyn <natalia.kislicyn@bosch.io> * don't add action history message when calling /installedBase Signed-off-by: Natalia Kislicyn <natalia.kislicyn@bosch.io> * fix test after removing action history message Signed-off-by: Natalia Kislicyn <natalia.kislicyn@bosch.io> * fix review comments Signed-off-by: Natalia Kislicyn <natalia.kislicyn@bosch.io> * fix review comments Signed-off-by: Natalia Kislicyn <natalia.kislicyn@bosch.io>
This commit is contained in:
@@ -108,17 +108,17 @@ public final class DataConversionHelper {
|
||||
|
||||
}
|
||||
|
||||
static DdiControllerBase fromTarget(final Target target, final Action action,
|
||||
final String defaultControllerPollTime, final TenantAware tenantAware) {
|
||||
public static DdiControllerBase fromTarget(final Target target, final Action installedAction,
|
||||
final Action activeAction, final String defaultControllerPollTime, final TenantAware tenantAware) {
|
||||
final DdiControllerBase result = new DdiControllerBase(
|
||||
new DdiConfig(new DdiPolling(defaultControllerPollTime)));
|
||||
|
||||
if (action != null) {
|
||||
if (action.isCancelingOrCanceled()) {
|
||||
if (activeAction != null) {
|
||||
if (activeAction.isCancelingOrCanceled()) {
|
||||
result.add(WebMvcLinkBuilder
|
||||
.linkTo(WebMvcLinkBuilder.methodOn(DdiRootController.class, tenantAware.getCurrentTenant())
|
||||
.getControllerCancelAction(tenantAware.getCurrentTenant(), target.getControllerId(),
|
||||
action.getId()))
|
||||
activeAction.getId()))
|
||||
.withRel(DdiRestConstants.CANCEL_ACTION));
|
||||
} else {
|
||||
// we need to add the hashcode here of the actionWithStatus
|
||||
@@ -129,11 +129,20 @@ public final class DataConversionHelper {
|
||||
result.add(WebMvcLinkBuilder
|
||||
.linkTo(WebMvcLinkBuilder.methodOn(DdiRootController.class, tenantAware.getCurrentTenant())
|
||||
.getControllerBasedeploymentAction(tenantAware.getCurrentTenant(),
|
||||
target.getControllerId(), action.getId(), calculateEtag(action), null))
|
||||
target.getControllerId(), activeAction.getId(), calculateEtag(activeAction), null))
|
||||
.withRel(DdiRestConstants.DEPLOYMENT_BASE_ACTION));
|
||||
}
|
||||
}
|
||||
|
||||
if (installedAction != null && !installedAction.isActive()) {
|
||||
result.add(
|
||||
WebMvcLinkBuilder
|
||||
.linkTo(WebMvcLinkBuilder.methodOn(DdiRootController.class, tenantAware.getCurrentTenant())
|
||||
.getControllerInstalledAction(tenantAware.getCurrentTenant(),
|
||||
target.getControllerId(), installedAction.getId(), null))
|
||||
.withRel(DdiRestConstants.INSTALLED_BASE_ACTION));
|
||||
}
|
||||
|
||||
if (target.isRequestControllerAttributes()) {
|
||||
result.add(WebMvcLinkBuilder
|
||||
.linkTo(WebMvcLinkBuilder.methodOn(DdiRootController.class, tenantAware.getCurrentTenant())
|
||||
|
||||
@@ -130,8 +130,7 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
||||
@PathVariable("softwareModuleId") final Long softwareModuleId) {
|
||||
LOG.debug("getSoftwareModulesArtifacts({})", controllerId);
|
||||
|
||||
final Target target = controllerManagement.getByControllerId(controllerId)
|
||||
.orElseThrow(() -> new EntityNotFoundException(Target.class, controllerId));
|
||||
final Target target = findTargetWithExceptionIfNotFound(controllerId);
|
||||
|
||||
final SoftwareModule softwareModule = controllerManagement.getSoftwareModule(softwareModuleId)
|
||||
.orElseThrow(() -> new EntityNotFoundException(SoftwareModule.class, softwareModuleId));
|
||||
@@ -149,14 +148,16 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
||||
|
||||
final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotExist(controllerId, IpUtil
|
||||
.getClientIpFromRequest(requestResponseContextHolder.getHttpServletRequest(), securityProperties));
|
||||
final Action action = controllerManagement.findActiveActionWithHighestWeight(controllerId).orElse(null);
|
||||
final Action activeAction = controllerManagement.findActiveActionWithHighestWeight(controllerId).orElse(null);
|
||||
|
||||
checkAndCancelExpiredAction(action);
|
||||
final Action installedAction = controllerManagement.getInstalledActionByTarget(controllerId).orElse(null);
|
||||
|
||||
checkAndCancelExpiredAction(activeAction);
|
||||
|
||||
return new ResponseEntity<>(
|
||||
DataConversionHelper.fromTarget(target, action,
|
||||
action == null ? controllerManagement.getPollingTime()
|
||||
: controllerManagement.getPollingTimeForAction(action.getId()),
|
||||
DataConversionHelper.fromTarget(target, installedAction, activeAction,
|
||||
activeAction == null ? controllerManagement.getPollingTime()
|
||||
: controllerManagement.getPollingTimeForAction(activeAction.getId()),
|
||||
tenantAware),
|
||||
HttpStatus.OK);
|
||||
}
|
||||
@@ -168,8 +169,7 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
||||
@PathVariable("fileName") final String fileName) {
|
||||
final ResponseEntity<InputStream> result;
|
||||
|
||||
final Target target = controllerManagement.getByControllerId(controllerId)
|
||||
.orElseThrow(() -> new EntityNotFoundException(Target.class, controllerId));
|
||||
final Target target = findTargetWithExceptionIfNotFound(controllerId);
|
||||
final SoftwareModule module = controllerManagement.getSoftwareModule(softwareModuleId)
|
||||
.orElseThrow(() -> new EntityNotFoundException(SoftwareModule.class, softwareModuleId));
|
||||
|
||||
@@ -239,8 +239,7 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
||||
@PathVariable("controllerId") final String controllerId,
|
||||
@PathVariable("softwareModuleId") final Long softwareModuleId,
|
||||
@PathVariable("fileName") final String fileName) {
|
||||
final Target target = controllerManagement.getByControllerId(controllerId)
|
||||
.orElseThrow(() -> new EntityNotFoundException(Target.class, controllerId));
|
||||
final Target target = findTargetWithExceptionIfNotFound(controllerId);
|
||||
|
||||
final SoftwareModule module = controllerManagement.getSoftwareModule(softwareModuleId)
|
||||
.orElseThrow(() -> new EntityNotFoundException(SoftwareModule.class, softwareModuleId));
|
||||
@@ -275,38 +274,15 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
||||
@RequestParam(value = "actionHistory", defaultValue = DdiRestConstants.NO_ACTION_HISTORY) final Integer actionHistoryMessageCount) {
|
||||
LOG.debug("getControllerBasedeploymentAction({},{})", controllerId, resource);
|
||||
|
||||
final Target target = controllerManagement.getByControllerId(controllerId)
|
||||
.orElseThrow(() -> new EntityNotFoundException(Target.class, controllerId));
|
||||
|
||||
final Target target = findTargetWithExceptionIfNotFound(controllerId);
|
||||
final Action action = findActionWithExceptionIfNotFound(actionId);
|
||||
if (!action.getTarget().getId().equals(target.getId())) {
|
||||
LOG.warn(GIVEN_ACTION_IS_NOT_ASSIGNED_TO_GIVEN_TARGET, action.getId(), target.getId());
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
verifyActionAssignedToTarget(target, action);
|
||||
|
||||
checkAndCancelExpiredAction(action);
|
||||
|
||||
if (!action.isCancelingOrCanceled()) {
|
||||
|
||||
final List<DdiChunk> chunks = DataConversionHelper.createChunks(target, action, artifactUrlHandler,
|
||||
systemManagement,
|
||||
new ServletServerHttpRequest(requestResponseContextHolder.getHttpServletRequest()),
|
||||
controllerManagement);
|
||||
|
||||
final List<String> actionHistoryMsgs = controllerManagement.getActionHistoryMessages(action.getId(),
|
||||
actionHistoryMessageCount == null ? Integer.parseInt(DdiRestConstants.NO_ACTION_HISTORY)
|
||||
: actionHistoryMessageCount);
|
||||
|
||||
final DdiActionHistory actionHistory = actionHistoryMsgs.isEmpty() ? null
|
||||
: new DdiActionHistory(action.getStatus().name(), actionHistoryMsgs);
|
||||
|
||||
final HandlingType downloadType = calculateDownloadType(action);
|
||||
final HandlingType updateType = calculateUpdateType(action, downloadType);
|
||||
|
||||
final DdiMaintenanceWindowStatus maintenanceWindow = calculateMaintenanceWindow(action);
|
||||
|
||||
final DdiDeploymentBase base = new DdiDeploymentBase(Long.toString(action.getId()),
|
||||
new DdiDeployment(downloadType, updateType, chunks, maintenanceWindow), actionHistory);
|
||||
final DdiDeploymentBase base = generateDdiDeploymentBase(target, action, actionHistoryMessageCount);
|
||||
|
||||
LOG.debug("Found an active UpdateAction for target {}. returning deployment: {}", controllerId, base);
|
||||
|
||||
@@ -349,14 +325,9 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
||||
@PathVariable("actionId") @NotEmpty final Long actionId) {
|
||||
LOG.debug("provideBasedeploymentActionFeedback for target [{},{}]: {}", controllerId, actionId, feedback);
|
||||
|
||||
final Target target = controllerManagement.getByControllerId(controllerId)
|
||||
.orElseThrow(() -> new EntityNotFoundException(Target.class, controllerId));
|
||||
|
||||
final Target target = findTargetWithExceptionIfNotFound(controllerId);
|
||||
final Action action = findActionWithExceptionIfNotFound(actionId);
|
||||
if (!action.getTarget().getId().equals(target.getId())) {
|
||||
LOG.warn(GIVEN_ACTION_IS_NOT_ASSIGNED_TO_GIVEN_TARGET, action.getId(), target.getId());
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
verifyActionAssignedToTarget(target, action);
|
||||
|
||||
if (!action.isActive()) {
|
||||
LOG.warn("Updating action {} with feedback {} not possible since action not active anymore.",
|
||||
@@ -461,14 +432,9 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
||||
@PathVariable("actionId") @NotEmpty final Long actionId) {
|
||||
LOG.debug("getControllerCancelAction({})", controllerId);
|
||||
|
||||
final Target target = controllerManagement.getByControllerId(controllerId)
|
||||
.orElseThrow(() -> new EntityNotFoundException(Target.class, controllerId));
|
||||
|
||||
final Target target = findTargetWithExceptionIfNotFound(controllerId);
|
||||
final Action action = findActionWithExceptionIfNotFound(actionId);
|
||||
if (!action.getTarget().getId().equals(target.getId())) {
|
||||
LOG.warn(GIVEN_ACTION_IS_NOT_ASSIGNED_TO_GIVEN_TARGET, action.getId(), target.getId());
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
verifyActionAssignedToTarget(target, action);
|
||||
|
||||
if (action.isCancelingOrCanceled()) {
|
||||
final DdiCancel cancel = new DdiCancel(String.valueOf(action.getId()),
|
||||
@@ -492,20 +458,58 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
||||
@PathVariable("actionId") @NotEmpty final Long actionId) {
|
||||
LOG.debug("provideCancelActionFeedback for target [{}]: {}", controllerId, feedback);
|
||||
|
||||
final Target target = controllerManagement.getByControllerId(controllerId)
|
||||
.orElseThrow(() -> new EntityNotFoundException(Target.class, controllerId));
|
||||
|
||||
final Target target = findTargetWithExceptionIfNotFound(controllerId);
|
||||
final Action action = findActionWithExceptionIfNotFound(actionId);
|
||||
if (!action.getTarget().getId().equals(target.getId())) {
|
||||
LOG.warn(GIVEN_ACTION_IS_NOT_ASSIGNED_TO_GIVEN_TARGET, action.getId(), target.getId());
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
verifyActionAssignedToTarget(target, action);
|
||||
|
||||
controllerManagement
|
||||
.addCancelActionStatus(generateActionCancelStatus(feedback, target, actionId, entityFactory));
|
||||
return ResponseEntity.ok().build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<DdiDeploymentBase> getControllerInstalledAction(@PathVariable("tenant") final String tenant,
|
||||
@PathVariable("controllerId") final String controllerId, @PathVariable("actionId") final Long actionId,
|
||||
@RequestParam(value = "actionHistory", defaultValue = DdiRestConstants.NO_ACTION_HISTORY) final Integer actionHistoryMessageCount) {
|
||||
LOG.debug("getControllerInstalledAction({})", controllerId);
|
||||
|
||||
final Target target = findTargetWithExceptionIfNotFound(controllerId);
|
||||
final Action action = findActionWithExceptionIfNotFound(actionId);
|
||||
verifyActionAssignedToTarget(target, action);
|
||||
|
||||
if (action.isActive() || action.isCancelingOrCanceled()) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
|
||||
final DdiDeploymentBase base = generateDdiDeploymentBase(target, action, actionHistoryMessageCount);
|
||||
|
||||
LOG.debug("Found an installed UpdateAction for target {}. returning deployment: {}", controllerId, base);
|
||||
return new ResponseEntity<>(base, HttpStatus.OK);
|
||||
|
||||
}
|
||||
|
||||
private DdiDeploymentBase generateDdiDeploymentBase(Target target, Action action,
|
||||
Integer actionHistoryMessageCount) {
|
||||
final List<DdiChunk> chunks = DataConversionHelper.createChunks(target, action, artifactUrlHandler,
|
||||
systemManagement, new ServletServerHttpRequest(requestResponseContextHolder.getHttpServletRequest()),
|
||||
controllerManagement);
|
||||
|
||||
final List<String> actionHistoryMsgs = controllerManagement.getActionHistoryMessages(action.getId(),
|
||||
actionHistoryMessageCount == null ? Integer.parseInt(DdiRestConstants.NO_ACTION_HISTORY)
|
||||
: actionHistoryMessageCount);
|
||||
|
||||
final DdiActionHistory actionHistory = actionHistoryMsgs.isEmpty() ? null
|
||||
: new DdiActionHistory(action.getStatus().name(), actionHistoryMsgs);
|
||||
|
||||
final HandlingType downloadType = calculateDownloadType(action);
|
||||
final HandlingType updateType = calculateUpdateType(action, downloadType);
|
||||
|
||||
final DdiMaintenanceWindowStatus maintenanceWindow = calculateMaintenanceWindow(action);
|
||||
|
||||
return new DdiDeploymentBase(Long.toString(action.getId()),
|
||||
new DdiDeployment(downloadType, updateType, chunks, maintenanceWindow), actionHistory);
|
||||
}
|
||||
|
||||
private static ActionStatusCreate generateActionCancelStatus(final DdiActionFeedback feedback, final Target target,
|
||||
final Long actionid, final EntityFactory entityFactory) {
|
||||
|
||||
@@ -561,11 +565,23 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
||||
return status;
|
||||
}
|
||||
|
||||
private Target findTargetWithExceptionIfNotFound(final String controllerId) {
|
||||
return controllerManagement.getByControllerId(controllerId)
|
||||
.orElseThrow(() -> new EntityNotFoundException(Target.class, controllerId));
|
||||
}
|
||||
|
||||
private Action findActionWithExceptionIfNotFound(final Long actionId) {
|
||||
return controllerManagement.findActionWithDetails(actionId)
|
||||
.orElseThrow(() -> new EntityNotFoundException(Action.class, actionId));
|
||||
}
|
||||
|
||||
private void verifyActionAssignedToTarget(final Target target, final Action action) {
|
||||
if (!action.getTarget().getId().equals(target.getId())) {
|
||||
LOG.warn(GIVEN_ACTION_IS_NOT_ASSIGNED_TO_GIVEN_TARGET, action.getId(), target.getId());
|
||||
throw new EntityNotFoundException(Action.class, action.getId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the action has a maintenance schedule defined but is no longer valid,
|
||||
* cancel the action.
|
||||
|
||||
@@ -8,17 +8,32 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.ddi.rest.resource;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
|
||||
import org.eclipse.hawkbit.repository.jpa.RepositoryApplicationConfiguration;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.Artifact;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.test.TestConfiguration;
|
||||
import org.eclipse.hawkbit.rest.AbstractRestIntegrationTest;
|
||||
import org.eclipse.hawkbit.rest.RestConfiguration;
|
||||
import org.eclipse.hawkbit.rest.util.MockMvcResultPrinter;
|
||||
import org.springframework.cloud.stream.test.binder.TestSupportBinderAutoConfiguration;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.web.servlet.ResultActions;
|
||||
import org.springframework.test.web.servlet.ResultMatcher;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonFactory;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
@@ -32,6 +47,19 @@ import com.fasterxml.jackson.dataformat.cbor.CBORParser;
|
||||
@TestPropertySource(locations = "classpath:/ddi-test.properties")
|
||||
public abstract class AbstractDDiApiIntegrationTest extends AbstractRestIntegrationTest {
|
||||
|
||||
protected static final String HTTP_LOCALHOST = "http://localhost:8080/";
|
||||
protected static final String CONTROLLER_BASE = "/{tenant}/controller/v1/{controllerId}";
|
||||
|
||||
protected static final String SOFTWARE_MODULE_ARTIFACTS = CONTROLLER_BASE
|
||||
+ "/softwaremodules/{softwareModuleId}/artifacts";
|
||||
protected static final String DEPLOYMENT_BASE = CONTROLLER_BASE + "/deploymentBase/{actionId}";
|
||||
protected static final String CANCEL_ACTION = CONTROLLER_BASE + "/cancelAction/{actionId}";
|
||||
protected static final String INSTALLED_BASE = CONTROLLER_BASE + "/installedBase/{actionId}";
|
||||
protected static final String DEPLOYMENT_FEEDBACK = DEPLOYMENT_BASE + "/feedback";
|
||||
protected static final String CANCEL_FEEDBACK = CANCEL_ACTION + "/feedback";
|
||||
|
||||
protected static final int ARTIFACT_SIZE = 5 * 1024;
|
||||
|
||||
/**
|
||||
* Convert JSON to a CBOR equivalent.
|
||||
*
|
||||
@@ -75,4 +103,121 @@ public abstract class AbstractDDiApiIntegrationTest extends AbstractRestIntegrat
|
||||
jsonGenerator.flush();
|
||||
return stringWriter.toString();
|
||||
}
|
||||
|
||||
protected ResultActions postDeploymentFeedback(final String controllerId, final Long actionId, final String content,
|
||||
final ResultMatcher statusMatcher) throws Exception {
|
||||
return postDeploymentFeedback(MediaType.APPLICATION_JSON, controllerId, actionId, content.getBytes(),
|
||||
statusMatcher);
|
||||
}
|
||||
|
||||
protected ResultActions postDeploymentFeedback(final MediaType mediaType, final String controllerId,
|
||||
final Long actionId, final byte[] content, final ResultMatcher statusMatcher) throws Exception {
|
||||
return mvc
|
||||
.perform(post(DEPLOYMENT_FEEDBACK, tenantAware.getCurrentTenant(), controllerId, actionId)
|
||||
.content(content).contentType(mediaType).accept(mediaType))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(statusMatcher);
|
||||
}
|
||||
|
||||
protected ResultActions performGet(final String url, final MediaType mediaType, final ResultMatcher statusMatcher,
|
||||
final String... values) throws Exception {
|
||||
return mvc.perform(MockMvcRequestBuilders.get(url, values).accept(mediaType))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(statusMatcher)
|
||||
.andExpect(content().contentTypeCompatibleWith(mediaType));
|
||||
}
|
||||
|
||||
protected ResultActions getAndVerifyDeploymentBasePayload(final String controllerId, final MediaType mediaType,
|
||||
final DistributionSet ds, final Artifact artifact, final Artifact artifactSignature, final Long actionId,
|
||||
final Long osModuleId, final String downloadType, final String updateType) throws Exception {
|
||||
final ResultActions resultActions = performGet(DEPLOYMENT_BASE, mediaType, status().isOk(),
|
||||
tenantAware.getCurrentTenant(), controllerId, actionId.toString());
|
||||
return verifyBasePayload(resultActions, controllerId, ds, artifact, artifactSignature, actionId, osModuleId,
|
||||
downloadType, updateType);
|
||||
}
|
||||
|
||||
protected ResultActions getAndVerifyDeploymentBasePayload(final String controllerId, final MediaType mediaType,
|
||||
final DistributionSet ds, final Artifact artifact, final Artifact artifactSignature, final Long actionId,
|
||||
final Long osModuleId, final Action.ActionType actionType) throws Exception {
|
||||
return getAndVerifyDeploymentBasePayload(controllerId, mediaType, ds, artifact, artifactSignature, actionId,
|
||||
osModuleId, getDownloadAndUploadType(actionType), getDownloadAndUploadType(actionType));
|
||||
}
|
||||
|
||||
protected ResultActions getAndVerifyInstalledBasePayload(final String controllerId, final MediaType mediaType,
|
||||
final DistributionSet ds, final Artifact artifact, final Artifact artifactSignature, final Long actionId,
|
||||
final Long osModuleId, final Action.ActionType actionType) throws Exception {
|
||||
final ResultActions resultActions = performGet(INSTALLED_BASE, mediaType, status().isOk(),
|
||||
tenantAware.getCurrentTenant(), controllerId, actionId.toString());
|
||||
return verifyBasePayload(resultActions, controllerId, ds, artifact, artifactSignature, actionId, osModuleId,
|
||||
getDownloadAndUploadType(actionType), getDownloadAndUploadType(actionType));
|
||||
}
|
||||
|
||||
private ResultActions verifyBasePayload(ResultActions resultActions, final String controllerId,
|
||||
final DistributionSet ds, final Artifact artifact, final Artifact artifactSignature, final Long actionId,
|
||||
final Long osModuleId, final String downloadType, final String updateType) throws Exception {
|
||||
return resultActions.andExpect(jsonPath("$.id", equalTo(String.valueOf(actionId))))
|
||||
.andExpect(jsonPath("$.deployment.download", equalTo(downloadType)))
|
||||
.andExpect(jsonPath("$.deployment.update", equalTo(updateType)))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='jvm')].name",
|
||||
contains(ds.findFirstModuleByType(runtimeType).get().getName())))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='jvm')].version",
|
||||
contains(ds.findFirstModuleByType(runtimeType).get().getVersion())))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='os')].name",
|
||||
contains(ds.findFirstModuleByType(osType).get().getName())))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='os')].version",
|
||||
contains(ds.findFirstModuleByType(osType).get().getVersion())))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='os')].artifacts[0].size", contains(ARTIFACT_SIZE)))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='os')].artifacts[0].filename",
|
||||
contains(artifact.getFilename())))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='os')].artifacts[0].hashes.md5",
|
||||
contains(artifact.getMd5Hash())))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='os')].artifacts[0].hashes.sha1",
|
||||
contains(artifact.getSha1Hash())))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='os')].artifacts[0].hashes.sha256",
|
||||
contains(artifact.getSha256Hash())))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='os')].artifacts[0]._links.download-http.href",
|
||||
contains(HTTP_LOCALHOST + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId
|
||||
+ "/softwaremodules/" + osModuleId + "/artifacts/" + artifact.getFilename())))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='os')].artifacts[0]._links.md5sum-http.href",
|
||||
contains(HTTP_LOCALHOST + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId
|
||||
+ "/softwaremodules/" + osModuleId + "/artifacts/" + artifact.getFilename()
|
||||
+ ".MD5SUM")))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='os')].artifacts[1].size", contains(ARTIFACT_SIZE)))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='os')].artifacts[1].filename",
|
||||
contains(artifactSignature.getFilename())))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='os')].artifacts[1].hashes.md5",
|
||||
contains(artifactSignature.getMd5Hash())))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='os')].artifacts[1].hashes.sha1",
|
||||
contains(artifactSignature.getSha1Hash())))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='os')].artifacts[1].hashes.sha256",
|
||||
contains(artifactSignature.getSha256Hash())))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='os')].artifacts[1]._links.download-http.href",
|
||||
contains(HTTP_LOCALHOST + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId
|
||||
+ "/softwaremodules/" + osModuleId + "/artifacts/" + artifactSignature.getFilename())))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='os')].artifacts[1]._links.md5sum-http.href",
|
||||
contains(HTTP_LOCALHOST + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId
|
||||
+ "/softwaremodules/" + osModuleId + "/artifacts/" + artifactSignature.getFilename()
|
||||
+ ".MD5SUM")))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='bApp')].version",
|
||||
contains(ds.findFirstModuleByType(appType).get().getVersion())))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='bApp')].metadata").doesNotExist())
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='bApp')].name")
|
||||
.value(ds.findFirstModuleByType(appType).get().getName()));
|
||||
}
|
||||
|
||||
protected String installedBaseLink(final String controllerId, final String actionId) {
|
||||
return "http://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId
|
||||
+ "/installedBase/" + actionId;
|
||||
}
|
||||
|
||||
protected String deploymentBaseLink(final String controllerId, final String actionId) {
|
||||
return "http://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId
|
||||
+ "/deploymentBase/" + actionId;
|
||||
}
|
||||
|
||||
private static String getDownloadAndUploadType(final Action.ActionType actionType) {
|
||||
if (Action.ActionType.FORCED.equals(actionType)) {
|
||||
return "forced";
|
||||
}
|
||||
return "attempt";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,13 +10,11 @@ package org.eclipse.hawkbit.ddi.rest.resource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@@ -55,8 +53,6 @@ import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.hateoas.MediaTypes;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.test.web.servlet.ResultActions;
|
||||
import org.springframework.test.web.servlet.ResultMatcher;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import com.jayway.jsonpath.JsonPath;
|
||||
@@ -72,12 +68,6 @@ import io.qameta.allure.Story;
|
||||
@Story("Deployment Action Resource")
|
||||
public class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
|
||||
private static final String HTTP_LOCALHOST = "http://localhost:8080/";
|
||||
private static final String CONTROLLER_BY_ID = "/{tenant}/controller/v1/{controllerId}";
|
||||
private static final String SOFTWARE_MODULE_ARTIFACTS = CONTROLLER_BY_ID
|
||||
+ "/softwaremodules/{softwareModuleId}/artifacts";
|
||||
private static final String DEPLOYMENT_BASE = CONTROLLER_BY_ID + "/deploymentBase/";
|
||||
private static final int ARTIFACT_SIZE = 5 * 1024;
|
||||
private static final String DEFAULT_CONTROLLER_ID = "4712";
|
||||
|
||||
@Test
|
||||
@@ -91,9 +81,9 @@ public class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
.getContent().get(0);
|
||||
|
||||
// get deployment base
|
||||
performGet(DEPLOYMENT_BASE + action.getId().toString(),
|
||||
performGet(DEPLOYMENT_BASE,
|
||||
MediaType.parseMediaType(DdiRestConstants.MEDIA_TYPE_CBOR), status().isOk(),
|
||||
tenantAware.getCurrentTenant(), target.getControllerId());
|
||||
tenantAware.getCurrentTenant(), target.getControllerId(), action.getId().toString());
|
||||
|
||||
final Long softwareModuleId = distributionSet.getModules().stream().findAny().get().getId();
|
||||
testdataFactory.createArtifacts(softwareModuleId);
|
||||
@@ -105,7 +95,7 @@ public class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
final byte[] feedback = jsonToCbor(
|
||||
JsonBuilder.deploymentActionFeedback(action.getId().toString(), "proceeding"));
|
||||
|
||||
postFeedback(MediaType.parseMediaType(DdiRestConstants.MEDIA_TYPE_CBOR), target.getControllerId(),
|
||||
postDeploymentFeedback(MediaType.parseMediaType(DdiRestConstants.MEDIA_TYPE_CBOR), target.getControllerId(),
|
||||
action.getId(), feedback, status().isOk());
|
||||
}
|
||||
|
||||
@@ -173,12 +163,11 @@ public class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
|
||||
// Run test
|
||||
final long current = System.currentTimeMillis();
|
||||
performGet(CONTROLLER_BY_ID, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(),
|
||||
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(),
|
||||
DEFAULT_CONTROLLER_ID)
|
||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||
.andExpect(jsonPath("$._links.deploymentBase.href",
|
||||
startsWith("http://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/"
|
||||
+ DEFAULT_CONTROLLER_ID + "/deploymentBase/" + uaction.getId())));
|
||||
startsWith(deploymentBaseLink(DEFAULT_CONTROLLER_ID, uaction.getId().toString()))));
|
||||
assertThat(targetManagement.getByControllerID(DEFAULT_CONTROLLER_ID).get().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
assertThat(targetManagement.getByControllerID(DEFAULT_CONTROLLER_ID).get().getLastTargetQuery())
|
||||
@@ -209,24 +198,23 @@ public class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
final Long actionId = getFirstAssignedActionId(assignDistributionSet(ds.getId(), target.getControllerId(),
|
||||
ActionType.TIMEFORCED, System.currentTimeMillis() + 2_000));
|
||||
|
||||
MvcResult mvcResult = performGet("/{tenant}/controller/v1/" + DEFAULT_CONTROLLER_ID, MediaTypes.HAL_JSON,
|
||||
status().isOk(), tenantAware.getCurrentTenant()).andReturn();
|
||||
MvcResult mvcResult = performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(),
|
||||
tenantAware.getCurrentTenant(), DEFAULT_CONTROLLER_ID).andReturn();
|
||||
|
||||
final String urlBeforeSwitch = JsonPath.compile("_links.deploymentBase.href")
|
||||
.read(mvcResult.getResponse().getContentAsString()).toString();
|
||||
|
||||
// Time is not yet over, so we should see the same URL
|
||||
mvcResult = performGet(CONTROLLER_BY_ID, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(),
|
||||
mvcResult = performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(),
|
||||
DEFAULT_CONTROLLER_ID).andReturn();
|
||||
assertThat(JsonPath.compile("_links.deploymentBase.href").read(mvcResult.getResponse().getContentAsString())
|
||||
.toString()).isEqualTo(urlBeforeSwitch)
|
||||
.startsWith("http://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/"
|
||||
+ DEFAULT_CONTROLLER_ID + "/deploymentBase/" + actionId);
|
||||
.startsWith(deploymentBaseLink(DEFAULT_CONTROLLER_ID, actionId.toString()));
|
||||
|
||||
// After the time is over we should see a new etag
|
||||
TimeUnit.MILLISECONDS.sleep(2_000);
|
||||
|
||||
mvcResult = performGet(CONTROLLER_BY_ID, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(),
|
||||
mvcResult = performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(),
|
||||
DEFAULT_CONTROLLER_ID).andReturn();
|
||||
|
||||
assertThat(JsonPath.compile("_links.deploymentBase.href").read(mvcResult.getResponse().getContentAsString())
|
||||
@@ -273,12 +261,11 @@ public class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
// Run test
|
||||
|
||||
final long current = System.currentTimeMillis();
|
||||
performGet(CONTROLLER_BY_ID, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(),
|
||||
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(),
|
||||
DEFAULT_CONTROLLER_ID)
|
||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||
.andExpect(jsonPath("$._links.deploymentBase.href",
|
||||
startsWith("http://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/"
|
||||
+ DEFAULT_CONTROLLER_ID + "/deploymentBase/" + uaction.getId())));
|
||||
startsWith(deploymentBaseLink(DEFAULT_CONTROLLER_ID, uaction.getId().toString()))));
|
||||
assertThat(targetManagement.getByControllerID(DEFAULT_CONTROLLER_ID).get().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
assertThat(targetManagement.getByControllerID(DEFAULT_CONTROLLER_ID).get().getLastTargetQuery())
|
||||
@@ -333,12 +320,11 @@ public class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
// Run test
|
||||
|
||||
final long current = System.currentTimeMillis();
|
||||
performGet(CONTROLLER_BY_ID, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(),
|
||||
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(),
|
||||
DEFAULT_CONTROLLER_ID)
|
||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||
.andExpect(jsonPath("$._links.deploymentBase.href",
|
||||
startsWith("http://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/"
|
||||
+ DEFAULT_CONTROLLER_ID + "/deploymentBase/" + uaction.getId())));
|
||||
startsWith(deploymentBaseLink(DEFAULT_CONTROLLER_ID, uaction.getId().toString()))));
|
||||
assertThat(targetManagement.getByControllerID(DEFAULT_CONTROLLER_ID).get().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
assertThat(targetManagement.getByControllerID(DEFAULT_CONTROLLER_ID).get().getLastTargetQuery())
|
||||
@@ -401,12 +387,11 @@ public class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
// Run test
|
||||
|
||||
final long current = System.currentTimeMillis();
|
||||
performGet(CONTROLLER_BY_ID, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(),
|
||||
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(),
|
||||
DEFAULT_CONTROLLER_ID)
|
||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||
.andExpect(jsonPath("$._links.deploymentBase.href",
|
||||
startsWith("http://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/"
|
||||
+ DEFAULT_CONTROLLER_ID + "/deploymentBase/" + uaction.getId())));
|
||||
startsWith(deploymentBaseLink(DEFAULT_CONTROLLER_ID, uaction.getId().toString()))));
|
||||
assertThat(targetManagement.getByControllerID(DEFAULT_CONTROLLER_ID).get().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
assertThat(targetManagement.getByControllerID(DEFAULT_CONTROLLER_ID).get().getLastTargetQuery())
|
||||
@@ -439,97 +424,39 @@ public class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
.value(visibleMetadataOsValue));
|
||||
}
|
||||
|
||||
private ResultActions getAndVerifyDeploymentBasePayload(final String controllerId, final MediaType mediaType,
|
||||
final DistributionSet ds, final Artifact artifact, final Artifact artifactSignature, final Long actionId,
|
||||
final Long osModuleId, final String downloadType, final String updateType) throws Exception {
|
||||
return performGet("/{tenant}/controller/v1/" + controllerId + "/deploymentBase/{actionId}", mediaType,
|
||||
status().isOk(), tenantAware.getCurrentTenant(), actionId.toString())
|
||||
.andExpect(jsonPath("$.id", equalTo(String.valueOf(actionId))))
|
||||
.andExpect(jsonPath("$.deployment.download", equalTo(downloadType)))
|
||||
.andExpect(jsonPath("$.deployment.update", equalTo(updateType)))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='jvm')].name",
|
||||
contains(ds.findFirstModuleByType(runtimeType).get().getName())))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='jvm')].version",
|
||||
contains(ds.findFirstModuleByType(runtimeType).get().getVersion())))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='os')].name",
|
||||
contains(ds.findFirstModuleByType(osType).get().getName())))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='os')].version",
|
||||
contains(ds.findFirstModuleByType(osType).get().getVersion())))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='os')].artifacts[0].size",
|
||||
contains(ARTIFACT_SIZE)))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='os')].artifacts[0].filename",
|
||||
contains("test1")))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='os')].artifacts[0].hashes.md5",
|
||||
contains(artifact.getMd5Hash())))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='os')].artifacts[0].hashes.sha1",
|
||||
contains(artifact.getSha1Hash())))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='os')].artifacts[0].hashes.sha256",
|
||||
contains(artifact.getSha256Hash())))
|
||||
.andExpect(jsonPath(
|
||||
"$.deployment.chunks[?(@.part=='os')].artifacts[0]._links.download-http.href",
|
||||
contains(HTTP_LOCALHOST + tenantAware.getCurrentTenant() + "/controller/v1/"
|
||||
+ controllerId + "/softwaremodules/" + osModuleId + "/artifacts/test1")))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='os')].artifacts[0]._links.md5sum-http.href",
|
||||
contains(HTTP_LOCALHOST + tenantAware.getCurrentTenant() + "/controller/v1/"
|
||||
+ controllerId + "/softwaremodules/" + osModuleId + "/artifacts/test1.MD5SUM")))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='os')].artifacts[1].size",
|
||||
contains(ARTIFACT_SIZE)))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='os')].artifacts[1].filename",
|
||||
contains("test1.signature")))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='os')].artifacts[1].hashes.md5",
|
||||
contains(artifactSignature.getMd5Hash())))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='os')].artifacts[1].hashes.sha1",
|
||||
contains(artifactSignature.getSha1Hash())))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='os')].artifacts[1].hashes.sha256",
|
||||
contains(artifactSignature.getSha256Hash())))
|
||||
.andExpect(
|
||||
jsonPath("$.deployment.chunks[?(@.part=='os')].artifacts[1]._links.download-http.href",
|
||||
contains(HTTP_LOCALHOST + tenantAware.getCurrentTenant() + "/controller/v1/"
|
||||
+ controllerId + "/softwaremodules/" + osModuleId
|
||||
+ "/artifacts/test1.signature")))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='os')].artifacts[1]._links.md5sum-http.href",
|
||||
contains(HTTP_LOCALHOST + tenantAware.getCurrentTenant() + "/controller/v1/"
|
||||
+ controllerId + "/softwaremodules/" + osModuleId
|
||||
+ "/artifacts/test1.signature.MD5SUM")))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='bApp')].version",
|
||||
contains(ds.findFirstModuleByType(appType).get().getVersion())))
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='bApp')].metadata").doesNotExist())
|
||||
.andExpect(jsonPath("$.deployment.chunks[?(@.part=='bApp')].name")
|
||||
.value(ds.findFirstModuleByType(appType).get().getName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Test various invalid access attempts to the deployment resource und the expected behaviour of the server.")
|
||||
public void badDeploymentAction() throws Exception {
|
||||
final Target target = testdataFactory.createTarget(DEFAULT_CONTROLLER_ID);
|
||||
|
||||
// not allowed methods
|
||||
mvc.perform(post(DEPLOYMENT_BASE + "1", tenantAware.getCurrentTenant(), DEFAULT_CONTROLLER_ID))
|
||||
mvc.perform(post(DEPLOYMENT_BASE, tenantAware.getCurrentTenant(), DEFAULT_CONTROLLER_ID, "1"))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isMethodNotAllowed());
|
||||
|
||||
mvc.perform(put(DEPLOYMENT_BASE + "1", tenantAware.getCurrentTenant(), DEFAULT_CONTROLLER_ID))
|
||||
mvc.perform(put(DEPLOYMENT_BASE, tenantAware.getCurrentTenant(), DEFAULT_CONTROLLER_ID, "1"))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isMethodNotAllowed());
|
||||
|
||||
mvc.perform(delete(DEPLOYMENT_BASE + "1", tenantAware.getCurrentTenant(), DEFAULT_CONTROLLER_ID))
|
||||
mvc.perform(delete(DEPLOYMENT_BASE, tenantAware.getCurrentTenant(), DEFAULT_CONTROLLER_ID, "1"))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isMethodNotAllowed());
|
||||
|
||||
// non existing target
|
||||
mvc.perform(MockMvcRequestBuilders.get(DEPLOYMENT_BASE + "1", tenantAware.getCurrentTenant(), "not-existing"))
|
||||
mvc.perform(MockMvcRequestBuilders.get(DEPLOYMENT_BASE, tenantAware.getCurrentTenant(), "not-existing", "1"))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound());
|
||||
|
||||
// no deployment
|
||||
mvc.perform(MockMvcRequestBuilders.get(DEPLOYMENT_BASE + "1", tenantAware.getCurrentTenant(),
|
||||
DEFAULT_CONTROLLER_ID)).andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound());
|
||||
mvc.perform(
|
||||
MockMvcRequestBuilders.get(DEPLOYMENT_BASE, tenantAware.getCurrentTenant(), DEFAULT_CONTROLLER_ID, "1"))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound());
|
||||
|
||||
// wrong media type
|
||||
final List<Target> toAssign = Collections.singletonList(target);
|
||||
final DistributionSet savedSet = testdataFactory.createDistributionSet("");
|
||||
|
||||
final Long actionId = getFirstAssignedActionId(assignDistributionSet(savedSet, toAssign));
|
||||
mvc.perform(MockMvcRequestBuilders.get(DEPLOYMENT_BASE + actionId, tenantAware.getCurrentTenant(),
|
||||
DEFAULT_CONTROLLER_ID)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
mvc.perform(MockMvcRequestBuilders.get(DEPLOYMENT_BASE, tenantAware.getCurrentTenant(), DEFAULT_CONTROLLER_ID,
|
||||
actionId)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
mvc.perform(MockMvcRequestBuilders
|
||||
.get(DEPLOYMENT_BASE + actionId, tenantAware.getCurrentTenant(), DEFAULT_CONTROLLER_ID)
|
||||
.get(DEPLOYMENT_BASE, tenantAware.getCurrentTenant(), DEFAULT_CONTROLLER_ID, actionId)
|
||||
.accept(MediaType.APPLICATION_ATOM_XML)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isNotAcceptable());
|
||||
}
|
||||
@@ -548,11 +475,10 @@ public class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
final String feedback = JsonBuilder.deploymentActionFeedback(action.getId().toString(), "proceeding");
|
||||
// assign distribution set creates an action status, so only 99 left
|
||||
for (int i = 0; i < 99; i++) {
|
||||
postFeedback(MediaType.APPLICATION_JSON, DEFAULT_CONTROLLER_ID, action.getId(), feedback, status().isOk());
|
||||
postDeploymentFeedback(DEFAULT_CONTROLLER_ID, action.getId(), feedback, status().isOk());
|
||||
}
|
||||
|
||||
postFeedback(MediaType.APPLICATION_JSON, DEFAULT_CONTROLLER_ID, action.getId(), feedback,
|
||||
status().isForbidden());
|
||||
postDeploymentFeedback(DEFAULT_CONTROLLER_ID, action.getId(), feedback, status().isForbidden());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -573,7 +499,7 @@ public class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
|
||||
final String feedback = JsonBuilder.deploymentActionFeedback(action.getId().toString(), "proceeding", "none",
|
||||
messages);
|
||||
postFeedback(MediaType.APPLICATION_JSON, DEFAULT_CONTROLLER_ID, action.getId(), feedback,
|
||||
postDeploymentFeedback(DEFAULT_CONTROLLER_ID, action.getId(), feedback,
|
||||
status().isForbidden());
|
||||
}
|
||||
|
||||
@@ -596,21 +522,21 @@ public class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
assertThat(targetManagement.findByUpdateStatus(PageRequest.of(0, 10), TargetUpdateStatus.UNKNOWN)).hasSize(2);
|
||||
|
||||
// action1 done
|
||||
postFeedback(MediaType.APPLICATION_JSON, DEFAULT_CONTROLLER_ID, actionId1,
|
||||
postDeploymentFeedback(DEFAULT_CONTROLLER_ID, actionId1,
|
||||
JsonBuilder.deploymentActionFeedback(actionId1.toString(), "closed"), status().isOk());
|
||||
|
||||
findTargetAndAssertUpdateStatus(Optional.of(ds3), TargetUpdateStatus.PENDING, 2, Optional.of(ds1));
|
||||
assertStatusMessagesCount(4);
|
||||
|
||||
// action2 done
|
||||
postFeedback(MediaType.APPLICATION_JSON, DEFAULT_CONTROLLER_ID, actionId2,
|
||||
postDeploymentFeedback(DEFAULT_CONTROLLER_ID, actionId2,
|
||||
JsonBuilder.deploymentActionFeedback(actionId2.toString(), "closed"), status().isOk());
|
||||
|
||||
findTargetAndAssertUpdateStatus(Optional.of(ds3), TargetUpdateStatus.PENDING, 1, Optional.of(ds2));
|
||||
assertStatusMessagesCount(5);
|
||||
|
||||
// action3 done
|
||||
postFeedback(MediaType.APPLICATION_JSON, DEFAULT_CONTROLLER_ID, actionId3,
|
||||
postDeploymentFeedback(DEFAULT_CONTROLLER_ID, actionId3,
|
||||
JsonBuilder.deploymentActionFeedback(actionId3.toString(), "closed"), status().isOk());
|
||||
|
||||
findTargetAndAssertUpdateStatus(Optional.of(ds3), TargetUpdateStatus.IN_SYNC, 0, Optional.of(ds3));
|
||||
@@ -629,7 +555,7 @@ public class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
assignDistributionSet(ds, Collections.singletonList(savedTarget));
|
||||
final Action action = deploymentManagement.findActionsByDistributionSet(PAGE, ds.getId()).getContent().get(0);
|
||||
|
||||
postFeedback(MediaType.APPLICATION_JSON, DEFAULT_CONTROLLER_ID, action.getId(),
|
||||
postDeploymentFeedback(DEFAULT_CONTROLLER_ID, action.getId(),
|
||||
JsonBuilder.deploymentActionFeedback(action.getId().toString(), "closed", "failure", "error message"),
|
||||
status().isOk());
|
||||
|
||||
@@ -643,7 +569,7 @@ public class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
Collections.singletonList(targetManagement.getByControllerID(DEFAULT_CONTROLLER_ID).get()));
|
||||
final Action action2 = deploymentManagement.findActiveActionsByTarget(PAGE, DEFAULT_CONTROLLER_ID).getContent()
|
||||
.get(0);
|
||||
postFeedback(MediaType.APPLICATION_JSON, DEFAULT_CONTROLLER_ID, action2.getId(),
|
||||
postDeploymentFeedback(DEFAULT_CONTROLLER_ID, action2.getId(),
|
||||
JsonBuilder.deploymentActionFeedback(action2.getId().toString(), "closed", "SUCCESS"), status().isOk());
|
||||
findTargetAndAssertUpdateStatus(Optional.of(ds), TargetUpdateStatus.IN_SYNC, 0, Optional.of(ds));
|
||||
assertTargetCountByStatus(0, 0, 1);
|
||||
@@ -666,32 +592,32 @@ public class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
|
||||
// Now valid Feedback
|
||||
for (int i = 0; i < 4; i++) {
|
||||
postFeedback(MediaType.APPLICATION_JSON, DEFAULT_CONTROLLER_ID, actionId,
|
||||
postDeploymentFeedback(DEFAULT_CONTROLLER_ID, actionId,
|
||||
JsonBuilder.deploymentActionFeedback(actionId.toString(), "proceeding"), status().isOk());
|
||||
assertActionStatusCount(i + 2, i);
|
||||
|
||||
}
|
||||
|
||||
postFeedback(MediaType.APPLICATION_JSON, DEFAULT_CONTROLLER_ID, actionId,
|
||||
postDeploymentFeedback(DEFAULT_CONTROLLER_ID, actionId,
|
||||
JsonBuilder.deploymentActionFeedback(actionId.toString(), "scheduled"), status().isOk());
|
||||
assertActionStatusCount(6, 5);
|
||||
|
||||
postFeedback(MediaType.APPLICATION_JSON, DEFAULT_CONTROLLER_ID, actionId,
|
||||
postDeploymentFeedback(DEFAULT_CONTROLLER_ID, actionId,
|
||||
JsonBuilder.deploymentActionFeedback(actionId.toString(), "resumed"), status().isOk());
|
||||
assertActionStatusCount(7, 6);
|
||||
|
||||
postFeedback(MediaType.APPLICATION_JSON, DEFAULT_CONTROLLER_ID, actionId,
|
||||
postDeploymentFeedback(DEFAULT_CONTROLLER_ID, actionId,
|
||||
JsonBuilder.deploymentActionFeedback(actionId.toString(), "canceled"), status().isOk());
|
||||
assertStatusAndActiveActionsCount(TargetUpdateStatus.PENDING, 1);
|
||||
assertActionStatusCount(8, 7, 0, 0, 1);
|
||||
assertTargetCountByStatus(1, 0, 0);
|
||||
|
||||
postFeedback(MediaType.APPLICATION_JSON, DEFAULT_CONTROLLER_ID, actionId,
|
||||
postDeploymentFeedback(DEFAULT_CONTROLLER_ID, actionId,
|
||||
JsonBuilder.deploymentActionFeedback(actionId.toString(), "rejected"), status().isOk());
|
||||
assertStatusAndActiveActionsCount(TargetUpdateStatus.PENDING, 1);
|
||||
assertActionStatusCount(9, 6, 1, 0, 1);
|
||||
|
||||
postFeedback(MediaType.APPLICATION_JSON, DEFAULT_CONTROLLER_ID, actionId,
|
||||
postDeploymentFeedback(DEFAULT_CONTROLLER_ID, actionId,
|
||||
JsonBuilder.deploymentActionFeedback(actionId.toString(), "closed"), status().isOk());
|
||||
assertStatusAndActiveActionsCount(TargetUpdateStatus.IN_SYNC, 0);
|
||||
assertActionStatusCount(10, 7, 1, 1, 1);
|
||||
@@ -709,13 +635,13 @@ public class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
|
||||
// target does not exist
|
||||
|
||||
postFeedback(MediaType.APPLICATION_JSON, DEFAULT_CONTROLLER_ID, 1234L,
|
||||
postDeploymentFeedback(DEFAULT_CONTROLLER_ID, 1234L,
|
||||
JsonBuilder.deploymentActionInProgressFeedback("1234"), status().isNotFound());
|
||||
|
||||
final Target savedTarget = testdataFactory.createTarget(DEFAULT_CONTROLLER_ID);
|
||||
|
||||
// Action does not exists
|
||||
postFeedback(MediaType.APPLICATION_JSON, "4713", 1234L, JsonBuilder.deploymentActionInProgressFeedback("1234"),
|
||||
// Action does not exist
|
||||
postDeploymentFeedback("4713", 1234L, JsonBuilder.deploymentActionInProgressFeedback("1234"),
|
||||
status().isNotFound());
|
||||
|
||||
assignDistributionSet(savedSet, Collections.singletonList(savedTarget)).getAssignedEntity().iterator().next();
|
||||
@@ -725,17 +651,18 @@ public class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
.getContent().get(0);
|
||||
|
||||
// action exists but is not assigned to this target
|
||||
postFeedback(MediaType.APPLICATION_JSON, "4713", updateAction.getId(),
|
||||
postDeploymentFeedback("4713", updateAction.getId(),
|
||||
JsonBuilder.deploymentActionInProgressFeedback(updateAction.getId().toString()), status().isNotFound());
|
||||
|
||||
// not allowed methods
|
||||
mvc.perform(MockMvcRequestBuilders.get(DEPLOYMENT_BASE + "2/feedback", tenantAware.getCurrentTenant(),
|
||||
DEFAULT_CONTROLLER_ID)).andDo(MockMvcResultPrinter.print()).andExpect(status().isMethodNotAllowed());
|
||||
mvc.perform(MockMvcRequestBuilders.get(DEPLOYMENT_FEEDBACK, tenantAware.getCurrentTenant(),
|
||||
DEFAULT_CONTROLLER_ID, "2")).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isMethodNotAllowed());
|
||||
|
||||
mvc.perform(put(DEPLOYMENT_BASE + "2/feedback", tenantAware.getCurrentTenant(), DEFAULT_CONTROLLER_ID))
|
||||
mvc.perform(put(DEPLOYMENT_FEEDBACK, tenantAware.getCurrentTenant(), DEFAULT_CONTROLLER_ID, "2"))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isMethodNotAllowed());
|
||||
|
||||
mvc.perform(delete(DEPLOYMENT_BASE + "2/feedback", tenantAware.getCurrentTenant(), DEFAULT_CONTROLLER_ID))
|
||||
mvc.perform(delete(DEPLOYMENT_FEEDBACK, tenantAware.getCurrentTenant(), DEFAULT_CONTROLLER_ID, "2"))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isMethodNotAllowed());
|
||||
|
||||
}
|
||||
@@ -754,7 +681,7 @@ public class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
assignDistributionSet(ds.getId(), "1080");
|
||||
final Action action = deploymentManagement.findActionsByTarget(target.getControllerId(), PAGE).getContent()
|
||||
.get(0);
|
||||
postFeedback(MediaType.APPLICATION_JSON, "1080", action.getId(),
|
||||
postDeploymentFeedback("1080", action.getId(),
|
||||
JsonBuilder.deploymentActionInProgressFeedback("AAAA"), status().isBadRequest());
|
||||
}
|
||||
|
||||
@@ -775,7 +702,7 @@ public class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
.get(0);
|
||||
final String missingResultInFeedback = JsonBuilder.missingResultInFeedback(action.getId().toString(), "closed",
|
||||
"test");
|
||||
postFeedback(MediaType.APPLICATION_JSON, "1080", action.getId(), missingResultInFeedback,
|
||||
postDeploymentFeedback("1080", action.getId(), missingResultInFeedback,
|
||||
status().isBadRequest()).andExpect(jsonPath("$.*", hasSize(3))).andExpect(
|
||||
jsonPath("$.exceptionClass", equalTo(MessageNotReadableException.class.getCanonicalName())));
|
||||
}
|
||||
@@ -797,7 +724,7 @@ public class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
.get(0);
|
||||
final String missingFinishedResultInFeedback = JsonBuilder
|
||||
.missingFinishedResultInFeedback(action.getId().toString(), "closed", "test");
|
||||
postFeedback(MediaType.APPLICATION_JSON, "1080", action.getId(), missingFinishedResultInFeedback,
|
||||
postDeploymentFeedback("1080", action.getId(), missingFinishedResultInFeedback,
|
||||
status().isBadRequest()).andExpect(jsonPath("$.*", hasSize(3))).andExpect(
|
||||
jsonPath("$.exceptionClass", equalTo(MessageNotReadableException.class.getCanonicalName())));
|
||||
}
|
||||
@@ -814,7 +741,7 @@ public class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
new ActionStatusCondition(Status.RUNNING));
|
||||
}
|
||||
|
||||
private class ActionStatusCondition extends Condition<ActionStatus> {
|
||||
private static class ActionStatusCondition extends Condition<ActionStatus> {
|
||||
private final Status status;
|
||||
|
||||
public ActionStatusCondition(final Status status) {
|
||||
@@ -827,31 +754,11 @@ public class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
}
|
||||
}
|
||||
|
||||
private ResultActions performGet(final String url, final MediaType mediaType, final ResultMatcher statusMatcher,
|
||||
final String... values) throws Exception {
|
||||
return mvc.perform(MockMvcRequestBuilders.get(url, values).accept(mediaType))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(statusMatcher)
|
||||
.andExpect(content().contentTypeCompatibleWith(mediaType));
|
||||
}
|
||||
|
||||
private ResultActions postFeedback(final MediaType mediaType, final String controllerId, final Long id,
|
||||
final String content, final ResultMatcher statusMatcher) throws Exception {
|
||||
return postFeedback(mediaType, controllerId, id, content.getBytes(), statusMatcher);
|
||||
}
|
||||
|
||||
private ResultActions postFeedback(final MediaType mediaType, final String controllerId, final Long id,
|
||||
final byte[] content, final ResultMatcher statusMatcher) throws Exception {
|
||||
return mvc
|
||||
.perform(post(DEPLOYMENT_BASE + id + "/feedback", tenantAware.getCurrentTenant(), controllerId)
|
||||
.content(content).contentType(mediaType).accept(mediaType))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(statusMatcher);
|
||||
}
|
||||
|
||||
private Target createTargetAndAssertNoActiveActions() {
|
||||
final Target savedTarget = testdataFactory.createTarget(DdiDeploymentBaseTest.DEFAULT_CONTROLLER_ID);
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(PAGE, savedTarget.getControllerId())).isEmpty();
|
||||
assertThat(deploymentManagement.countActionsAll()).isEqualTo(0);
|
||||
assertThat(deploymentManagement.countActionStatusAll()).isEqualTo(0);
|
||||
assertThat(deploymentManagement.countActionsAll()).isZero();
|
||||
assertThat(deploymentManagement.countActionStatusAll()).isZero();
|
||||
return savedTarget;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,415 @@
|
||||
/**
|
||||
* Copyright (c) 2022 Bosch.IO GmbH and others.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.ddi.rest.resource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.hasItem;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.commons.lang3.RandomUtils;
|
||||
import org.eclipse.hawkbit.ddi.rest.api.DdiRestConstants;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetAttributesRequestedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetPollEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.ActionCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.ActionUpdatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleUpdatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
||||
import org.eclipse.hawkbit.repository.model.Artifact;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.test.matcher.Expect;
|
||||
import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents;
|
||||
import org.eclipse.hawkbit.rest.util.JsonBuilder;
|
||||
import org.eclipse.hawkbit.rest.util.MockMvcResultPrinter;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.hateoas.MediaTypes;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.servlet.ResultActions;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
/**
|
||||
* Test installed base from the controller.
|
||||
*/
|
||||
@Feature("Component Tests - Direct Device Integration API")
|
||||
@Story("Installed Base Resource")
|
||||
public class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
|
||||
private static final int ARTIFACT_SIZE = 5 * 1024;
|
||||
private static final String CONTROLLER_ID = "4715";
|
||||
|
||||
@Test
|
||||
@Description("Ensure that the installed base resource is available as CBOR")
|
||||
public void installedBaseResourceCbor() throws Exception {
|
||||
final Target target = testdataFactory.createTarget();
|
||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||
final Long actionId = getFirstAssignedActionId(assignDistributionSet(ds, target));
|
||||
postDeploymentFeedback(target.getControllerId(), actionId,
|
||||
JsonBuilder.deploymentActionFeedback(actionId.toString(), "closed"), status().isOk());
|
||||
|
||||
// get installed base
|
||||
performGet(INSTALLED_BASE, MediaType.parseMediaType(DdiRestConstants.MEDIA_TYPE_CBOR), status().isOk(),
|
||||
tenantAware.getCurrentTenant(), target.getControllerId(), actionId.toString());
|
||||
|
||||
final Long softwareModuleId = ds.getModules().stream().findAny().get().getId();
|
||||
testdataFactory.createArtifacts(softwareModuleId);
|
||||
// get artifacts
|
||||
performGet(SOFTWARE_MODULE_ARTIFACTS, MediaType.parseMediaType(DdiRestConstants.MEDIA_TYPE_CBOR),
|
||||
status().isOk(), tenantAware.getCurrentTenant(), target.getControllerId(),
|
||||
String.valueOf(softwareModuleId));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Test several deployments to a controller. Checks that action is represented as installedBase after installation.")
|
||||
public void deploymentSeveralActionsInInstalledBase() throws Exception {
|
||||
// Prepare test data
|
||||
final Target target = createTargetAndAssertNoActiveActions();
|
||||
|
||||
final DistributionSet ds1 = testdataFactory.createDistributionSet("1", true);
|
||||
final Artifact artifact1 = testdataFactory.createArtifact(RandomUtils.nextBytes(ARTIFACT_SIZE),
|
||||
getOsModule(ds1), "test1", ARTIFACT_SIZE);
|
||||
final Artifact artifactSignature1 = testdataFactory.createArtifact(RandomUtils.nextBytes(ARTIFACT_SIZE),
|
||||
getOsModule(ds1), "test1.signature", ARTIFACT_SIZE);
|
||||
|
||||
final DistributionSet ds2 = testdataFactory.createDistributionSet("2", true);
|
||||
final Artifact artifact2 = testdataFactory.createArtifact(RandomUtils.nextBytes(ARTIFACT_SIZE),
|
||||
getOsModule(ds2), "test2", ARTIFACT_SIZE);
|
||||
final Artifact artifactSignature2 = testdataFactory.createArtifact(RandomUtils.nextBytes(ARTIFACT_SIZE),
|
||||
getOsModule(ds2), "test2.signature", ARTIFACT_SIZE);
|
||||
|
||||
// Run test with 1st action
|
||||
final Long actionId1 = getFirstAssignedActionId(
|
||||
assignDistributionSet(ds1.getId(), target.getControllerId(), Action.ActionType.SOFT));
|
||||
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(), CONTROLLER_ID)
|
||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||
.andExpect(jsonPath("$._links.installedBase.href").doesNotExist())
|
||||
.andExpect(jsonPath("$._links.deploymentBase.href",
|
||||
startsWith(deploymentBaseLink(CONTROLLER_ID, actionId1.toString()))));
|
||||
|
||||
getAndVerifyDeploymentBasePayload(CONTROLLER_ID, MediaType.APPLICATION_JSON, ds1, artifact1, artifactSignature1,
|
||||
actionId1, ds1.findFirstModuleByType(osType).get().getId(), Action.ActionType.SOFT);
|
||||
|
||||
postDeploymentFeedback(target.getControllerId(), actionId1,
|
||||
JsonBuilder.deploymentActionFeedback(actionId1.toString(), "closed", "success", "Closed"),
|
||||
status().isOk());
|
||||
|
||||
getAndVerifyInstalledBasePayload(CONTROLLER_ID, MediaType.APPLICATION_JSON, ds1, artifact1, artifactSignature1,
|
||||
actionId1, ds1.findFirstModuleByType(osType).get().getId(), Action.ActionType.SOFT);
|
||||
|
||||
// Run test with 2nd action
|
||||
final Long actionId2 = getFirstAssignedActionId(
|
||||
assignDistributionSet(ds2.getId(), target.getControllerId(), Action.ActionType.FORCED));
|
||||
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(), CONTROLLER_ID)
|
||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||
.andExpect(jsonPath("$._links.installedBase.href",
|
||||
startsWith(installedBaseLink(CONTROLLER_ID, actionId1.toString()))))
|
||||
.andExpect(jsonPath("$._links.deploymentBase.href",
|
||||
startsWith(deploymentBaseLink(CONTROLLER_ID, actionId2.toString()))));
|
||||
|
||||
getAndVerifyDeploymentBasePayload(CONTROLLER_ID, MediaType.APPLICATION_JSON, ds2, artifact2, artifactSignature2,
|
||||
actionId2, ds2.findFirstModuleByType(osType).get().getId(), Action.ActionType.FORCED);
|
||||
|
||||
postDeploymentFeedback(target.getControllerId(), actionId2,
|
||||
JsonBuilder.deploymentActionFeedback(actionId2.toString(), "closed", "success", "Closed"),
|
||||
status().isOk());
|
||||
|
||||
getAndVerifyInstalledBasePayload(CONTROLLER_ID, MediaType.APPLICATION_JSON, ds2, artifact2, artifactSignature2,
|
||||
actionId2, ds2.findFirstModuleByType(osType).get().getId(), Action.ActionType.FORCED);
|
||||
|
||||
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(), CONTROLLER_ID)
|
||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||
.andExpect(jsonPath("$._links.installedBase.href",
|
||||
startsWith(installedBaseLink(CONTROLLER_ID, actionId2.toString()))))
|
||||
.andExpect(jsonPath("$._links.deploymentBase.href").doesNotExist());
|
||||
|
||||
// older installed action is still accessible, although not part of controller base
|
||||
getAndVerifyInstalledBasePayload(CONTROLLER_ID, MediaType.APPLICATION_JSON, ds1, artifact1, artifactSignature1,
|
||||
actionId1, ds1.findFirstModuleByType(osType).get().getId(), Action.ActionType.SOFT);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Test open deployment to a controller. Checks that installedBase returns 404 for a pending action.")
|
||||
public void installedBaseReturns404ForPendingAction() throws Exception {
|
||||
// Prepare test data
|
||||
final Target target = createTargetAndAssertNoActiveActions();
|
||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||
final Long actionId = getFirstAssignedActionId(assignDistributionSet(ds, target));
|
||||
|
||||
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(), CONTROLLER_ID)
|
||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||
.andExpect(jsonPath("$._links.installedBase.href").doesNotExist())
|
||||
.andExpect(jsonPath("$._links.deploymentBase.href",
|
||||
startsWith(deploymentBaseLink(CONTROLLER_ID, actionId.toString()))));
|
||||
|
||||
performGet(DEPLOYMENT_BASE, MediaType.APPLICATION_JSON, status().isOk(), tenantAware.getCurrentTenant(),
|
||||
target.getControllerId(), actionId.toString());
|
||||
|
||||
mvc.perform(MockMvcRequestBuilders.get(INSTALLED_BASE, tenantAware.getCurrentTenant(), target.getControllerId(),
|
||||
actionId.toString())).andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Ensures that artifacts are found, after the action was already closed.")
|
||||
public void artifactsOfInstalledActionExist() throws Exception {
|
||||
final Target target = createTargetAndAssertNoActiveActions();
|
||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||
final Long actionId = getFirstAssignedActionId(assignDistributionSet(ds, target));
|
||||
|
||||
postDeploymentFeedback(target.getControllerId(), actionId,
|
||||
JsonBuilder.deploymentActionFeedback(actionId.toString(), "closed"), status().isOk());
|
||||
|
||||
final Long softwareModuleId = ds.getModules().stream().findAny().get().getId();
|
||||
performGet(SOFTWARE_MODULE_ARTIFACTS, MediaType.APPLICATION_JSON, status().isOk(),
|
||||
tenantAware.getCurrentTenant(), target.getControllerId(), softwareModuleId.toString())
|
||||
.andExpect(jsonPath("$", hasSize(0)));
|
||||
|
||||
testdataFactory.createArtifacts(softwareModuleId);
|
||||
|
||||
performGet(SOFTWARE_MODULE_ARTIFACTS, MediaType.APPLICATION_JSON, status().isOk(),
|
||||
tenantAware.getCurrentTenant(), target.getControllerId(), softwareModuleId.toString())
|
||||
.andExpect(jsonPath("$", hasSize(3)))
|
||||
.andExpect(jsonPath("$.[?(@.filename=='filename0')]", hasSize(1)))
|
||||
.andExpect(jsonPath("$.[?(@.filename=='filename1')]", hasSize(1)))
|
||||
.andExpect(jsonPath("$.[?(@.filename=='filename2')]", hasSize(1)));
|
||||
|
||||
}
|
||||
|
||||
private static Stream<Action.ActionType> actionTypeForDeployment() {
|
||||
return Stream.of(Action.ActionType.SOFT, Action.ActionType.FORCED);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("org.eclipse.hawkbit.ddi.rest.resource.DdiInstalledBaseTest#actionTypeForDeployment")
|
||||
@Description("Test forced deployment to a controller. Checks that action is represented as installedBase after installation.")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
|
||||
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 2),
|
||||
@Expect(type = TargetPollEvent.class, count = 1) })
|
||||
public void deploymentActionInInstalledBase(final Action.ActionType actionType) throws Exception {
|
||||
// Prepare test data
|
||||
final Target target = createTargetAndAssertNoActiveActions();
|
||||
final DistributionSet ds = testdataFactory.createDistributionSet("", true);
|
||||
final Artifact artifact = testdataFactory.createArtifact(RandomUtils.nextBytes(ARTIFACT_SIZE), getOsModule(ds),
|
||||
"test1", ARTIFACT_SIZE);
|
||||
final Artifact artifactSignature = testdataFactory.createArtifact(RandomUtils.nextBytes(ARTIFACT_SIZE),
|
||||
getOsModule(ds), "test1.signature", ARTIFACT_SIZE);
|
||||
final Long actionId = getFirstAssignedActionId(
|
||||
assignDistributionSet(ds.getId(), target.getControllerId(), actionType));
|
||||
|
||||
postDeploymentFeedback(target.getControllerId(), actionId,
|
||||
JsonBuilder.deploymentActionFeedback(actionId.toString(), "closed", "success", "Closed"),
|
||||
status().isOk());
|
||||
|
||||
// Run test
|
||||
final ResultActions resultActions = performGet(CONTROLLER_BASE, MediaType.APPLICATION_JSON, status().isOk(),
|
||||
tenantAware.getCurrentTenant(), target.getControllerId());
|
||||
resultActions.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._links.deploymentBase.href").doesNotExist())
|
||||
.andExpect(jsonPath("$._links.installedBase.href",
|
||||
containsString(String.format("/%s/controller/v1/%s/installedBase/%d",
|
||||
tenantAware.getCurrentTenant(), target.getControllerId(), actionId))));
|
||||
|
||||
getAndVerifyInstalledBasePayload(CONTROLLER_ID, MediaType.APPLICATION_JSON, ds, artifact, artifactSignature,
|
||||
actionId, ds.findFirstModuleByType(osType).get().getId(), actionType);
|
||||
|
||||
getAndVerifyInstalledBasePayload(CONTROLLER_ID, MediaTypes.HAL_JSON, ds, artifact, artifactSignature, actionId,
|
||||
ds.findFirstModuleByType(osType).get().getId(), actionType);
|
||||
|
||||
// Action is still finished after calling installedBase
|
||||
final Iterable<ActionStatus> actionStatusMessages = deploymentManagement
|
||||
.findActionStatusByAction(PageRequest.of(0, 100, Sort.Direction.DESC, "id"), actionId);
|
||||
assertThat(actionStatusMessages).hasSize(2);
|
||||
final ActionStatus actionStatusMessage = actionStatusMessages.iterator().next();
|
||||
assertThat(actionStatusMessage.getStatus()).isEqualTo(Action.Status.FINISHED);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Test download-only deployment to a controller. Checks that download-only is not represented as installedBase.")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
|
||||
@Expect(type = TargetPollEvent.class, count = 2) })
|
||||
public void deploymentDownloadOnlyActionNotInInstalledBase() throws Exception {
|
||||
// Prepare test data
|
||||
final Target target = testdataFactory.createTarget();
|
||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||
final Long actionId = getFirstAssignedActionId(
|
||||
assignDistributionSet(ds.getId(), target.getControllerId(), Action.ActionType.DOWNLOAD_ONLY));
|
||||
|
||||
performGet(CONTROLLER_BASE, MediaType.APPLICATION_JSON, status().isOk(), tenantAware.getCurrentTenant(),
|
||||
target.getControllerId()).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._links.deploymentBase.href").exists())
|
||||
.andExpect(jsonPath("$._links.installedBase.href").doesNotExist());
|
||||
|
||||
postDeploymentFeedback(target.getControllerId(), actionId,
|
||||
JsonBuilder.deploymentActionFeedback(actionId.toString(), "download"), status().isOk());
|
||||
postDeploymentFeedback(target.getControllerId(), actionId,
|
||||
JsonBuilder.deploymentActionFeedback(actionId.toString(), "downloaded"), status().isOk());
|
||||
|
||||
// Test
|
||||
performGet(CONTROLLER_BASE, MediaType.APPLICATION_JSON, status().isOk(), tenantAware.getCurrentTenant(),
|
||||
target.getControllerId()).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._links.deploymentBase.href").doesNotExist())
|
||||
.andExpect(jsonPath("$._links.installedBase.href").doesNotExist());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("org.eclipse.hawkbit.ddi.rest.resource.DdiInstalledBaseTest#actionTypeForDeployment")
|
||||
@Description("Test a failed deployment to a controller. Checks that closed action is not represented as installedBase.")
|
||||
public void deploymentActionFailedNotInInstalledBase(Action.ActionType actionType) throws Exception {
|
||||
// Prepare test data
|
||||
final Target target = testdataFactory.createTarget();
|
||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||
final Long actionId = getFirstAssignedActionId(
|
||||
assignDistributionSet(ds.getId(), target.getControllerId(), actionType));
|
||||
|
||||
performGet(CONTROLLER_BASE, MediaType.APPLICATION_JSON, status().isOk(), tenantAware.getCurrentTenant(),
|
||||
target.getControllerId()).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._links.deploymentBase.href").exists())
|
||||
.andExpect(jsonPath("$._links.installedBase.href").doesNotExist());
|
||||
|
||||
postDeploymentFeedback(target.getControllerId(), actionId,
|
||||
JsonBuilder.deploymentActionFeedback(actionId.toString(), "proceeding"), status().isOk());
|
||||
postDeploymentFeedback(target.getControllerId(), actionId,
|
||||
JsonBuilder.deploymentActionFeedback(actionId.toString(), "closed", "failure", "Installation failed"),
|
||||
status().isOk());
|
||||
|
||||
// Test
|
||||
performGet(CONTROLLER_BASE, MediaType.APPLICATION_JSON, status().isOk(), tenantAware.getCurrentTenant(),
|
||||
target.getControllerId()).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._links.deploymentBase.href").doesNotExist())
|
||||
.andExpect(jsonPath("$._links.installedBase.href").doesNotExist());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Test to verify that only a specific count of messages are returned based on the input actionHistory for getControllerInstalledAction endpoint.")
|
||||
public void testActionHistoryCount() throws Exception {
|
||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||
Target savedTarget = testdataFactory.createTarget("911");
|
||||
savedTarget = getFirstAssignedTarget(assignDistributionSet(ds.getId(), savedTarget.getControllerId()));
|
||||
final Action savedAction = deploymentManagement.findActiveActionsByTarget(PAGE, savedTarget.getControllerId())
|
||||
.getContent().get(0);
|
||||
|
||||
postDeploymentFeedback(savedTarget.getControllerId(), savedAction.getId(), JsonBuilder.deploymentActionFeedback(
|
||||
savedAction.getId().toString(), "scheduled", "Installation scheduled"), status().isOk());
|
||||
|
||||
postDeploymentFeedback(savedTarget.getControllerId(), savedAction.getId(), JsonBuilder.deploymentActionFeedback(
|
||||
savedAction.getId().toString(), "proceeding", "Installation proceeding"), status().isOk());
|
||||
// only this feedback triggers the ActionUpdateEvent
|
||||
postDeploymentFeedback(savedTarget.getControllerId(), savedAction.getId(), JsonBuilder.deploymentActionFeedback(
|
||||
savedAction.getId().toString(), "closed", "success", "Installation completed"), status().isOk());
|
||||
|
||||
// Test
|
||||
// for zero input no action history is returned
|
||||
mvc.perform(get(INSTALLED_BASE + "?actionHistory", tenantAware.getCurrentTenant(), 911, savedAction.getId())
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.actionHistory.messages").doesNotExist());
|
||||
|
||||
// depending on given query parameter value, only the latest messages are
|
||||
// returned
|
||||
mvc.perform(get(INSTALLED_BASE + "?actionHistory=2", tenantAware.getCurrentTenant(), 911, savedAction.getId())
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.actionHistory.messages", hasItem(containsString("Installation completed"))))
|
||||
.andExpect(jsonPath("$.actionHistory.messages", hasItem(containsString("Installation proceeding"))))
|
||||
.andExpect(
|
||||
jsonPath("$.actionHistory.messages", not(hasItem(containsString("Installation scheduled")))));
|
||||
|
||||
// for negative input the entire action history is returned
|
||||
mvc.perform(get(INSTALLED_BASE + "?actionHistory=-3", tenantAware.getCurrentTenant(), 911, savedAction.getId())
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.actionHistory.messages", hasItem(containsString("Installation completed"))))
|
||||
.andExpect(jsonPath("$.actionHistory.messages", hasItem(containsString("Installation proceeding"))))
|
||||
.andExpect(jsonPath("$.actionHistory.messages", hasItem(containsString("Installation scheduled"))));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Test various invalid access attempts to the installed resource und the expected behaviour of the server.")
|
||||
public void badInstalledAction() throws Exception {
|
||||
final Target target = testdataFactory.createTarget(CONTROLLER_ID);
|
||||
|
||||
// not allowed methods
|
||||
mvc.perform(post(INSTALLED_BASE, tenantAware.getCurrentTenant(), CONTROLLER_ID, "1"))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isMethodNotAllowed());
|
||||
|
||||
mvc.perform(put(INSTALLED_BASE, tenantAware.getCurrentTenant(), CONTROLLER_ID, "1"))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isMethodNotAllowed());
|
||||
|
||||
mvc.perform(delete(INSTALLED_BASE, tenantAware.getCurrentTenant(), CONTROLLER_ID, "1"))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isMethodNotAllowed());
|
||||
|
||||
// non existing target
|
||||
mvc.perform(MockMvcRequestBuilders.get(INSTALLED_BASE, tenantAware.getCurrentTenant(), "not-existing", "1"))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound());
|
||||
|
||||
// no deployment
|
||||
mvc.perform(MockMvcRequestBuilders.get(INSTALLED_BASE, tenantAware.getCurrentTenant(), CONTROLLER_ID, "1"))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound());
|
||||
|
||||
// wrong media type
|
||||
final List<Target> toAssign = Collections.singletonList(target);
|
||||
final DistributionSet savedSet = testdataFactory.createDistributionSet("");
|
||||
|
||||
final Long actionId = getFirstAssignedActionId(assignDistributionSet(savedSet, toAssign));
|
||||
postDeploymentFeedback(CONTROLLER_ID, actionId,
|
||||
JsonBuilder.deploymentActionFeedback(actionId.toString(), "closed", "success"), status().isOk());
|
||||
mvc.perform(MockMvcRequestBuilders.get(INSTALLED_BASE, tenantAware.getCurrentTenant(), CONTROLLER_ID, actionId))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
mvc.perform(MockMvcRequestBuilders.get(INSTALLED_BASE, tenantAware.getCurrentTenant(), CONTROLLER_ID, actionId)
|
||||
.accept(MediaType.APPLICATION_ATOM_XML)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isNotAcceptable());
|
||||
}
|
||||
|
||||
private Target createTargetAndAssertNoActiveActions() {
|
||||
final Target savedTarget = testdataFactory.createTarget(CONTROLLER_ID);
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(PAGE, savedTarget.getControllerId())).isEmpty();
|
||||
assertThat(deploymentManagement.countActionsAll()).isZero();
|
||||
assertThat(deploymentManagement.countActionStatusAll()).isZero();
|
||||
return savedTarget;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,6 +18,7 @@ import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
||||
import static org.hamcrest.Matchers.hasItem;
|
||||
import static org.hamcrest.Matchers.lessThan;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
@@ -87,7 +88,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
@Test
|
||||
@Description("Ensure that the root poll resource is available as CBOR")
|
||||
public void rootPollResourceCbor() throws Exception {
|
||||
mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant())
|
||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), 4711)
|
||||
.accept(DdiRestConstants.MEDIA_TYPE_CBOR)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(content().contentType(DdiRestConstants.MEDIA_TYPE_CBOR)).andExpect(status().isOk());
|
||||
}
|
||||
@@ -95,7 +96,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
@Test
|
||||
@Description("Ensures that the API returns JSON when no Accept header is specified by the client.")
|
||||
public void apiReturnsJSONByDefault() throws Exception {
|
||||
final MvcResult result = mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant()))
|
||||
final MvcResult result = mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), 4711))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaTypes.HAL_JSON)).andReturn();
|
||||
|
||||
@@ -120,13 +121,13 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
// create tenant -- creates softwaremoduletypes and distributionsettypes
|
||||
systemManagement.getTenantMetadata("tenantDoesNotExists");
|
||||
|
||||
mvc.perform(get("/{}/controller/v1/aControllerId", tenantAware.getCurrentTenant()))
|
||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), "aControllerId"))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
|
||||
// delete tenant again, will also deleted target aControllerId
|
||||
systemManagement.deleteTenant("tenantDoesNotExists");
|
||||
|
||||
mvc.perform(get("/{}/controller/v1/aControllerId", tenantAware.getCurrentTenant()))
|
||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), "aControllerId"))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest());
|
||||
}
|
||||
|
||||
@@ -148,7 +149,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
// make a poll, audit information should not be changed, run as
|
||||
// controller principal!
|
||||
WithSpringAuthorityRule.runAs(WithSpringAuthorityRule.withController("controller", CONTROLLER_ROLE_ANONYMOUS), () -> {
|
||||
mvc.perform(get("/{tenant}/controller/v1/" + knownTargetControllerId, tenantAware.getCurrentTenant()))
|
||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), knownTargetControllerId))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
return null;
|
||||
});
|
||||
@@ -162,7 +163,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Ensures that server returns a not found response in case of empty controlloer ID.")
|
||||
@Description("Ensures that server returns a not found response in case of empty controller ID.")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
||||
public void rootRsWithoutId() throws Exception {
|
||||
mvc.perform(get("/controller/v1/")).andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound());
|
||||
@@ -175,24 +176,25 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
public void rootRsPlugAndPlay() throws Exception {
|
||||
|
||||
final long current = System.currentTimeMillis();
|
||||
String controllerId = "4711";
|
||||
|
||||
mvc.perform(get("/default-tenant/controller/v1/4711")).andDo(MockMvcResultPrinter.print())
|
||||
mvc.perform(get(CONTROLLER_BASE, "default-tenant", controllerId)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk()).andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")));
|
||||
assertThat(targetManagement.getByControllerID("4711").get().getLastTargetQuery())
|
||||
assertThat(targetManagement.getByControllerID(controllerId).get().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
|
||||
assertThat(targetManagement.getByControllerID("4711").get().getUpdateStatus())
|
||||
assertThat(targetManagement.getByControllerID(controllerId).get().getUpdateStatus())
|
||||
.isEqualTo(TargetUpdateStatus.REGISTERED);
|
||||
|
||||
// not allowed methods
|
||||
mvc.perform(post("/default-tenant/controller/v1/4711")).andDo(MockMvcResultPrinter.print())
|
||||
mvc.perform(post(CONTROLLER_BASE, "default-tenant", controllerId)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isMethodNotAllowed());
|
||||
|
||||
mvc.perform(put("/default-tenant/controller/v1/4711")).andDo(MockMvcResultPrinter.print())
|
||||
mvc.perform(put(CONTROLLER_BASE, "default-tenant", controllerId)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isMethodNotAllowed());
|
||||
|
||||
mvc.perform(delete("/default-tenant/controller/v1/4711")).andDo(MockMvcResultPrinter.print())
|
||||
mvc.perform(delete(CONTROLLER_BASE, "default-tenant", controllerId)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isMethodNotAllowed());
|
||||
}
|
||||
|
||||
@@ -210,7 +212,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
});
|
||||
|
||||
WithSpringAuthorityRule.runAs(WithSpringAuthorityRule.withUser("controller", CONTROLLER_ROLE_ANONYMOUS), () -> {
|
||||
mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant()))
|
||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), 4711))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:02:00")));
|
||||
@@ -229,63 +231,76 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6) })
|
||||
public void rootRsNotModified() throws Exception {
|
||||
final String etag = mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant()))
|
||||
String controllerId = "4711";
|
||||
final String etag = mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||
.andExpect(jsonPath("$._links.deploymentBase.href").doesNotExist())
|
||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00"))).andReturn().getResponse()
|
||||
.getHeader("ETag");
|
||||
|
||||
mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant()).header("If-None-Match", etag))
|
||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId).header("If-None-Match", etag))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isNotModified());
|
||||
|
||||
final Target target = targetManagement.getByControllerID("4711").get();
|
||||
final Target target = targetManagement.getByControllerID(controllerId).get();
|
||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||
|
||||
assignDistributionSet(ds.getId(), "4711");
|
||||
assignDistributionSet(ds.getId(), controllerId);
|
||||
|
||||
final Action updateAction = deploymentManagement.findActiveActionsByTarget(PAGE, target.getControllerId())
|
||||
.getContent().get(0);
|
||||
final String etagWithFirstUpdate = mvc
|
||||
.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant())
|
||||
.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId)
|
||||
.header("If-None-Match", etag).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||
.andExpect(jsonPath("$._links.installedBase.href").doesNotExist())
|
||||
.andExpect(jsonPath("$._links.deploymentBase.href",
|
||||
startsWith("http://localhost/" + tenantAware.getCurrentTenant()
|
||||
+ "/controller/v1/4711/deploymentBase/" + updateAction.getId())))
|
||||
startsWith(deploymentBaseLink("4711", updateAction.getId().toString()))))
|
||||
.andReturn().getResponse().getHeader("ETag");
|
||||
|
||||
assertThat(etagWithFirstUpdate).isNotNull();
|
||||
|
||||
mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant()).header("If-None-Match",
|
||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId).header("If-None-Match",
|
||||
etagWithFirstUpdate)).andDo(MockMvcResultPrinter.print()).andExpect(status().isNotModified());
|
||||
|
||||
// now lets finish the update
|
||||
sendDeploymentActionFeedback(target, updateAction, "closed", null).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk());
|
||||
|
||||
// we are again at the original state
|
||||
mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant()).header("If-None-Match", etag))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isNotModified());
|
||||
// as the update was installed, and we always receive the installed action, the
|
||||
// original state cannot be restored
|
||||
final String etagAfterInstallation = mvc
|
||||
.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId)
|
||||
.header("If-None-Match", etag).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||
.andExpect(jsonPath("$._links.deploymentBase.href").doesNotExist())
|
||||
.andExpect(jsonPath("$._links.installedBase.href",
|
||||
startsWith(installedBaseLink("4711", updateAction.getId().toString()))))
|
||||
.andReturn().getResponse().getHeader("ETag");
|
||||
|
||||
// Now another deployment
|
||||
final DistributionSet ds2 = testdataFactory.createDistributionSet("2");
|
||||
|
||||
assignDistributionSet(ds2.getId(), "4711");
|
||||
assignDistributionSet(ds2.getId(), controllerId);
|
||||
|
||||
final Action updateAction2 = deploymentManagement.findActiveActionsByTarget(PAGE, target.getControllerId())
|
||||
.getContent().get(0);
|
||||
|
||||
mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant())
|
||||
.header("If-None-Match", etagWithFirstUpdate).accept(MediaType.APPLICATION_JSON))
|
||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId)
|
||||
.header("If-None-Match", etagAfterInstallation).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||
.andExpect(jsonPath("$._links.installedBase.href",
|
||||
startsWith(installedBaseLink("4711", updateAction.getId().toString()))))
|
||||
.andExpect(jsonPath("$._links.deploymentBase.href",
|
||||
startsWith("http://localhost/" + tenantAware.getCurrentTenant()
|
||||
+ "/controller/v1/4711/deploymentBase/" + updateAction2.getId())))
|
||||
startsWith(deploymentBaseLink("4711", updateAction2.getId().toString()))))
|
||||
.andReturn().getResponse().getHeader("ETag");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -294,23 +309,24 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||
public void rootRsPrecommissioned() throws Exception {
|
||||
testdataFactory.createTarget("4711");
|
||||
String controllerId = "4711";
|
||||
testdataFactory.createTarget(controllerId);
|
||||
|
||||
assertThat(targetManagement.getByControllerID("4711").get().getUpdateStatus())
|
||||
assertThat(targetManagement.getByControllerID(controllerId).get().getUpdateStatus())
|
||||
.isEqualTo(TargetUpdateStatus.UNKNOWN);
|
||||
|
||||
final long current = System.currentTimeMillis();
|
||||
mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant()))
|
||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")));
|
||||
|
||||
assertThat(targetManagement.getByControllerID("4711").get().getLastTargetQuery())
|
||||
assertThat(targetManagement.getByControllerID(controllerId).get().getLastTargetQuery())
|
||||
.isLessThanOrEqualTo(System.currentTimeMillis());
|
||||
assertThat(targetManagement.getByControllerID("4711").get().getLastTargetQuery())
|
||||
assertThat(targetManagement.getByControllerID(controllerId).get().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
|
||||
assertThat(targetManagement.getByControllerID("4711").get().getUpdateStatus())
|
||||
assertThat(targetManagement.getByControllerID(controllerId).get().getUpdateStatus())
|
||||
.isEqualTo(TargetUpdateStatus.REGISTERED);
|
||||
}
|
||||
|
||||
@@ -326,7 +342,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
// make a poll, audit information should be set on plug and play
|
||||
WithSpringAuthorityRule.runAs(WithSpringAuthorityRule.withController("controller", CONTROLLER_ROLE_ANONYMOUS), () -> {
|
||||
mvc.perform(
|
||||
get("/{tenant}/controller/v1/{controllerId}", tenantAware.getCurrentTenant(), knownControllerId1))
|
||||
get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), knownControllerId1))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
return null;
|
||||
});
|
||||
@@ -350,7 +366,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
|
||||
// test
|
||||
final String knownControllerId1 = "0815";
|
||||
mvc.perform(get("/{tenant}/controller/v1/{controllerId}", tenantAware.getCurrentTenant(), knownControllerId1))
|
||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), knownControllerId1))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
|
||||
// verify
|
||||
@@ -399,7 +415,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
final Map<String, String> attributes = Collections.singletonMap("AttributeKey", "AttributeValue");
|
||||
assertThatAttributesUpdateIsRequested(savedTarget.getControllerId());
|
||||
|
||||
mvc.perform(put("/{tenant}/controller/v1/{controllerId}/configData", tenantAware.getCurrentTenant(),
|
||||
mvc.perform(put(CONTROLLER_BASE + "/configData", tenantAware.getCurrentTenant(),
|
||||
savedTarget.getControllerId()).content(JsonBuilder.configData(attributes).toString())
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk());
|
||||
@@ -431,13 +447,13 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
}
|
||||
|
||||
private void assertThatAttributesUpdateIsRequested(final String targetControllerId) throws Exception {
|
||||
mvc.perform(get("/{tenant}/controller/v1/{controllerId}", tenantAware.getCurrentTenant(), targetControllerId)
|
||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), targetControllerId)
|
||||
.accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._links.configData.href").isNotEmpty());
|
||||
}
|
||||
|
||||
private void assertThatAttributesUpdateIsNotRequested(final String targetControllerId) throws Exception {
|
||||
mvc.perform(get("/{tenant}/controller/v1/{controllerId}", tenantAware.getCurrentTenant(), targetControllerId)
|
||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), targetControllerId)
|
||||
.accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._links.configData").doesNotExist());
|
||||
}
|
||||
@@ -452,9 +468,9 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
}
|
||||
final String feedback = JsonBuilder.deploymentActionFeedback(action.getId().toString(), execution, finished,
|
||||
message);
|
||||
return mvc.perform(post("/{tenant}/controller/v1/{controllerId}/deploymentBase/{actionId}/feedback",
|
||||
tenantAware.getCurrentTenant(), target.getControllerId(), action.getId()).content(feedback)
|
||||
.contentType(MediaType.APPLICATION_JSON));
|
||||
return mvc.perform(
|
||||
post(DEPLOYMENT_FEEDBACK, tenantAware.getCurrentTenant(), target.getControllerId(), action.getId())
|
||||
.content(feedback).contentType(MediaType.APPLICATION_JSON));
|
||||
}
|
||||
|
||||
private ResultActions sendDeploymentActionFeedback(final Target target, final Action action, final String execution,
|
||||
@@ -487,14 +503,16 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
sendDeploymentActionFeedback(savedTarget, savedAction, "closed", "success", TARGET_COMPLETED_INSTALLATION_MSG)
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
|
||||
mvc.perform(get("/{tenant}/controller/v1/911/deploymentBase/" + savedAction.getId() + "?actionHistory=3",
|
||||
tenantAware.getCurrentTenant()).contentType(MediaType.APPLICATION_JSON)
|
||||
mvc.perform(get(DEPLOYMENT_BASE + "?actionHistory=2", tenantAware.getCurrentTenant(), 911, savedAction.getId())
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.actionHistory.messages",
|
||||
hasItem(containsString(TARGET_COMPLETED_INSTALLATION_MSG))))
|
||||
.andExpect(jsonPath("$.actionHistory.messages",
|
||||
hasItem(containsString(TARGET_PROCEEDING_INSTALLATION_MSG))))
|
||||
.andExpect(jsonPath("$.actionHistory.messages",
|
||||
hasItem(containsString(TARGET_SCHEDULED_INSTALLATION_MSG))));
|
||||
not(hasItem(containsString(TARGET_SCHEDULED_INSTALLATION_MSG)))));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -522,10 +540,16 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
sendDeploymentActionFeedback(savedTarget, savedAction, "closed", "success", TARGET_COMPLETED_INSTALLATION_MSG)
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
|
||||
mvc.perform(get("/{tenant}/controller/v1/911/deploymentBase/" + savedAction.getId() + "?actionHistory=-2",
|
||||
tenantAware.getCurrentTenant()).contentType(MediaType.APPLICATION_JSON)
|
||||
mvc.perform(get(DEPLOYMENT_BASE + "?actionHistory=0", tenantAware.getCurrentTenant(), 911, savedAction.getId())
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.actionHistory.messages").doesNotExist());
|
||||
|
||||
mvc.perform(get(DEPLOYMENT_BASE + "?actionHistory", tenantAware.getCurrentTenant(), 911, savedAction.getId())
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.actionHistory.messages").doesNotExist());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -553,8 +577,8 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
sendDeploymentActionFeedback(savedTarget, savedAction, "closed", "success", TARGET_COMPLETED_INSTALLATION_MSG)
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
|
||||
mvc.perform(get("/{tenant}/controller/v1/911/deploymentBase/" + savedAction.getId() + "?actionHistory=-1",
|
||||
tenantAware.getCurrentTenant()).contentType(MediaType.APPLICATION_JSON)
|
||||
mvc.perform(get(DEPLOYMENT_BASE + "?actionHistory=-1", tenantAware.getCurrentTenant(), 911, savedAction.getId())
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.actionHistory.messages",
|
||||
@@ -582,7 +606,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
assignDistributionSetWithMaintenanceWindow(ds.getId(), savedTarget.getControllerId(), getTestSchedule(16),
|
||||
getTestDuration(10), getTestTimeZone()).getAssignedEntity().iterator().next();
|
||||
|
||||
mvc.perform(get("/default-tenant/controller/v1/1911/")).andExpect(status().isOk())
|
||||
mvc.perform(get(CONTROLLER_BASE, "default-tenant", "1911")).andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.config.polling.sleep", greaterThanOrEqualTo("00:05:00")));
|
||||
|
||||
final Target savedTarget1 = testdataFactory.createTarget("2911");
|
||||
@@ -590,7 +614,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
assignDistributionSetWithMaintenanceWindow(ds1.getId(), savedTarget1.getControllerId(), getTestSchedule(10),
|
||||
getTestDuration(10), getTestTimeZone()).getAssignedEntity().iterator().next();
|
||||
|
||||
mvc.perform(get("/default-tenant/controller/v1/2911/")).andExpect(status().isOk())
|
||||
mvc.perform(get(CONTROLLER_BASE, "default-tenant", "2911")).andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.config.polling.sleep", lessThan("00:05:00")))
|
||||
.andExpect(jsonPath("$.config.polling.sleep", greaterThanOrEqualTo("00:03:00")));
|
||||
|
||||
@@ -599,7 +623,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
assignDistributionSetWithMaintenanceWindow(ds2.getId(), savedTarget2.getControllerId(), getTestSchedule(5),
|
||||
getTestDuration(5), getTestTimeZone()).getAssignedEntity().iterator().next();
|
||||
|
||||
mvc.perform(get("/default-tenant/controller/v1/3911/")).andExpect(status().isOk())
|
||||
mvc.perform(get(CONTROLLER_BASE, "default-tenant", "3911")).andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.config.polling.sleep", lessThan("00:02:00")));
|
||||
|
||||
final Target savedTarget3 = testdataFactory.createTarget("4911");
|
||||
@@ -607,7 +631,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
assignDistributionSetWithMaintenanceWindow(ds3.getId(), savedTarget3.getControllerId(), getTestSchedule(-5),
|
||||
getTestDuration(15), getTestTimeZone()).getAssignedEntity().iterator().next();
|
||||
|
||||
mvc.perform(get("/default-tenant/controller/v1/4911/")).andExpect(status().isOk())
|
||||
mvc.perform(get(CONTROLLER_BASE, "default-tenant", "4911")).andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:05:00")));
|
||||
|
||||
}
|
||||
@@ -620,12 +644,12 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
savedTarget = getFirstAssignedTarget(assignDistributionSetWithMaintenanceWindow(ds.getId(),
|
||||
savedTarget.getControllerId(), getTestSchedule(2), getTestDuration(1), getTestTimeZone()));
|
||||
|
||||
mvc.perform(get("/default-tenant/controller/v1/1911/")).andExpect(status().isOk());
|
||||
mvc.perform(get(CONTROLLER_BASE, "default-tenant", "1911")).andExpect(status().isOk());
|
||||
|
||||
final Action action = deploymentManagement.findActiveActionsByTarget(PAGE, savedTarget.getControllerId())
|
||||
.getContent().get(0);
|
||||
|
||||
mvc.perform(get("/{tenant}/controller/v1/1911/deploymentBase/{actionId}", tenantAware.getCurrentTenant(),
|
||||
mvc.perform(get(DEPLOYMENT_BASE, tenantAware.getCurrentTenant(), "1911",
|
||||
action.getId()).accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk()).andExpect(jsonPath("$.deployment.download", equalTo("forced")))
|
||||
.andExpect(jsonPath("$.deployment.update", equalTo("skip")))
|
||||
@@ -640,12 +664,12 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
savedTarget = getFirstAssignedTarget(assignDistributionSetWithMaintenanceWindow(ds.getId(),
|
||||
savedTarget.getControllerId(), getTestSchedule(-5), getTestDuration(10), getTestTimeZone()));
|
||||
|
||||
mvc.perform(get("/default-tenant/controller/v1/1911/")).andExpect(status().isOk());
|
||||
mvc.perform(get(CONTROLLER_BASE, "default-tenant", "1911")).andExpect(status().isOk());
|
||||
|
||||
final Action action = deploymentManagement.findActiveActionsByTarget(PAGE, savedTarget.getControllerId())
|
||||
.getContent().get(0);
|
||||
|
||||
mvc.perform(get("/{tenant}/controller/v1/1911/deploymentBase/{actionId}", tenantAware.getCurrentTenant(),
|
||||
mvc.perform(get(DEPLOYMENT_BASE, tenantAware.getCurrentTenant(), "1911",
|
||||
action.getId()).accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk()).andExpect(jsonPath("$.deployment.download", equalTo("forced")))
|
||||
.andExpect(jsonPath("$.deployment.update", equalTo("forced")))
|
||||
@@ -673,15 +697,15 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
@Description("The system should not create a new target because of a too long controller id.")
|
||||
public void rootRsWithInvalidControllerId() throws Exception {
|
||||
final String invalidControllerId = RandomStringUtils.randomAlphabetic(Target.CONTROLLER_ID_MAX_SIZE + 1);
|
||||
mvc.perform(get("/{tenant}/controller/v1/{controllerId}", tenantAware.getCurrentTenant(), invalidControllerId))
|
||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), invalidControllerId))
|
||||
.andExpect(status().isBadRequest());
|
||||
}
|
||||
|
||||
public void assertDeploymentActionIsExposedToTarget(final String controllerId, final long expectedActionId)
|
||||
private void assertDeploymentActionIsExposedToTarget(final String controllerId, final long expectedActionId)
|
||||
throws Exception {
|
||||
final String expectedDeploymentBaseLink = String.format("/%s/controller/v1/%s/deploymentBase/%d",
|
||||
tenantAware.getCurrentTenant(), controllerId, expectedActionId);
|
||||
mvc.perform(get("/{tenant}/controller/v1/{controllerId}", tenantAware.getCurrentTenant(), controllerId)
|
||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId)
|
||||
.accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._links.deploymentBase.href", containsString(expectedDeploymentBaseLink)));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user