/* * Copyright (c) 2015 EMC Corporation * All Rights Reserved */ package com.emc.storageos.systemservices.impl.propertyhandler; import com.emc.storageos.model.property.*; import com.emc.storageos.svcs.errorhandling.resources.*; import com.emc.storageos.systemservices.impl.upgrade.*; import org.slf4j.*; import java.util.*; public class UniqueNodeNameHandler implements UpdateHandler{ private static final Logger _log = LoggerFactory.getLogger(UniqueNodeNameHandler.class); private static volatile CoordinatorClientExt _coordinator; private static final String USE_SHORT_NODE_NAME= "use_short_node_name"; private static final String NODE_COUNT = "node_count"; private static final String NODE_STANDALONE_NAME = "node_standalone_name"; public static void setCoordinator(CoordinatorClientExt coordinator) { _coordinator = coordinator; } /** * Checks if node_x_name properties have unique names * * If unique_short_name property is true then only short names are checked * Else full node names are checked for uniqueness * * @param oldProps * @param newProps */ public void before(PropertyInfoRestRep oldProps,PropertyInfoRestRep newProps){ Map<String, String> propInfo = _coordinator.getPropertyInfo().getProperties(); // get all node name properties (# of these change depending on deployment) ArrayList<String> nodeNameProperties = getNodeNameProperties(propInfo); ArrayList<String> changedProperties = new ArrayList<String>(); String uniqueShortNameValue = getLatestValue(USE_SHORT_NODE_NAME,newProps,propInfo); // if unique short name is changed to true check all node name properties, otherwise check only changed if (isProprotyChanged(oldProps,newProps,USE_SHORT_NODE_NAME) && uniqueShortNameValue.equalsIgnoreCase("true")) { changedProperties.addAll(nodeNameProperties); } else { for(String prop : nodeNameProperties){ if(isProprotyChanged(oldProps,newProps,prop)){ changedProperties.add(prop); } } } // no changed node name properties then return if (changedProperties.isEmpty()){ return; } // check that node names can't be confused with node id of other nodes // ex: node name of vipr1 cannot be vipr2 but can be vipr1 // ex: standalone can have any name for(String changedProp : changedProperties){ String changedValue=getLatestValue(changedProp,newProps,propInfo).toLowerCase(); // get node number from property (empty for standalone) String nodeNum=changedProp.replaceAll("\\D+",""); // check if new value has name similar to node id and is not on standalone if (changedValue.matches("vipr\\d+") && !nodeNum.isEmpty()){ // check that node name is not the same as it's node id (which would be ok) if (!changedValue.equals("vipr"+nodeNum)){ throw BadRequestException.badRequests.invalidNodeNameIsIdOfAnotherNode(changedProp,changedValue); } } } if (uniqueShortNameValue.equalsIgnoreCase("true")){ // validates short names are unique (implies full hostname is unique as well) for(String changedProp : changedProperties){ String changedValue=getLatestValue(changedProp,newProps,propInfo).split("\\.")[0]; for(String prop : nodeNameProperties){ String compareValue=getLatestValue(prop,newProps,propInfo).split("\\.")[0]; if(!changedProp.equals(prop)&&changedValue.equals(compareValue)){ throw BadRequestException.badRequests.invalidNodeShortNamesAreNotUnique(changedValue,changedProp,prop); } } } } else { // validates that full hostname is unique for(String changedProp : changedProperties){ String changedValue=getLatestValue(changedProp,newProps,propInfo); for(String prop : nodeNameProperties){ String compareValue=getLatestValue(prop,newProps,propInfo); if(!changedProp.equals(prop)&&changedValue.equals(compareValue)){ throw BadRequestException.badRequests.invalidNodeNamesAreNotUnique(changedValue,changedProp,prop); } } } } } /** * After method is not needed, but must be implemented * * @param oldProps * @param newProps */ public void after(PropertyInfoRestRep oldProps,PropertyInfoRestRep newProps){ } public String getLatestValue(String property, PropertyInfoRestRep newProps, Map<String, String> propInfo) { String value = newProps.getProperty(property); if (value != null) { return value; } return propInfo.get(property); } public boolean isProprotyChanged(PropertyInfoRestRep oldProps, PropertyInfoRestRep newProps, String property) { String oldValue = oldProps.getProperty(property); String newValue = newProps.getProperty(property); if (newValue == null) { return false; } if (oldValue == null) { oldValue = "0"; } if (oldValue.equals(newValue)) { return false; } return true; } private ArrayList<String> getNodeNameProperties(Map<String, String> propInfo) { ArrayList<String> nodeNameProperties = new ArrayList<String>(); // check if standalone otherwise generate properties based on node count if (propInfo.containsKey(NODE_STANDALONE_NAME)) { nodeNameProperties.add(NODE_STANDALONE_NAME); return nodeNameProperties; } int nodeCount = Integer.parseInt(propInfo.get(NODE_COUNT)); for (int i = 1; i <= nodeCount; i++) { nodeNameProperties.add("node_" + i + "_name"); } return nodeNameProperties; } }