package org.ovirt.engine.core.common.businessentities; import java.io.Serializable; import java.util.HashSet; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlType; import org.ovirt.engine.core.common.config.Config; import org.ovirt.engine.core.common.config.ConfigValues; import org.ovirt.engine.core.common.queries.ValueObjectMap; import org.ovirt.engine.core.compat.DoubleCompat; import org.ovirt.engine.core.compat.IntegerCompat; import org.ovirt.engine.core.compat.LogCompat; import org.ovirt.engine.core.compat.LogFactoryCompat; import org.ovirt.engine.core.compat.LongCompat; import org.ovirt.engine.core.compat.RefObject; import org.ovirt.engine.core.compat.StringHelper; @XmlAccessorType(XmlAccessType.NONE) @XmlType(name = "VdsFencingOptions") public class VdsFencingOptions implements Serializable { private static final long serialVersionUID = -8832636627473217232L; private static final char COMMA = ','; private static final char EQUAL = '='; private static final char NEWLINE = '\n'; private static final char SEMICOLON = ';'; private static final char COLON = ':'; private static final String TRUE_STRING = "true"; private static final String FALSE_STRING = "false"; private static final String YES = "yes"; private static final String NO = "no"; private static final String AGENT_ERROR = "Cannot find fencing agent named {0} in fencing option mapping"; private static final String MAPPING_FORMAT_ERROR = "Illegal fencing mapping format {0}"; @XmlElement private String fenceAgent = ""; @XmlElement private String fencingOptions; private static java.util.HashMap<String, String> fencingAgentInstanceOptions; private static HashSet<String> fencingSpecialParams; @XmlElement(name = "FencingAgentInstanceOptionsMap") public ValueObjectMap getFencingAgentInstanceOptionsMap() { return new ValueObjectMap(fencingAgentInstanceOptions, false); } @SuppressWarnings("unchecked") public void setFencingAgentInstanceOptionsMap(ValueObjectMap value) { fencingAgentInstanceOptions = (value != null) ? new java.util.HashMap<String, String>( value.asMap()) : null; } private static java.util.HashMap<String, java.util.HashMap<String, String>> fencingOptionMapping; @XmlElement(name = "FencingOptionMappingMap") public ValueObjectMap getFencingOptionMappingMap() { return new ValueObjectMap(fencingOptionMapping, true); } @SuppressWarnings("unchecked") public void setFencingOptionMappingMap(ValueObjectMap value) { fencingOptionMapping = (value != null) ? new java.util.HashMap<String, java.util.HashMap<String, String>>( value.asMap()) : null; } @XmlElement(name = "FencingOptionMappingMap") public java.util.HashMap<String, java.util.HashMap<String, String>> getFencingOptionMappingMap2() { return fencingOptionMapping; } public void setFencingOptionMappingMap2(java.util.HashMap<String, java.util.HashMap<String, String>> value) { fencingOptionMapping = value; } private static java.util.HashMap<String, String> fencingOptionTypes; @XmlElement(name = "FencingOptionTypesMap") public ValueObjectMap getFencingOptionTypesMap() { return new ValueObjectMap(fencingOptionTypes, false); } @SuppressWarnings("unchecked") public void setFencingOptionTypesMap(ValueObjectMap value) { fencingOptionTypes = (value != null) ? new java.util.HashMap<String, String>(value.asMap()) : null; } /** * Caches the fencing agents options mapping. Mapping are stored in the following format <!-- * <agent>:{var=value}{[,]var=value}*; --> for example : * alom:secure=secure,port=ipport;apc:secure=secure,port=ipport,slot=port */ private void CacheFencingAgentsOptionMapping() { String localfencingOptionMapping = Config.<String> GetValue(ConfigValues.VdsFenceOptionMapping); String[] agentsOptionsStr = localfencingOptionMapping.split(StringHelper.quote((new Character( SEMICOLON)).toString()), -1); for (String agentOptionsStr : agentsOptionsStr) { String[] parts = agentOptionsStr.split(StringHelper.quote((new Character(COLON)) .toString()), -1); if (parts.length == 2) { String agent = parts[0]; java.util.HashMap<String, String> agentOptions = new java.util.HashMap<String, String>(); // check for empty options if (!StringHelper.isNullOrEmpty(parts[1])) { String[] options = parts[1].split(StringHelper.quote((new Character(COMMA)) .toString()), -1); for (String option : options) { String[] optionKeyVal = option.split(StringHelper.quote((new Character( EQUAL)).toString()), -1); agentOptions.put(optionKeyVal[0], optionKeyVal[1]); // add mapped keys to special params fencingSpecialParams.add(optionKeyVal[1]); } } fencingOptionMapping.put(agent, agentOptions); } else { log.errorFormat(MAPPING_FORMAT_ERROR, agentOptionsStr); break; } } } /** * Caches the fencing agents option types. Types are stored in the following format <!-- [key=type][,][key=type]*--> * for example : secure=bool,port=int,slot=int */ private void CacheFencingAgentsOptionTypes() { String localfencingOptionTypes = Config.<String> GetValue(ConfigValues.VdsFenceOptionTypes); String[] types = localfencingOptionTypes.split(StringHelper.quote((new Character(COMMA)) .toString()), -1); for (String entry : types) { String[] optionKeyVal = entry.split(StringHelper.quote((new Character(EQUAL)) .toString()), -1); fencingOptionTypes.put(optionKeyVal[0], optionKeyVal[1]); } } /** * Gets the real key given the displayed key. * * @param agent * The agent. * @param displayedKey * The displayed key. * @return */ private String GetRealKey(String agent, String displayedKey) { String result = ""; if (!StringHelper.isNullOrEmpty(agent) && !StringHelper.isNullOrEmpty(displayedKey)) { if (fencingOptionMapping.containsKey(agent)) { java.util.HashMap<String, String> agentOptions = fencingOptionMapping.get(agent); result = agentOptions.containsKey(displayedKey) ? agentOptions.get(displayedKey) : displayedKey; } else { log.errorFormat(AGENT_ERROR, agent); } } return result; } /** * Gets the displayed key given the real key. * * @param agent * The agent. * @param realKey * The real key. * @return */ private String GetDisplayedKey(String agent, String realKey) { String result = ""; if (!StringHelper.isNullOrEmpty(agent) && !StringHelper.isNullOrEmpty(realKey)) { if (fencingOptionMapping.containsKey(agent)) { java.util.HashMap<String, String> agentOptions = fencingOptionMapping.get(agent); if (agentOptions.containsValue(realKey)) { for (java.util.Map.Entry<String, String> pair : agentOptions.entrySet()) { if (StringHelper.EqOp(pair.getValue(), realKey)) { result = pair.getKey(); break; } } } else { // assume that a legal flag that not exists in mapping was // used result = realKey; } } else { log.errorFormat(AGENT_ERROR, agent); } } return result; } /** * Gets the type of the key. * * @param key * The key. * @return */ private String GetOptionType(String key) { String result = ""; if (!StringHelper.isNullOrEmpty(key) && fencingOptionTypes.containsKey(key)) { result = fencingOptionTypes.get(key); } return result; } /** * Translates the bool value to yes/no. * * @param value * The value. * @return */ private static String TranslateBoolValue(String value) { String result; // VB & C# TO JAVA CONVERTER NOTE: The following 'switch' operated on a // string member and was converted to Java 'if-else' logic: // switch (value.Trim().ToLower()) // ORIGINAL LINE: case (TRUE): if (value.equalsIgnoreCase(TRUE_STRING) || value.equalsIgnoreCase(FALSE_STRING)) { if (Boolean.parseBoolean(value)) { result = YES; } // ORIGINAL LINE: case FALSE: else { result = NO; } } else { result = value; } return result; } /** * Inits this instance. */ private void Init() { InitCache(); CacheFencingAgentInstanceOptions(); } /** * Cleans up. */ private void CleanUp() { if (fencingAgentInstanceOptions != null && fencingOptionMapping != null && fencingOptionTypes != null) { fencingAgentInstanceOptions.clear(); fencingOptionMapping.clear(); fencingOptionTypes.clear(); fencingSpecialParams.clear(); } Init(); } /** * Inits the cache. */ private void InitCache() { if (fencingOptionMapping == null) { fencingAgentInstanceOptions = new java.util.HashMap<String, String>(); fencingOptionMapping = new java.util.HashMap<String, java.util.HashMap<String, String>>(); fencingOptionTypes = new java.util.HashMap<String, String>(); fencingSpecialParams = new HashSet<String>(); CacheFencingAgentsOptionMapping(); CacheFencingAgentsOptionTypes(); } } /** * Caches the fencing agent instance options. */ private void CacheFencingAgentInstanceOptions() { if (!StringHelper.isNullOrEmpty(getAgent()) && !StringHelper.isNullOrEmpty(getFencingOptions())) { String[] options = getFencingOptions().split( StringHelper.quote((new Character(COMMA)).toString()), -1); fencingAgentInstanceOptions.clear(); for (String option : options) { String[] optionKeyVal = option.split(StringHelper.quote((new Character(EQUAL)) .toString()), -1); if (optionKeyVal.length == 1) { add(getAgent(), optionKeyVal[0], ""); } else { add(getAgent(), optionKeyVal[0], optionKeyVal[1]); } } } } /** * handles agent mapping, get the real agent for a given agent name * * @param agent * the agent name * @return string , the agent real name to be used */ public static String getRealAgent(String agent) { String agentMapping = Config.<String> GetValue(ConfigValues.FenceAgentMapping); String realAgent = agent; // result has the format [<agent>=<real agent>[,]]* String[] settings = agentMapping.split(StringHelper.quote(new Character(COMMA).toString()), -1); if (settings.length > 0) { for (String setting : settings) { // get the <agent>=<real agent> pair String[] pair = setting.split(StringHelper.quote(new Character(EQUAL).toString()), -1); if (pair.length == 2) { if (agent.equalsIgnoreCase(pair[0])) { realAgent = pair[1]; break; } } } } return realAgent; } /** * handles agent default options * * @param agent * @param fenceOptions * @return String the options after adding default agent parameters */ public static String getDefaultAgentOptions(String agent, String fenceOptions) { String agentdefaultParams = Config.<String> GetValue(ConfigValues.FenceAgentDefaultParams); StringBuilder realOptions = new StringBuilder(fenceOptions); // result has the format [<agent>:param=value[,]...;]* String[] params = agentdefaultParams.split(StringHelper.quote(new Character(SEMICOLON).toString()), -1); for (String agentOptionsStr : params) { String[] parts = agentOptionsStr.split(StringHelper.quote((new Character(COLON)) .toString()), -1); if (parts.length == 2) { if (agent.equalsIgnoreCase(parts[0])) { // check for empty options if (!StringHelper.isNullOrEmpty(parts[1])) { String[] options = parts[1].split(StringHelper.quote((new Character(COMMA)) .toString()), -1); for (String option : options) { String[] optionKeyVal = option.split(StringHelper.quote((new Character( EQUAL)).toString()), -1); // if a value is set explicitly for a default param // we respect that value and not use the default value if (!fenceOptions.contains(optionKeyVal[0])) { if (realOptions.length() > 0) { realOptions.append(COMMA); } realOptions.append(optionKeyVal[0]); if (optionKeyVal.length == 2) { String val = (optionKeyVal[1] == null) ? "" : optionKeyVal[1]; realOptions.append(EQUAL); realOptions.append(val); } } } } break; } } } return realOptions.toString(); } @XmlElement(name = "Agent") public String getAgent() { return fenceAgent; } public void setAgent(String value) { fenceAgent = value; CleanUp(); } @XmlElement(name = "FencingOptions") public String getFencingOptions() { return fencingOptions; } public void setFencingOptions(String value) { fencingOptions = value; CleanUp(); } /** * Initializes a new instance of the <see cref="VdsFencingOptions"/> class. */ public VdsFencingOptions() { InitCache(); Init(); } /** * Initializes a new instance of the <see cref="VdsFencingOptions"/> class. * * @param agent * The agent. * @param fencingOptions * The fencing options. */ public VdsFencingOptions(String agent, String fencingOptions) { if (!StringHelper.isNullOrEmpty(agent)) { this.fenceAgent = agent; this.fencingOptions = fencingOptions; } InitCache(); Init(); } /** * Adds the specified key. * * @param key * The key. * @param value * The value. */ public void add(String key, String value) { add(getAgent(), key, value); } /** * Adds the specified key. * * @param agent * The agent. * @param key * The key. * @param value * The value. */ public void add(String agent, String key, String value) { key = GetRealKey(agent, key); fencingAgentInstanceOptions.put(key, value); } /** * Determines whether the specified current agent key is supported . * * @param key * The key. * @return <c>true</c> if the specified key is supported; otherwise, <c>false</c>. */ public boolean IsSupported(String key) { return IsSupported(getAgent(), key); } /** * Determines whether the specified agent key is supported. * * @param agent * The agent. * @param key * The key. * @return <c>true</c> if the specified agent is supported; otherwise, <c>false</c>. */ public boolean IsSupported(String agent, String key) { boolean result = false; if (!StringHelper.isNullOrEmpty(agent) && !StringHelper.isNullOrEmpty(key) && fencingOptionMapping.containsKey(agent)) { java.util.HashMap<String, String> agentOptions = fencingOptionMapping.get(agent); result = (agentOptions == null) ? false : agentOptions.containsKey(key); } else { log.errorFormat(AGENT_ERROR, agent); } return result; } /** * Gets the current agent supported options. * * @return */ public java.util.ArrayList<String> GetSupportedOptions() { return GetSupportedOptions(getAgent()); } /** * Gets the agent supported options. * * @param agent * The agent. * @return */ public java.util.ArrayList<String> GetSupportedOptions(String agent) { java.util.ArrayList<String> agentOptions = new java.util.ArrayList<String>(); if (fencingOptionMapping.containsKey(agent)) { java.util.HashMap<String, String> options = fencingOptionMapping.get(agent); for (java.util.Map.Entry<String, String> pair : options.entrySet()) { agentOptions.add(pair.getKey()); } } else { log.errorFormat(AGENT_ERROR, agent); } return agentOptions; } /** * Gets the specified key. * * @param key * The key. * @return The key value, null if key is not exist */ public Object Get(String key) { final String BOOL = "bool"; final String INT = "int"; final String LONG = "long"; final String DOUBLE = "double"; Object result = null; if (!StringHelper.isNullOrEmpty(key)) { String type = GetOptionType(key); key = GetRealKey(getAgent(), key); if (fencingAgentInstanceOptions != null && fencingAgentInstanceOptions.containsKey(key)) { if (!StringHelper.isNullOrEmpty(type)) { // Convert to the suitable type according to metadata. // VB & C# TO JAVA CONVERTER NOTE: The following 'switch' // operated on a string member and was converted to Java // 'if-else' logic: // switch (type.Trim().ToLower()) // ORIGINAL LINE: case BOOL: if (type.equalsIgnoreCase(BOOL)) { result = Boolean.parseBoolean(fencingAgentInstanceOptions.get(key)); } // ORIGINAL LINE: case INT: else if (type.equalsIgnoreCase(INT)) { int intVal = 0; RefObject<Integer> tempRefObject = new RefObject<Integer>(intVal); boolean tempVar = IntegerCompat.TryParse(fencingAgentInstanceOptions .get(key), tempRefObject); intVal = tempRefObject.argvalue; if (tempVar) { result = intVal; } } // ORIGINAL LINE: case LONG: else if (type.equalsIgnoreCase(LONG)) { long longVal = 0; RefObject<Long> tempRefObject2 = new RefObject<Long>(longVal); boolean tempVar2 = LongCompat.TryParse(fencingAgentInstanceOptions .get(key), tempRefObject2); longVal = tempRefObject2.argvalue; if (tempVar2) { result = longVal; } } // ORIGINAL LINE: case DOUBLE: else if (type.equalsIgnoreCase(DOUBLE)) { double doubleVal = 0; RefObject<Double> tempRefObject3 = new RefObject<Double>(doubleVal); boolean tempVar3 = DoubleCompat.TryParse2(fencingAgentInstanceOptions .get(key), tempRefObject3); doubleVal = tempRefObject3.argvalue; if (tempVar3) { result = doubleVal; } } else // return as string { result = fencingAgentInstanceOptions.get(key); } } else { // return value as an object result = fencingAgentInstanceOptions.get(key); } } } return result; } /** * Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>. * * @return A <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>. */ @Override public String toString() { String value = ""; String delimiter = ""; for (java.util.Map.Entry<String, String> pair : fencingAgentInstanceOptions.entrySet()) { value = value + delimiter + GetDisplayedKey(getAgent(), pair.getKey()) + (pair.getValue().length() > 0 ? EQUAL + pair.getValue() : ""); delimiter = (new Character(COMMA)).toString(); } return value; } /** * Gets the unsupported options string. * * @return */ public String ToUnsupportedOptionsString() { String value = ""; String delimiter = ""; for (java.util.Map.Entry<String, String> pair : fencingAgentInstanceOptions.entrySet()) { String displayedKey = GetDisplayedKey(getAgent(), pair.getKey()); if (!IsSupported(displayedKey)) { value = value + delimiter + displayedKey + (pair.getValue().length() > 0 ? EQUAL + pair.getValue() : ""); delimiter = (new Character(COMMA)).toString(); } } return value; } /** * Gets the internal representation of the options. * * @return */ public String ToInternalString() { String value = ""; String delimiter = ""; for (java.util.Map.Entry<String, String> pair : fencingAgentInstanceOptions.entrySet()) { if (pair.getValue().trim().length() > 0) { value = value + delimiter + pair.getKey() + EQUAL + TranslateBoolValue(pair.getValue()); // special params should not be sent if value is empty } else if (!fencingSpecialParams.contains(pair.getKey())) { value = value + delimiter + pair.getKey(); } delimiter = (new Character(NEWLINE)).toString(); } return value; } private static LogCompat log = LogFactoryCompat.getLog(VdsFencingOptions.class); }