Move DDI resources and annotation to module hawkbit-ddi-resource
- created module and moved resources Signed-off-by: Jonathan Philip Knoblauch <JonathanPhilip.Knoblauch@bosch-si.com>
This commit is contained in:
@@ -0,0 +1,573 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations 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.resource;
|
||||
|
||||
import static org.fest.assertions.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
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.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.RandomUtils;
|
||||
import org.eclipse.hawkbit.AbstractIntegrationTestWithMongoDB;
|
||||
import org.eclipse.hawkbit.TestDataUtil;
|
||||
import org.eclipse.hawkbit.WithUser;
|
||||
import org.eclipse.hawkbit.eventbus.event.DownloadProgressEvent;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.Action.Status;
|
||||
import org.eclipse.hawkbit.repository.model.Artifact;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.LocalArtifact;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import com.google.common.net.HttpHeaders;
|
||||
|
||||
import ru.yandex.qatools.allure.annotations.Description;
|
||||
import ru.yandex.qatools.allure.annotations.Features;
|
||||
import ru.yandex.qatools.allure.annotations.Stories;
|
||||
|
||||
/**
|
||||
* Test artifact downloads from the controller.
|
||||
*
|
||||
*/
|
||||
|
||||
@ActiveProfiles({ "im", "test" })
|
||||
@Features("Component Tests - Direct Device Integration API")
|
||||
@Stories("Artifact Download Resource")
|
||||
public class ArtifactDownloadTest extends AbstractIntegrationTestWithMongoDB {
|
||||
|
||||
public ArtifactDownloadTest() {
|
||||
LOG = LoggerFactory.getLogger(ArtifactDownloadTest.class);
|
||||
}
|
||||
|
||||
private volatile int downLoadProgress = 0;
|
||||
|
||||
@Autowired
|
||||
private EventBus eventBus;
|
||||
|
||||
@Test
|
||||
@Description("Tests non allowed requests on the artifact ressource, e.g. invalid URI, wrong if-match, wrong command.")
|
||||
public void invalidRequestsOnArtifactResource() throws Exception {
|
||||
// create target
|
||||
Target target = new Target("4712");
|
||||
target = targetManagement.createTarget(target);
|
||||
final List<Target> targets = new ArrayList<>();
|
||||
targets.add(target);
|
||||
|
||||
// create ds
|
||||
final DistributionSet ds = TestDataUtil.generateDistributionSet("", softwareManagement,
|
||||
distributionSetManagement);
|
||||
deploymentManagement.assignDistributionSet(ds, targets);
|
||||
|
||||
// create artifact
|
||||
final byte random[] = RandomUtils.nextBytes(5 * 1024);
|
||||
final LocalArtifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
|
||||
ds.findFirstModuleByType(osType).getId(), "file1", false);
|
||||
|
||||
// no artifact available
|
||||
mvc.perform(get("/controller/v1/{targetid}/softwaremodules/{softwareModuleId}/artifacts/123455",
|
||||
target.getControllerId(), ds.findFirstModuleByType(osType).getId())).andExpect(status().isNotFound());
|
||||
mvc.perform(get("/controller/v1/{targetid}/softwaremodules/{softwareModuleId}/artifacts/123455.MD5SUM",
|
||||
target.getControllerId(), ds.findFirstModuleByType(osType).getId())).andExpect(status().isNotFound());
|
||||
|
||||
// SM does not exist
|
||||
mvc.perform(get("/controller/v1/{targetid}/softwaremodules/1234567890/artifacts/{filename}",
|
||||
target.getControllerId(), artifact.getFilename())).andExpect(status().isNotFound());
|
||||
mvc.perform(get("/controller/v1/{targetid}/softwaremodules/1234567890/artifacts/{filename}.MD5SUM",
|
||||
target.getControllerId(), artifact.getFilename())).andExpect(status().isNotFound());
|
||||
|
||||
// test now consistent data to test allowed methods
|
||||
mvc.perform(get("/{tenant}/controller/v1/{targetid}/softwaremodules/{smId}/artifacts/{filename}",
|
||||
tenantAware.getCurrentTenant(), target.getControllerId(), ds.findFirstModuleByType(osType).getId(),
|
||||
artifact.getFilename()).header(HttpHeaders.IF_MATCH, artifact.getSha1Hash()))
|
||||
.andExpect(status().isOk());
|
||||
mvc.perform(get("/{tenant}/controller/v1/{targetid}/softwaremodules/{smId}/artifacts/{filename}.MD5SUM",
|
||||
tenantAware.getCurrentTenant(), target.getControllerId(), ds.findFirstModuleByType(osType).getId(),
|
||||
artifact.getFilename())).andExpect(status().isOk());
|
||||
|
||||
// test failed If-match
|
||||
mvc.perform(get("/{tenant}/controller/v1/{targetid}/softwaremodules/{smId}/artifacts/{filename}",
|
||||
tenantAware.getCurrentTenant(), target.getControllerId(), ds.findFirstModuleByType(osType).getId(),
|
||||
artifact.getFilename()).header("If-Match", "fsjkhgjfdhg")).andExpect(status().isPreconditionFailed());
|
||||
|
||||
// test invalid range
|
||||
mvc.perform(get("/{tenant}/controller/v1/{targetid}/softwaremodules/{smId}/artifacts/{filename}",
|
||||
tenantAware.getCurrentTenant(), target.getControllerId(), ds.findFirstModuleByType(osType).getId(),
|
||||
artifact.getFilename()).header("Range", "bytes=1-10,hdsfjksdh"))
|
||||
.andExpect(header().string("Content-Range", "bytes */" + 5 * 1024))
|
||||
.andExpect(status().isRequestedRangeNotSatisfiable());
|
||||
|
||||
mvc.perform(get("/{tenant}/controller/v1/{targetid}/softwaremodules/{smId}/artifacts/{filename}",
|
||||
tenantAware.getCurrentTenant(), target.getControllerId(), ds.findFirstModuleByType(osType).getId(),
|
||||
artifact.getFilename()).header("Range", "bytes=100-10"))
|
||||
.andExpect(header().string("Content-Range", "bytes */" + 5 * 1024))
|
||||
.andExpect(status().isRequestedRangeNotSatisfiable());
|
||||
|
||||
// not allowed methods
|
||||
mvc.perform(put("/{tenant}/controller/v1/{targetid}/softwaremodules/{smId}/artifacts/{filename}",
|
||||
tenantAware.getCurrentTenant(), target.getControllerId(), ds.findFirstModuleByType(osType).getId(),
|
||||
artifact.getFilename())).andExpect(status().isMethodNotAllowed());
|
||||
|
||||
mvc.perform(delete("/{tenant}/controller/v1/{targetid}/softwaremodules/{smId}/artifacts/{filename}",
|
||||
tenantAware.getCurrentTenant(), target.getControllerId(), ds.findFirstModuleByType(osType).getId(),
|
||||
artifact.getFilename())).andExpect(status().isMethodNotAllowed());
|
||||
|
||||
mvc.perform(post("/{tenant}/controller/v1/{targetid}/softwaremodules/{smId}/artifacts/{filename}",
|
||||
tenantAware.getCurrentTenant(), target.getControllerId(), ds.findFirstModuleByType(osType).getId(),
|
||||
artifact.getFilename())).andExpect(status().isMethodNotAllowed());
|
||||
|
||||
mvc.perform(put("/{tenant}/controller/v1/{targetid}/softwaremodules/{smId}/artifacts/{filename}.MD5SUM",
|
||||
tenantAware.getCurrentTenant(), target.getControllerId(), ds.findFirstModuleByType(osType).getId(),
|
||||
artifact.getFilename())).andExpect(status().isMethodNotAllowed());
|
||||
|
||||
mvc.perform(delete("/{tenant}/controller/v1/{targetid}/softwaremodules/{smId}/artifacts/{filename}.MD5SUM",
|
||||
tenantAware.getCurrentTenant(), target.getControllerId(), ds.findFirstModuleByType(osType).getId(),
|
||||
artifact.getFilename())).andExpect(status().isMethodNotAllowed());
|
||||
|
||||
mvc.perform(post("/{tenant}/controller/v1/{targetid}/softwaremodules/{smId}/artifacts/{filename}.MD5SUM",
|
||||
tenantAware.getCurrentTenant(), target.getControllerId(), ds.findFirstModuleByType(osType).getId(),
|
||||
artifact.getFilename())).andExpect(status().isMethodNotAllowed());
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithUser(principal = "4712", authorities = "ROLE_CONTROLLER", allSpPermissions = true)
|
||||
@Description("Tests non allowed requests on the artifact ressource, e.g. invalid URI, wrong if-match, wrong command.")
|
||||
public void invalidRequestsOnArtifactResourceByName() throws Exception {
|
||||
// create target
|
||||
Target target = new Target("4712");
|
||||
target = targetManagement.createTarget(target);
|
||||
final List<Target> targets = new ArrayList<>();
|
||||
targets.add(target);
|
||||
|
||||
// create ds
|
||||
final DistributionSet ds = TestDataUtil.generateDistributionSet("", softwareManagement,
|
||||
distributionSetManagement);
|
||||
deploymentManagement.assignDistributionSet(ds, targets);
|
||||
|
||||
// create artifact
|
||||
final byte random[] = RandomUtils.nextBytes(5 * 1024);
|
||||
|
||||
// Binary
|
||||
// no artifact available
|
||||
mvc.perform(get("/controller/artifacts/v1/filename/{filename}", "file1")).andExpect(status().isNotFound());
|
||||
|
||||
// no artifact available
|
||||
mvc.perform(get("/controller/artifacts/v1/filename/{filename}.MD5SUM", "file1"))
|
||||
.andExpect(status().isNotFound());
|
||||
|
||||
// test now consistent data to test allowed methods
|
||||
final Artifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
|
||||
ds.findFirstModuleByType(osType).getId(), "file1", false);
|
||||
|
||||
mvc.perform(
|
||||
get("/{tenant}/controller/artifacts/v1/filename/{filename}", tenantAware.getCurrentTenant(), "file1")
|
||||
.header(HttpHeaders.IF_MATCH, artifact.getSha1Hash()))
|
||||
.andExpect(status().isOk());
|
||||
|
||||
mvc.perform(get("/{tenant}/controller/artifacts/v1/filename/{filename}.MD5SUM", tenantAware.getCurrentTenant(),
|
||||
"file1")).andExpect(status().isOk());
|
||||
|
||||
// test failed If-match
|
||||
mvc.perform(
|
||||
get("/{tenant}/controller/artifacts/v1/filename/{filename}", tenantAware.getCurrentTenant(), "file1")
|
||||
.header("If-Match", "fsjkhgjfdhg"))
|
||||
.andExpect(status().isPreconditionFailed());
|
||||
|
||||
// test invalid range
|
||||
mvc.perform(
|
||||
get("/{tenant}/controller/artifacts/v1/filename/{filename}", tenantAware.getCurrentTenant(), "file1")
|
||||
.header("Range", "bytes=1-10,hdsfjksdh"))
|
||||
.andExpect(header().string("Content-Range", "bytes */" + 5 * 1024))
|
||||
.andExpect(status().isRequestedRangeNotSatisfiable());
|
||||
|
||||
mvc.perform(
|
||||
get("/{tenant}/controller/artifacts/v1/filename/{filename}", tenantAware.getCurrentTenant(), "file1")
|
||||
.header("Range", "bytes=100-10"))
|
||||
.andExpect(header().string("Content-Range", "bytes */" + 5 * 1024))
|
||||
.andExpect(status().isRequestedRangeNotSatisfiable());
|
||||
|
||||
// not allowed methods
|
||||
mvc.perform(
|
||||
put("/{tenant}/controller/artifacts/v1/filename/{filename}", tenantAware.getCurrentTenant(), "file1"))
|
||||
.andExpect(status().isMethodNotAllowed());
|
||||
|
||||
mvc.perform(delete("/{tenant}/controller/artifacts/v1/filename/{filename}", tenantAware.getCurrentTenant(),
|
||||
"file1")).andExpect(status().isMethodNotAllowed());
|
||||
|
||||
mvc.perform(
|
||||
post("/{tenant}/controller/artifacts/v1/filename/{filename}", tenantAware.getCurrentTenant(), "file1"))
|
||||
.andExpect(status().isMethodNotAllowed());
|
||||
|
||||
// not allowed methods
|
||||
mvc.perform(put("/{tenant}/controller/artifacts/v1/filename/{filename}.MD5SUM", tenantAware.getCurrentTenant(),
|
||||
"file1")).andExpect(status().isMethodNotAllowed());
|
||||
|
||||
mvc.perform(delete("/{tenant}/controller/artifacts/v1/filename/{filename}.MD5SUM",
|
||||
tenantAware.getCurrentTenant(), "file1")).andExpect(status().isMethodNotAllowed());
|
||||
|
||||
mvc.perform(post("/{tenant}/controller/artifacts/v1/filename/{filename}.MD5SUM", tenantAware.getCurrentTenant(),
|
||||
"file1")).andExpect(status().isMethodNotAllowed());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithUser(principal = "4712", authorities = "ROLE_CONTROLLER", allSpPermissions = true)
|
||||
@Description("Tests valid downloads through the artifact resource by identifying the artifact not by ID but file name.")
|
||||
public void downloadArtifactThroughFileName() throws Exception {
|
||||
downLoadProgress = 1;
|
||||
eventBus.register(this);
|
||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0);
|
||||
assertThat(artifactRepository.findAll()).hasSize(0);
|
||||
|
||||
// create target
|
||||
Target target = new Target("4712");
|
||||
target = targetManagement.createTarget(target);
|
||||
final List<Target> targets = new ArrayList<Target>();
|
||||
targets.add(target);
|
||||
|
||||
// create ds
|
||||
final DistributionSet ds = TestDataUtil.generateDistributionSet("", softwareManagement,
|
||||
distributionSetManagement);
|
||||
|
||||
// create artifact
|
||||
final byte random[] = RandomUtils.nextBytes(5 * 1024 * 1024);
|
||||
final LocalArtifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
|
||||
ds.findFirstModuleByType(osType).getId(), "file1", false);
|
||||
|
||||
// download fails as artifact is not yet assigned
|
||||
mvc.perform(get("/controller/v1/{targetid}/softwaremodules/{softwareModuleId}/artifacts/{filename}",
|
||||
target.getControllerId(), ds.findFirstModuleByType(osType).getId(), artifact.getFilename()))
|
||||
.andExpect(status().isNotFound());
|
||||
|
||||
// now assign and download successful
|
||||
deploymentManagement.assignDistributionSet(ds, targets);
|
||||
final MvcResult result = mvc
|
||||
.perform(
|
||||
get("/{tenant}/controller/v1/{targetid}/softwaremodules/{softwareModuleId}/artifacts/{filename}",
|
||||
tenantAware.getCurrentTenant(), target.getControllerId(),
|
||||
ds.findFirstModuleByType(osType).getId(), artifact.getFilename()))
|
||||
.andExpect(status().isOk()).andExpect(content().contentType(MediaType.APPLICATION_OCTET_STREAM))
|
||||
.andExpect(header().string("Accept-Ranges", "bytes"))
|
||||
.andExpect(header().longValue("Last-Modified", artifact.getCreatedAt()))
|
||||
.andExpect(header().string("Content-Disposition", "attachment;filename=" + artifact.getFilename()))
|
||||
.andReturn();
|
||||
|
||||
assertTrue("The same file that was uploaded is expected when downloaded",
|
||||
Arrays.equals(result.getResponse().getContentAsByteArray(), random));
|
||||
|
||||
// download complete
|
||||
assertThat(downLoadProgress).isEqualTo(10);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Tests valid MD5SUm file downloads through the artifact resource by identifying the artifact by ID.")
|
||||
public void downloadMd5sumThroughControllerApi() throws Exception {
|
||||
// create target
|
||||
Target target = new Target("4712");
|
||||
target = targetManagement.createTarget(target);
|
||||
|
||||
// create ds
|
||||
final DistributionSet ds = TestDataUtil.generateDistributionSet("", softwareManagement,
|
||||
distributionSetManagement);
|
||||
|
||||
// create artifact
|
||||
final byte random[] = RandomUtils.nextBytes(5 * 1024);
|
||||
final LocalArtifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
|
||||
ds.findFirstModuleByType(osType).getId(), "file1", false);
|
||||
|
||||
// download
|
||||
final MvcResult result = mvc
|
||||
.perform(
|
||||
get("/{tenant}/controller/v1/{targetid}/softwaremodules/{softwareModuleId}/artifacts/{filename}.MD5SUM",
|
||||
tenantAware.getCurrentTenant(), target.getControllerId(),
|
||||
ds.findFirstModuleByType(osType).getId(), artifact.getFilename()))
|
||||
.andExpect(status().isOk()).andExpect(header().string("Content-Disposition",
|
||||
"attachment;filename=" + artifact.getFilename() + ".MD5SUM"))
|
||||
.andReturn();
|
||||
|
||||
assertThat(result.getResponse().getContentAsByteArray()).isEqualTo(
|
||||
new String(artifact.getMd5Hash() + " " + artifact.getFilename()).getBytes(Charsets.US_ASCII));
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithUser(authorities = "ROLE_CONTROLLER_ANONYMOUS", allSpPermissions = true)
|
||||
@Description("Ensures that even an authenticated controller is not permitted to download if "
|
||||
+ "anonymous as authorization is notpossible, e.g. chekc if the controller has the artifact assigned.")
|
||||
public void downloadArtifactByNameFailsIfNotAuthenticated() throws Exception {
|
||||
downLoadProgress = 1;
|
||||
eventBus.register(this);
|
||||
|
||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0);
|
||||
assertThat(artifactRepository.findAll()).hasSize(0);
|
||||
|
||||
// create target
|
||||
Target target = new Target("4712");
|
||||
target = targetManagement.createTarget(target);
|
||||
final List<Target> targets = new ArrayList();
|
||||
targets.add(target);
|
||||
|
||||
// create ds
|
||||
final DistributionSet ds = TestDataUtil.generateDistributionSet("", softwareManagement,
|
||||
distributionSetManagement);
|
||||
|
||||
// create artifact
|
||||
final byte random[] = RandomUtils.nextBytes(5 * 1024);
|
||||
final Artifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
|
||||
ds.findFirstModuleByType(osType).getId(), "file1.tar.bz2", false);
|
||||
|
||||
// download fails as artifact is not yet assigned to target
|
||||
deploymentManagement.assignDistributionSet(ds, targets);
|
||||
mvc.perform(get("/controller/artifacts/v1/filename/{filename}", "file1.tar.bz2"))
|
||||
.andExpect(status().isNotFound());
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithUser(principal = "4712", authorities = "ROLE_CONTROLLER", allSpPermissions = true)
|
||||
@Description("Ensures that an authenticated and named controller is permitted to download.")
|
||||
public void downloadArtifactByNameByNamedController() throws Exception {
|
||||
downLoadProgress = 1;
|
||||
eventBus.register(this);
|
||||
|
||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0);
|
||||
assertThat(artifactRepository.findAll()).hasSize(0);
|
||||
|
||||
// create target
|
||||
Target target = new Target("4712");
|
||||
target = targetManagement.createTarget(target);
|
||||
final List<Target> targets = new ArrayList<>();
|
||||
targets.add(target);
|
||||
|
||||
// create ds
|
||||
final DistributionSet ds = TestDataUtil.generateDistributionSet("", softwareManagement,
|
||||
distributionSetManagement);
|
||||
|
||||
// create artifact
|
||||
final byte random[] = RandomUtils.nextBytes(5 * 1024 * 1024);
|
||||
final Artifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
|
||||
ds.findFirstModuleByType(osType).getId(), "file1", false);
|
||||
|
||||
// download fails as artifact is not yet assigned to target
|
||||
mvc.perform(get("/{tenant}/controller/artifacts/v1/filename/{filename}", tenantAware.getCurrentTenant(),
|
||||
"file1.tar.bz2")).andExpect(status().isNotFound());
|
||||
|
||||
// now assign and download successful
|
||||
deploymentManagement.assignDistributionSet(ds, targets);
|
||||
final MvcResult result = mvc
|
||||
.perform(get("/{tenant}/controller/artifacts/v1/filename/{filename}", tenantAware.getCurrentTenant(),
|
||||
"file1"))
|
||||
.andExpect(status().isOk()).andExpect(header().string("ETag", artifact.getSha1Hash()))
|
||||
.andExpect(content().contentType(MediaType.APPLICATION_OCTET_STREAM))
|
||||
.andExpect(header().string("Accept-Ranges", "bytes"))
|
||||
.andExpect(header().longValue("Last-Modified", artifact.getCreatedAt()))
|
||||
.andExpect(header().string("Content-Disposition", "attachment;filename=file1")).andReturn();
|
||||
|
||||
assertTrue("The same file that was uploaded is expected when downloaded",
|
||||
Arrays.equals(result.getResponse().getContentAsByteArray(), random));
|
||||
|
||||
// one (update) action
|
||||
assertThat(actionRepository.findByTargetAndDistributionSet(pageReq, target, ds).getContent()).hasSize(1);
|
||||
final Action action = actionRepository.findByTargetAndDistributionSet(pageReq, target, ds).getContent().get(0);
|
||||
|
||||
// one status - download
|
||||
assertThat(actionStatusRepository.findAll()).hasSize(2);
|
||||
assertThat(actionStatusRepository.findByAction(pageReq, action).getContent()).hasSize(2);
|
||||
assertThat(actionStatusRepository.findByAction(new PageRequest(0, 400, Direction.DESC, "id"), action)
|
||||
.getContent().get(0).getStatus()).isEqualTo(Status.DOWNLOAD);
|
||||
|
||||
// download complete
|
||||
assertThat(downLoadProgress).isEqualTo(10);
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithUser(principal = "4712", authorities = "ROLE_CONTROLLER", allSpPermissions = true)
|
||||
@Description("Test various HTTP range requests for artifact download, e.g. chunk download or download resume.")
|
||||
public void rangeDownloadArtifactByName() throws Exception {
|
||||
// create target
|
||||
Target target = new Target("4712");
|
||||
target = targetManagement.createTarget(target);
|
||||
final List<Target> targets = new ArrayList<>();
|
||||
targets.add(target);
|
||||
|
||||
// create ds
|
||||
final DistributionSet ds = TestDataUtil.generateDistributionSet("", softwareManagement,
|
||||
distributionSetManagement);
|
||||
|
||||
final int resultLength = 5 * 1000 * 1024;
|
||||
|
||||
// create artifact
|
||||
final byte random[] = RandomUtils.nextBytes(resultLength);
|
||||
final Artifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
|
||||
ds.findFirstModuleByType(osType).getId(), "file1", false);
|
||||
|
||||
assertThat(random.length).isEqualTo(resultLength);
|
||||
|
||||
// now assign and download successful
|
||||
deploymentManagement.assignDistributionSet(ds, targets);
|
||||
|
||||
final int range = 100 * 1024;
|
||||
|
||||
// full file download with standard range request
|
||||
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
for (int i = 0; i < resultLength / range; i++) {
|
||||
final String rangeString = "" + i * range + "-" + ((i + 1) * range - 1);
|
||||
|
||||
final MvcResult result = mvc
|
||||
.perform(get("/{tenant}/controller/artifacts/v1/filename/{filename}",
|
||||
tenantAware.getCurrentTenant(), "file1").header("Range", "bytes=" + rangeString))
|
||||
.andExpect(status().isPartialContent()).andExpect(header().string("ETag", artifact.getSha1Hash()))
|
||||
.andExpect(content().contentType(MediaType.APPLICATION_OCTET_STREAM))
|
||||
.andExpect(header().string("Accept-Ranges", "bytes"))
|
||||
.andExpect(header().longValue("Last-Modified", artifact.getCreatedAt()))
|
||||
.andExpect(header().longValue("Content-Length", range))
|
||||
.andExpect(header().string("Content-Range", "bytes " + rangeString + "/" + resultLength))
|
||||
.andExpect(header().string("Content-Disposition", "attachment;filename=file1")).andReturn();
|
||||
|
||||
outputStream.write(result.getResponse().getContentAsByteArray());
|
||||
}
|
||||
|
||||
assertThat(outputStream.toByteArray()).isEqualTo(random);
|
||||
|
||||
// return last 1000 Bytes
|
||||
MvcResult result = mvc
|
||||
.perform(get("/${tenant}/controller/artifacts/v1/filename/{filename}", tenantAware.getCurrentTenant(),
|
||||
"file1").header("Range", "bytes=-1000"))
|
||||
.andExpect(status().isPartialContent()).andExpect(header().string("ETag", artifact.getSha1Hash()))
|
||||
.andExpect(content().contentType(MediaType.APPLICATION_OCTET_STREAM))
|
||||
.andExpect(header().string("Accept-Ranges", "bytes"))
|
||||
.andExpect(header().longValue("Last-Modified", artifact.getCreatedAt()))
|
||||
.andExpect(header().longValue("Content-Length", 1000))
|
||||
.andExpect(header().string("Content-Range",
|
||||
"bytes " + (resultLength - 1000) + "-" + (resultLength - 1) + "/" + resultLength))
|
||||
.andExpect(header().string("Content-Disposition", "attachment;filename=file1")).andReturn();
|
||||
|
||||
assertThat(result.getResponse().getContentAsByteArray())
|
||||
.isEqualTo(Arrays.copyOfRange(random, resultLength - 1000, resultLength));
|
||||
|
||||
// skip first 1000 Bytes and return the rest
|
||||
result = mvc
|
||||
.perform(get("/{tenant}/controller/artifacts/v1/filename/{filename}", tenantAware.getCurrentTenant(),
|
||||
"file1").header("Range", "bytes=1000-"))
|
||||
.andExpect(status().isPartialContent()).andExpect(header().string("ETag", artifact.getSha1Hash()))
|
||||
.andExpect(content().contentType(MediaType.APPLICATION_OCTET_STREAM))
|
||||
.andExpect(header().string("Accept-Ranges", "bytes"))
|
||||
.andExpect(header().longValue("Last-Modified", artifact.getCreatedAt()))
|
||||
.andExpect(header().longValue("Content-Length", resultLength - 1000))
|
||||
.andExpect(header().string("Content-Range",
|
||||
"bytes " + 1000 + "-" + (resultLength - 1) + "/" + resultLength))
|
||||
.andExpect(header().string("Content-Disposition", "attachment;filename=file1")).andReturn();
|
||||
|
||||
assertThat(result.getResponse().getContentAsByteArray())
|
||||
.isEqualTo(Arrays.copyOfRange(random, 1000, resultLength));
|
||||
|
||||
// multipart download - first 20 bytes in 2 parts
|
||||
result = mvc
|
||||
.perform(get("/{tenant}/controller/artifacts/v1/filename/{filename}", tenantAware.getCurrentTenant(),
|
||||
"file1").header("Range", "bytes=0-9,10-19"))
|
||||
.andExpect(status().isPartialContent()).andExpect(header().string("ETag", artifact.getSha1Hash()))
|
||||
.andExpect(content().contentType("multipart/byteranges; boundary=THIS_STRING_SEPARATES_MULTIPART"))
|
||||
.andExpect(header().string("Accept-Ranges", "bytes"))
|
||||
.andExpect(header().longValue("Last-Modified", artifact.getCreatedAt()))
|
||||
.andExpect(header().string("Content-Disposition", "attachment;filename=file1")).andReturn();
|
||||
|
||||
outputStream.reset();
|
||||
|
||||
outputStream.write("\r\n--THIS_STRING_SEPARATES_MULTIPART\r\n".getBytes(StandardCharsets.ISO_8859_1));
|
||||
outputStream.write(("Content-Range: bytes 0-9/" + resultLength + "\r\n").getBytes(StandardCharsets.ISO_8859_1));
|
||||
outputStream.write(Arrays.copyOfRange(random, 0, 10));
|
||||
outputStream.write("\r\n--THIS_STRING_SEPARATES_MULTIPART\r\n".getBytes(StandardCharsets.ISO_8859_1));
|
||||
outputStream
|
||||
.write(("Content-Range: bytes 10-19/" + resultLength + "\r\n").getBytes(StandardCharsets.ISO_8859_1));
|
||||
outputStream.write(Arrays.copyOfRange(random, 10, 20));
|
||||
outputStream.write("\r\n--THIS_STRING_SEPARATES_MULTIPART--".getBytes(StandardCharsets.ISO_8859_1));
|
||||
|
||||
assertThat(result.getResponse().getContentAsByteArray()).isEqualTo(outputStream.toByteArray());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Ensures that the download fails if te controller is not authenticated.")
|
||||
public void faildDownloadArtifactByNameIfAuthenticationMissing() throws Exception {
|
||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0);
|
||||
assertThat(artifactRepository.findAll()).hasSize(0);
|
||||
|
||||
// create target
|
||||
Target target = new Target("4712");
|
||||
target = targetManagement.createTarget(target);
|
||||
final List<Target> targets = new ArrayList<>();
|
||||
targets.add(target);
|
||||
|
||||
// create ds
|
||||
final DistributionSet ds = TestDataUtil.generateDistributionSet("", softwareManagement,
|
||||
distributionSetManagement);
|
||||
|
||||
// create artifact
|
||||
final byte random[] = RandomUtils.nextBytes(5 * 1024);
|
||||
final Artifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
|
||||
ds.findFirstModuleByType(osType).getId(), "file1.tar.bz2", false);
|
||||
|
||||
// download fails as artifact is not yet assigned to target
|
||||
mvc.perform(get("/controller/artifacts/v1/filename/{filename}", "file1.tar.bz2"))
|
||||
.andExpect(status().isNotFound());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Downloads an MD5SUM file by the related artifacts filename.")
|
||||
public void downloadMd5sumFileByName() throws Exception {
|
||||
// create target
|
||||
Target target = new Target("4712");
|
||||
target = targetManagement.createTarget(target);
|
||||
|
||||
// create ds
|
||||
final DistributionSet ds = TestDataUtil.generateDistributionSet("", softwareManagement,
|
||||
distributionSetManagement);
|
||||
|
||||
// create artifact
|
||||
final byte random[] = RandomUtils.nextBytes(5 * 1024);
|
||||
final Artifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
|
||||
ds.findFirstModuleByType(osType).getId(), "file1.tar.bz2", false);
|
||||
|
||||
// download
|
||||
final MvcResult result = mvc
|
||||
.perform(get("/{tenant}/controller/artifacts/v1/filename/file1.tar.bz2.MD5SUM",
|
||||
tenantAware.getCurrentTenant()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(header().string("Content-Disposition", "attachment;filename=file1.tar.bz2.MD5SUM"))
|
||||
.andReturn();
|
||||
|
||||
assertThat(result.getResponse().getContentAsByteArray())
|
||||
.isEqualTo(new String(artifact.getMd5Hash() + " file1.tar.bz2").getBytes(Charsets.US_ASCII));
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void listen(final DownloadProgressEvent event) {
|
||||
downLoadProgress++;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,552 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations 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.resource;
|
||||
|
||||
import static org.fest.assertions.api.Assertions.assertThat;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
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.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.hawkbit.AbstractIntegrationTest;
|
||||
import org.eclipse.hawkbit.MockMvcResultPrinter;
|
||||
import org.eclipse.hawkbit.TestDataUtil;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.Action.Status;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.rest.resource.JsonBuilder;
|
||||
import org.junit.Test;
|
||||
import org.springframework.hateoas.MediaTypes;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
|
||||
import ru.yandex.qatools.allure.annotations.Description;
|
||||
import ru.yandex.qatools.allure.annotations.Features;
|
||||
import ru.yandex.qatools.allure.annotations.Stories;
|
||||
|
||||
@ActiveProfiles({ "im", "test" })
|
||||
@Features("Component Tests - Direct Device Integration API")
|
||||
@Stories("Cancel Action Resource")
|
||||
public class CancelActionTest extends AbstractIntegrationTest {
|
||||
|
||||
@Test
|
||||
@Description("Test of the controller can continue a started update even after a cancel command if it so desires.")
|
||||
public void rootRsCancelActionButContinueAnyway() throws Exception {
|
||||
// prepare test data
|
||||
final Target target = new Target("4712");
|
||||
final DistributionSet ds = TestDataUtil.generateDistributionSet("", softwareManagement,
|
||||
distributionSetManagement);
|
||||
final Target savedTarget = targetManagement.createTarget(target);
|
||||
|
||||
final List<Target> toAssign = new ArrayList<Target>();
|
||||
toAssign.add(savedTarget);
|
||||
|
||||
final Action updateAction = deploymentManagement
|
||||
.findActionWithDetails(deploymentManagement.assignDistributionSet(ds, toAssign).getActions().get(0));
|
||||
|
||||
final Action cancelAction = deploymentManagement.cancelAction(updateAction,
|
||||
targetManagement.findTargetByControllerID(savedTarget.getControllerId()));
|
||||
|
||||
// controller rejects cancelation
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/cancelAction/" + cancelAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.cancelActionFeedback(cancelAction.getId().toString(), "rejected"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
|
||||
final long current = System.currentTimeMillis();
|
||||
|
||||
// get update action anyway
|
||||
mvc.perform(get("/{tenant}/controller/v1/4712/deploymentBase/" + updateAction.getId(),
|
||||
tenantAware.getCurrentTenant()).accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk()).andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(jsonPath("$id", equalTo(String.valueOf(updateAction.getId()))))
|
||||
.andExpect(jsonPath("$deployment.download", equalTo("forced")))
|
||||
.andExpect(jsonPath("$deployment.update", equalTo("forced")))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==jvm)][0].version",
|
||||
equalTo(ds.findFirstModuleByType(runtimeType).getVersion())))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].version",
|
||||
equalTo(ds.findFirstModuleByType(osType).getVersion())))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==bApp)][0].version",
|
||||
equalTo(ds.findFirstModuleByType(appType).getVersion())));
|
||||
|
||||
// and finish it
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/deploymentBase/" + updateAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant()).content(
|
||||
JsonBuilder.deploymentActionFeedback(updateAction.getId().toString(), "closed", "success"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
|
||||
// check database after test
|
||||
assertThat(targetManagement.findTargetByControllerID("4712").getAssignedDistributionSet().getId())
|
||||
.isEqualTo(ds.getId());
|
||||
assertThat(targetManagement.findTargetByControllerIDWithDetails("4712").getTargetInfo()
|
||||
.getInstalledDistributionSet().getId()).isEqualTo(ds.getId());
|
||||
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getInstallationDate())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Test for cancel operation of a update action.")
|
||||
public void rootRsCancelAction() throws Exception {
|
||||
final Target target = new Target("4712");
|
||||
final DistributionSet ds = TestDataUtil.generateDistributionSet("", softwareManagement,
|
||||
distributionSetManagement);
|
||||
final Target savedTarget = targetManagement.createTarget(target);
|
||||
|
||||
final List<Target> toAssign = new ArrayList<Target>();
|
||||
toAssign.add(savedTarget);
|
||||
|
||||
final Action updateAction = deploymentManagement
|
||||
.findActionWithDetails(deploymentManagement.assignDistributionSet(ds, toAssign).getActions().get(0));
|
||||
|
||||
long current = System.currentTimeMillis();
|
||||
mvc.perform(get("/{tenant}/controller/v1/4712", tenantAware.getCurrentTenant()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||
.andExpect(jsonPath("$config.polling.sleep", equalTo("00:01:00")))
|
||||
.andExpect(jsonPath("$_links.deploymentBase.href",
|
||||
startsWith("http://localhost/" + tenantAware.getCurrentTenant()
|
||||
+ "/controller/v1/4712/deploymentBase/" + updateAction.getId())));
|
||||
Thread.sleep(1); // is required: otherwise processing the next line is
|
||||
// often too fast and
|
||||
// the following assert will fail
|
||||
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getLastTargetQuery())
|
||||
.isLessThanOrEqualTo(System.currentTimeMillis());
|
||||
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
|
||||
// Retrieved is reported
|
||||
|
||||
List<Action> activeActionsByTarget = deploymentManagement.findActiveActionsByTarget(savedTarget);
|
||||
|
||||
assertThat(activeActionsByTarget).hasSize(1);
|
||||
assertThat(activeActionsByTarget.get(0).getStatus()).isEqualTo(Status.RUNNING);
|
||||
final Action cancelAction = deploymentManagement.cancelAction(updateAction,
|
||||
targetManagement.findTargetByControllerID(savedTarget.getControllerId()));
|
||||
|
||||
activeActionsByTarget = deploymentManagement.findActiveActionsByTarget(savedTarget);
|
||||
|
||||
// the canceled action should still be active!
|
||||
assertThat(cancelAction.isActive()).isTrue();
|
||||
assertThat(activeActionsByTarget).hasSize(1);
|
||||
assertThat(activeActionsByTarget.get(0).getStatus()).isEqualTo(Status.CANCELING);
|
||||
|
||||
current = System.currentTimeMillis();
|
||||
mvc.perform(get("/{tenant}/controller/v1/4712", tenantAware.getCurrentTenant()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||
.andExpect(jsonPath("$config.polling.sleep", equalTo("00:01:00")))
|
||||
.andExpect(jsonPath("$_links.cancelAction.href",
|
||||
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
||||
+ "/controller/v1/4712/cancelAction/" + cancelAction.getId())));
|
||||
Thread.sleep(1); // is required: otherwise processing the next line is
|
||||
// often too fast and
|
||||
// the following assert will fail
|
||||
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getLastTargetQuery())
|
||||
.isLessThanOrEqualTo(System.currentTimeMillis());
|
||||
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
|
||||
current = System.currentTimeMillis();
|
||||
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getLastTargetQuery())
|
||||
.isLessThanOrEqualTo(System.currentTimeMillis());
|
||||
mvc.perform(
|
||||
get("/{tenant}/controller/v1/4712/cancelAction/" + cancelAction.getId(), tenantAware.getCurrentTenant())
|
||||
.accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(jsonPath("$id", equalTo(String.valueOf(cancelAction.getId()))))
|
||||
.andExpect(jsonPath("$cancelAction.stopId", equalTo(String.valueOf(updateAction.getId()))));
|
||||
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getLastTargetQuery())
|
||||
.isLessThanOrEqualTo(System.currentTimeMillis());
|
||||
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
|
||||
// controller confirmed cancelled action, should not be active anymore
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/cancelAction/" + cancelAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant()).accept(MediaType.APPLICATION_JSON)
|
||||
.content(JsonBuilder.cancelActionFeedback(updateAction.getId().toString(), "closed"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
|
||||
activeActionsByTarget = deploymentManagement.findActiveActionsByTarget(savedTarget);
|
||||
assertThat(activeActionsByTarget).hasSize(0);
|
||||
final Action canceledAction = deploymentManagement.findAction(cancelAction.getId());
|
||||
assertThat(canceledAction.isActive()).isFalse();
|
||||
assertThat(canceledAction.getStatus()).isEqualTo(Status.CANCELED);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Tests various bad requests and if the server handles them as expected.")
|
||||
public void badCancelAction() throws Exception {
|
||||
|
||||
// not allowed methods
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/cancelAction/1", tenantAware.getCurrentTenant()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isMethodNotAllowed());
|
||||
|
||||
mvc.perform(put("/{tenant}/controller/v1/4712/cancelAction/1", tenantAware.getCurrentTenant()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isMethodNotAllowed());
|
||||
|
||||
mvc.perform(delete("/{tenant}/controller/v1/4712/cancelAction/1", tenantAware.getCurrentTenant()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isMethodNotAllowed());
|
||||
|
||||
// non existing target
|
||||
mvc.perform(get("/{tenant}/controller/v1/34534543/cancelAction/1", tenantAware.getCurrentTenant())
|
||||
.accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isNotFound());
|
||||
|
||||
createCancelAction("34534543");
|
||||
|
||||
// wrong media type
|
||||
mvc.perform(get("/{tenant}/controller/v1/34534543/cancelAction/1", tenantAware.getCurrentTenant())
|
||||
.accept(MediaType.APPLICATION_ATOM_XML)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isNotAcceptable());
|
||||
|
||||
}
|
||||
|
||||
private Action createCancelAction(final String targetid) {
|
||||
final Target target = new Target(targetid);
|
||||
final DistributionSet ds = TestDataUtil.generateDistributionSet(targetid, softwareManagement,
|
||||
distributionSetManagement);
|
||||
final Target savedTarget = targetManagement.createTarget(target);
|
||||
final List<Target> toAssign = new ArrayList<Target>();
|
||||
toAssign.add(savedTarget);
|
||||
final Action updateAction = deploymentManagement
|
||||
.findActionWithDetails(deploymentManagement.assignDistributionSet(ds, toAssign).getActions().get(0));
|
||||
|
||||
return deploymentManagement.cancelAction(updateAction,
|
||||
targetManagement.findTargetByControllerID(savedTarget.getControllerId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Tests the feedback channel of the cancel operation.")
|
||||
public void rootRsCancelActionFeedback() throws Exception {
|
||||
|
||||
final Target target = new Target("4712");
|
||||
final DistributionSet ds = TestDataUtil.generateDistributionSet("", softwareManagement,
|
||||
distributionSetManagement);
|
||||
|
||||
final Target savedTarget = targetManagement.createTarget(target);
|
||||
|
||||
final Action updateAction = deploymentManagement.findActionWithDetails(
|
||||
deploymentManagement.assignDistributionSet(ds.getId(), new String[] { "4712" }).getActions().get(0));
|
||||
|
||||
// cancel action manually
|
||||
final Action cancelAction = deploymentManagement.cancelAction(updateAction,
|
||||
targetManagement.findTargetByControllerID(savedTarget.getControllerId()));
|
||||
assertThat(actionStatusRepository.findAll()).hasSize(2);
|
||||
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).hasSize(1);
|
||||
long current = System.currentTimeMillis();
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/cancelAction/" + cancelAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.cancelActionFeedback(cancelAction.getId().toString(), "proceeding"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).hasSize(1);
|
||||
assertThat(actionStatusRepository.findAll()).hasSize(3);
|
||||
|
||||
current = System.currentTimeMillis();
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/cancelAction/" + cancelAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.cancelActionFeedback(cancelAction.getId().toString(), "resumed"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).hasSize(1);
|
||||
assertThat(actionStatusRepository.findAll()).hasSize(4);
|
||||
|
||||
current = System.currentTimeMillis();
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/cancelAction/" + cancelAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.cancelActionFeedback(cancelAction.getId().toString(), "scheduled"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
assertThat(actionStatusRepository.findAll()).hasSize(5);
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).hasSize(1);
|
||||
|
||||
// cancelation canceled -> should remove the action from active
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).hasSize(1);
|
||||
current = System.currentTimeMillis();
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/cancelAction/" + cancelAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.cancelActionFeedback(cancelAction.getId().toString(), "canceled"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
assertThat(actionStatusRepository.findAll()).hasSize(6);
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).hasSize(1);
|
||||
|
||||
// cancelation rejected -> action still active until controller close it
|
||||
// with finished or
|
||||
// error
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).hasSize(1);
|
||||
current = System.currentTimeMillis();
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/cancelAction/" + cancelAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.cancelActionFeedback(cancelAction.getId().toString(), "rejected"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
assertThat(actionStatusRepository.findAll()).hasSize(7);
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).hasSize(1);
|
||||
|
||||
// cancelaction closed -> should remove the action from active
|
||||
current = System.currentTimeMillis();
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/cancelAction/" + cancelAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.cancelActionFeedback(cancelAction.getId().toString(), "closed"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
assertThat(actionStatusRepository.findAll()).hasSize(8);
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).hasSize(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Tests the feeback chanel of for multiple open cancel operations on the same target.")
|
||||
public void multipleCancelActionFeedback() throws Exception {
|
||||
final Target target = new Target("4712");
|
||||
final DistributionSet ds = TestDataUtil.generateDistributionSet("", softwareManagement,
|
||||
distributionSetManagement, true);
|
||||
final DistributionSet ds2 = TestDataUtil.generateDistributionSet("2", softwareManagement,
|
||||
distributionSetManagement, true);
|
||||
final DistributionSet ds3 = TestDataUtil.generateDistributionSet("3", softwareManagement,
|
||||
distributionSetManagement, true);
|
||||
|
||||
final Target savedTarget = targetManagement.createTarget(target);
|
||||
|
||||
final Action updateAction = deploymentManagement.findActionWithDetails(
|
||||
deploymentManagement.assignDistributionSet(ds.getId(), new String[] { "4712" }).getActions().get(0));
|
||||
final Action updateAction2 = deploymentManagement.findActionWithDetails(
|
||||
deploymentManagement.assignDistributionSet(ds2.getId(), new String[] { "4712" }).getActions().get(0));
|
||||
final Action updateAction3 = deploymentManagement.findActionWithDetails(
|
||||
deploymentManagement.assignDistributionSet(ds3.getId(), new String[] { "4712" }).getActions().get(0));
|
||||
|
||||
assertThat(actionStatusRepository.findAll()).hasSize(3);
|
||||
|
||||
// 3 update actions, 0 cancel actions
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).hasSize(3);
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).hasSize(3);
|
||||
final Action cancelAction = deploymentManagement.cancelAction(updateAction,
|
||||
targetManagement.findTargetByControllerID(savedTarget.getControllerId()));
|
||||
final Action cancelAction2 = deploymentManagement.cancelAction(updateAction2,
|
||||
targetManagement.findTargetByControllerID(savedTarget.getControllerId()));
|
||||
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).hasSize(3);
|
||||
assertThat(deploymentManagement.findActionsByTarget(savedTarget)).hasSize(3);
|
||||
mvc.perform(
|
||||
get("/{tenant}/controller/v1/4712/cancelAction/" + cancelAction.getId(), tenantAware.getCurrentTenant())
|
||||
.accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(jsonPath("$id", equalTo(String.valueOf(cancelAction.getId()))))
|
||||
.andExpect(jsonPath("$cancelAction.stopId", equalTo(String.valueOf(updateAction.getId()))));
|
||||
assertThat(actionStatusRepository.findAll()).hasSize(6);
|
||||
|
||||
mvc.perform(get("/{tenant}/controller/v1/4712", tenantAware.getCurrentTenant()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||
.andExpect(jsonPath("$config.polling.sleep", equalTo("00:01:00")))
|
||||
.andExpect(jsonPath("$_links.cancelAction.href",
|
||||
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
||||
+ "/controller/v1/4712/cancelAction/" + cancelAction.getId())));
|
||||
|
||||
// now lets return feedback for the first cancelation
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/cancelAction/" + cancelAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.cancelActionFeedback(cancelAction.getId().toString(), "closed"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
assertThat(actionStatusRepository.findAll()).hasSize(7);
|
||||
|
||||
// 1 update actions, 1 cancel actions
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).hasSize(2);
|
||||
assertThat(deploymentManagement.findActionsByTarget(savedTarget)).hasSize(3);
|
||||
mvc.perform(get("/{tenant}/controller/v1/4712/cancelAction/" + cancelAction2.getId(),
|
||||
tenantAware.getCurrentTenant()).accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk()).andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(jsonPath("$id", equalTo(String.valueOf(cancelAction2.getId()))))
|
||||
.andExpect(jsonPath("$cancelAction.stopId", equalTo(String.valueOf(updateAction2.getId()))));
|
||||
assertThat(actionStatusRepository.findAll()).hasSize(8);
|
||||
|
||||
mvc.perform(get("/{tenant}/controller/v1/4712", tenantAware.getCurrentTenant()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||
.andExpect(jsonPath("$config.polling.sleep", equalTo("00:01:00")))
|
||||
.andExpect(jsonPath("$_links.cancelAction.href",
|
||||
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
||||
+ "/controller/v1/4712/cancelAction/" + cancelAction2.getId())));
|
||||
|
||||
// now lets return feedback for the second cancelation
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/cancelAction/" + cancelAction2.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.cancelActionFeedback(cancelAction2.getId().toString(), "closed"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
assertThat(actionStatusRepository.findAll()).hasSize(9);
|
||||
|
||||
assertThat(targetManagement.findTargetByControllerID("4712").getAssignedDistributionSet()).isEqualTo(ds3);
|
||||
mvc.perform(get("/{tenant}/controller/v1/4712/deploymentBase/" + updateAction3.getId(),
|
||||
tenantAware.getCurrentTenant())).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
assertThat(actionStatusRepository.findAll()).hasSize(10);
|
||||
|
||||
// 1 update actions, 0 cancel actions
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).hasSize(1);
|
||||
|
||||
final Action cancelAction3 = deploymentManagement.cancelAction(actionRepository.findOne(updateAction3.getId()),
|
||||
targetManagement.findTargetByControllerID(savedTarget.getControllerId()));
|
||||
|
||||
// action is in cancelling state
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).hasSize(1);
|
||||
assertThat(deploymentManagement.findActionsByTarget(savedTarget)).hasSize(3);
|
||||
assertThat(targetManagement.findTargetByControllerID("4712").getAssignedDistributionSet()).isEqualTo(ds3);
|
||||
|
||||
mvc.perform(get("/{tenant}/controller/v1/4712/cancelAction/" + cancelAction3.getId(),
|
||||
tenantAware.getCurrentTenant()).accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk()).andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(jsonPath("$id", equalTo(String.valueOf(cancelAction3.getId()))))
|
||||
.andExpect(jsonPath("$cancelAction.stopId", equalTo(String.valueOf(updateAction3.getId()))));
|
||||
assertThat(actionStatusRepository.findAll()).hasSize(12);
|
||||
|
||||
// now lets return feedback for the third cancelation
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/cancelAction/" + cancelAction3.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.cancelActionFeedback(cancelAction3.getId().toString(), "closed"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
assertThat(actionStatusRepository.findAll()).hasSize(13);
|
||||
|
||||
// final status
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).hasSize(0);
|
||||
assertThat(deploymentManagement.findActionsByTarget(savedTarget)).hasSize(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Tests the feeback channel closing for too many feedbacks, i.e. denial of service prevention.")
|
||||
public void tooMuchCancelActionFeedback() throws Exception {
|
||||
final Target target = targetManagement.createTarget(new Target("4712"));
|
||||
final DistributionSet ds = TestDataUtil.generateDistributionSet("", softwareManagement,
|
||||
distributionSetManagement);
|
||||
|
||||
final List<Target> toAssign = new ArrayList<Target>();
|
||||
toAssign.add(target);
|
||||
|
||||
final Action action = deploymentManagement.findActionWithDetails(
|
||||
deploymentManagement.assignDistributionSet(ds.getId(), new String[] { "4712" }).getActions().get(0));
|
||||
|
||||
final Action cancelAction = deploymentManagement.cancelAction(action,
|
||||
targetManagement.findTargetByControllerID(target.getControllerId()));
|
||||
|
||||
final String feedback = JsonBuilder.cancelActionFeedback(cancelAction.getId().toString(), "proceeding");
|
||||
// assignDistributionSet creates an ActionStatus and cancel action
|
||||
// stores an action status, so
|
||||
// only 97 action status left
|
||||
for (int i = 0; i < 98; i++) {
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/cancelAction/" + cancelAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant()).content(feedback).contentType(MediaType.APPLICATION_JSON)
|
||||
.accept(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/cancelAction/" + cancelAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant()).content(feedback).contentType(MediaType.APPLICATION_JSON)
|
||||
.accept(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isForbidden());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("test the correct rejection of various invalid feedback requests")
|
||||
public void badCancelActionFeedback() throws Exception {
|
||||
final Action cancelAction = createCancelAction("4712");
|
||||
final Action cancelAction2 = createCancelAction("4715");
|
||||
|
||||
// not allowed methods
|
||||
mvc.perform(put("/{tenant}/controller/v1/4712/cancelAction/" + cancelAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.cancelActionFeedback(cancelAction.getId().toString(), "closed"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isMethodNotAllowed());
|
||||
|
||||
mvc.perform(delete("/{tenant}/controller/v1/4712/cancelAction/" + cancelAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isMethodNotAllowed());
|
||||
|
||||
mvc.perform(get("/{tenant}/controller/v1/4712/cancelAction/" + cancelAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isMethodNotAllowed());
|
||||
|
||||
// bad content type
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/cancelAction/" + cancelAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.cancelActionFeedback(cancelAction.getId().toString(), "closed"))
|
||||
.contentType(MediaType.APPLICATION_ATOM_XML).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isUnsupportedMediaType());
|
||||
|
||||
// bad body
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/cancelAction/" + cancelAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.cancelActionFeedback(cancelAction.getId().toString(), "546456456"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest());
|
||||
|
||||
// non existing target
|
||||
mvc.perform(post("/{tenant}/controller/v1/12345/cancelAction/" + cancelAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.cancelActionFeedback(cancelAction.getId().toString(), "closed"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound());
|
||||
|
||||
// invalid action
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/cancelAction/" + cancelAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant()).content(JsonBuilder.cancelActionFeedback("sdfsdfsdfs", "closed"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest());
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/cancelAction/" + cancelAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant()).content(JsonBuilder.cancelActionFeedback("1234", "closed"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound());
|
||||
|
||||
// right action but for wrong target
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/cancelAction/" + cancelAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.cancelActionFeedback(cancelAction2.getId().toString(), "closed"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound());
|
||||
|
||||
// finally get it right :)
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/cancelAction/" + cancelAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.cancelActionFeedback(cancelAction.getId().toString(), "closed"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations 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.resource;
|
||||
|
||||
import static org.fest.assertions.api.Assertions.assertThat;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
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.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.hawkbit.AbstractIntegrationTest;
|
||||
import org.eclipse.hawkbit.MockMvcResultPrinter;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.rest.resource.JsonBuilder;
|
||||
import org.junit.Test;
|
||||
import org.springframework.hateoas.MediaTypes;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
|
||||
import ru.yandex.qatools.allure.annotations.Description;
|
||||
import ru.yandex.qatools.allure.annotations.Features;
|
||||
import ru.yandex.qatools.allure.annotations.Stories;
|
||||
|
||||
@ActiveProfiles({ "im", "test" })
|
||||
@Features("Component Tests - Direct Device Integration API")
|
||||
@Stories("Config Data Resource")
|
||||
public class ConfigDataTest extends AbstractIntegrationTest {
|
||||
|
||||
@Test
|
||||
@Description("We verify that the config data (i.e. device attributes like serial number, hardware revision etc.) "
|
||||
+ "are requested only once from the device.")
|
||||
public void requestConfigDataIfEmpty() throws Exception {
|
||||
final Target target = new Target("4712");
|
||||
final Target savedTarget = targetManagement.createTarget(target);
|
||||
|
||||
final long current = System.currentTimeMillis();
|
||||
mvc.perform(get("/{tenant}/controller/v1/4712", tenantAware.getCurrentTenant()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||
.andExpect(jsonPath("$config.polling.sleep", equalTo("00:01:00")))
|
||||
.andExpect(jsonPath("$_links.configData.href", equalTo(
|
||||
"http://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/4712/configData")));
|
||||
Thread.sleep(1); // is required: otherwise processing the next line is
|
||||
// often too fast and
|
||||
// the following assert will fail
|
||||
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getLastTargetQuery())
|
||||
.isLessThanOrEqualTo(System.currentTimeMillis());
|
||||
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
|
||||
savedTarget.getTargetInfo().getControllerAttributes().put("dsafsdf", "sdsds");
|
||||
|
||||
final Target updateControllerAttributes = controllerManagament.updateControllerAttributes(
|
||||
savedTarget.getControllerId(), savedTarget.getTargetInfo().getControllerAttributes());
|
||||
// request controller attributes need to be false because we don't want
|
||||
// to request the
|
||||
// controller attributes again
|
||||
assertThat(updateControllerAttributes.getTargetInfo().isRequestControllerAttributes()).isFalse();
|
||||
|
||||
mvc.perform(get("/{tenant}/controller/v1/4712", tenantAware.getCurrentTenant()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||
.andExpect(jsonPath("$config.polling.sleep", equalTo("00:01:00")))
|
||||
.andExpect(jsonPath("$_links.configData.href").doesNotExist());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("We verify that the config data (i.e. device attributes like serial number, hardware revision etc.) "
|
||||
+ "can be uploaded correctly by the controller.")
|
||||
public void putConfigData() throws Exception {
|
||||
targetManagement.createTarget(new Target("4717"));
|
||||
|
||||
// initial
|
||||
final Map<String, String> attributes = new HashMap<>();
|
||||
attributes.put("dsafsdf", "sdsds");
|
||||
|
||||
long current = System.currentTimeMillis();
|
||||
mvc.perform(put("/{tenant}/controller/v1/4717/configData", tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.configData("", attributes, "closed")).contentType(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
Thread.sleep(1); // is required: otherwise processing the next line is
|
||||
// often too fast and
|
||||
// the following assert will fail
|
||||
assertThat(targetManagement.findTargetByControllerID("4717").getTargetInfo().getLastTargetQuery())
|
||||
.isLessThanOrEqualTo(System.currentTimeMillis());
|
||||
assertThat(targetManagement.findTargetByControllerID("4717").getTargetInfo().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
assertThat(
|
||||
targetManagement.findTargetByControllerIDWithDetails("4717").getTargetInfo().getControllerAttributes())
|
||||
.isEqualTo(attributes);
|
||||
|
||||
// update
|
||||
attributes.put("sdsds", "123412");
|
||||
current = System.currentTimeMillis();
|
||||
mvc.perform(put("/{tenant}/controller/v1/4717/configData", tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.configData("", attributes, "closed")).contentType(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
Thread.sleep(1); // is required: otherwise processing the next line is
|
||||
// often too fast and
|
||||
// the following assert will fail
|
||||
assertThat(targetManagement.findTargetByControllerID("4717").getTargetInfo().getLastTargetQuery())
|
||||
.isLessThanOrEqualTo(System.currentTimeMillis());
|
||||
assertThat(targetManagement.findTargetByControllerID("4717").getTargetInfo().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
assertThat(
|
||||
targetManagement.findTargetByControllerIDWithDetails("4717").getTargetInfo().getControllerAttributes())
|
||||
.isEqualTo(attributes);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("We verify that the config data (i.e. device attributes like serial number, hardware revision etc.) "
|
||||
+ "upload limitation is inplace which is meant to protect the server from malicious attempts.")
|
||||
public void putToMuchConfigData() throws Exception {
|
||||
targetManagement.createTarget(new Target("4717"));
|
||||
|
||||
// initial
|
||||
Map<String, String> attributes = new HashMap<>();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
attributes.put("dsafsdf" + i, "sdsds" + i);
|
||||
}
|
||||
mvc.perform(put("/{tenant}/controller/v1/4717/configData", tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.configData("", attributes, "closed")).contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk());
|
||||
|
||||
attributes = new HashMap<>();
|
||||
attributes.put("on too many", "sdsds");
|
||||
mvc.perform(put("/{tenant}/controller/v1/4717/configData", tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.configData("", attributes, "closed")).contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isForbidden());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("We verify that the config data (i.e. device attributes like serial number, hardware revision etc.) "
|
||||
+ "resource behaves as exptected in cae of invalid request attempts.")
|
||||
public void badConfigData() throws Exception {
|
||||
final Target target = new Target("4712");
|
||||
final Target savedTarget = targetManagement.createTarget(target);
|
||||
|
||||
// not allowed methods
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/configData", tenantAware.getCurrentTenant()))
|
||||
.andDo(MockMvcResultPrinter.print()).//
|
||||
andExpect(status().isMethodNotAllowed());
|
||||
|
||||
mvc.perform(get("/{tenant}/controller/v1/4712/configData", tenantAware.getCurrentTenant()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isMethodNotAllowed());
|
||||
|
||||
mvc.perform(delete("/{tenant}/controller/v1/4712/configData", tenantAware.getCurrentTenant()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isMethodNotAllowed());
|
||||
|
||||
// bad content type
|
||||
final Map<String, String> attributes = new HashMap<>();
|
||||
attributes.put("dsafsdf", "sdsds");
|
||||
mvc.perform(put("/{tenant}/controller/v1/4712/configData", tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.configData("", attributes, "closed")).contentType(MediaTypes.HAL_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isUnsupportedMediaType());
|
||||
|
||||
// non existing target
|
||||
mvc.perform(put("/{tenant}/controller/v1/456456/configData", tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.configData("", attributes, "closed")).contentType(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound());
|
||||
|
||||
// bad body
|
||||
mvc.perform(put("/{tenant}/controller/v1/4712/configData", tenantAware.getCurrentTenant())
|
||||
.content("{\"id\": \"51659181\"}").contentType(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,990 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations 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.resource;
|
||||
|
||||
import static org.fest.assertions.api.Assertions.assertThat;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
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.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.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.RandomUtils;
|
||||
import org.eclipse.hawkbit.AbstractIntegrationTestWithMongoDB;
|
||||
import org.eclipse.hawkbit.MockMvcResultPrinter;
|
||||
import org.eclipse.hawkbit.TestDataUtil;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||
import org.eclipse.hawkbit.repository.model.Action.Status;
|
||||
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.LocalArtifact;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||
import org.eclipse.hawkbit.rest.resource.JsonBuilder;
|
||||
import org.fest.assertions.core.Condition;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.hateoas.MediaTypes;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
|
||||
import ru.yandex.qatools.allure.annotations.Description;
|
||||
import ru.yandex.qatools.allure.annotations.Features;
|
||||
import ru.yandex.qatools.allure.annotations.Stories;
|
||||
|
||||
@ActiveProfiles({ "im", "test" })
|
||||
@Features("Component Tests - Direct Device Integration API")
|
||||
@Stories("Deployment Action Resource")
|
||||
public class DeploymentBaseTest extends AbstractIntegrationTestWithMongoDB {
|
||||
|
||||
@Test()
|
||||
@Description("Ensures that artifacts are not found, when softare module does not exists.")
|
||||
public void artifactsNotFound() throws Exception {
|
||||
final Target target = TestDataUtil.createTarget(targetManagement);
|
||||
final Long softwareModuleIdNotExist = 1l;
|
||||
mvc.perform(get("/{tenant}/controller/v1/{targetNotExist}/softwaremodules/{softwareModuleId}/artifacts",
|
||||
tenantAware.getCurrentTenant(), target.getName(), softwareModuleIdNotExist))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound());
|
||||
}
|
||||
|
||||
@Test()
|
||||
@Description("Ensures that artifacts are found, when software module exists.")
|
||||
public void artifactsExists() throws Exception {
|
||||
final Target target = TestDataUtil.createTarget(targetManagement);
|
||||
final DistributionSet distributionSet = TestDataUtil.generateDistributionSet("", softwareManagement,
|
||||
distributionSetManagement);
|
||||
|
||||
deploymentManagement.assignDistributionSet(distributionSet.getId(), new String[] { target.getName() });
|
||||
|
||||
final Long softwareModuleId = distributionSet.getModules().stream().findFirst().get().getId();
|
||||
mvc.perform(get("/{tenant}/controller/v1/{targetNotExist}/softwaremodules/{softwareModuleId}/artifacts",
|
||||
tenantAware.getCurrentTenant(), target.getName(), softwareModuleId)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk()).andExpect(jsonPath("$", hasSize(0)));
|
||||
|
||||
TestDataUtil.generateArtifacts(artifactManagement, softwareModuleId);
|
||||
|
||||
mvc.perform(get("/{tenant}/controller/v1/{targetNotExist}/softwaremodules/{softwareModuleId}/artifacts",
|
||||
tenantAware.getCurrentTenant(), target.getName(), softwareModuleId)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk()).andExpect(jsonPath("$", hasSize(3)))
|
||||
.andExpect(jsonPath("$[?(@.filename==filename0)]", hasSize(1)))
|
||||
.andExpect(jsonPath("$[?(@.filename==filename1)]", hasSize(1)))
|
||||
.andExpect(jsonPath("$[?(@.filename==filename2)]", hasSize(1)));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Forced deployment to a controller. Checks if the resource reponse payload for a given deployment is as expected.")
|
||||
public void deplomentForceAction() throws Exception {
|
||||
// Prepare test data
|
||||
final Target target = new Target("4712");
|
||||
final DistributionSet ds = TestDataUtil.generateDistributionSet("", softwareManagement,
|
||||
distributionSetManagement, true);
|
||||
final DistributionSet ds2 = TestDataUtil.generateDistributionSet("2", softwareManagement,
|
||||
distributionSetManagement, true);
|
||||
|
||||
final byte random[] = RandomUtils.nextBytes(5 * 1024);
|
||||
final LocalArtifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
|
||||
ds.findFirstModuleByType(osType).getId(), "test1", false);
|
||||
final LocalArtifact artifactSignature = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
|
||||
ds.findFirstModuleByType(osType).getId(), "test1.signature", false);
|
||||
|
||||
final Target savedTarget = targetManagement.createTarget(target);
|
||||
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).isEmpty();
|
||||
assertThat(actionRepository.findAll()).isEmpty();
|
||||
assertThat(actionStatusRepository.findAll()).isEmpty();
|
||||
|
||||
List<Target> saved = deploymentManagement.assignDistributionSet(ds.getId(), ActionType.FORCED,
|
||||
Action.NO_FORCE_TIME, savedTarget.getControllerId()).getAssignedEntity();
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).hasSize(1);
|
||||
|
||||
final Action action = deploymentManagement.findActiveActionsByTarget(savedTarget).get(0);
|
||||
assertThat(actionRepository.findAll()).hasSize(1);
|
||||
saved = deploymentManagement.assignDistributionSet(ds2, saved).getAssignedEntity();
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).hasSize(2);
|
||||
assertThat(actionRepository.findAll()).hasSize(2);
|
||||
|
||||
final Action uaction = deploymentManagement.findActiveActionsByTarget(savedTarget).get(0);
|
||||
assertThat(uaction.getDistributionSet()).isEqualTo(ds);
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).hasSize(2);
|
||||
|
||||
// Run test
|
||||
long current = System.currentTimeMillis();
|
||||
mvc.perform(get("/{tenant}/controller/v1/4712", tenantAware.getCurrentTenant()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||
.andExpect(jsonPath("$config.polling.sleep", equalTo("00:01:00")))
|
||||
.andExpect(jsonPath("$_links.deploymentBase.href", startsWith("http://localhost/"
|
||||
+ tenantAware.getCurrentTenant() + "/controller/v1/4712/deploymentBase/" + uaction.getId())));
|
||||
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getLastTargetQuery())
|
||||
.isLessThanOrEqualTo(System.currentTimeMillis());
|
||||
assertThat(actionStatusRepository.findAll()).hasSize(2);
|
||||
|
||||
current = System.currentTimeMillis();
|
||||
|
||||
final DistributionSet findDistributionSetByAction = distributionSetManagement
|
||||
.findDistributionSetByAction(action);
|
||||
|
||||
mvc.perform(
|
||||
get("/{tenant}/controller/v1/4712/deploymentBase/" + uaction.getId(), tenantAware.getCurrentTenant())
|
||||
.accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(jsonPath("$id", equalTo(String.valueOf(action.getId()))))
|
||||
.andExpect(jsonPath("$deployment.download", equalTo("forced")))
|
||||
.andExpect(jsonPath("$deployment.update", equalTo("forced")))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==jvm)][0].name",
|
||||
equalTo(ds.findFirstModuleByType(runtimeType).getName())))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==jvm)][0].version",
|
||||
equalTo(ds.findFirstModuleByType(runtimeType).getVersion())))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].name",
|
||||
equalTo(ds.findFirstModuleByType(osType).getName())))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].version",
|
||||
equalTo(ds.findFirstModuleByType(osType).getVersion())))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0].size", equalTo(5 * 1024)))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0].filename", equalTo("test1")))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0].hashes.md5",
|
||||
equalTo(artifact.getMd5Hash())))
|
||||
.andExpect(
|
||||
jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0].hashes.sha1",
|
||||
equalTo(artifact.getSha1Hash())))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.download.href",
|
||||
equalTo("https://localhost/" + tenantAware.getCurrentTenant()
|
||||
+ "/controller/v1/4712/softwaremodules/"
|
||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||
+ "/artifacts/test1")))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.md5sum.href",
|
||||
equalTo("https://localhost/" + tenantAware.getCurrentTenant()
|
||||
+ "/controller/v1/4712/softwaremodules/"
|
||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||
+ "/artifacts/test1.MD5SUM")))
|
||||
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.download-http.href",
|
||||
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
||||
+ "/controller/v1/4712/softwaremodules/"
|
||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||
+ "/artifacts/test1")))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.md5sum-http.href",
|
||||
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
||||
+ "/controller/v1/4712/softwaremodules/"
|
||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||
+ "/artifacts/test1.MD5SUM")))
|
||||
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1].size", equalTo(5 * 1024)))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1].filename",
|
||||
equalTo("test1.signature")))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1].hashes.md5",
|
||||
equalTo(artifactSignature.getMd5Hash())))
|
||||
.andExpect(
|
||||
jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1].hashes.sha1",
|
||||
equalTo(artifactSignature.getSha1Hash())))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.download.href",
|
||||
equalTo("https://localhost/" + tenantAware.getCurrentTenant()
|
||||
+ "/controller/v1/4712/softwaremodules/"
|
||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||
+ "/artifacts/test1.signature")))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.md5sum.href",
|
||||
equalTo("https://localhost/" + tenantAware.getCurrentTenant()
|
||||
+ "/controller/v1/4712/softwaremodules/"
|
||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||
+ "/artifacts/test1.signature.MD5SUM")))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.download-http.href",
|
||||
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
||||
+ "/controller/v1/4712/softwaremodules/"
|
||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||
+ "/artifacts/test1.signature")))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.md5sum-http.href",
|
||||
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
||||
+ "/controller/v1/4712/softwaremodules/"
|
||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||
+ "/artifacts/test1.signature.MD5SUM")))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==bApp)][0].version",
|
||||
equalTo(ds.findFirstModuleByType(appType).getVersion())))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==bApp)][0].name",
|
||||
equalTo(ds.findFirstModuleByType(appType).getName())));
|
||||
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
|
||||
// Retrieved is reported
|
||||
final Iterable<ActionStatus> actionStatusMessages = actionStatusRepository
|
||||
.findAll(new PageRequest(0, 100, Direction.DESC, "id"));
|
||||
assertThat(actionStatusMessages).hasSize(3);
|
||||
final ActionStatus actionStatusMessage = actionStatusMessages.iterator().next();
|
||||
assertThat(actionStatusMessage.getStatus()).isEqualTo(Status.RETRIEVED);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Attempt/soft deployment to a controller. Checks if the resource reponse payload for a given deployment is as expected.")
|
||||
public void deplomentAttemptAction() throws Exception {
|
||||
// Prepare test data
|
||||
final Target target = new Target("4712");
|
||||
final DistributionSet ds = TestDataUtil.generateDistributionSet("", softwareManagement,
|
||||
distributionSetManagement, true);
|
||||
final DistributionSet ds2 = TestDataUtil.generateDistributionSet("2", softwareManagement,
|
||||
distributionSetManagement, true);
|
||||
|
||||
final byte random[] = RandomUtils.nextBytes(5 * 1024);
|
||||
final LocalArtifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
|
||||
ds.findFirstModuleByType(osType).getId(), "test1", false);
|
||||
final LocalArtifact artifactSignature = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
|
||||
ds.findFirstModuleByType(osType).getId(), "test1.signature", false);
|
||||
|
||||
final Target savedTarget = targetManagement.createTarget(target);
|
||||
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).isEmpty();
|
||||
assertThat(actionRepository.findAll()).isEmpty();
|
||||
assertThat(actionStatusRepository.findAll()).isEmpty();
|
||||
|
||||
List<Target> saved = deploymentManagement
|
||||
.assignDistributionSet(ds.getId(), ActionType.SOFT, Action.NO_FORCE_TIME, savedTarget.getControllerId())
|
||||
.getAssignedEntity();
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).hasSize(1);
|
||||
|
||||
final Action action = deploymentManagement.findActiveActionsByTarget(savedTarget).get(0);
|
||||
assertThat(actionRepository.findAll()).hasSize(1);
|
||||
saved = deploymentManagement.assignDistributionSet(ds2, saved).getAssignedEntity();
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).hasSize(2);
|
||||
assertThat(actionRepository.findAll()).hasSize(2);
|
||||
|
||||
final Action uaction = deploymentManagement.findActiveActionsByTarget(savedTarget).get(0);
|
||||
assertThat(uaction.getDistributionSet()).isEqualTo(ds);
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).hasSize(2);
|
||||
|
||||
// Run test
|
||||
|
||||
long current = System.currentTimeMillis();
|
||||
mvc.perform(get("/{tenant}/controller/v1/4712", tenantAware.getCurrentTenant()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||
.andExpect(jsonPath("$config.polling.sleep", equalTo("00:01:00")))
|
||||
.andExpect(jsonPath("$_links.deploymentBase.href", startsWith("http://localhost/"
|
||||
+ tenantAware.getCurrentTenant() + "/controller/v1/4712/deploymentBase/" + uaction.getId())));
|
||||
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getLastTargetQuery())
|
||||
.isLessThanOrEqualTo(System.currentTimeMillis());
|
||||
assertThat(actionStatusRepository.findAll()).hasSize(2);
|
||||
|
||||
current = System.currentTimeMillis();
|
||||
|
||||
final DistributionSet findDistributionSetByAction = distributionSetManagement
|
||||
.findDistributionSetByAction(action);
|
||||
|
||||
mvc.perform(
|
||||
get("/{tenant}/controller/v1/4712/deploymentBase/" + uaction.getId(), tenantAware.getCurrentTenant())
|
||||
.accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(jsonPath("$id", equalTo(String.valueOf(action.getId()))))
|
||||
.andExpect(jsonPath("$deployment.download", equalTo("attempt")))
|
||||
.andExpect(jsonPath("$deployment.update", equalTo("attempt")))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==jvm)][0].name",
|
||||
equalTo(ds.findFirstModuleByType(runtimeType).getName())))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==jvm)][0].version",
|
||||
equalTo(ds.findFirstModuleByType(runtimeType).getVersion())))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].name",
|
||||
equalTo(ds.findFirstModuleByType(osType).getName())))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].version",
|
||||
equalTo(ds.findFirstModuleByType(osType).getVersion())))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0].size", equalTo(5 * 1024)))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0].filename", equalTo("test1")))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0].hashes.md5",
|
||||
equalTo(artifact.getMd5Hash())))
|
||||
.andExpect(
|
||||
jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0].hashes.sha1",
|
||||
equalTo(artifact.getSha1Hash())))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.download.href",
|
||||
equalTo("https://localhost/" + tenantAware.getCurrentTenant()
|
||||
+ "/controller/v1/4712/softwaremodules/"
|
||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||
+ "/artifacts/test1")))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.md5sum.href",
|
||||
equalTo("https://localhost/" + tenantAware.getCurrentTenant()
|
||||
+ "/controller/v1/4712/softwaremodules/"
|
||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||
+ "/artifacts/test1.MD5SUM")))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1].size", equalTo(5 * 1024)))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1].filename",
|
||||
equalTo("test1.signature")))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1].hashes.md5",
|
||||
equalTo(artifactSignature.getMd5Hash())))
|
||||
.andExpect(
|
||||
jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1].hashes.sha1",
|
||||
equalTo(artifactSignature.getSha1Hash())))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.download.href",
|
||||
equalTo("https://localhost/" + tenantAware.getCurrentTenant()
|
||||
+ "/controller/v1/4712/softwaremodules/"
|
||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||
+ "/artifacts/test1.signature")))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.md5sum.href",
|
||||
equalTo("https://localhost/" + tenantAware.getCurrentTenant()
|
||||
+ "/controller/v1/4712/softwaremodules/"
|
||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||
+ "/artifacts/test1.signature.MD5SUM")))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.download-http.href",
|
||||
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
||||
+ "/controller/v1/4712/softwaremodules/"
|
||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||
+ "/artifacts/test1.signature")))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.md5sum-http.href",
|
||||
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
||||
+ "/controller/v1/4712/softwaremodules/"
|
||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||
+ "/artifacts/test1.signature.MD5SUM")))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==bApp)][0].version",
|
||||
equalTo(ds.findFirstModuleByType(appType).getVersion())))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==bApp)][0].name",
|
||||
equalTo(ds.findFirstModuleByType(appType).getName())));
|
||||
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
|
||||
// Retrieved is reported
|
||||
final Iterable<ActionStatus> actionStatusMessages = actionStatusRepository
|
||||
.findAll(new PageRequest(0, 100, Direction.DESC, "id"));
|
||||
assertThat(actionStatusMessages).hasSize(3);
|
||||
final ActionStatus actionStatusMessage = actionStatusMessages.iterator().next();
|
||||
assertThat(actionStatusMessage.getStatus()).isEqualTo(Status.RETRIEVED);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Attempt/soft deployment to a controller including automated switch to hard. Checks if the resource reponse payload for a given deployment is as expected.")
|
||||
public void deplomentAutoForceAction() throws Exception {
|
||||
// Prepare test data
|
||||
final Target target = new Target("4712");
|
||||
final DistributionSet ds = TestDataUtil.generateDistributionSet("", softwareManagement,
|
||||
distributionSetManagement, true);
|
||||
final DistributionSet ds2 = TestDataUtil.generateDistributionSet("2", softwareManagement,
|
||||
distributionSetManagement, true);
|
||||
|
||||
final byte random[] = RandomUtils.nextBytes(5 * 1024);
|
||||
final LocalArtifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
|
||||
ds.findFirstModuleByType(osType).getId(), "test1", false);
|
||||
final LocalArtifact artifactSignature = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
|
||||
ds.findFirstModuleByType(osType).getId(), "test1.signature", false);
|
||||
|
||||
final Target savedTarget = targetManagement.createTarget(target);
|
||||
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).isEmpty();
|
||||
assertThat(actionRepository.findAll()).isEmpty();
|
||||
assertThat(actionStatusRepository.findAll()).isEmpty();
|
||||
|
||||
List<Target> saved = deploymentManagement.assignDistributionSet(ds.getId(), ActionType.TIMEFORCED,
|
||||
System.currentTimeMillis(), savedTarget.getControllerId()).getAssignedEntity();
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).hasSize(1);
|
||||
|
||||
final Action action = deploymentManagement.findActiveActionsByTarget(savedTarget).get(0);
|
||||
assertThat(actionRepository.findAll()).hasSize(1);
|
||||
saved = deploymentManagement.assignDistributionSet(ds2, saved).getAssignedEntity();
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).hasSize(2);
|
||||
assertThat(actionRepository.findAll()).hasSize(2);
|
||||
|
||||
final Action uaction = deploymentManagement.findActiveActionsByTarget(savedTarget).get(0);
|
||||
assertThat(uaction.getDistributionSet()).isEqualTo(ds);
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).hasSize(2);
|
||||
|
||||
// Run test
|
||||
|
||||
long current = System.currentTimeMillis();
|
||||
mvc.perform(get("/{tenant}/controller/v1/4712", tenantAware.getCurrentTenant()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||
.andExpect(jsonPath("$config.polling.sleep", equalTo("00:01:00")))
|
||||
.andExpect(jsonPath("$_links.deploymentBase.href", startsWith("http://localhost/"
|
||||
+ tenantAware.getCurrentTenant() + "/controller/v1/4712/deploymentBase/" + uaction.getId())));
|
||||
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getLastTargetQuery())
|
||||
.isLessThanOrEqualTo(System.currentTimeMillis());
|
||||
assertThat(actionStatusRepository.findAll()).hasSize(2);
|
||||
|
||||
current = System.currentTimeMillis();
|
||||
|
||||
final DistributionSet findDistributionSetByAction = distributionSetManagement
|
||||
.findDistributionSetByAction(action);
|
||||
|
||||
mvc.perform(get("/{tenant}/controller/v1/4712/deploymentBase/{actionId}", tenantAware.getCurrentTenant(),
|
||||
uaction.getId()).accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk()).andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(jsonPath("$id", equalTo(String.valueOf(action.getId()))))
|
||||
.andExpect(jsonPath("$deployment.download", equalTo("forced")))
|
||||
.andExpect(jsonPath("$deployment.update", equalTo("forced")))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==jvm)][0].name",
|
||||
equalTo(ds.findFirstModuleByType(runtimeType).getName())))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==jvm)][0].version",
|
||||
equalTo(ds.findFirstModuleByType(runtimeType).getVersion())))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].name",
|
||||
equalTo(ds.findFirstModuleByType(osType).getName())))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].version",
|
||||
equalTo(ds.findFirstModuleByType(osType).getVersion())))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0].size", equalTo(5 * 1024)))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0].filename", equalTo("test1")))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0].hashes.md5",
|
||||
equalTo(artifact.getMd5Hash())))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0].hashes.sha1",
|
||||
equalTo(artifact.getSha1Hash())))
|
||||
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.download.href",
|
||||
equalTo("https://localhost/" + tenantAware.getCurrentTenant()
|
||||
+ "/controller/v1/4712/softwaremodules/"
|
||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||
+ "/artifacts/test1")))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.md5sum.href",
|
||||
equalTo("https://localhost/" + tenantAware.getCurrentTenant()
|
||||
+ "/controller/v1/4712/softwaremodules/"
|
||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||
+ "/artifacts/test1.MD5SUM")))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.download-http.href",
|
||||
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
||||
+ "/controller/v1/4712/softwaremodules/"
|
||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||
+ "/artifacts/test1")))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.md5sum-http.href",
|
||||
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
||||
+ "/controller/v1/4712/softwaremodules/"
|
||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||
+ "/artifacts/test1.MD5SUM")))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1].size", equalTo(5 * 1024)))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1].filename",
|
||||
equalTo("test1.signature")))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1].hashes.md5",
|
||||
equalTo(artifactSignature.getMd5Hash())))
|
||||
.andExpect(
|
||||
jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1].hashes.sha1",
|
||||
equalTo(artifactSignature.getSha1Hash())))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.download.href",
|
||||
equalTo("https://localhost/" + tenantAware.getCurrentTenant()
|
||||
+ "/controller/v1/4712/softwaremodules/"
|
||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||
+ "/artifacts/test1.signature")))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.md5sum.href",
|
||||
equalTo("https://localhost/" + tenantAware.getCurrentTenant()
|
||||
+ "/controller/v1/4712/softwaremodules/"
|
||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||
+ "/artifacts/test1.signature.MD5SUM")))
|
||||
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.download-http.href",
|
||||
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
||||
+ "/controller/v1/4712/softwaremodules/"
|
||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||
+ "/artifacts/test1.signature")))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.md5sum-http.href",
|
||||
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
||||
+ "/controller/v1/4712/softwaremodules/"
|
||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||
+ "/artifacts/test1.signature.MD5SUM")))
|
||||
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==bApp)][0].version",
|
||||
equalTo(ds.findFirstModuleByType(appType).getVersion())))
|
||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==bApp)][0].name",
|
||||
equalTo(ds.findFirstModuleByType(appType).getName())));
|
||||
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
|
||||
// Retrieved is reported
|
||||
final Iterable<ActionStatus> actionStatusMessages = actionStatusRepository
|
||||
.findAll(new PageRequest(0, 100, Direction.DESC, "id"));
|
||||
assertThat(actionStatusMessages).hasSize(3);
|
||||
final ActionStatus actionStatusMessage = actionStatusMessages.iterator().next();
|
||||
assertThat(actionStatusMessage.getStatus()).isEqualTo(Status.RETRIEVED);
|
||||
}
|
||||
|
||||
@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 = targetManagement.createTarget(new Target("4712"));
|
||||
|
||||
// not allowed methods
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/deploymentBase/1", tenantAware.getCurrentTenant()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isMethodNotAllowed());
|
||||
|
||||
mvc.perform(put("/{tenant}/controller/v1/4712/deploymentBase/1", tenantAware.getCurrentTenant()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isMethodNotAllowed());
|
||||
|
||||
mvc.perform(delete("/{tenant}/controller/v1/4712/deploymentBase/1", tenantAware.getCurrentTenant()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isMethodNotAllowed());
|
||||
|
||||
// non existing target
|
||||
mvc.perform(get("/{tenant}/controller/v1/4715/deploymentBase/1", tenantAware.getCurrentTenant()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound());
|
||||
|
||||
// no deployment
|
||||
mvc.perform(get("/controller/v1/4712/deploymentBase/1", tenantAware.getCurrentTenant()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound());
|
||||
|
||||
// wrong media type
|
||||
final List<Target> toAssign = new ArrayList<Target>();
|
||||
toAssign.add(target);
|
||||
final DistributionSet savedSet = TestDataUtil.generateDistributionSet("", softwareManagement,
|
||||
distributionSetManagement);
|
||||
|
||||
final Action action1 = deploymentManagement.findActionWithDetails(
|
||||
deploymentManagement.assignDistributionSet(savedSet, toAssign).getActions().get(0));
|
||||
mvc.perform(
|
||||
get("/{tenant}/controller/v1/4712/deploymentBase/" + action1.getId(), tenantAware.getCurrentTenant()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
mvc.perform(
|
||||
get("/{tenant}/controller/v1/4712/deploymentBase/" + action1.getId(), tenantAware.getCurrentTenant())
|
||||
.accept(MediaType.APPLICATION_ATOM_XML))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isNotAcceptable());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("The server protects itself against to many feedback upload attempts. The test verfies that "
|
||||
+ "it is not possible to exceed the configured maximum number of feedback uplods.")
|
||||
public void toMuchDeplomentActionFeedback() throws Exception {
|
||||
final Target target = targetManagement.createTarget(new Target("4712"));
|
||||
final DistributionSet ds = TestDataUtil.generateDistributionSet("", softwareManagement,
|
||||
distributionSetManagement);
|
||||
|
||||
final List<Target> toAssign = new ArrayList<Target>();
|
||||
toAssign.add(target);
|
||||
|
||||
deploymentManagement.assignDistributionSet(ds.getId(), new String[] { "4712" });
|
||||
final Pageable pageReq = new PageRequest(0, 100);
|
||||
final Action action = actionRepository.findByDistributionSet(pageReq, ds).getContent().get(0);
|
||||
|
||||
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++) {
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/deploymentBase/" + action.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant()).content(feedback).contentType(MediaType.APPLICATION_JSON)
|
||||
.accept(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/deploymentBase/" + action.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant()).content(feedback).contentType(MediaType.APPLICATION_JSON)
|
||||
.accept(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isForbidden());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Multiple uploads of deployment status feedback to the server.")
|
||||
public void multipleDeplomentActionFeedback() throws Exception {
|
||||
final Target target1 = new Target("4712");
|
||||
final Target target2 = new Target("4713");
|
||||
final Target target3 = new Target("4714");
|
||||
final Target savedTarget1 = targetManagement.createTarget(target1);
|
||||
targetManagement.createTarget(target2);
|
||||
targetManagement.createTarget(target3);
|
||||
|
||||
final DistributionSet ds1 = TestDataUtil.generateDistributionSet("1", softwareManagement,
|
||||
distributionSetManagement, true);
|
||||
final DistributionSet ds2 = TestDataUtil.generateDistributionSet("2", softwareManagement,
|
||||
distributionSetManagement, true);
|
||||
final DistributionSet ds3 = TestDataUtil.generateDistributionSet("3", softwareManagement,
|
||||
distributionSetManagement, true);
|
||||
|
||||
final List<Target> toAssign = new ArrayList<Target>();
|
||||
toAssign.add(savedTarget1);
|
||||
|
||||
final Action action1 = deploymentManagement.findActionWithDetails(
|
||||
deploymentManagement.assignDistributionSet(ds1.getId(), new String[] { "4712" }).getActions().get(0));
|
||||
final Action action2 = deploymentManagement.findActionWithDetails(
|
||||
deploymentManagement.assignDistributionSet(ds2.getId(), new String[] { "4712" }).getActions().get(0));
|
||||
final Action action3 = deploymentManagement.findActionWithDetails(
|
||||
deploymentManagement.assignDistributionSet(ds3.getId(), new String[] { "4712" }).getActions().get(0));
|
||||
|
||||
Target myT = targetManagement.findTargetByControllerID("4712");
|
||||
assertThat(myT.getTargetInfo().getUpdateStatus()).isEqualTo(TargetUpdateStatus.PENDING);
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(myT)).hasSize(3);
|
||||
assertThat(myT.getAssignedDistributionSet()).isEqualTo(ds3);
|
||||
assertThat(myT.getTargetInfo().getInstalledDistributionSet()).isNull();
|
||||
assertThat(targetManagement.findTargetByUpdateStatus(new PageRequest(0, 10), TargetUpdateStatus.UNKNOWN))
|
||||
.hasSize(2);
|
||||
|
||||
// action1 done
|
||||
|
||||
long current = System.currentTimeMillis();
|
||||
long lastModified = targetManagement.findTargetByControllerID("4712").getLastModifiedAt();
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/deploymentBase/" + action1.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.deploymentActionFeedback(action1.getId().toString(), "closed"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
myT = targetManagement.findTargetByControllerIDWithDetails("4712");
|
||||
assertThat(myT.getTargetInfo().getLastTargetQuery()).isLessThanOrEqualTo(System.currentTimeMillis());
|
||||
assertThat(myT.getTargetInfo().getLastTargetQuery()).isGreaterThanOrEqualTo(current);
|
||||
// assertThat( myT.getLastModifiedAt() ).isEqualTo( lastModified );
|
||||
|
||||
final long timeDiff = Math
|
||||
.abs(myT.getTargetInfo().getLastTargetQuery() - myT.getTargetInfo().getInstallationDate());
|
||||
|
||||
assertThat(myT.getTargetInfo().getUpdateStatus()).isEqualTo(TargetUpdateStatus.PENDING);
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(myT)).hasSize(2);
|
||||
assertThat(myT.getTargetInfo().getInstalledDistributionSet().getId()).isEqualTo(ds1.getId());
|
||||
assertThat(myT.getAssignedDistributionSet()).isEqualTo(ds3);
|
||||
|
||||
Iterable<ActionStatus> actionStatusMessages = actionStatusRepository.findAll(new Sort(Direction.DESC, "id"));
|
||||
assertThat(actionStatusMessages).hasSize(4);
|
||||
assertThat(actionStatusMessages.iterator().next().getStatus()).isEqualTo(Status.FINISHED);
|
||||
|
||||
// action2 done
|
||||
current = System.currentTimeMillis();
|
||||
lastModified = targetManagement.findTargetByControllerID("4712").getLastModifiedAt();
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/deploymentBase/" + action2.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.deploymentActionFeedback(action2.getId().toString(), "closed"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
myT = targetManagement.findTargetByControllerIDWithDetails("4712");
|
||||
assertThat(myT.getTargetInfo().getLastTargetQuery()).isLessThanOrEqualTo(System.currentTimeMillis());
|
||||
assertThat(myT.getTargetInfo().getLastTargetQuery()).isGreaterThanOrEqualTo(current);
|
||||
|
||||
assertThat(myT.getTargetInfo().getUpdateStatus()).isEqualTo(TargetUpdateStatus.PENDING);
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(myT)).hasSize(1);
|
||||
assertThat(myT.getTargetInfo().getInstalledDistributionSet().getId()).isEqualTo(ds2.getId());
|
||||
assertThat(myT.getAssignedDistributionSet()).isEqualTo(ds3);
|
||||
actionStatusMessages = actionStatusRepository.findAll(new PageRequest(0, 100, Direction.DESC, "id"));
|
||||
assertThat(actionStatusMessages).hasSize(5);
|
||||
assertThat(actionStatusMessages).haveAtLeast(1, new ActionStatusCondition(Status.FINISHED));
|
||||
|
||||
// action3 done
|
||||
current = System.currentTimeMillis();
|
||||
lastModified = targetManagement.findTargetByControllerID("4712").getLastModifiedAt();
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/deploymentBase/" + action3.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.deploymentActionFeedback(action3.getId().toString(), "closed"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
myT = targetManagement.findTargetByControllerID("4712");
|
||||
assertThat(myT.getTargetInfo().getLastTargetQuery()).isLessThanOrEqualTo(System.currentTimeMillis());
|
||||
assertThat(myT.getTargetInfo().getLastTargetQuery()).isGreaterThanOrEqualTo(current);
|
||||
assertThat(myT.getTargetInfo().getUpdateStatus()).isEqualTo(TargetUpdateStatus.IN_SYNC);
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(myT)).hasSize(0);
|
||||
assertThat(myT.getTargetInfo().getInstalledDistributionSet()).isEqualTo(ds3);
|
||||
assertThat(myT.getAssignedDistributionSet()).isEqualTo(ds3);
|
||||
actionStatusMessages = actionStatusRepository.findAll();
|
||||
assertThat(actionStatusMessages).hasSize(6);
|
||||
assertThat(actionStatusMessages).haveAtLeast(1, new ActionStatusCondition(Status.FINISHED));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verfies that an update action is correctly set to error if the controller provides error feedback.")
|
||||
public void rootRsSingleDeplomentActionWithErrorFeedback() throws Exception {
|
||||
final Target target = new Target("4712");
|
||||
DistributionSet ds = TestDataUtil.generateDistributionSet("", softwareManagement, distributionSetManagement);
|
||||
|
||||
final Target savedTarget = targetManagement.createTarget(target);
|
||||
|
||||
List<Target> toAssign = new ArrayList<Target>();
|
||||
toAssign.add(savedTarget);
|
||||
|
||||
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getUpdateStatus())
|
||||
.isEqualTo(TargetUpdateStatus.UNKNOWN);
|
||||
deploymentManagement.assignDistributionSet(ds, toAssign);
|
||||
final Action action = actionRepository.findByDistributionSet(pageReq, ds).getContent().get(0);
|
||||
|
||||
long current = System.currentTimeMillis();
|
||||
long lastModified = targetManagement.findTargetByControllerID("4712").getLastModifiedAt();
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/deploymentBase/" + action.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.deploymentActionFeedback(action.getId().toString(), "closed", "failure",
|
||||
"error message"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
Target myT = targetManagement.findTargetByControllerID("4712");
|
||||
assertThat(myT.getTargetInfo().getLastTargetQuery()).isLessThanOrEqualTo(System.currentTimeMillis());
|
||||
assertThat(myT.getTargetInfo().getLastTargetQuery()).isGreaterThanOrEqualTo(current);
|
||||
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getUpdateStatus())
|
||||
.isEqualTo(TargetUpdateStatus.ERROR);
|
||||
assertThat(targetManagement.findTargetByUpdateStatus(new PageRequest(0, 10), TargetUpdateStatus.PENDING))
|
||||
.hasSize(0);
|
||||
assertThat(targetManagement.findTargetByUpdateStatus(new PageRequest(0, 10), TargetUpdateStatus.ERROR))
|
||||
.hasSize(1);
|
||||
assertThat(targetManagement.findTargetByUpdateStatus(new PageRequest(0, 10), TargetUpdateStatus.IN_SYNC))
|
||||
.hasSize(0);
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(myT)).hasSize(0);
|
||||
assertThat(deploymentManagement.findActionsByTarget(myT)).hasSize(1);
|
||||
final Iterable<ActionStatus> actionStatusMessages = actionStatusRepository.findAll();
|
||||
assertThat(actionStatusMessages).hasSize(2);
|
||||
assertThat(actionStatusMessages).haveAtLeast(1, new ActionStatusCondition(Status.ERROR));
|
||||
|
||||
// redo
|
||||
toAssign = new ArrayList<Target>();
|
||||
toAssign.add(targetManagement.findTargetByControllerID("4712"));
|
||||
ds = distributionSetManagement.findDistributionSetByIdWithDetails(ds.getId());
|
||||
deploymentManagement.assignDistributionSet(ds, toAssign);
|
||||
final Action action2 = deploymentManagement.findActiveActionsByTarget(myT).get(0);
|
||||
current = System.currentTimeMillis();
|
||||
lastModified = targetManagement.findTargetByControllerID("4712").getLastModifiedAt();
|
||||
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/deploymentBase/" + action2.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.deploymentActionFeedback(action2.getId().toString(), "closed", "success"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
|
||||
myT = targetManagement.findTargetByControllerID("4712");
|
||||
assertThat(myT.getTargetInfo().getLastTargetQuery()).isLessThanOrEqualTo(System.currentTimeMillis());
|
||||
assertThat(myT.getTargetInfo().getLastTargetQuery()).isGreaterThanOrEqualTo(current);
|
||||
assertThat(myT.getTargetInfo().getUpdateStatus()).isEqualTo(TargetUpdateStatus.IN_SYNC);
|
||||
assertThat(targetManagement.findTargetByUpdateStatus(new PageRequest(0, 10), TargetUpdateStatus.PENDING))
|
||||
.hasSize(0);
|
||||
assertThat(targetManagement.findTargetByUpdateStatus(new PageRequest(0, 10), TargetUpdateStatus.ERROR))
|
||||
.hasSize(0);
|
||||
assertThat(targetManagement.findTargetByUpdateStatus(new PageRequest(0, 10), TargetUpdateStatus.IN_SYNC))
|
||||
.hasSize(1);
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(myT)).hasSize(0);
|
||||
assertThat(deploymentManagement.findInActiveActionsByTarget(myT)).hasSize(2);
|
||||
assertThat(actionStatusRepository.findAll()).hasSize(4);
|
||||
assertThat(actionStatusRepository.findByAction(pageReq, action).getContent()).haveAtLeast(1,
|
||||
new ActionStatusCondition(Status.ERROR));
|
||||
assertThat(actionStatusRepository.findByAction(pageReq, action2).getContent()).haveAtLeast(1,
|
||||
new ActionStatusCondition(Status.FINISHED));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verfies that the controller can provided as much feedback entries as necessry as long as it is in the configured limites.")
|
||||
public void rootRsSingleDeplomentActionFeedback() throws Exception {
|
||||
final Target target = new Target("4712");
|
||||
final DistributionSet ds = TestDataUtil.generateDistributionSet("", softwareManagement,
|
||||
distributionSetManagement);
|
||||
|
||||
final Target savedTarget = targetManagement.createTarget(target);
|
||||
|
||||
final List<Target> toAssign = new ArrayList<Target>();
|
||||
toAssign.add(savedTarget);
|
||||
|
||||
Target myT = targetManagement.findTargetByControllerID("4712");
|
||||
assertThat(myT.getTargetInfo().getUpdateStatus()).isEqualTo(TargetUpdateStatus.UNKNOWN);
|
||||
deploymentManagement.assignDistributionSet(ds, toAssign);
|
||||
final Action action = actionRepository.findByDistributionSet(pageReq, ds).getContent().get(0);
|
||||
|
||||
myT = targetManagement.findTargetByControllerID("4712");
|
||||
assertThat(myT.getTargetInfo().getUpdateStatus()).isEqualTo(TargetUpdateStatus.PENDING);
|
||||
assertThat(targetRepository.findByTargetInfoInstalledDistributionSet(new PageRequest(0, 10), ds)).hasSize(0);
|
||||
assertThat(targetRepository.findByAssignedDistributionSet(new PageRequest(0, 10), ds)).hasSize(1);
|
||||
assertThat(targetRepository
|
||||
.findByAssignedDistributionSetOrTargetInfoInstalledDistributionSet(new PageRequest(0, 10), ds, ds))
|
||||
.hasSize(1);
|
||||
|
||||
// Now valid Feedback
|
||||
|
||||
long current = System.currentTimeMillis();
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/deploymentBase/" + action.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.deploymentActionFeedback(action.getId().toString(), "proceeding"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
}
|
||||
|
||||
myT = targetManagement.findTargetByControllerID("4712");
|
||||
assertThat(myT.getTargetInfo().getLastTargetQuery()).isGreaterThanOrEqualTo(current);
|
||||
assertThat(myT.getTargetInfo().getUpdateStatus()).isEqualTo(TargetUpdateStatus.PENDING);
|
||||
assertThat(targetManagement.findTargetByUpdateStatus(new PageRequest(0, 10), TargetUpdateStatus.PENDING))
|
||||
.hasSize(1);
|
||||
assertThat(targetManagement.findTargetByUpdateStatus(new PageRequest(0, 10), TargetUpdateStatus.ERROR))
|
||||
.hasSize(0);
|
||||
assertThat(targetManagement.findTargetByUpdateStatus(new PageRequest(0, 10), TargetUpdateStatus.IN_SYNC))
|
||||
.hasSize(0);
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(myT)).hasSize(1);
|
||||
assertThat(actionStatusRepository.findAll()).hasSize(5);
|
||||
assertThat(actionStatusRepository.findAll()).haveAtLeast(5, new ActionStatusCondition(Status.RUNNING));
|
||||
|
||||
current = System.currentTimeMillis();
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/deploymentBase/" + action.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.deploymentActionFeedback(action.getId().toString(), "scheduled"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
myT = targetManagement.findTargetByControllerID("4712");
|
||||
assertThat(myT.getTargetInfo().getLastTargetQuery()).isGreaterThanOrEqualTo(current);
|
||||
assertThat(myT.getTargetInfo().getUpdateStatus()).isEqualTo(TargetUpdateStatus.PENDING);
|
||||
assertThat(targetManagement.findTargetByUpdateStatus(new PageRequest(0, 10), TargetUpdateStatus.PENDING))
|
||||
.hasSize(1);
|
||||
assertThat(targetManagement.findTargetByUpdateStatus(new PageRequest(0, 10), TargetUpdateStatus.ERROR))
|
||||
.hasSize(0);
|
||||
assertThat(targetManagement.findTargetByUpdateStatus(new PageRequest(0, 10), TargetUpdateStatus.IN_SYNC))
|
||||
.hasSize(0);
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(myT)).hasSize(1);
|
||||
assertThat(actionStatusRepository.findAll()).hasSize(6);
|
||||
assertThat(actionStatusRepository.findAll()).haveAtLeast(5, new ActionStatusCondition(Status.RUNNING));
|
||||
|
||||
current = System.currentTimeMillis();
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/deploymentBase/" + action.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.deploymentActionFeedback(action.getId().toString(), "resumed"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
myT = targetManagement.findTargetByControllerID("4712");
|
||||
assertThat(myT.getTargetInfo().getLastTargetQuery()).isGreaterThanOrEqualTo(current);
|
||||
assertThat(myT.getTargetInfo().getUpdateStatus()).isEqualTo(TargetUpdateStatus.PENDING);
|
||||
assertThat(targetManagement.findTargetByUpdateStatus(new PageRequest(0, 10), TargetUpdateStatus.PENDING))
|
||||
.hasSize(1);
|
||||
assertThat(targetManagement.findTargetByUpdateStatus(new PageRequest(0, 10), TargetUpdateStatus.ERROR))
|
||||
.hasSize(0);
|
||||
assertThat(targetManagement.findTargetByUpdateStatus(new PageRequest(0, 10), TargetUpdateStatus.IN_SYNC))
|
||||
.hasSize(0);
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(myT)).hasSize(1);
|
||||
assertThat(actionStatusRepository.findAll()).hasSize(7);
|
||||
assertThat(actionStatusRepository.findAll()).haveAtLeast(6, new ActionStatusCondition(Status.RUNNING));
|
||||
|
||||
current = System.currentTimeMillis();
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/deploymentBase/" + action.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.deploymentActionFeedback(action.getId().toString(), "canceled"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
myT = targetManagement.findTargetByControllerID("4712");
|
||||
assertThat(myT.getTargetInfo().getLastTargetQuery()).isGreaterThanOrEqualTo(current);
|
||||
assertThat(myT.getTargetInfo().getUpdateStatus()).isEqualTo(TargetUpdateStatus.PENDING);
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(myT)).hasSize(1);
|
||||
assertThat(targetManagement.findTargetByUpdateStatus(new PageRequest(0, 10), TargetUpdateStatus.PENDING))
|
||||
.hasSize(1);
|
||||
assertThat(targetManagement.findTargetByUpdateStatus(new PageRequest(0, 10), TargetUpdateStatus.ERROR))
|
||||
.hasSize(0);
|
||||
assertThat(targetManagement.findTargetByUpdateStatus(new PageRequest(0, 10), TargetUpdateStatus.IN_SYNC))
|
||||
.hasSize(0);
|
||||
|
||||
assertThat(actionStatusRepository.findAll()).hasSize(8);
|
||||
assertThat(actionStatusRepository.findAll()).haveAtLeast(7, new ActionStatusCondition(Status.RUNNING));
|
||||
assertThat(actionStatusRepository.findAll()).haveAtLeast(1, new ActionStatusCondition(Status.CANCELED));
|
||||
|
||||
current = System.currentTimeMillis();
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/deploymentBase/" + action.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.deploymentActionFeedback(action.getId().toString(), "rejected"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
myT = targetManagement.findTargetByControllerID("4712");
|
||||
assertThat(myT.getTargetInfo().getLastTargetQuery()).isGreaterThanOrEqualTo(current);
|
||||
assertThat(myT.getTargetInfo().getUpdateStatus()).isEqualTo(TargetUpdateStatus.PENDING);
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(myT)).hasSize(1);
|
||||
assertThat(actionStatusRepository.findAll()).hasSize(9);
|
||||
assertThat(actionStatusRepository.findAll()).haveAtLeast(6, new ActionStatusCondition(Status.RUNNING));
|
||||
assertThat(actionStatusRepository.findAll()).haveAtLeast(1, new ActionStatusCondition(Status.WARNING));
|
||||
assertThat(actionStatusRepository.findAll()).haveAtLeast(1, new ActionStatusCondition(Status.CANCELED));
|
||||
|
||||
current = System.currentTimeMillis();
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/deploymentBase/" + action.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.deploymentActionFeedback(action.getId().toString(), "closed"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
myT = targetManagement.findTargetByControllerID("4712");
|
||||
assertThat(myT.getTargetInfo().getLastTargetQuery()).isGreaterThanOrEqualTo(current);
|
||||
assertThat(myT.getTargetInfo().getUpdateStatus()).isEqualTo(TargetUpdateStatus.IN_SYNC);
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(myT)).hasSize(0);
|
||||
assertThat(targetManagement.findTargetByUpdateStatus(new PageRequest(0, 10), TargetUpdateStatus.ERROR))
|
||||
.hasSize(0);
|
||||
assertThat(targetManagement.findTargetByUpdateStatus(new PageRequest(0, 10), TargetUpdateStatus.IN_SYNC))
|
||||
.hasSize(1);
|
||||
|
||||
assertThat(actionStatusRepository.findAll()).hasSize(10);
|
||||
assertThat(actionStatusRepository.findAll()).haveAtLeast(7, new ActionStatusCondition(Status.RUNNING));
|
||||
assertThat(actionStatusRepository.findAll()).haveAtLeast(1, new ActionStatusCondition(Status.WARNING));
|
||||
assertThat(actionStatusRepository.findAll()).haveAtLeast(1, new ActionStatusCondition(Status.CANCELED));
|
||||
assertThat(actionStatusRepository.findAll()).haveAtLeast(1, new ActionStatusCondition(Status.FINISHED));
|
||||
|
||||
assertThat(targetRepository.findByTargetInfoInstalledDistributionSet(new PageRequest(0, 10), ds)).hasSize(1);
|
||||
assertThat(targetRepository.findByAssignedDistributionSet(new PageRequest(0, 10), ds)).hasSize(1);
|
||||
assertThat(targetRepository
|
||||
.findByAssignedDistributionSetOrTargetInfoInstalledDistributionSet(new PageRequest(0, 10), ds, ds))
|
||||
.hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Various forbidden request appempts on the feedback resource. Ensures correct answering behaviour as expected to these kind of errors.")
|
||||
public void badDeplomentActionFeedback() throws Exception {
|
||||
final Target target = new Target("4712");
|
||||
final Target target2 = new Target("4713");
|
||||
final DistributionSet savedSet = TestDataUtil.generateDistributionSet("", softwareManagement,
|
||||
distributionSetManagement);
|
||||
final DistributionSet savedSet2 = TestDataUtil.generateDistributionSet("1", softwareManagement,
|
||||
distributionSetManagement);
|
||||
|
||||
// target does not exist
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/deploymentBase/1234/feedback", tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.deploymentActionInProgressFeedback("1234")).contentType(MediaType.APPLICATION_JSON)
|
||||
.accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isNotFound());
|
||||
|
||||
Target savedTarget = targetManagement.createTarget(target);
|
||||
final Target savedTarget2 = targetManagement.createTarget(target2);
|
||||
|
||||
// Action does not exists
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/deploymentBase/1234/feedback", tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.deploymentActionInProgressFeedback("1234")).contentType(MediaType.APPLICATION_JSON)
|
||||
.accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isNotFound());
|
||||
|
||||
final List<Target> toAssign = new ArrayList<Target>();
|
||||
toAssign.add(savedTarget);
|
||||
final List<Target> toAssign2 = new ArrayList<Target>();
|
||||
toAssign2.add(savedTarget2);
|
||||
|
||||
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getUpdateStatus())
|
||||
.isEqualTo(TargetUpdateStatus.UNKNOWN);
|
||||
savedTarget = deploymentManagement.assignDistributionSet(savedSet, toAssign).getAssignedEntity().iterator()
|
||||
.next();
|
||||
deploymentManagement.assignDistributionSet(savedSet2, toAssign2);
|
||||
|
||||
// wrong format
|
||||
mvc.perform(post("/{tenant}/controller/v1/4712/deploymentBase/AAAA/feedback", tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.deploymentActionInProgressFeedback("AAAA")).contentType(MediaType.APPLICATION_JSON)
|
||||
.accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isBadRequest());
|
||||
|
||||
final Action updateAction = deploymentManagement.findActiveActionsByTarget(savedTarget).get(0);
|
||||
|
||||
// action exists but is not assigned to this target
|
||||
mvc.perform(post("/{tenant}/controller/v1/4713/deploymentBase/" + updateAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.deploymentActionInProgressFeedback(updateAction.getId().toString()))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound());
|
||||
|
||||
// not allowed methods
|
||||
mvc.perform(get("/{tenant}/controller/v1/4712/deploymentBase/2/feedback", tenantAware.getCurrentTenant()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isMethodNotAllowed());
|
||||
|
||||
mvc.perform(put("/{tenant}/controller/v1/4712/deploymentBase/2/feedback", tenantAware.getCurrentTenant()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isMethodNotAllowed());
|
||||
|
||||
mvc.perform(delete("/{tenant}/controller/v1/4712/deploymentBase/2/feedback", tenantAware.getCurrentTenant()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isMethodNotAllowed());
|
||||
|
||||
}
|
||||
|
||||
private class ActionStatusCondition extends Condition<ActionStatus> {
|
||||
private final Status status;
|
||||
|
||||
/**
|
||||
* @param status
|
||||
*/
|
||||
public ActionStatusCondition(final Status status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(final ActionStatus actionStatus) {
|
||||
return actionStatus.getStatus() == status;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,294 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations 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.resource;
|
||||
|
||||
import static org.fest.assertions.api.Assertions.assertThat;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
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.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.hawkbit.AbstractIntegrationTestWithMongoDB;
|
||||
import org.eclipse.hawkbit.MockMvcResultPrinter;
|
||||
import org.eclipse.hawkbit.TestDataUtil;
|
||||
import org.eclipse.hawkbit.WithSpringAuthorityRule;
|
||||
import org.eclipse.hawkbit.WithUser;
|
||||
import org.eclipse.hawkbit.im.authentication.SpPermission;
|
||||
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||
import org.eclipse.hawkbit.rest.resource.JsonBuilder;
|
||||
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
|
||||
import org.eclipse.hawkbit.util.IpUtil;
|
||||
import org.junit.Test;
|
||||
import org.springframework.hateoas.MediaTypes;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
|
||||
import ru.yandex.qatools.allure.annotations.Description;
|
||||
import ru.yandex.qatools.allure.annotations.Features;
|
||||
import ru.yandex.qatools.allure.annotations.Stories;
|
||||
|
||||
@ActiveProfiles({ "im", "test" })
|
||||
@Features("Component Tests - Direct Device Integration API")
|
||||
@Stories("Root Poll Resource")
|
||||
public class RootControllerTest extends AbstractIntegrationTestWithMongoDB {
|
||||
|
||||
@Test
|
||||
@Description("Ensures that targets cannot be created e.g. in plug'n play scenarios when tenant does not exists but can be created if the tenant exists.")
|
||||
@WithUser(tenantId = "tenantDoesNotExists", allSpPermissions = true, authorities = "ROLE_CONTROLLER", autoCreateTenant = false)
|
||||
public void targetCannotBeRegisteredIfTenantDoesNotExistsButWhenExists() throws Exception {
|
||||
|
||||
mvc.perform(get("/default-tenant/", tenantAware.getCurrentTenant())).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isNotFound());
|
||||
|
||||
// create tenant
|
||||
systemManagement.getTenantMetadata("tenantDoesNotExists");
|
||||
|
||||
mvc.perform(get("/{}/controller/v1/aControllerId", tenantAware.getCurrentTenant()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
|
||||
// delete tenant again
|
||||
systemManagement.deleteTenant("tenantDoesNotExists");
|
||||
|
||||
mvc.perform(get("/{}/controller/v1/aControllerId", tenantAware.getCurrentTenant()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Ensures that target poll request does not change audit data on the entity.")
|
||||
@WithUser(principal = "knownPrincipal", authorities = { SpPermission.READ_TARGET, SpPermission.UPDATE_TARGET,
|
||||
SpPermission.CREATE_TARGET }, allSpPermissions = false)
|
||||
public void targetPollDoesNotModifyAuditData() throws Exception {
|
||||
// create target first with "knownPrincipal" user and audit data
|
||||
final String knownTargetControllerId = "target1";
|
||||
final String knownCreatedBy = "knownPrincipal";
|
||||
targetManagement.createTarget(new Target(knownTargetControllerId));
|
||||
final Target findTargetByControllerID = targetManagement.findTargetByControllerID(knownTargetControllerId);
|
||||
assertThat(findTargetByControllerID.getCreatedBy()).isEqualTo(knownCreatedBy);
|
||||
assertThat(findTargetByControllerID.getCreatedAt()).isNotNull();
|
||||
|
||||
// make a poll, audit information should not be changed, run as
|
||||
// controller principal!
|
||||
securityRule.runAs(
|
||||
WithSpringAuthorityRule.withUser("controller", SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS), () -> {
|
||||
mvc.perform(
|
||||
get("/{tenant}/controller/v1/" + knownTargetControllerId, tenantAware.getCurrentTenant()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
return null;
|
||||
});
|
||||
|
||||
// verify that audit information has not changed
|
||||
final Target targetVerify = targetManagement.findTargetByControllerID(knownTargetControllerId);
|
||||
assertThat(targetVerify.getCreatedBy()).isEqualTo(findTargetByControllerID.getCreatedBy());
|
||||
assertThat(targetVerify.getCreatedAt()).isEqualTo(findTargetByControllerID.getCreatedAt());
|
||||
assertThat(targetVerify.getLastModifiedBy()).isEqualTo(findTargetByControllerID.getLastModifiedBy());
|
||||
assertThat(targetVerify.getLastModifiedAt()).isEqualTo(findTargetByControllerID.getLastModifiedAt());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Ensures that server returns a not found response in case of empty controlloer ID.")
|
||||
public void rootRsWithoutId() throws Exception {
|
||||
mvc.perform(get("/controller/v1/")).andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Ensures that the system creates a new target in plug and play manner, i.e. target is authenticated but does not exist yet.")
|
||||
public void rootRsPlugAndPlay() throws Exception {
|
||||
|
||||
final long current = System.currentTimeMillis();
|
||||
mvc.perform(get("/default-tenant/controller/v1/4711")).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk()).andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||
.andExpect(jsonPath("$config.polling.sleep", equalTo("00:01:00")));
|
||||
assertThat(targetManagement.findTargetByControllerID("4711").getTargetInfo().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
|
||||
assertThat(targetRepository.findByControllerId("4711").getTargetInfo().getUpdateStatus())
|
||||
.isEqualTo(TargetUpdateStatus.REGISTERED);
|
||||
|
||||
// not allowed methods
|
||||
mvc.perform(post("/default-tenant/controller/v1/4711")).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isMethodNotAllowed());
|
||||
|
||||
mvc.perform(put("/default-tenant/controller/v1/4711")).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isMethodNotAllowed());
|
||||
|
||||
mvc.perform(delete("/default-tenant/controller/v1/4711")).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isMethodNotAllowed());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Ensures that tenant specific polling time, which is saved in the db, is delivered to the controller.")
|
||||
@WithUser(principal = "knownpricipal", allSpPermissions = false)
|
||||
public void pollWithModifiedGloablPollingTime() throws Exception {
|
||||
securityRule.runAs(
|
||||
WithSpringAuthorityRule.withUser("tenantadmin", SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION),
|
||||
() -> {
|
||||
tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.POLLING_TIME_INTERVAL,
|
||||
"00:02:00");
|
||||
return null;
|
||||
});
|
||||
|
||||
securityRule.runAs(
|
||||
WithSpringAuthorityRule.withUser("controller", SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS), () -> {
|
||||
mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||
.andExpect(jsonPath("$config.polling.sleep", equalTo("00:02:00")));
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Ensures that etag check results in not modified response if provided etag by client is identical to entity in repository.")
|
||||
public void rootRsNotModified() throws Exception {
|
||||
final String etag = mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||
.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))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isNotModified());
|
||||
|
||||
final Target target = targetRepository.findByControllerId("4711");
|
||||
final DistributionSet ds = TestDataUtil.generateDistributionSet("", softwareManagement,
|
||||
distributionSetManagement);
|
||||
|
||||
deploymentManagement.assignDistributionSet(ds.getId(), new String[] { "4711" });
|
||||
|
||||
final Action updateAction = deploymentManagement.findActiveActionsByTarget(target).get(0);
|
||||
final String etagWithFirstUpdate = mvc
|
||||
.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant())
|
||||
.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",
|
||||
startsWith("http://localhost/" + tenantAware.getCurrentTenant()
|
||||
+ "/controller/v1/4711/deploymentBase/" + updateAction.getId())))
|
||||
.andReturn().getResponse().getHeader("ETag");
|
||||
|
||||
assertThat(etagWithFirstUpdate).isNotNull();
|
||||
|
||||
mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant()).header("If-None-Match",
|
||||
etagWithFirstUpdate)).andDo(MockMvcResultPrinter.print()).andExpect(status().isNotModified());
|
||||
|
||||
// now lets finish the update
|
||||
mvc.perform(post("/{tenant}/controller/v1/4711/deploymentBase/" + updateAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.deploymentActionFeedback(updateAction.getId().toString(), "closed"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.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());
|
||||
|
||||
// Now another deployment
|
||||
final DistributionSet ds2 = TestDataUtil.generateDistributionSet("2", softwareManagement,
|
||||
distributionSetManagement);
|
||||
|
||||
deploymentManagement.assignDistributionSet(ds2.getId(), new String[] { "4711" });
|
||||
|
||||
final Action updateAction2 = deploymentManagement.findActiveActionsByTarget(target).get(0);
|
||||
|
||||
mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant())
|
||||
.header("If-None-Match", etagWithFirstUpdate).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",
|
||||
startsWith("http://localhost/" + tenantAware.getCurrentTenant()
|
||||
+ "/controller/v1/4711/deploymentBase/" + updateAction2.getId())))
|
||||
.andReturn().getResponse().getHeader("ETag");
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Ensures that the target state machine of a precomissioned target switches from "
|
||||
+ "UNKNOWN to REGISTERED when the target polls for the first time.")
|
||||
public void rootRsPrecommissioned() throws Exception {
|
||||
final Target target = new Target("4711");
|
||||
targetManagement.createTarget(target);
|
||||
|
||||
assertThat(targetRepository.findByControllerId("4711").getTargetInfo().getUpdateStatus())
|
||||
.isEqualTo(TargetUpdateStatus.UNKNOWN);
|
||||
|
||||
final long current = System.currentTimeMillis();
|
||||
mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||
.andExpect(jsonPath("$config.polling.sleep", equalTo("00:01:00")));
|
||||
assertThat(targetManagement.findTargetByControllerID("4711").getTargetInfo().getLastTargetQuery())
|
||||
.isLessThanOrEqualTo(System.currentTimeMillis());
|
||||
assertThat(targetManagement.findTargetByControllerID("4711").getTargetInfo().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
|
||||
assertThat(targetRepository.findByControllerId("4711").getTargetInfo().getUpdateStatus())
|
||||
.isEqualTo(TargetUpdateStatus.REGISTERED);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Ensures that the source IP address of the polling target is correctly stored in repository")
|
||||
public void rootRsPlugAndPlayIpAddress() throws Exception {
|
||||
// test
|
||||
final String knownControllerId1 = "0815";
|
||||
mvc.perform(get("/{tenant}/controller/v1/{controllerId}", tenantAware.getCurrentTenant(), knownControllerId1))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
|
||||
// verify
|
||||
final Target target = targetManagement.findTargetByControllerID(knownControllerId1);
|
||||
assertThat(target.getTargetInfo().getAddress()).isEqualTo(IpUtil.createHttpUri("127.0.0.1"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Controller trys to finish an update process after it has been finished by an error action status.")
|
||||
public void tryToFinishAnUpdateProcessAfterItHasBeenFinished() throws Exception {
|
||||
|
||||
// mock
|
||||
final Target target = new Target("911");
|
||||
final DistributionSet ds = TestDataUtil.generateDistributionSet("", softwareManagement,
|
||||
distributionSetManagement);
|
||||
Target savedTarget = targetManagement.createTarget(target);
|
||||
final List<Target> toAssign = new ArrayList<Target>();
|
||||
toAssign.add(savedTarget);
|
||||
savedTarget = deploymentManagement.assignDistributionSet(ds, toAssign).getAssignedEntity().iterator().next();
|
||||
final Action savedAction = deploymentManagement.findActiveActionsByTarget(savedTarget).get(0);
|
||||
mvc.perform(post("/{tenant}/controller/v1/911/deploymentBase/" + savedAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant())
|
||||
.content(JsonBuilder.deploymentActionFeedback(savedAction.getId().toString(), "proceeding"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
|
||||
mvc.perform(post("/{tenant}/controller/v1/911/deploymentBase/" + savedAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant()).content(
|
||||
JsonBuilder.deploymentActionFeedback(savedAction.getId().toString(), "closed", "failure"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
|
||||
mvc.perform(post("/{tenant}/controller/v1/911/deploymentBase/" + savedAction.getId() + "/feedback",
|
||||
tenantAware.getCurrentTenant()).content(
|
||||
JsonBuilder.deploymentActionFeedback(savedAction.getId().toString(), "closed", "success"))
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isGone());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user