From 0e631e0f3bc93a6d02d2f99dcb8e427cc6044dae Mon Sep 17 00:00:00 2001 From: Vasil Ilchev Date: Tue, 24 Oct 2023 11:02:36 +0300 Subject: [PATCH] =?UTF-8?q?REST=20API=20extend=20System=20Configuration=20?= =?UTF-8?q?to=20support=20Default=20DistributionS=E2=80=A6=20(#1457)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * REST API extend System Configuration to support Default DistributionSet Type * Remove leftover comment * After review - changing the Default DistributionSetType type to long * After review - Remove CustomMatcher for Numbers equals, rename test methods to more descriptive naming * Simplify --- .../resource/MgmtTenantManagementMapper.java | 30 +-- .../MgmtTenantManagementResource.java | 112 +++++++++-- .../MgmtTenantManagementResourceTest.java | 189 ++++++++++++++++-- 3 files changed, 272 insertions(+), 59 deletions(-) diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementMapper.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementMapper.java index 68a7c9798..eb91d1789 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementMapper.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementMapper.java @@ -11,49 +11,39 @@ package org.eclipse.hawkbit.mgmt.rest.resource; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; - -import java.util.Map; -import java.util.stream.Collectors; - import org.eclipse.hawkbit.mgmt.json.model.system.MgmtSystemTenantConfigurationValue; -import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; -import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties; -import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey; /** * A mapper which maps repository model to RESTful model representation and * back. */ public final class MgmtTenantManagementMapper { + public static String DEFAULT_DISTRIBUTION_SET_TYPE_KEY = "default.ds.type"; private MgmtTenantManagementMapper() { // Utility class } - static Map toResponse( - final TenantConfigurationManagement tenantConfigurationManagement, - final TenantConfigurationProperties tenantConfigurationProperties) { - - return tenantConfigurationProperties.getConfigurationKeys().stream() - .collect(Collectors.toMap(TenantConfigurationKey::getKeyName, key -> toResponse(key.getKeyName(), - tenantConfigurationManagement.getConfigurationValue(key.getKeyName())))); - } - - static MgmtSystemTenantConfigurationValue toResponse(final String key, - final TenantConfigurationValue repoConfValue) { + public static MgmtSystemTenantConfigurationValue toResponseTenantConfigurationValue(String key, TenantConfigurationValue repoConfValue) { final MgmtSystemTenantConfigurationValue restConfValue = new MgmtSystemTenantConfigurationValue(); - restConfValue.setValue(repoConfValue.getValue()); restConfValue.setGlobal(repoConfValue.isGlobal()); restConfValue.setCreatedAt(repoConfValue.getCreatedAt()); restConfValue.setCreatedBy(repoConfValue.getCreatedBy()); restConfValue.setLastModifiedAt(repoConfValue.getLastModifiedAt()); restConfValue.setLastModifiedBy(repoConfValue.getLastModifiedBy()); - restConfValue.add(linkTo(methodOn(MgmtTenantManagementResource.class).getTenantConfigurationValue(key)) .withSelfRel().expand()); + return restConfValue; + } + public static MgmtSystemTenantConfigurationValue toResponseDefaultDsType(Long defaultDistributionSetType) { + final MgmtSystemTenantConfigurationValue restConfValue = new MgmtSystemTenantConfigurationValue(); + restConfValue.setValue(defaultDistributionSetType); + restConfValue.setGlobal(Boolean.FALSE); + restConfValue.add(linkTo(methodOn(MgmtTenantManagementResource.class).getTenantConfigurationValue(DEFAULT_DISTRIBUTION_SET_TYPE_KEY)) + .withSelfRel().expand()); return restConfValue; } } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResource.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResource.java index 8092117c1..9f96e205e 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResource.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResource.java @@ -13,13 +13,16 @@ import java.io.Serializable; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.stream.Collectors; import org.eclipse.hawkbit.mgmt.json.model.system.MgmtSystemTenantConfigurationValue; import org.eclipse.hawkbit.mgmt.json.model.system.MgmtSystemTenantConfigurationValueRequest; import org.eclipse.hawkbit.mgmt.rest.api.MgmtTenantManagementRestApi; +import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties; +import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationValidatorException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; @@ -38,45 +41,77 @@ public class MgmtTenantManagementResource implements MgmtTenantManagementRestApi private final TenantConfigurationManagement tenantConfigurationManagement; private final TenantConfigurationProperties tenantConfigurationProperties; + private final SystemManagement systemManagement; MgmtTenantManagementResource(final TenantConfigurationManagement tenantConfigurationManagement, - final TenantConfigurationProperties tenantConfigurationProperties) { + final TenantConfigurationProperties tenantConfigurationProperties, + final SystemManagement systemManagement) { this.tenantConfigurationManagement = tenantConfigurationManagement; this.tenantConfigurationProperties = tenantConfigurationProperties; + this.systemManagement = systemManagement; } @Override public ResponseEntity> getTenantConfiguration() { - return ResponseEntity.ok( - MgmtTenantManagementMapper.toResponse(tenantConfigurationManagement, tenantConfigurationProperties)); + //Load and Construct default Tenant Configuration + Map tenantConfigurationValueMap = tenantConfigurationProperties.getConfigurationKeys().stream().collect( + Collectors.toMap(TenantConfigurationProperties.TenantConfigurationKey::getKeyName, + key -> loadTenantConfigurationValueBy(key.getKeyName()))); + //Load and Add Default DistributionSetType + MgmtSystemTenantConfigurationValue defaultDsTypeId = loadTenantConfigurationValueBy(MgmtTenantManagementMapper.DEFAULT_DISTRIBUTION_SET_TYPE_KEY); + tenantConfigurationValueMap.put(MgmtTenantManagementMapper.DEFAULT_DISTRIBUTION_SET_TYPE_KEY, defaultDsTypeId); + //return combined TenantConfiguration and TenantMetadata + LOG.debug("getTenantConfiguration, return status {}", HttpStatus.OK); + return ResponseEntity.ok(tenantConfigurationValueMap); + } + + @Override + public ResponseEntity getTenantConfigurationValue( + @PathVariable("keyName") final String keyName) { + return ResponseEntity.ok(loadTenantConfigurationValueBy(keyName)); + } + + private MgmtSystemTenantConfigurationValue loadTenantConfigurationValueBy(String keyName) { + + //Check if requested key is TenantConfiguration or TenantMetadata, load it and return it as rest response + MgmtSystemTenantConfigurationValue response; + if (isDefaultDistributionSetTypeKey(keyName)) { + response = MgmtTenantManagementMapper.toResponseDefaultDsType(systemManagement.getTenantMetadata().getDefaultDsType().getId()); + } else { + response = MgmtTenantManagementMapper.toResponseTenantConfigurationValue(keyName, tenantConfigurationManagement.getConfigurationValue(keyName)); + } + return response; } @Override public ResponseEntity deleteTenantConfigurationValue(@PathVariable("keyName") final String keyName) { + //Default DistributionSet Type cannot be deleted as is part of TenantMetadata + if (isDefaultDistributionSetTypeKey(keyName)) { + return ResponseEntity.badRequest().build(); + } + tenantConfigurationManagement.deleteConfiguration(keyName); LOG.debug("{} config value deleted, return status {}", keyName, HttpStatus.OK); return ResponseEntity.ok().build(); } - @Override - public ResponseEntity getTenantConfigurationValue( - @PathVariable("keyName") final String keyName) { - - LOG.debug("{} config value getted, return status {}", keyName, HttpStatus.OK); - return ResponseEntity.ok(MgmtTenantManagementMapper.toResponse(keyName, - tenantConfigurationManagement.getConfigurationValue(keyName))); - } - @Override public ResponseEntity updateTenantConfigurationValue( @PathVariable("keyName") final String keyName, @RequestBody final MgmtSystemTenantConfigurationValueRequest configurationValueRest) { - - final TenantConfigurationValue updatedValue = tenantConfigurationManagement + Serializable configurationValue = configurationValueRest.getValue(); + final MgmtSystemTenantConfigurationValue responseUpdatedValue; + if (isDefaultDistributionSetTypeKey(keyName)) { + responseUpdatedValue = updateDefaultDsType(configurationValue); + } else { + final TenantConfigurationValue updatedTenantConfigurationValue = tenantConfigurationManagement .addOrUpdateConfiguration(keyName, configurationValueRest.getValue()); - return ResponseEntity.ok(MgmtTenantManagementMapper.toResponse(keyName, updatedValue)); + responseUpdatedValue = MgmtTenantManagementMapper.toResponseTenantConfigurationValue(keyName, updatedTenantConfigurationValue); + } + + return ResponseEntity.ok(responseUpdatedValue); } @Override @@ -90,11 +125,50 @@ public class MgmtTenantManagementResource implements MgmtTenantManagementRestApi return ResponseEntity.badRequest().build(); } - Map> tenantConfigurationValues = tenantConfigurationManagement - .addOrUpdateConfiguration(configurationValueMap); + //Try update TenantMetadata first + Serializable defaultDsTypeValueUpdate = configurationValueMap.remove(MgmtTenantManagementMapper.DEFAULT_DISTRIBUTION_SET_TYPE_KEY); + Long oldDefaultDsType = null; + MgmtSystemTenantConfigurationValue updatedDefaultDsType = null; + if (defaultDsTypeValueUpdate != null) { + oldDefaultDsType = systemManagement.getTenantMetadata().getDefaultDsType().getId(); + updatedDefaultDsType = updateDefaultDsType(defaultDsTypeValueUpdate); + } + //try update TenantConfiguration, in case of Error -> rollback TenantMetadata + Map> tenantConfigurationValues; + try { + tenantConfigurationValues = tenantConfigurationManagement.addOrUpdateConfiguration(configurationValueMap); + } catch (Exception ex) { + //if DefaultDsType was updated, rollback it in case of TenantConfiguration update. + if (updatedDefaultDsType != null) { + systemManagement.updateTenantMetadata(oldDefaultDsType); + } + throw ex; + } - return ResponseEntity.ok(tenantConfigurationValues.entrySet().stream().map(entry -> - MgmtTenantManagementMapper.toResponse(entry.getKey(), entry.getValue())).toList()); + List tenantConfigurationListUpdated = new java.util.ArrayList<>(tenantConfigurationValues.entrySet().stream() + .map(entry -> MgmtTenantManagementMapper.toResponseTenantConfigurationValue(entry.getKey(), entry.getValue())).toList()); + if (updatedDefaultDsType != null) { + tenantConfigurationListUpdated.add(updatedDefaultDsType); + } + + + return ResponseEntity.ok(tenantConfigurationListUpdated); + } + private MgmtSystemTenantConfigurationValue updateDefaultDsType(Serializable defaultDsType) { + long updateDefaultDsType; + try { + updateDefaultDsType = ((Number) defaultDsType).longValue(); + } catch (ClassCastException cce) { + throw new TenantConfigurationValidatorException(String.format( + "Default DistributionSetType Value Type is incorrect. Expected Long, received %s", defaultDsType.getClass().getName())); + } + systemManagement.updateTenantMetadata(updateDefaultDsType); + return MgmtTenantManagementMapper.toResponseDefaultDsType(updateDefaultDsType); } + private static boolean isDefaultDistributionSetTypeKey(String keyName) { + return MgmtTenantManagementMapper.DEFAULT_DISTRIBUTION_SET_TYPE_KEY.equals(keyName); + } + + } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResourceTest.java b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResourceTest.java index c691540a8..20d8cb170 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResourceTest.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResourceTest.java @@ -9,14 +9,18 @@ */ package org.eclipse.hawkbit.mgmt.rest.resource; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.jupiter.api.Assertions.assertEquals; 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.put; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import com.fasterxml.jackson.databind.ObjectMapper; import org.eclipse.hawkbit.mgmt.json.model.system.MgmtSystemTenantConfigurationValueRequest; import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants; +import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.rest.util.MockMvcResultPrinter; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties; import org.json.JSONObject; @@ -26,6 +30,7 @@ import org.springframework.http.MediaType; import io.qameta.allure.Description; import io.qameta.allure.Feature; import io.qameta.allure.Story; +import org.springframework.test.web.servlet.ResultMatcher; /** * Spring MVC Tests against the MgmtTenantManagementResource. @@ -43,24 +48,41 @@ public class MgmtTenantManagementResourceTest extends AbstractManagementApiInteg private static final String AUTHENTICATION_GATEWAYTOKEN_ENABLED = "authentication.gatewaytoken.enabled"; private static final String AUTHENTICATION_GATEWAYTOKEN_KEY = "authentication.gatewaytoken.key"; + private static final String DEFAULT_DISTRIBUTION_SET_TYPE_KEY = "default.ds.type"; @Test @Description("Handles GET request for receiving all tenant specific configurations.") public void getTenantConfigurations() throws Exception { mvc.perform(get(MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs/")) .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()); + .andExpect(status().isOk()) + //check for TenantMetadata additional properties + .andExpect(jsonPath("$.['" + DEFAULT_DISTRIBUTION_SET_TYPE_KEY + "']").exists()) + .andExpect(jsonPath("$.['" + DEFAULT_DISTRIBUTION_SET_TYPE_KEY + "'].value", equalTo(getActualDefaultDsType().intValue()))); + } @Test @Description("Handles GET request for receiving a tenant specific configuration.") public void getTenantConfiguration() throws Exception { + //Test TenantConfiguration property mvc.perform(get(MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs/{keyName}/", TenantConfigurationProperties.TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY)) .andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()); } + @Test + @Description("Handles GET request for receiving (TenantMetadata - DefaultDsType) a tenant specific configuration.") + public void getTenantMetadata() throws Exception { + //Test TenantMetadata property + mvc.perform(get(MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs/{keyName}/", + DEFAULT_DISTRIBUTION_SET_TYPE_KEY)) + .andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.value", equalTo(getActualDefaultDsType().intValue()))); + } + @Test @Description("Handles PUT request for settings values in tenant specific configuration.") public void putTenantConfiguration() throws Exception { @@ -76,6 +98,59 @@ public class MgmtTenantManagementResourceTest extends AbstractManagementApiInteg .andExpect(status().isOk()); } + @Test + @Description("Handles PUT request for settings values (TenantMetadata - DefaultDsType) in tenant specific configuration, which is TenantMetadata") + public void putTenantMetadata() throws Exception { + final MgmtSystemTenantConfigurationValueRequest bodyPut = new MgmtSystemTenantConfigurationValueRequest(); + + long updatedTestDefaultDsType = createTestDistributionSetType(); + bodyPut.setValue(updatedTestDefaultDsType); + + final ObjectMapper mapper = new ObjectMapper(); + final String json = mapper.writeValueAsString(bodyPut); + + mvc.perform(put(MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs/{keyName}/", + DEFAULT_DISTRIBUTION_SET_TYPE_KEY).content(json) + .contentType(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()); + + //check if after Rest success, value is really changed in TenantMetadata + assertEquals(updatedTestDefaultDsType, getActualDefaultDsType(), "Rest endpoint for updating the Default DistributionSetType completed successfully, but the actual value was not changed."); + } + + private Long createTestDistributionSetType() { + DistributionSetType testDefaultDsType = distributionSetTypeManagement.create(entityFactory.distributionSetType().create() + .key("test123").name("TestName123").description("TestDefaultDsType")); + testDefaultDsType = distributionSetTypeManagement + .update(entityFactory.distributionSetType().update(testDefaultDsType.getId()).description("TestDefaultDsType")); + return testDefaultDsType.getId(); + } + + @Test + @Description("Update DefaultDistributionSetType Fails if given DistributionSetType ID does not exist.") + public void putTenantMetadataFails() throws Exception{ + long oldDefaultDsType = getActualDefaultDsType(); + //try an invalid input + String newDefaultDsType = new JSONObject().put("value", true).toString(); + assertDefaultDsTypeUpdateBadRequestFails(newDefaultDsType, oldDefaultDsType, status().isBadRequest()); + //try an invalid input + newDefaultDsType = new JSONObject().put("value", "someInvalidInput").toString(); + assertDefaultDsTypeUpdateBadRequestFails(newDefaultDsType, oldDefaultDsType, status().isBadRequest()); + //try valid input, but the given DistributionSetType Id does not exist.. + newDefaultDsType = new JSONObject().put("value", 99999).toString(); + assertDefaultDsTypeUpdateBadRequestFails(newDefaultDsType, oldDefaultDsType, status().isNotFound()); + } + + private void assertDefaultDsTypeUpdateBadRequestFails(String newDefaultDsType, long oldDefaultDsType, ResultMatcher resultMatchers) throws Exception { + mvc.perform(put(MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs/{keyName}/", + DEFAULT_DISTRIBUTION_SET_TYPE_KEY).content(newDefaultDsType) + .contentType(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultPrinter.print()) + .andExpect(resultMatchers); + assertEquals(oldDefaultDsType, getActualDefaultDsType(), "Rest endpoint for updating DefaultDistributionType failed, but actual value changed unexpectedly."); + } + @Test @Description("The 'multi.assignments.enabled' property must not be changed to false.") public void deactivateMultiAssignment() throws Exception { @@ -92,33 +167,93 @@ public class MgmtTenantManagementResourceTest extends AbstractManagementApiInteg } @Test - @Description("The Batch configuration should be applied") - public void changeBatchConfiguration() throws Exception { - JSONObject configuration = new JSONObject(); - configuration.put(ROLLOUT_APPROVAL_ENABLED, true); - configuration.put(AUTHENTICATION_GATEWAYTOKEN_ENABLED, true); - configuration.put(AUTHENTICATION_GATEWAYTOKEN_KEY, "1234"); - - String body = configuration.toString(); - - mvc.perform(put(MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs") - .content(body).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()); + @Description("The Batch configuration should not be applied, because of invalid TenantConfiguration props") + public void changeBatchConfigurationShouldFailOnInvalidTenantConfiguration() throws Exception { + //in this scenario + // some TenantConfiguration are not valid, + // TenantMetadata - DefaultDSType ID is valid, + //in the end batch configuration update must fail, and thus, not a single config should be actually changed + long testValidDistributionSetType = createTestDistributionSetType(); + boolean oldRolloutApprovalConfig = (Boolean) tenantConfigurationManagement.getConfigurationValue(ROLLOUT_APPROVAL_ENABLED).getValue(); + String oldAuthGatewayToken = (String) tenantConfigurationManagement.getConfigurationValue(AUTHENTICATION_GATEWAYTOKEN_KEY).getValue(); + //test TenantConfiguration with invalid config value, and a valid TenantMetadata - Default DistributionSetType id + assertBatchConfigurationFails(!oldRolloutApprovalConfig, "invalid-config-value", oldAuthGatewayToken + "randomSuffix0", testValidDistributionSetType, status().isBadRequest()); } @Test - @Description("The Batch configuration should not be applied") - public void changeBatchConfigurationFail() throws Exception { + @Description("The Batch configuration should not be applied, because of invalid TenantMetadata (DefaultDistributionSetType)") + public void changeBatchConfigurationShouldOnInvalidTenantMetadata() throws Exception { + //in this scenario + // all TenantConfiguration have valid and new values - using old values, inverted + // TenantMetadata - DefaultDSType ID is invalid + //in the end batch configuration update must fail, and thus, not a single config should be actually changed. + boolean oldRolloutApprovalConfig = (Boolean) tenantConfigurationManagement.getConfigurationValue(ROLLOUT_APPROVAL_ENABLED).getValue(); + boolean oldAuthGatewayTokenEnabled = (Boolean) tenantConfigurationManagement.getConfigurationValue(AUTHENTICATION_GATEWAYTOKEN_ENABLED).getValue(); + String oldAuthGatewayToken = (String) tenantConfigurationManagement.getConfigurationValue(AUTHENTICATION_GATEWAYTOKEN_KEY).getValue(); + + //invalid TenantMetadata Default DistributionSetType, it is expected to be a number. Testing invalid type - string + //not a single configuration should be changed after the failure + Object testInvalidDistributionSetType = "someInvalidInput"; + assertBatchConfigurationFails(!oldRolloutApprovalConfig, !oldAuthGatewayTokenEnabled, oldAuthGatewayToken + "randomSuffix1", testInvalidDistributionSetType, status().isBadRequest()); + + //invalid TenantMetadata Default DistributionSetType, it is expected to be a number. Testing invalid type - bool + //not a single configuration should be changed after the failure + testInvalidDistributionSetType = true; + assertBatchConfigurationFails(!oldRolloutApprovalConfig, !oldAuthGatewayTokenEnabled, oldAuthGatewayToken + "randomSuffix2", testInvalidDistributionSetType, status().isBadRequest()); + + //Valid TenantMetadata Default DistributionSetType, it is expected to be a number. Testing valid type - but given DistributionSetType Id does not exist. + //not a single configuration should be changed after the failure + testInvalidDistributionSetType = 9999; + assertBatchConfigurationFails(!oldRolloutApprovalConfig, !oldAuthGatewayTokenEnabled, oldAuthGatewayToken + "randomSuffix2", testInvalidDistributionSetType, status().isNotFound()); + } + + private void assertBatchConfigurationFails(Object newRolloutApprovalEnabled, Object newAuthGatewayTokenEnabled, Object newGatewayToken, Object newDistributionSetTypeId, ResultMatcher resultMatchers) throws Exception { + long oldDefaultDsType = getActualDefaultDsType(); + boolean oldRolloutApprovalConfig = (Boolean) tenantConfigurationManagement.getConfigurationValue(ROLLOUT_APPROVAL_ENABLED).getValue(); + boolean oldAuthGatewayTokenEnabled = (Boolean) tenantConfigurationManagement.getConfigurationValue(AUTHENTICATION_GATEWAYTOKEN_ENABLED).getValue(); + String oldAuthGatewayToken = (String) tenantConfigurationManagement.getConfigurationValue(AUTHENTICATION_GATEWAYTOKEN_KEY).getValue(); + JSONObject configuration = new JSONObject(); - configuration.put(ROLLOUT_APPROVAL_ENABLED, true); - configuration.put(AUTHENTICATION_GATEWAYTOKEN_ENABLED, "wrong"); - configuration.put(AUTHENTICATION_GATEWAYTOKEN_KEY, "1234"); + configuration.put(ROLLOUT_APPROVAL_ENABLED, newRolloutApprovalEnabled); + configuration.put(AUTHENTICATION_GATEWAYTOKEN_ENABLED, newAuthGatewayTokenEnabled); + configuration.put(AUTHENTICATION_GATEWAYTOKEN_KEY, newGatewayToken); + configuration.put(DEFAULT_DISTRIBUTION_SET_TYPE_KEY, newDistributionSetTypeId); + String body = configuration.toString(); + + mvc.perform(put(MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs") + .content(body).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .andExpect(resultMatchers); + //Check if TenantMetadata and TenantConfiguration is not changed as Batch config failed + assertEquals(oldDefaultDsType, getActualDefaultDsType(), "Batch configuration update Failed, but TenantMetadata - DistributionSetType was actually changed."); + assertEquals(oldRolloutApprovalConfig, tenantConfigurationManagement.getConfigurationValue(ROLLOUT_APPROVAL_ENABLED).getValue(), "Batch configuration update Failed, but TenantConfiguration was actually changed."); + assertEquals(oldAuthGatewayTokenEnabled, tenantConfigurationManagement.getConfigurationValue(AUTHENTICATION_GATEWAYTOKEN_ENABLED).getValue(), "Batch configuration update Failed, but TenantConfiguration was actually changed."); + assertEquals(oldAuthGatewayToken, tenantConfigurationManagement.getConfigurationValue(AUTHENTICATION_GATEWAYTOKEN_KEY).getValue(), "Batch configuration update Failed, but TenantConfiguration was actually changed."); + } + + @Test + @Description("The Batch configuration should be applied") + public void changeBatchConfiguration() throws Exception { + long updatedDistributionSetType = createTestDistributionSetType(); + boolean updatedRolloutApprovalEnabled = true; + boolean updatedAuthGatewayTokenEnabled = true; + String updatedAuthGatewayTokenKey = "54321"; + JSONObject configuration = new JSONObject(); + configuration.put(ROLLOUT_APPROVAL_ENABLED, updatedRolloutApprovalEnabled); + configuration.put(AUTHENTICATION_GATEWAYTOKEN_ENABLED, updatedAuthGatewayTokenEnabled); + configuration.put(AUTHENTICATION_GATEWAYTOKEN_KEY, updatedAuthGatewayTokenKey); + configuration.put(DEFAULT_DISTRIBUTION_SET_TYPE_KEY, updatedDistributionSetType); String body = configuration.toString(); mvc.perform(put(MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs") - .content(body).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) - .andExpect(status().isBadRequest()); + .content(body).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()); + + //assert all changes were applied after Rest Success + assertEquals(updatedDistributionSetType, getActualDefaultDsType(), "Change BatchConfiguration was successful but TenantMetadata - Default DistributionSetType was not actually changed."); + assertEquals(updatedRolloutApprovalEnabled, tenantConfigurationManagement.getConfigurationValue(ROLLOUT_APPROVAL_ENABLED).getValue(), "Change BatchConfiguration was successful but TenantConfiguration property was not actually changed."); + assertEquals(updatedAuthGatewayTokenEnabled, tenantConfigurationManagement.getConfigurationValue(AUTHENTICATION_GATEWAYTOKEN_ENABLED).getValue(), "Change BatchConfiguration was successful but TenantConfiguration property was not actually changed."); + assertEquals(updatedAuthGatewayTokenKey, tenantConfigurationManagement.getConfigurationValue(AUTHENTICATION_GATEWAYTOKEN_KEY).getValue(), "Change BatchConfiguration was successful but TenantConfiguration property was not actually changed."); } @Test @@ -151,4 +286,18 @@ public class MgmtTenantManagementResourceTest extends AbstractManagementApiInteg .andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()); } + + @Test + @Description("Tests DELETE request must Fail for TenantMetadata properties.") + public void deleteTenantMetadataFail() throws Exception { + mvc.perform(delete(MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs/{keyName}/", + DEFAULT_DISTRIBUTION_SET_TYPE_KEY)) + .andDo(MockMvcResultPrinter.print()) + .andExpect(status().isBadRequest()); + } + + private Long getActualDefaultDsType() { + return systemManagement.getTenantMetadata().getDefaultDsType().getId(); + } + }