package org.sdnplatform.sync.internal.config; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Properties; import org.sdnplatform.sync.error.SyncException; import org.sdnplatform.sync.internal.SyncManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import net.floodlightcontroller.core.internal.FloodlightProvider; import net.floodlightcontroller.core.module.FloodlightModuleContext; import net.floodlightcontroller.storage.IResultSet; import net.floodlightcontroller.storage.IStorageSourceService; public class StorageCCProvider implements IClusterConfigProvider { protected static final Logger logger = LoggerFactory.getLogger(StorageCCProvider.class.getName()); private IStorageSourceService storageSource; String thisControllerID; AuthScheme authScheme; String keyStorePath; String keyStorePassword; protected static final String CONTROLLER_TABLE_NAME = "controller_controller"; protected static final String CONTROLLER_ID = "id"; protected static final String CONTROLLER_SYNC_ID = "sync_id"; protected static final String CONTROLLER_SYNC_DOMAIN_ID = "sync_domain_id"; protected static final String CONTROLLER_SYNC_PORT = "sync_port"; protected static final String CONTROLLER_INTERFACE_TABLE_NAME = "controller_controllerinterface"; protected static final String CONTROLLER_INTERFACE_CONTROLLER_ID = "controller_id"; protected static final String CONTROLLER_INTERFACE_DISCOVERED_IP = "discovered_ip"; protected static final String CONTROLLER_INTERFACE_TYPE = "type"; protected static final String CONTROLLER_INTERFACE_NUMBER = "number"; protected static final String BOOT_CONFIG = "/opt/bigswitch/run/boot-config"; // ********************** // IClusterConfigProvider // ********************** @Override public void init(SyncManager syncManager, FloodlightModuleContext context) { storageSource = context.getServiceImpl(IStorageSourceService.class); // storageSource.addListener(CONTROLLER_TABLE_NAME, this); Map<String, String> config = context.getConfigParams(FloodlightProvider.class); thisControllerID = config.get("controllerid"); config = context.getConfigParams(SyncManager.class); keyStorePath = config.get("keyStorePath"); keyStorePassword = config.get("keyStorePassword"); authScheme = AuthScheme.NO_AUTH; try { authScheme = AuthScheme.valueOf(config.get("authScheme")); } catch (Exception e) {} } @Override public ClusterConfig getConfig() throws SyncException { if (thisControllerID == null) { Properties bootConfig = new Properties(); FileInputStream is = null; try { is = new FileInputStream(BOOT_CONFIG); bootConfig.load(is); thisControllerID = bootConfig.getProperty("controller-id"); } catch (Exception e) { throw new SyncException("No controller ID configured and " + "could not read " + BOOT_CONFIG); } finally { if (is != null) try { is.close(); } catch (IOException e) { throw new SyncException(e); } } } if (thisControllerID == null) { throw new SyncException("No controller ID configured"); } logger.debug("Using controller ID: {}", thisControllerID); List<Node> nodes = new ArrayList<Node>(); short thisNodeId = -1; String[] cols = {CONTROLLER_ID, CONTROLLER_SYNC_ID, CONTROLLER_SYNC_DOMAIN_ID, CONTROLLER_SYNC_PORT}; IResultSet res = null; try { res = storageSource.executeQuery(CONTROLLER_TABLE_NAME, cols, null, null); while (res.next()) { String controllerId = res.getString(CONTROLLER_ID); if (!res.containsColumn(CONTROLLER_SYNC_ID) || !res.containsColumn(CONTROLLER_SYNC_DOMAIN_ID) || !res.containsColumn(CONTROLLER_SYNC_PORT)) { logger.debug("No sync data found for {}", controllerId); continue; } short nodeId = res.getShort(CONTROLLER_SYNC_ID); short domainId = res.getShort(CONTROLLER_SYNC_DOMAIN_ID); int port = res.getInt(CONTROLLER_SYNC_PORT); String syncIp = getNodeIP(controllerId); if (syncIp == null) { logger.debug("No sync IP found for {}", controllerId); continue; } Node node = new Node(syncIp, port, nodeId, domainId); nodes.add(node); if (thisControllerID.equals(controllerId)) thisNodeId = nodeId; } } finally { if (res != null) res.close(); } if (nodes.size() == 0) throw new SyncException("No valid nodes found"); if (thisNodeId < 0) throw new SyncException("Could not find a node for the local node"); return new ClusterConfig(nodes, thisNodeId, authScheme, keyStorePath, keyStorePassword); } // ************* // Local methods // ************* private String getNodeIP(String controllerID) { String[] cols = {CONTROLLER_INTERFACE_CONTROLLER_ID, CONTROLLER_INTERFACE_TYPE, CONTROLLER_INTERFACE_NUMBER, CONTROLLER_INTERFACE_DISCOVERED_IP}; IResultSet res = null; try { res = storageSource.executeQuery(CONTROLLER_INTERFACE_TABLE_NAME, cols, null, null); while (res.next()) { logger.debug("{} {} {} {}", new Object[] {res.getString(CONTROLLER_INTERFACE_CONTROLLER_ID), res.getString(CONTROLLER_INTERFACE_TYPE), res.getIntegerObject(CONTROLLER_INTERFACE_NUMBER), res.getString(CONTROLLER_INTERFACE_DISCOVERED_IP)}); if ("Ethernet".equals(res.getString(CONTROLLER_INTERFACE_TYPE)) && Integer.valueOf(0).equals(res.getIntegerObject(CONTROLLER_INTERFACE_NUMBER)) && controllerID.equals(res.getString(CONTROLLER_INTERFACE_CONTROLLER_ID))) return res.getString(CONTROLLER_INTERFACE_DISCOVERED_IP); } return null; } finally { if (res != null) res.close(); } } }