Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
// under the License.
package org.apache.cloudstack.hypervisor.xenserver;

import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;
import org.apache.xmlrpc.XmlRpcException;

import com.cloud.exception.InvalidParameterValueException;
import com.cloud.utils.Pair;
import com.cloud.utils.exception.CloudRuntimeException;
import com.xensource.xenapi.Connection;
import com.xensource.xenapi.Types;
Expand All @@ -35,16 +35,22 @@ public static void setExtraConfigurationToVm(Connection conn, VM.Record vmr, VM
Map<String, Object> recordMap = vmr.toMap();
for (String key : extraConfig.keySet()) {
String cfg = extraConfig.get(key);
Map<String, String> configParams = prepareKeyValuePair(cfg);
// cfg is either param=value or map-param:key=value
Pair<String, String> configParam = prepareKeyValuePair(cfg);
if (configParam == null) {
LOG.warn("Invalid extra config passed: " + cfg);
continue;
}

// paramKey is either param or param:key for map parameters
String paramKey = configParams.keySet().toString().replaceAll("[\\[\\]]", "");
String paramValue = configParams.get(paramKey);
// paramKey is either param or map-param:key for map parameters
String paramKey = configParam.first();
String paramValue = configParam.second();

//Map params
if (paramKey.contains(":")) {
// Map params - paramKey is map-param:key
applyConfigWithNestedKeyValue(conn, vm, recordMap, paramKey, paramValue);
} else {
// Params - paramKey is param
applyConfigWithKeyValue(conn, vm, recordMap, paramKey, paramValue);
}
}
Expand All @@ -58,6 +64,7 @@ private static boolean isValidOperation(Map<String, Object> recordMap, String ac
* Nested keys contain ":" between the paramKey and need to split into operation param and key
* */
private static void applyConfigWithNestedKeyValue(Connection conn, VM vm, Map<String, Object> recordMap, String paramKey, String paramValue) {
// paramKey is map-param:key
int i = paramKey.indexOf(":");
String actualParam = paramKey.substring(0, i);
String keyName = paramKey.substring(i + 1);
Expand All @@ -68,12 +75,13 @@ private static void applyConfigWithNestedKeyValue(Connection conn, VM vm, Map<St
}

try {
// map-param param with '_'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need this comment? what does it mean?

switch (actualParam) {
case "VCPUs_params":
vm.addToVCPUsParams(conn, keyName, paramValue);
break;
case "platform":
vm.addToOtherConfig(conn, keyName, paramValue);
vm.addToPlatform(conn, keyName, paramValue);
break;
case "HVM_boot_params":
vm.addToHVMBootParams(conn, keyName, paramValue);
Expand Down Expand Up @@ -101,6 +109,7 @@ private static void applyConfigWithKeyValue(Connection conn, VM vm, Map<String,
}

try {
// param with '_'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need this comment? it is a bit unclear if this is enforced or a contextual condition or ...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just to keep as note. these params are with underscore, as the hypens were replaced with underscores.

switch (paramKey) {
case "HVM_boot_policy":
vm.setHVMBootPolicy(conn, paramValue);
Expand Down Expand Up @@ -144,7 +153,7 @@ private static void applyConfigWithKeyValue(Connection conn, VM vm, Map<String,
case "VCPUs_at_startup":
vm.setVCPUsAtStartup(conn, Long.valueOf(paramValue));
break;
case "is-a-template":
case "is_a_template":
vm.setIsATemplate(conn, Boolean.valueOf(paramValue));
break;
case "memory_static_max":
Expand All @@ -169,12 +178,28 @@ private static void applyConfigWithKeyValue(Connection conn, VM vm, Map<String,
}
}

private static Map<String, String> prepareKeyValuePair(String cfg) {
Map<String, String> configKeyPair = new HashMap<>();
protected static Pair<String, String> prepareKeyValuePair(String cfg) {
// cfg is either param=value or map-param:key=value
int indexOfEqualSign = cfg.indexOf("=");
String key = cfg.substring(0, indexOfEqualSign).replace("-", "_");
if (indexOfEqualSign <= 0) {
return null;
}

String key;
// Replace '-' with '_' in param / map-param only
if (cfg.contains(":")) {
int indexOfColon = cfg.indexOf(":");
if (indexOfColon <= 0 || indexOfEqualSign < indexOfColon) {
return null;
}
String mapParam = cfg.substring(0, indexOfColon).replace("-", "_");
String paramKey = cfg.substring(indexOfColon + 1, indexOfEqualSign);
key = mapParam + ":" + paramKey;
} else {
key = cfg.substring(0, indexOfEqualSign).replace("-", "_");
}

String value = cfg.substring(indexOfEqualSign + 1);
configKeyPair.put(key, value);
return configKeyPair;
return new Pair<>(key, value);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* 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.hypervisor.xenserver;
Comment thread
DaanHoogland marked this conversation as resolved.

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;

import com.cloud.utils.Pair;

@RunWith(MockitoJUnitRunner.class)
public class ExtraConfigurationUtilityTest {

@Test
public void prepareKeyValuePairTest() {
// Map params
verifyKeyValuePairForConfigParam("platform:exp-nested-hvm=true", "platform:exp-nested-hvm", "true");
verifyKeyValuePairForConfigParam("other_config:my_key=my_value", "other_config:my_key", "my_value");
verifyKeyValuePairForConfigParam("test-config:test-key=test-value", "test_config:test-key", "test-value");

// Params
verifyKeyValuePairForConfigParam("is_a_template=true", "is_a_template", "true");
verifyKeyValuePairForConfigParam("is-a-template=true", "is_a_template", "true");
verifyKeyValuePairForConfigParam("memory_dynamic_min=536870912", "memory_dynamic_min", "536870912");
verifyKeyValuePairForConfigParam("VCPUs_at_startup=2", "VCPUs_at_startup", "2");
verifyKeyValuePairForConfigParam("VCPUs-max=4", "VCPUs_max", "4");
}

private void verifyKeyValuePairForConfigParam(String cfg, String expectedKey, String expectedValue) {
Pair<String, String> keyValuePair = ExtraConfigurationUtility.prepareKeyValuePair(cfg);
Assert.assertEquals(expectedKey, keyValuePair.first());
Assert.assertEquals(expectedValue, keyValuePair.second());
}
}