mirror of https://github.com/apache/cloudstack.git
api,server: normalize string empty value on config update (#11770)
Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
This commit is contained in:
parent
f570e16836
commit
39d0d62fdd
|
|
@ -150,7 +150,7 @@ public class UpdateCfgCmd extends BaseCmd {
|
||||||
ConfigurationResponse response = _responseGenerator.createConfigurationResponse(cfg);
|
ConfigurationResponse response = _responseGenerator.createConfigurationResponse(cfg);
|
||||||
response.setResponseName(getCommandName());
|
response.setResponseName(getCommandName());
|
||||||
response = setResponseScopes(response);
|
response = setResponseScopes(response);
|
||||||
response = setResponseValue(response, cfg);
|
setResponseValue(response, cfg);
|
||||||
this.setResponseObject(response);
|
this.setResponseObject(response);
|
||||||
} else {
|
} else {
|
||||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update config");
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update config");
|
||||||
|
|
@ -161,15 +161,13 @@ public class UpdateCfgCmd extends BaseCmd {
|
||||||
* Sets the configuration value in the response. If the configuration is in the `Hidden` or `Secure` categories, the value is encrypted before being set in the response.
|
* Sets the configuration value in the response. If the configuration is in the `Hidden` or `Secure` categories, the value is encrypted before being set in the response.
|
||||||
* @param response to be set with the configuration `cfg` value
|
* @param response to be set with the configuration `cfg` value
|
||||||
* @param cfg to be used in setting the response value
|
* @param cfg to be used in setting the response value
|
||||||
* @return the response with the configuration's value
|
|
||||||
*/
|
*/
|
||||||
public ConfigurationResponse setResponseValue(ConfigurationResponse response, Configuration cfg) {
|
public void setResponseValue(ConfigurationResponse response, Configuration cfg) {
|
||||||
|
String value = cfg.getValue();
|
||||||
if (cfg.isEncrypted()) {
|
if (cfg.isEncrypted()) {
|
||||||
response.setValue(DBEncryptionUtil.encrypt(getValue()));
|
value = DBEncryptionUtil.encrypt(value);
|
||||||
} else {
|
|
||||||
response.setValue(getValue());
|
|
||||||
}
|
}
|
||||||
return response;
|
response.setValue(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
// Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
// or more contributor license agreements. See the NOTICE file
|
||||||
|
// distributed with this work for additional information
|
||||||
|
// regarding copyright ownership. The ASF licenses this file
|
||||||
|
// to you under the Apache License, Version 2.0 (the
|
||||||
|
// "License"); you may not use this file except in compliance
|
||||||
|
// with the License. You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing,
|
||||||
|
// software distributed under the License is distributed on an
|
||||||
|
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
// KIND, either express or implied. See the License for the
|
||||||
|
// specific language governing permissions and limitations
|
||||||
|
// under the License.
|
||||||
|
package org.apache.cloudstack.api.command.admin.config;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.api.response.ConfigurationResponse;
|
||||||
|
import org.apache.cloudstack.config.Configuration;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.MockedStatic;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
import com.cloud.utils.crypt.DBEncryptionUtil;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class UpdateCfgCmdTest {
|
||||||
|
|
||||||
|
private UpdateCfgCmd updateCfgCmd;
|
||||||
|
|
||||||
|
private MockedStatic<DBEncryptionUtil> mockedStatic;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
updateCfgCmd = new UpdateCfgCmd();
|
||||||
|
mockedStatic = Mockito.mockStatic(DBEncryptionUtil.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
mockedStatic.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setResponseValueSetsEncryptedValueWhenConfigurationIsEncrypted() {
|
||||||
|
ConfigurationResponse response = new ConfigurationResponse();
|
||||||
|
Configuration cfg = Mockito.mock(Configuration.class);
|
||||||
|
Mockito.when(cfg.isEncrypted()).thenReturn(true);
|
||||||
|
Mockito.when(cfg.getValue()).thenReturn("testValue");
|
||||||
|
Mockito.when(DBEncryptionUtil.encrypt("testValue")).thenReturn("encryptedValue");
|
||||||
|
updateCfgCmd.setResponseValue(response, cfg);
|
||||||
|
Assert.assertEquals("encryptedValue", response.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setResponseValueSetsPlainValueWhenConfigurationIsNotEncrypted() {
|
||||||
|
ConfigurationResponse response = new ConfigurationResponse();
|
||||||
|
Configuration cfg = Mockito.mock(Configuration.class);
|
||||||
|
Mockito.when(cfg.isEncrypted()).thenReturn(false);
|
||||||
|
Mockito.when(cfg.getValue()).thenReturn("testValue");
|
||||||
|
updateCfgCmd.setResponseValue(response, cfg);
|
||||||
|
Assert.assertEquals("testValue", response.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setResponseValueHandlesNullConfigurationValueGracefully() {
|
||||||
|
ConfigurationResponse response = new ConfigurationResponse();
|
||||||
|
Configuration cfg = Mockito.mock(Configuration.class);
|
||||||
|
Mockito.when(cfg.isEncrypted()).thenReturn(false);
|
||||||
|
Mockito.when(cfg.getValue()).thenReturn(null);
|
||||||
|
updateCfgCmd.setResponseValue(response, cfg);
|
||||||
|
Assert.assertNull(response.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -990,6 +990,19 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected String getNormalizedEmptyValueForConfig(final String name, final String inputValue,
|
||||||
|
final Long configStorageId) {
|
||||||
|
String value = inputValue.trim();
|
||||||
|
if (!value.isEmpty() && !value.equals("null")) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
if (configStorageId != null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
ConfigKey<?> key = _configDepot.get(name);
|
||||||
|
return (key != null && key.type() == String.class) ? "" : null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ActionEvent(eventType = EventTypes.EVENT_CONFIGURATION_VALUE_EDIT, eventDescription = "updating configuration")
|
@ActionEvent(eventType = EventTypes.EVENT_CONFIGURATION_VALUE_EDIT, eventDescription = "updating configuration")
|
||||||
public Configuration updateConfiguration(final UpdateCfgCmd cmd) throws InvalidParameterValueException {
|
public Configuration updateConfiguration(final UpdateCfgCmd cmd) throws InvalidParameterValueException {
|
||||||
|
|
@ -1084,11 +1097,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||||
throw new InvalidParameterValueException("cannot handle multiple IDs, provide only one ID corresponding to the scope");
|
throw new InvalidParameterValueException("cannot handle multiple IDs, provide only one ID corresponding to the scope");
|
||||||
}
|
}
|
||||||
|
|
||||||
value = value.trim();
|
value = getNormalizedEmptyValueForConfig(name, value, id);
|
||||||
|
|
||||||
if (value.isEmpty() || value.equals("null")) {
|
|
||||||
value = (id == null) ? null : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
String currentValueInScope = getConfigurationValueInScope(config, name, scope, id);
|
String currentValueInScope = getConfigurationValueInScope(config, name, scope, id);
|
||||||
final String updatedValue = updateConfiguration(userId, name, category, value, scope, id);
|
final String updatedValue = updateConfiguration(userId, name, category, value, scope, id);
|
||||||
|
|
|
||||||
|
|
@ -1102,4 +1102,42 @@ public class ConfigurationManagerImplTest {
|
||||||
|
|
||||||
Assert.assertFalse(result);
|
Assert.assertFalse(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void normalizedEmptyValueForConfigReturnsTrimmedValueWhenInputIsValid() {
|
||||||
|
String result = configurationManagerImplSpy.getNormalizedEmptyValueForConfig("someConfig", " validValue ", null);
|
||||||
|
Assert.assertEquals("validValue", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void normalizedEmptyValueForConfigReturnsNullWhenInputIsNullAndNoConfigStorageId() {
|
||||||
|
String result = configurationManagerImplSpy.getNormalizedEmptyValueForConfig("someConfig", "null", null);
|
||||||
|
Assert.assertNull(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void normalizedEmptyValueForConfigReturnsEmptyStringWhenInputIsNullAndConfigStorageIdProvided() {
|
||||||
|
String result = configurationManagerImplSpy.getNormalizedEmptyValueForConfig("someConfig", "null", 123L);
|
||||||
|
Assert.assertEquals("", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void normalizedEmptyValueForConfigReturnsEmptyStringWhenKeyTypeIsStringAndInputIsEmpty() {
|
||||||
|
ConfigKey<String> mockKey = Mockito.mock(ConfigKey.class);
|
||||||
|
Mockito.when(mockKey.type()).thenReturn(String.class);
|
||||||
|
Mockito.doReturn(mockKey).when(configDepot).get("someConfig");
|
||||||
|
|
||||||
|
String result = configurationManagerImplSpy.getNormalizedEmptyValueForConfig("someConfig", "", null);
|
||||||
|
Assert.assertEquals("", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void normalizedEmptyValueForConfigReturnsNullWhenKeyTypeIsNotStringAndInputIsEmpty() {
|
||||||
|
ConfigKey<Integer> mockKey = Mockito.mock(ConfigKey.class);
|
||||||
|
Mockito.when(mockKey.type()).thenReturn(Integer.class);
|
||||||
|
Mockito.doReturn(mockKey).when(configDepot).get("someConfig");
|
||||||
|
|
||||||
|
String result = configurationManagerImplSpy.getNormalizedEmptyValueForConfig("someConfig", "", null);
|
||||||
|
Assert.assertNull(result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue