/*
* Copyright (c) 2008-2014 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.installer.controller;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import charva.awt.Component;
import charva.awt.event.ItemEvent;
import charva.awt.event.ItemListener;
import charvax.swing.JRadioButton;
import com.emc.storageos.services.util.Configuration;
import com.emc.storageos.installer.util.ClusterType;
import com.emc.storageos.installer.util.InstallerConstants;
import com.emc.storageos.installer.util.InstallerOperation;
import com.emc.storageos.services.util.ServerProbe;
import com.emc.storageos.installer.widget.SelectButtonPanel;
/**
* Class implements the control on the Cluster screen in config mode.
*
*/
public class ConfigClusterController implements IConfigPanelController {
private static final Logger log = LoggerFactory.getLogger(ConfigClusterController.class);
private Configuration config;
private SelectButtonPanel panel;
private String selectedCluster;
private Set<Configuration> availabelClusters;
private boolean isNewConfig = false;
private Configuration selectedConfig;
private boolean isSameClusterType = false;
private String nodeId;
private Configuration localConfig;
private String[] status = null;
public ConfigClusterController(Configuration config, SelectButtonPanel panel,
Set<Configuration> availabelClusters, Configuration localConfig) {
this.config = config;
this.panel = panel;
this.availabelClusters = availabelClusters;
this.localConfig = localConfig;
setupEventListener();
}
public boolean isNewConfig() {
return isNewConfig;
}
private boolean isReConfig() {
if (localConfig == null) {
log.debug("This is ECS case, local config is null");
return false;
} else {
log.debug("This is re-config, local config is NOT null");
return true;
}
}
// get user selected configuration
public Configuration getSelectedConfig() {
return selectedConfig;
}
private void setupEventListener() {
panel.selectList1ItemListener(new SelectClusterListener());
// in the ECS case, user needs to select node id
if (!isReConfig()) {
panel.selectList2ItemListener(new SelectNodeIdListener());
}
}
/**
* Class listens on cluster selection
*/
class SelectClusterListener implements ItemListener {
@Override
public void itemStateChanged(ItemEvent ie) {
int statechange = ie.getStateChange();
Component source = (Component) ie.getSource();
if (statechange == ItemEvent.SELECTED) {
JRadioButton button = (JRadioButton) source;
selectedCluster = button.getText();
log.info("Selected cluster: {}", selectedCluster);
clearConfiguration();
if (selectedCluster.equals(InstallerConstants.CLUSTER_CONFIG_NEW_CONFIG_LABEL)) {
isNewConfig = true;
disableNodeIdPanel();
if (!meetMinimumHwRequirement()) {
log.warn("Node does not meet minimum H/W requirement for Config");
}
} else {
// check if selected node count is the same as local one if has local config
if (!isReConfig() || isNodeCountSame(selectedCluster)) {
isNewConfig = false;
getConfiguration(selectedCluster);
isSameClusterType = true;
if (!hasSameHardware()) {
log.info("Node does not have the same H/W requirement as selected cluster {}",
selectedCluster);
}
} else {
isSameClusterType = false;
selectedConfig = null;
selectedCluster = null;
}
}
}
}
private boolean meetMinimumHwRequirement() {
log.debug("Check if local server meets minimum hardware requirement for config.");
if (!ServerProbe.getInstance().isMetMinimumRequirement()) {
status = new String[] { InstallerConstants.ERROR_MSG_NOT_MEET_MIN_REQ_1,
InstallerConstants.ERROR_MSG_NOT_MEET_MIN_REQ_2,
InstallerConstants.ERROR_MSG_NOT_MEET_MIN_REQ_3,
InstallerConstants.ERROR_MSG_NOT_MEET_MIN_REQ_4 };
return false;
} else {
status = null;
return true;
}
}
private boolean hasSameHardware() {
log.debug("Check if local hardware are the same as selected cluster {}",
selectedCluster);
if (selectedConfig != null && selectedConfig.getHwConfig() != null
&& !selectedConfig.getHwConfig().isEmpty()) {
// TODO: reassess later
// for now in config mode, don't compare disk
String compareMsg = InstallerOperation.compareHardware(selectedConfig.getHwConfig(), true);
if (compareMsg != null) {
status = new String[] { compareMsg, InstallerConstants.ERROR_MSG_HW_NOT_SAME_2 };
return false;
} else {
status = null;
}
}
return true;
}
/*
* Check node count between selected cluster and local configuration.
*
* @param cluster the selected cluster
*
* @return true if same, false if not same
*/
private boolean isNodeCountSame(String cluster) {
int nodeCount = 0;
if (cluster.contains(ClusterType.NODE_COUNT_1.getLabel())) {
nodeCount = ClusterType.NODE_COUNT_1.getCount();
} else if (cluster.contains(ClusterType.NODE_COUNT_3.getLabel())) {
nodeCount = ClusterType.NODE_COUNT_3.getCount();
} else if (cluster.contains(ClusterType.NODE_COUNT_5.getLabel())) {
nodeCount = ClusterType.NODE_COUNT_5.getCount();
}
if (nodeCount == localConfig.getNodeCount()) {
return true;
} else {
log.info("Selected node count: {}, local node count: {}",
nodeCount, config.getNodeCount());
return false;
}
}
/*
* Get the Configuration of selected cluster. Set the node id list based on
* the nodes already been taken.
*
* @param selectedCluster
* selected cluster label from GUI (e.g. "10.247.101.174 [2+1 (3 servers)]")
*/
private void getConfiguration(String selectedCluster) {
List<String> nodes = new ArrayList<String>();
for (Configuration c : availabelClusters) {
String selectedClusterVip = selectedCluster.split(InstallerConstants.CLUSTER_LABEL_DELIMITER)[0];
if (selectedClusterVip.equals(c.getNetworkVip())) {
nodes.add(c.getNodeId());
selectedConfig = c;
}
}
if (!isReConfig()) {
resetVisibility();
resetEnableDisable(nodes);
}
}
/*
* Clears the configuration contents
*/
private void clearConfiguration() {
status = null;
nodeId = null;
config.setNodeCount(0);
config.setNodeId(null);
config.getNetworkIpv4Config().clear();
config.getNetworkIpv6Config().clear();
}
/*
* Reset the visibility of the node id based on the node count of selected cluster.
*/
private void resetVisibility() {
// reset all buttons to invisible and clear the selection made
// before first
for (JRadioButton node : panel.getButtonList2()) {
node.setSelected(false);
node.setVisible(false);
}
// set the label back visible
panel.getEastLabel().setVisible(true);
// enable buttons based on node count
for (int i = 0; i < selectedConfig.getNodeCount(); i++) {
panel.getButtonList2().get(i).setVisible(true);
}
}
/*
* Disable/gray out the node id already taken
*/
private void resetEnableDisable(List<String> nodeIdTaken) {
// get the node already taken and disable it
for (int i = 0; i < selectedConfig.getNodeCount(); i++) {
JRadioButton node = panel.getButtonList2().get(i);
if (nodeIdTaken.contains(node.getText())) {
// this node already taken, disable it
node.setEnabled(false);
} else {
node.setEnabled(true);
}
}
}
/*
* Set the node id list to invisible when new configuration selects
*/
private void disableNodeIdPanel() {
for (JRadioButton node : panel.getButtonList2()) {
node.setVisible(false);
}
panel.getEastLabel().setVisible(false);
}
}
/**
* Class listens on node id selection
*/
class SelectNodeIdListener implements ItemListener {
@Override
public void itemStateChanged(ItemEvent ie) {
int statechange = ie.getStateChange();
Component source = (Component) ie.getSource();
if (statechange == ItemEvent.SELECTED) {
JRadioButton button = (JRadioButton) source;
nodeId = button.getText();
}
}
}
/*
* Save contents from selected cluster to Configuration object
*/
private String saveClusterConfig() {
String err = null;
log.debug("Before saving config {}", config.toString());
if (selectedConfig != null) {
log.debug("Selected cluster {} configuration {}", selectedCluster,
selectedConfig.toString());
// save node id from selection in ECS case; in re-config case, save it from local config
if (!isReConfig()) {
if (nodeId == null) {
err = InstallerConstants.CLUSTER_CONFIG_WARN_MSG;
return err;
}
log.debug("This is ECS case, save node id '{}' from selection.", nodeId);
config.setNodeId(nodeId);
} else {
log.debug("This is re-config case, save id '{}' from local config.", localConfig.getNodeId());
config.setNodeId(localConfig.getNodeId());
}
config.setNodeCount(selectedConfig.getNodeCount());
config.getHwConfig().putAll(selectedConfig.getHwConfig());
// clear network setting before putting new ones (node count may
// changed)
config.getNetworkIpv4Config().clear();
config.getNetworkIpv6Config().clear();
config.getNetworkIpv4Config().putAll(
selectedConfig.getNetworkIpv4Config());
config.getNetworkIpv6Config().putAll(
selectedConfig.getNetworkIpv6Config());
log.info("Saved config {}", config.toString());
}
return err;
}
@Override
public String[] configurationIsCompleted() {
if (status != null && status.length != 0) {
return status;
} else {
String err = null;
if (!isNewConfig) {
if (isSameClusterType) {
log.info("Saving selected configuration");
err = saveClusterConfig();
} else {
err = "Selected node count is not the same as local one.";
}
}
return (err == null) ? null : new String[] { err };
}
}
}