Protection against misuse with system-wide quota definitions (#670)

* Added quota for meta data per software module

Signed-off-by: stefbehl <stefan.behl@bosch-si.com>

* Added unit test for "meta data per module" quota

Signed-off-by: stefbehl <stefan.behl@bosch-si.com>

* quota test enhancements

Signed-off-by: stefbehl <stefan.behl@bosch-si.com>

* Verify enforcement of meta data quota via REST

Signed-off-by: stefbehl <stefan.behl@bosch-si.com>

* Quota for distribution set meta data

Signed-off-by: stefbehl <stefan.behl@bosch-si.com>

* Verify enforcement of distribution set meta data quota via REST

Signed-off-by: stefbehl <stefan.behl@bosch-si.com>

* software modules per distribution set quota

Signed-off-by: stefbehl <stefan.behl@bosch-si.com>

* Integration test enhancements for Modules per DistSet quota

Signed-off-by: stefbehl <stefan.behl@bosch-si.com>

* Quota for software module types per distribution set type

Signed-off-by: stefbehl <stefan.behl@bosch-si.com>

* Quota for max artifacts per software module

Signed-off-by: stefbehl <stefan.behl@bosch-si.com>

* Quotas for ActionStatus per Action and Messages per ActionStatus

Signed-off-by: stefbehl <stefan.behl@bosch-si.com>

* Quota attributes per target

Signed-off-by: stefbehl <stefan.behl@bosch-si.com>

* Quota targets per rollout group

Signed-off-by: stefbehl <stefan.behl@bosch-si.com>

* Quota max targets per rollout group

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max targets per rollout group

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max targets per rollout group

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max targets per rollout group

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max targets per group

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* quota max actions per target

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max targets per rollout group

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max actions per target

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max actions per target

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max targets per auto assignment

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max targets per manual assignment

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max targets per auto assignment

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max targets per auto assign

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max targets per auto assignment

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max actions per target

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max targets per manual assignment

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix issues caused by merge

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix failing tests

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix failing tests

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Improve JavaDoc

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix failing tests

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix Sonar issues

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix Sonar findings

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max artifact size

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Optimize quota configuration

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix test failures

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix failing tests

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Improve test coverage

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max rollout groups per rollout

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix failing tests

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Configure Rollout UI enhancements

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* UI enhancements

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Minor changes

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max targets per group

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max targets per group

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* fix failing tests

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix failing tests

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix Sonar findings

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix Sonar findings

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix failing tests

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix failing tests

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix Sonar finding

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix code review findings

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix review findings

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* New approach for 'max artifact size' enforcement

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix failing tests

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix failing tests

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix failing tests

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix Sonar findings

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix failing tests

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Reduce max artifact size for tests

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix Kai's review findings

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>
This commit is contained in:
Stefan Behl
2018-05-02 12:09:29 +02:00
committed by Kai Zimmermann
parent fcc15a0484
commit 6dd98d2134
63 changed files with 2383 additions and 523 deletions

View File

@@ -46,11 +46,13 @@ final class MgmtRestModelMapper {
}
/**
* Convert a action rest type to a action repository type.
* Convert the given {@link MgmtActionType} into a corresponding repository
* {@link ActionType}.
*
* @param actionTypeRest
* the rest type
* @return <null> or the action repository type
* the REST representation of the action type
*
* @return <null> or the repository action type
*/
public static ActionType convertActionType(final MgmtActionType actionTypeRest) {
if (actionTypeRest == null) {
@@ -70,11 +72,13 @@ final class MgmtRestModelMapper {
}
/**
* Convert a action repository type to rest type.
* Converts the given repository {@link ActionType} into a corresponding
* {@link MgmtActionType}.
*
* @param actionType
* the rest type
* @return <null> or the action repository type
* the repository representation of the action type
*
* @return <null> or the REST action type
*/
public static MgmtActionType convertActionType(final ActionType actionType) {
if (actionType == null) {

View File

@@ -83,7 +83,7 @@ public class MgmtSoftwareModuleResource implements MgmtSoftwareModuleRestApi {
try (InputStream in = file.getInputStream()) {
final Artifact result = artifactManagement.create(in, softwareModuleId, fileName,
md5Sum == null ? null : md5Sum.toLowerCase(), sha1Sum == null ? null : sha1Sum.toLowerCase(), false,
file.getContentType());
file.getContentType(), file.getSize());
final MgmtArtifact reponse = MgmtSoftwareModuleMapper.toResponse(result);
MgmtSoftwareModuleMapper.addLinks(result, reponse);

View File

@@ -27,9 +27,12 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.stream.IntStream;
import org.apache.commons.lang3.RandomStringUtils;
import org.eclipse.hawkbit.exception.SpServerError;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
import org.eclipse.hawkbit.repository.exception.QuotaExceededException;
import org.eclipse.hawkbit.repository.model.Action.Status;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
@@ -44,9 +47,11 @@ import org.eclipse.hawkbit.rest.util.MockMvcResultPrinter;
import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.Test;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MvcResult;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.jayway.jsonpath.JsonPath;
@@ -179,6 +184,45 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + disSet.getId() + "/assignedSM"))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
.andExpect(jsonPath("$.size", equalTo(smIDs.size())));
// verify quota enforcement
final int maxSoftwareModules = quotaManagement.getMaxSoftwareModulesPerDistributionSet();
final List<Long> moduleIDs = Lists.newArrayList();
for (int i = 0; i < maxSoftwareModules + 1; ++i) {
moduleIDs.add(testdataFactory.createSoftwareModuleApp("sm" + i).getId());
}
// post assignment
final String jsonIDs = JsonBuilder.ids(moduleIDs.subList(0, maxSoftwareModules - smIDs.size()));
mvc.perform(post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + disSet.getId() + "/assignedSM")
.contentType(MediaType.APPLICATION_JSON).content(jsonIDs)).andDo(MockMvcResultPrinter.print())
.andExpect(status().isOk());
// test if size corresponds with quota
mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + disSet.getId()
+ "/assignedSM?limit={limit}", maxSoftwareModules * 2)).andDo(MockMvcResultPrinter.print())
.andExpect(status().isOk()).andExpect(jsonPath("$.size", equalTo(maxSoftwareModules)));
// post one more to cause the quota to be exceeded
mvc.perform(post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + disSet.getId() + "/assignedSM")
.contentType(MediaType.APPLICATION_JSON)
.content(JsonBuilder.ids(Collections.singletonList(moduleIDs.get(moduleIDs.size() - 1)))))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isForbidden())
.andExpect(jsonPath("$.exceptionClass", equalTo(QuotaExceededException.class.getName())))
.andExpect(jsonPath("$.errorCode", equalTo(SpServerError.SP_QUOTA_EXCEEDED.getKey())));
// verify quota is also enforced for bulk uploads
final DistributionSet disSet2 = testdataFactory.createDistributionSetWithNoSoftwareModules("Saturn", "4.0");
mvc.perform(post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + disSet2.getId() + "/assignedSM")
.contentType(MediaType.APPLICATION_JSON).content(JsonBuilder.ids(moduleIDs)))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isForbidden())
.andExpect(jsonPath("$.exceptionClass", equalTo(QuotaExceededException.class.getName())))
.andExpect(jsonPath("$.errorCode", equalTo(SpServerError.SP_QUOTA_EXCEEDED.getKey())));
// verify size is still 0
mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + disSet2.getId() + "/assignedSM"))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
.andExpect(jsonPath("$.size", equalTo(0)));
}
@Test
@@ -229,6 +273,48 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
.as("Five targets in repository have DS assigned").hasSize(5);
}
@Test
@Description("Ensures that multi target assignment is protected by our 'max targets per manual assignment' quota.")
public void assignMultipleTargetsToDistributionSetUntilQuotaIsExceeded() throws Exception {
final int maxTargets = quotaManagement.getMaxTargetsPerManualAssignment();
final List<Target> targets = testdataFactory.createTargets(maxTargets + 1);
final DistributionSet ds = testdataFactory.createDistributionSet();
final JSONArray payload = new JSONArray();
targets.forEach(trg -> payload.put(new JSONObject().put("id", trg.getId())));
mvc.perform(post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + ds.getId() + "/assignedTargets")
.contentType(MediaType.APPLICATION_JSON).content(payload.toString())).andExpect(status().isForbidden());
assertThat(targetManagement.findByAssignedDistributionSet(PAGE, ds.getId()).getContent()).isEmpty();
}
@Test
@Description("Ensures that the 'max actions per target' quota is enforced if the distribution set assignment of a target is changed permanently")
public void changeDistributionSetAssignmentForTargetUntilQuotaIsExceeded() throws Exception {
// create one target
final Target testTarget = testdataFactory.createTarget("trg1");
final int maxActions = quotaManagement.getMaxActionsPerTarget();
// create a set of distribution sets
final DistributionSet ds1 = testdataFactory.createDistributionSet("ds1");
final DistributionSet ds2 = testdataFactory.createDistributionSet("ds2");
final DistributionSet ds3 = testdataFactory.createDistributionSet("ds3");
IntStream.range(0, maxActions).forEach(i -> {
// toggle the distribution set
assignDistributionSet(i % 2 == 0 ? ds1 : ds2, testTarget);
});
// assign our test target to another distribution set and verify that
// the 'max actions per target' quota is exceeded
final String json = new JSONArray().put(new JSONObject().put("id", testTarget.getControllerId())).toString();
mvc.perform(post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + ds3.getId() + "/assignedTargets")
.contentType(MediaType.APPLICATION_JSON).content(json)).andExpect(status().isForbidden());
}
@Test
@Description("Ensures that offline reported multi target assignment through API is reflected by the repository.")
public void offlineAssignmentOfMultipleTargetsToDistributionSet() throws Exception {
@@ -433,14 +519,13 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
final Set<DistributionSet> createDistributionSetsAlphabetical = createDistributionSetsAlphabetical(1);
final DistributionSet createdDs = createDistributionSetsAlphabetical.iterator().next();
targetFilterQueryManagement.updateAutoAssignDS(
targetFilterQueryManagement
.create(entityFactory.targetFilterQuery().create().name(knownFilterName).query("x==y")).getId(),
targetFilterQueryManagement.updateAutoAssignDS(targetFilterQueryManagement
.create(entityFactory.targetFilterQuery().create().name(knownFilterName).query("name==y")).getId(),
createdDs.getId());
// create some dummy target filter queries
targetFilterQueryManagement.create(entityFactory.targetFilterQuery().create().name("b").query("x==y"));
targetFilterQueryManagement.create(entityFactory.targetFilterQuery().create().name("c").query("x==y"));
targetFilterQueryManagement.create(entityFactory.targetFilterQuery().create().name("b").query("name==y"));
targetFilterQueryManagement.create(entityFactory.targetFilterQuery().create().name("c").query("name==y"));
mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + createdDs.getId()
+ "/autoAssignTargetFilters")).andExpect(status().isOk()).andExpect(jsonPath("$.size", equalTo(1)))
@@ -495,16 +580,16 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
private void prepareTestFilters(final String filterNamePrefix, final DistributionSet createdDs) {
// create target filter queries that should be found
targetFilterQueryManagement.updateAutoAssignDS(targetFilterQueryManagement
.create(entityFactory.targetFilterQuery().create().name(filterNamePrefix + "1").query("x==y")).getId(),
createdDs.getId());
.create(entityFactory.targetFilterQuery().create().name(filterNamePrefix + "1").query("name==y"))
.getId(), createdDs.getId());
targetFilterQueryManagement.updateAutoAssignDS(targetFilterQueryManagement
.create(entityFactory.targetFilterQuery().create().name(filterNamePrefix + "2").query("x==y")).getId(),
createdDs.getId());
.create(entityFactory.targetFilterQuery().create().name(filterNamePrefix + "2").query("name==y"))
.getId(), createdDs.getId());
// create some dummy target filter queries
targetFilterQueryManagement
.create(entityFactory.targetFilterQuery().create().name(filterNamePrefix + "b").query("x==y"));
.create(entityFactory.targetFilterQuery().create().name(filterNamePrefix + "b").query("name==y"));
targetFilterQueryManagement
.create(entityFactory.targetFilterQuery().create().name(filterNamePrefix + "c").query("x==y"));
.create(entityFactory.targetFilterQuery().create().name(filterNamePrefix + "c").query("name==y"));
}
@Test
@@ -902,12 +987,12 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
final String knownValue1 = "knownValue1";
final String knownValue2 = "knownValue2";
final JSONArray jsonArray = new JSONArray();
jsonArray.put(new JSONObject().put("key", knownKey1).put("value", knownValue1));
jsonArray.put(new JSONObject().put("key", knownKey2).put("value", knownValue2));
final JSONArray metaData1 = new JSONArray();
metaData1.put(new JSONObject().put("key", knownKey1).put("value", knownValue1));
metaData1.put(new JSONObject().put("key", knownKey2).put("value", knownValue2));
mvc.perform(post("/rest/v1/distributionsets/{dsId}/metadata", testDS.getId()).accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON).content(jsonArray.toString()))
.contentType(MediaType.APPLICATION_JSON).content(metaData1.toString()))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
.andExpect(jsonPath("[0]key", equalTo(knownKey1))).andExpect(jsonPath("[0]value", equalTo(knownValue1)))
@@ -921,6 +1006,25 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
assertThat(metaKey1.getValue()).isEqualTo(knownValue1);
assertThat(metaKey2.getValue()).isEqualTo(knownValue2);
// verify quota enforcement
final int maxMetaData = quotaManagement.getMaxMetaDataEntriesPerDistributionSet();
final JSONArray metaData2 = new JSONArray();
for (int i = 0; i < maxMetaData - metaData1.length() + 1; ++i) {
metaData2.put(new JSONObject().put("key", knownKey1 + i).put("value", knownValue1 + i));
}
mvc.perform(post("/rest/v1/distributionsets/{dsId}/metadata", testDS.getId()).accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON).content(metaData2.toString()))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isForbidden());
// verify that the number of meta data entries has not changed
// (we cannot use the PAGE constant here as it tries to sort by ID)
assertThat(distributionSetManagement
.findMetaDataByDistributionSetId(new PageRequest(0, Integer.MAX_VALUE), testDS.getId())
.getTotalElements()).isEqualTo(metaData1.length());
}
@Test

View File

@@ -27,7 +27,11 @@ import java.util.Collections;
import java.util.List;
import org.apache.commons.lang3.RandomStringUtils;
import org.assertj.core.util.Lists;
import org.eclipse.hawkbit.exception.SpServerError;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleTypeCreate;
import org.eclipse.hawkbit.repository.exception.QuotaExceededException;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.test.util.WithUser;
@@ -239,6 +243,60 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn
}
@Test
@WithUser(principal = "uploadTester", allSpPermissions = true)
@Description("Verifies quota enforcement for /rest/v1/distributionsettypes/{ID}/optionalmoduletypes POST requests.")
public void assignModuleTypesToDistributionSetTypeUntilQuotaExceeded() throws Exception {
// create software module types
final int maxSoftwareModuleTypes = quotaManagement.getMaxSoftwareModuleTypesPerDistributionSetType();
final List<Long> moduleTypeIds = Lists.newArrayList();
for (int i = 0; i < maxSoftwareModuleTypes + 1; ++i) {
final SoftwareModuleTypeCreate smCreate = entityFactory.softwareModuleType().create().name("smType_" + i)
.description("smType_" + i).maxAssignments(1).colour("blue").key("smType_" + i);
moduleTypeIds.add(softwareModuleTypeManagement.create(smCreate).getId());
}
// verify quota enforcement for optional module types
final DistributionSetType testType = distributionSetTypeManagement.create(entityFactory.distributionSetType()
.create().key("testType").name("testType").description("testType").colour("col12"));
assertThat(testType.getOptLockRevision()).isEqualTo(1);
for (int i = 0; i < moduleTypeIds.size() - 1; ++i) {
mvc.perform(post("/rest/v1/distributionsettypes/{dstID}/optionalmoduletypes", testType.getId())
.content("{\"id\":" + moduleTypeIds.get(i) + "}").contentType(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
}
mvc.perform(post("/rest/v1/distributionsettypes/{dstID}/optionalmoduletypes", testType.getId())
.content("{\"id\":" + moduleTypeIds.get(moduleTypeIds.size() - 1) + "}")
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
.andExpect(status().isForbidden())
.andExpect(jsonPath("$.exceptionClass", equalTo(QuotaExceededException.class.getName())))
.andExpect(jsonPath("$.errorCode", equalTo(SpServerError.SP_QUOTA_EXCEEDED.getKey())));
// verify quota enforcement for mandatory module types
final DistributionSetType testType2 = distributionSetTypeManagement.create(entityFactory.distributionSetType()
.create().key("testType2").name("testType2").description("testType2").colour("col12"));
assertThat(testType2.getOptLockRevision()).isEqualTo(1);
for (int i = 0; i < moduleTypeIds.size() - 1; ++i) {
mvc.perform(post("/rest/v1/distributionsettypes/{dstID}/mandatorymoduletypes", testType2.getId())
.content("{\"id\":" + moduleTypeIds.get(i) + "}").contentType(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
}
mvc.perform(post("/rest/v1/distributionsettypes/{dstID}/mandatorymoduletypes", testType2.getId())
.content("{\"id\":" + moduleTypeIds.get(moduleTypeIds.size() - 1) + "}")
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
.andExpect(status().isForbidden())
.andExpect(jsonPath("$.exceptionClass", equalTo(QuotaExceededException.class.getName())))
.andExpect(jsonPath("$.errorCode", equalTo(SpServerError.SP_QUOTA_EXCEEDED.getKey())));
}
@Test
@WithUser(principal = "uploadTester", allSpPermissions = true)
@Description("Checks the correct behaviour of /rest/v1/distributionsettypes/{ID}/mandatorymoduletypes GET requests.")

View File

@@ -27,9 +27,11 @@ import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;
import org.eclipse.hawkbit.exception.SpServerError;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
import org.eclipse.hawkbit.repository.RolloutGroupManagement;
import org.eclipse.hawkbit.repository.RolloutManagement;
import org.eclipse.hawkbit.repository.exception.QuotaExceededException;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus;
@@ -131,9 +133,45 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
postRollout("rollout1", 10, dsA.getId(), "id==target*", 20);
}
@Test
@Description("Verifies that rollout cannot be created if too many rollout groups are specified.")
public void createRolloutWithTooManyRolloutGroups() throws Exception {
final int maxGroups = quotaManagement.getMaxRolloutGroupsPerRollout();
testdataFactory.createTargets(20, "target", "rollout");
mvc.perform(post("/rest/v1/rollouts")
.content(JsonBuilder.rollout("rollout1", "rollout1Desc", maxGroups + 1,
testdataFactory.createDistributionSet("ds").getId(), "id==target*",
new RolloutGroupConditionBuilder().withDefaults().build()))
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isForbidden())
.andExpect(jsonPath("$.exceptionClass", equalTo(QuotaExceededException.class.getName())))
.andExpect(jsonPath("$.errorCode", equalTo(SpServerError.SP_QUOTA_EXCEEDED.getKey())));
}
@Test
@Description("Verifies that rollout cannot be created if the 'max targets per rollout group' quota would be violated for one of the groups.")
public void createRolloutFailsIfRolloutGroupQuotaIsViolated() throws Exception {
final int maxTargets = quotaManagement.getMaxTargetsPerRolloutGroup();
testdataFactory.createTargets(maxTargets + 1, "target", "rollout");
mvc.perform(post("/rest/v1/rollouts")
.content(JsonBuilder.rollout("rollout1", "rollout1Desc", 1,
testdataFactory.createDistributionSet("ds").getId(), "id==target*",
new RolloutGroupConditionBuilder().withDefaults().build()))
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isForbidden())
.andExpect(jsonPath("$.exceptionClass", equalTo(QuotaExceededException.class.getName())))
.andExpect(jsonPath("$.errorCode", equalTo(SpServerError.SP_QUOTA_EXCEEDED.getKey())));
}
@Test
@Description("Testing that rollout can be created with groups")
public void createRolloutWithGroupsDefinitions() throws Exception {
public void createRolloutWithGroupDefinitions() throws Exception {
final DistributionSet dsA = testdataFactory.createDistributionSet("ro");
final int amountTargets = 10;
@@ -160,7 +198,7 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
@Test
@Description("Testing that no rollout with groups that have illegal percentages can be created")
public void createRolloutWithToLowlPercentage() throws Exception {
public void createRolloutWithTooLowPercentage() throws Exception {
final DistributionSet dsA = testdataFactory.createDistributionSet("ro2");
final int amountTargets = 10;
@@ -185,7 +223,7 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
@Test
@Description("Testing that no rollout with groups that have illegal percentages can be created")
public void createRolloutWithToHighPercentage() throws Exception {
public void createRolloutWithTooHighPercentage() throws Exception {
final DistributionSet dsA = testdataFactory.createDistributionSet("ro2");
final int amountTargets = 10;
@@ -217,7 +255,7 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
}
@Test
@Description("Terives sinle rollout from management API includinfg extra data that is delieverd only for single rollout access.")
@Description("Retrieves single rollout from management API including extra data that is delivered only for single rollout access.")
public void retrieveSingleRollout() throws Exception {
testdataFactory.createTargets(20, "rollout", "rollout");
final DistributionSet dsA = testdataFactory.createDistributionSet("");

View File

@@ -29,6 +29,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.RandomStringUtils;
@@ -36,6 +37,7 @@ import org.eclipse.hawkbit.exception.SpServerError;
import org.eclipse.hawkbit.mgmt.json.model.artifact.MgmtArtifact;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
import org.eclipse.hawkbit.repository.Constants;
import org.eclipse.hawkbit.repository.exception.QuotaExceededException;
import org.eclipse.hawkbit.repository.model.Artifact;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
@@ -49,8 +51,10 @@ import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Test;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.web.bind.annotation.RestController;
@@ -66,6 +70,7 @@ import ru.yandex.qatools.allure.annotations.Stories;
*/
@Features("Component Tests - Management API")
@Stories("Software Module Resource")
@TestPropertySource(properties = { "hawkbit.server.security.dos.maxArtifactSize=100000" })
public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTest {
@Before
@@ -147,7 +152,7 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
}
@Test
@Description("Tests the uppload of an artifact binary. The upload is executed and the content checked in the repository for completenes.")
@Description("Tests the upload of an artifact binary. The upload is executed and the content checked in the repository for completeness.")
public void uploadArtifact() throws Exception {
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
@@ -183,6 +188,24 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
assertArtifact(sm, random);
}
@Test
@Description("Verifies that artifacts which exceed the configured maximum size cannot be uploaded.")
public void uploadArtifactFailsIfTooLarge() throws Exception {
final SoftwareModule sm = testdataFactory.createSoftwareModule("quota", "quota");
final long maxSize = quotaManagement.getMaxArtifactSize();
// create a file which exceeds the configured maximum size
final byte[] randomBytes = new byte[Math.toIntExact(maxSize) + 1024];
new Random().nextBytes(randomBytes);
final MockMultipartFile file = new MockMultipartFile("file", "origFilename", null, randomBytes);
// try to upload
mvc.perform(fileUpload("/rest/v1/softwaremodules/{smId}/artifacts", sm.getId()).file(file)
.accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
.andExpect(status().isForbidden());
}
private void assertArtifact(final SoftwareModule sm, final byte[] random) throws IOException {
// check result in db...
// repo
@@ -312,17 +335,57 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
}
@Test
@Description("Verifies that only a limited number of artifacts can be uploaded for one software module.")
public void uploadArtifactsUntilQuotaExceeded() throws Exception {
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
final long maxArtifacts = quotaManagement.getMaxArtifactsPerSoftwareModule();
for (int i = 0; i < maxArtifacts; ++i) {
// create test file
final byte random[] = RandomStringUtils.random(5 * 1024).getBytes();
final String md5sum = HashGeneratorUtils.generateMD5(random);
final String sha1sum = HashGeneratorUtils.generateSHA1(random);
final MockMultipartFile file = new MockMultipartFile("file", "origFilename" + i, null, random);
// upload
mvc.perform(fileUpload("/rest/v1/softwaremodules/{smId}/artifacts", sm.getId()).file(file)
.accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
.andExpect(status().isCreated())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
.andExpect(jsonPath("$.hashes.md5", equalTo(md5sum)))
.andExpect(jsonPath("$.hashes.sha1", equalTo(sha1sum)))
.andExpect(jsonPath("$.size", equalTo(random.length)))
.andExpect(jsonPath("$.providedFilename", equalTo("origFilename" + i))).andReturn();
}
// upload one more file to cause the quota to be exceeded
final byte random[] = RandomStringUtils.random(5 * 1024).getBytes();
HashGeneratorUtils.generateMD5(random);
HashGeneratorUtils.generateSHA1(random);
final MockMultipartFile file = new MockMultipartFile("file", "origFilename_final", null, random);
// upload
mvc.perform(fileUpload("/rest/v1/softwaremodules/{smId}/artifacts", sm.getId()).file(file)
.accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
.andExpect(status().isForbidden())
.andExpect(jsonPath("$.exceptionClass", equalTo(QuotaExceededException.class.getName())))
.andExpect(jsonPath("$.errorCode", equalTo(SpServerError.SP_QUOTA_EXCEEDED.getKey())));
}
@Test
@Description("Tests binary download of an artifact including verfication that the downloaded binary is consistent and that the etag header is as expected identical to the SHA1 hash of the file.")
public void downloadArtifact() throws Exception {
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
final byte random[] = RandomStringUtils.random(5 * 1024).getBytes();
final int artifactSize = 5 * 1024;
final byte random[] = RandomStringUtils.random(artifactSize).getBytes();
final Artifact artifact = artifactManagement.create(new ByteArrayInputStream(random), sm.getId(), "file1",
false);
false, artifactSize);
final Artifact artifact2 = artifactManagement.create(new ByteArrayInputStream(random), sm.getId(), "file2",
false);
false, artifactSize);
downloadAndVerify(sm, random, artifact);
downloadAndVerify(sm, random, artifact2);
@@ -348,9 +411,11 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
// prepare data for test
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
final byte random[] = RandomStringUtils.random(5 * 1024).getBytes();
final int artifactSize = 5 * 1024;
final byte random[] = RandomStringUtils.random(artifactSize).getBytes();
final Artifact artifact = artifactManagement.create(new ByteArrayInputStream(random), sm.getId(), "file1",
false);
false, artifactSize);
// perform test
mvc.perform(get("/rest/v1/softwaremodules/{smId}/artifacts/{artId}", sm.getId(), artifact.getId())
@@ -373,12 +438,13 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
public void getArtifacts() throws Exception {
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
final byte random[] = RandomStringUtils.random(5 * 1024).getBytes();
final int artifactSize = 5 * 1024;
final byte random[] = RandomStringUtils.random(artifactSize).getBytes();
final Artifact artifact = artifactManagement.create(new ByteArrayInputStream(random), sm.getId(), "file1",
false);
false, artifactSize);
final Artifact artifact2 = artifactManagement.create(new ByteArrayInputStream(random), sm.getId(), "file2",
false);
false, artifactSize);
mvc.perform(get("/rest/v1/softwaremodules/{smId}/artifacts", sm.getId()).accept(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
@@ -402,7 +468,9 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
@Test
@Description("Verfies that the system refuses unsupported request types and answers as defined to them, e.g. NOT FOUND on a non existing resource. Or a HTTP POST for updating a resource results in METHOD NOT ALLOWED etc.")
public void invalidRequestsOnArtifactResource() throws Exception {
final byte random[] = RandomStringUtils.random(5 * 1024).getBytes();
final int artifactSize = 5 * 1024;
final byte random[] = RandomStringUtils.random(artifactSize).getBytes();
final MockMultipartFile file = new MockMultipartFile("file", "orig", null, random);
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
@@ -415,7 +483,7 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
.andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound());
// SM does not exist
artifactManagement.create(new ByteArrayInputStream(random), sm.getId(), "file1", false);
artifactManagement.create(new ByteArrayInputStream(random), sm.getId(), "file1", false, artifactSize);
mvc.perform(get("/rest/v1/softwaremodules/1234567890/artifacts")).andDo(MockMvcResultPrinter.print())
.andExpect(status().isNotFound());
@@ -723,9 +791,10 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
final byte random[] = RandomStringUtils.random(5 * 1024).getBytes();
final int artifactSize = 5 * 1024;
final byte random[] = RandomStringUtils.random(artifactSize).getBytes();
artifactManagement.create(new ByteArrayInputStream(random), sm.getId(), "file1", false);
artifactManagement.create(new ByteArrayInputStream(random), sm.getId(), "file1", false, artifactSize);
assertThat(softwareModuleManagement.findAll(PAGE)).as("Softwaremoudle size is wrong").hasSize(1);
assertThat(artifactManagement.count()).isEqualTo(1);
@@ -743,11 +812,12 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
public void deleteAssignedSoftwareModule() throws Exception {
final DistributionSet ds1 = testdataFactory.createDistributionSet("a");
final byte random[] = RandomStringUtils.random(5 * 1024).getBytes();
final int artifactSize = 5 * 1024;
final byte random[] = RandomStringUtils.random(artifactSize).getBytes();
final Long appTypeSmId = ds1.findFirstModuleByType(appType).get().getId();
artifactManagement.create(new ByteArrayInputStream(random), appTypeSmId, "file1", false);
artifactManagement.create(new ByteArrayInputStream(random), appTypeSmId, "file1", false, artifactSize);
assertThat(softwareModuleManagement.count()).isEqualTo(3);
assertThat(artifactManagement.count()).isEqualTo(1);
@@ -771,12 +841,13 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
// Create 1 SM
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
final byte random[] = RandomStringUtils.random(5 * 1024).getBytes();
final int artifactSize = 5 * 1024;
final byte random[] = RandomStringUtils.random(artifactSize).getBytes();
// Create 2 artifacts
final Artifact artifact = artifactManagement.create(new ByteArrayInputStream(random), sm.getId(), "file1",
false);
artifactManagement.create(new ByteArrayInputStream(random), sm.getId(), "file2", false);
false, artifactSize);
artifactManagement.create(new ByteArrayInputStream(random), sm.getId(), "file2", false, artifactSize);
// check repo before delete
assertThat(softwareModuleManagement.findAll(PAGE)).hasSize(1);
@@ -797,7 +868,7 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
}
@Test
@Description("Verfies the successfull creation of metadata.")
@Description("Verfies the successful creation of metadata and the enforcement of the meta data quota.")
public void createMetadata() throws Exception {
final String knownKey1 = "knownKey1";
@@ -807,12 +878,12 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
final SoftwareModule sm = testdataFactory.createSoftwareModuleOs();
final JSONArray jsonArray = new JSONArray();
jsonArray.put(new JSONObject().put("key", knownKey1).put("value", knownValue1));
jsonArray.put(new JSONObject().put("key", knownKey2).put("value", knownValue2).put("targetVisible", true));
final JSONArray metaData1 = new JSONArray();
metaData1.put(new JSONObject().put("key", knownKey1).put("value", knownValue1));
metaData1.put(new JSONObject().put("key", knownKey2).put("value", knownValue2).put("targetVisible", true));
mvc.perform(post("/rest/v1/softwaremodules/{swId}/metadata", sm.getId()).accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON).content(jsonArray.toString()))
.contentType(MediaType.APPLICATION_JSON).content(metaData1.toString()))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
.andExpect(jsonPath("[0]key", equalTo(knownKey1))).andExpect(jsonPath("[0]value", equalTo(knownValue1)))
@@ -827,6 +898,25 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
assertThat(metaKey1.getValue()).as("Metadata key is wrong").isEqualTo(knownValue1);
assertThat(metaKey2.getValue()).as("Metadata key is wrong").isEqualTo(knownValue2);
// verify quota enforcement
final int maxMetaData = quotaManagement.getMaxMetaDataEntriesPerSoftwareModule();
final JSONArray metaData2 = new JSONArray();
for (int i = 0; i < maxMetaData - metaData1.length() + 1; ++i) {
metaData2.put(new JSONObject().put("key", knownKey1 + i).put("value", knownValue1 + i));
}
mvc.perform(post("/rest/v1/softwaremodules/{swId}/metadata", sm.getId()).accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON).content(metaData2.toString()))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isForbidden());
// verify that the number of meta data entries has not changed
// (we cannot use the PAGE constant here as it tries to sort by ID)
assertThat(softwareModuleManagement
.findMetaDataBySoftwareModuleId(new PageRequest(0, Integer.MAX_VALUE), sm.getId()).getTotalElements())
.isEqualTo(metaData1.length());
}
@Test
@@ -930,4 +1020,5 @@ public class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegra
character++;
}
}
}

View File

@@ -21,6 +21,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import org.eclipse.hawkbit.exception.SpServerError;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
import org.eclipse.hawkbit.repository.exception.QuotaExceededException;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
import org.eclipse.hawkbit.rest.exception.MessageNotReadableException;
@@ -53,6 +54,8 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInte
private static final String JSON_PATH_FIELD_SIZE = ".size";
private static final String JSON_PATH_FIELD_TOTAL = ".total";
private static final String JSON_PATH_FIELD_AUTO_ASSIGN_DS = ".autoAssignDistributionSet";
private static final String JSON_PATH_FIELD_EXCEPTION_CLASS = ".exceptionClass";
private static final String JSON_PATH_FIELD_ERROR_CODE = ".errorCode";
// target
// $.field
@@ -64,6 +67,8 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInte
private static final String JSON_PATH_ID = JSON_PATH_ROOT + JSON_PATH_FIELD_ID;
private static final String JSON_PATH_QUERY = JSON_PATH_ROOT + JSON_PATH_FIELD_QUERY;
private static final String JSON_PATH_AUTO_ASSIGN_DS = JSON_PATH_ROOT + JSON_PATH_FIELD_AUTO_ASSIGN_DS;
private static final String JSON_PATH_EXCEPTION_CLASS = JSON_PATH_ROOT + JSON_PATH_FIELD_EXCEPTION_CLASS;
private static final String JSON_PATH_ERROR_CODE = JSON_PATH_ROOT + JSON_PATH_FIELD_ERROR_CODE;
@Test
@Description("Ensures that deletion is executed if permitted.")
@@ -126,8 +131,8 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInte
final String body = new JSONObject().put("name", filterName2).toString();
// prepare
final TargetFilterQuery tfq = targetFilterQueryManagement.create(
entityFactory.targetFilterQuery().create().name(filterName).query(filterQuery));
final TargetFilterQuery tfq = targetFilterQueryManagement
.create(entityFactory.targetFilterQuery().create().name(filterName).query(filterQuery));
mvc.perform(put(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId()).content(body)
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
@@ -230,6 +235,7 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInte
}
@Test
@Description("Ensures that a single target filter query can be retrieved via its id.")
public void getSingleTarget() throws Exception {
// create first a target which can be retrieved by rest interface
final String knownQuery = "name=test01";
@@ -247,6 +253,7 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInte
}
@Test
@Description("Ensures that the retrieval of a non-existing target filter query results in a HTTP Not found error (404).")
public void getSingleTargetNoExistsResponseNotFound() throws Exception {
final String targetIdNotExists = "546546";
// test
@@ -262,6 +269,7 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInte
}
@Test
@Description("Ensures that the creation of a target filter query based on an invalid request payload results in a HTTP Bad Request error (400).")
public void createTargetFilterQueryWithBadPayloadBadRequest() throws Exception {
final String notJson = "abc";
@@ -279,22 +287,72 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInte
assertThat(exceptionInfo.getErrorCode()).isEqualTo(SpServerError.SP_REST_BODY_NOT_READABLE.getKey());
}
@Test
@Description("Ensures that the assignment of an auto-assign distribution set results in a HTTP Forbidden error (403) "
+ "if the (existing) query addresses too many targets.")
public void setAutoAssignDistributionSetOnFilterQueryThatExceedsQuota() throws Exception {
// create targets
final int maxTargets = quotaManagement.getMaxTargetsPerAutoAssignment();
testdataFactory.createTargets(maxTargets + 1, "target%s");
// create the filter query and the distribution set
final DistributionSet set = testdataFactory.createDistributionSet();
final TargetFilterQuery filterQuery = createSingleTargetFilterQuery("1", "controllerId==target*");
mvc.perform(
post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + filterQuery.getId() + "/autoAssignDS")
.content("{\"id\":" + set.getId() + "}").contentType(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isForbidden())
.andExpect(jsonPath(JSON_PATH_EXCEPTION_CLASS, equalTo(QuotaExceededException.class.getName())))
.andExpect(jsonPath(JSON_PATH_ERROR_CODE, equalTo(SpServerError.SP_QUOTA_EXCEEDED.getKey())));
}
@Test
@Description("Ensures that the update of a target filter query results in a HTTP Forbidden error (403) "
+ "if the updated query addresses too many targets.")
public void updateTargetFilterQueryWithQueryThatExceedsQuota() throws Exception {
// create targets
final int maxTargets = quotaManagement.getMaxTargetsPerAutoAssignment();
testdataFactory.createTargets(maxTargets + 1, "target%s");
// create the filter query and the distribution set
final DistributionSet set = testdataFactory.createDistributionSet();
final TargetFilterQuery filterQuery = createSingleTargetFilterQuery("1", "controllerId==target1");
// assign the auto-assign distribution set, this should work
mvc.perform(
post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + filterQuery.getId() + "/autoAssignDS")
.content("{\"id\":" + set.getId() + "}").contentType(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
assertThat(targetFilterQueryManagement.get(filterQuery.getId()).get().getAutoAssignDistributionSet())
.isEqualTo(set);
// update the query of the filter query to trigger a quota hit
mvc.perform(put(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + filterQuery.getId())
.content("{\"query\":\"controllerId==target*\"}").contentType(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isForbidden())
.andExpect(jsonPath(JSON_PATH_EXCEPTION_CLASS, equalTo(QuotaExceededException.class.getName())))
.andExpect(jsonPath(JSON_PATH_ERROR_CODE, equalTo(SpServerError.SP_QUOTA_EXCEEDED.getKey())));
}
@Test
public void setAutoAssignDistributionSetToTargetFilterQuery() throws Exception {
final String knownQuery = "name=test05";
final String knownQuery = "name==test05";
final String knownName = "filter05";
final DistributionSet set = testdataFactory.createDistributionSet("one");
final DistributionSet set = testdataFactory.createDistributionSet();
final TargetFilterQuery tfq = createSingleTargetFilterQuery(knownName, knownQuery);
mvc.perform(post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId() + "/autoAssignDS")
.content("{\"id\":" + set.getId() + "}").contentType(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
assertThat(
targetFilterQueryManagement.get(tfq.getId()).get().getAutoAssignDistributionSet())
.isEqualTo(set);
assertThat(targetFilterQueryManagement.get(tfq.getId()).get().getAutoAssignDistributionSet()).isEqualTo(set);
final String hrefPrefix = "http://localhost" + MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/"
+ tfq.getId();
@@ -311,7 +369,7 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInte
@Test
public void deleteAutoAssignDistributionSetOfTargetFilterQuery() throws Exception {
final String knownQuery = "name=test06";
final String knownQuery = "name==test06";
final String knownName = "filter06";
final String dsName = "testDS";
@@ -319,9 +377,7 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInte
final TargetFilterQuery tfq = createSingleTargetFilterQuery(knownName, knownQuery);
targetFilterQueryManagement.updateAutoAssignDS(tfq.getId(), set.getId());
assertThat(
targetFilterQueryManagement.get(tfq.getId()).get().getAutoAssignDistributionSet())
.isEqualTo(set);
assertThat(targetFilterQueryManagement.get(tfq.getId()).get().getAutoAssignDistributionSet()).isEqualTo(set);
mvc.perform(get(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId() + "/autoAssignDS"))
.andExpect(status().isOk()).andExpect(jsonPath(JSON_PATH_NAME, equalTo(dsName)));
@@ -329,9 +385,7 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInte
mvc.perform(delete(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId() + "/autoAssignDS"))
.andExpect(status().isNoContent());
assertThat(
targetFilterQueryManagement.get(tfq.getId()).get().getAutoAssignDistributionSet())
.isNull();
assertThat(targetFilterQueryManagement.get(tfq.getId()).get().getAutoAssignDistributionSet()).isNull();
mvc.perform(get(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId() + "/autoAssignDS"))
.andExpect(status().isNoContent());
@@ -339,8 +393,7 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInte
}
private TargetFilterQuery createSingleTargetFilterQuery(final String name, final String query) {
return targetFilterQueryManagement
.create(entityFactory.targetFilterQuery().create().name(name).query(query));
return targetFilterQueryManagement.create(entityFactory.targetFilterQuery().create().name(name).query(query));
}
}