...
Code Block | ||
---|---|---|
| ||
# keytool -list -alias AliasChallengeResponse -keystore myKey.jceks -storetype JCEKS Enter keystore password: AliasChallengeResponse, 24/Mar/2016, PrivateKeyEntry, Certificate fingerprint (SHA1): A2:1B:49:1B:18:D8:DC:95:CC:9F:C3:33:94:04:39:EE:44:DD:CF:BE |
Note that the controllerId and thisNodeId are the same.
Note also that all switches defined in switchesInitialState are MASTER in primary controller and SLAVE at backup controller.
Code Block | ||||
---|---|---|---|---|
| ||||
org.sdnplatform.sync.internal.SyncManager.authScheme=CHALLENGE_RESPONSE
org.sdnplatform.sync.internal.SyncManager.keyStorePath=/etc/floodlight/myKey.jceks
org.sdnplatform.sync.internal.SyncManager.dbPath=/var/lib/floodlight/
org.sdnplatform.sync.internal.SyncManager.keyStorePassword=YourPassWord
org.sdnplatform.sync.internal.SyncManager.port=6642
org.sdnplatform.sync.internal.SyncManager.thisNodeId=1
org.sdnplatform.sync.internal.SyncManager.persistenceEnabled=FALSE
org.sdnplatform.sync.internal.SyncManager.nodes=[\
{"nodeId": 1, "domainId": 1, "hostname": "192.168.1.100", "port": 6642},\
{"nodeId": 2, "domainId": 1, "hostname": "192.168.1.100", "port": 6643}\
]
net.floodlightcontroller.core.internal.FloodlightProvider.controllerId=1
net.floodlightcontroller.core.internal.OFSwitchManager.switchesInitialState={"00:00:00:00:00:00:00:01":"ROLE_MASTER","00:00:00:00:00:00:00:02":"ROLE_MASTER", "00:00:00:00:00:00:00:03":"ROLE_MASTER", "00:00:00:00:00:00:00:04":"ROLE_MASTER","00:00:00:00:00:00:00:05":"ROLE_MASTER"} |
Note that the controllerId and thisNodeId are the same.
Note also that all switches defined in switchesInitialState are as SLAVE in de primary controller.
Code Block | ||||
---|---|---|---|---|
| ||||
org.sdnplatform.sync.internal.SyncManager.authScheme=CHALLENGE_RESPONSE
org.sdnplatform.sync.internal.SyncManager.keyStorePath=/etc/floodlight/key2.jceks
org.sdnplatform.sync.internal.SyncManager.dbPath=/var/lib/floodlight2/
org.sdnplatform.sync.internal.SyncManager.keyStorePassword=PassWord
org.sdnplatform.sync.internal.SyncManager.port=6643
org.sdnplatform.sync.internal.SyncManager.thisNodeId=2
org.sdnplatform.sync.internal.SyncManager.persistenceEnabled=FALSE
org.sdnplatform.sync.internal.SyncManager.nodes=[\
{"nodeId": 1, "domainId": 1, "hostname": "192.168.1.100", "port": 6642},\
{"nodeId": 2, "domainId": 1, "hostname": "192.168.1.100", "port": 6643}\
]
net.floodlightcontroller.core.internal.FloodlightProvider.controllerId=2
net.floodlightcontroller.core.internal.OFSwitchManager.switchesInitialState={"00:00:00:00:00:00:00:01":"ROLE_SLAVE","00:00:00:00:00:00:00:02":"ROLE_SLAVE", "00:00:00:00:00:00:00:03":"ROLE_SLAVE", "00:00:00:00:00:00:00:04":"ROLE_SLAVE","00:00:00:00:00:00:00:05":"ROLE_SLAVE"}
|
To use the sync service, you need create two vars ISyncService and IStoreClient and initiate the syncService:
...
And finally, if you want monitor your store, it is necessary implement interface IStoreListener<String>.
In this case our the store has the String type.
In the example below we are just showing the remote sync events.
But you can uncomment the code and see local and remote updates from your sync store.
Code Block |
---|
@Override public void keysModified(Iterator<String> keys, org.sdnplatform.sync.IStoreListener.UpdateType type) { while(keys.hasNext()){ String k = keys.next(); try { /* logger.debug("keysModified: Key:{}, Value:{}, Type: {}", new Object[] { k, storeFT.get(k).getValue().toString(), type.name() } ); */ if(type.name().equals("REMOTE")){ String info = storeFT.get(k).getValue(); logger.debug("REMOTE: Key:{}, Value:{}", k, value); } } catch (SyncException e) { e.printStackTrace(); } } } |
Follow the complete code. The code below is part of the FT class from simpleFT simpleft package.
The class uses an RPCListener to monitor RPC connections among the cluster and inform all synced nodes
from connections and disconnections from nodes.
The fault tolerance module define a RPCListener and monitore RPC connections.
In each event (connect or disconnect nodes and switches events) the module informe the store about his
Code Block | ||
---|---|---|
| ||
/** * Tulio Alberton Ribeiro * * LaSIGE - Large-Scale Informatics Systems Laboratory * * Licensed 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 */ package net.floodlightcontroller.simpleft; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.Map; import net.floodlightcontroller.core.FloodlightContext; import net.floodlightcontroller.core.IOFMessageListener; import net.floodlightcontroller.core.IOFSwitch; import net.floodlightcontroller.core.IOFSwitchListener; import net.floodlightcontroller.core.PortChangeType; import net.floodlightcontroller.core.internal.FloodlightProvider; import net.floodlightcontroller.core.internal.IOFSwitchService; import net.floodlightcontroller.core.module.FloodlightModuleContext; import net.floodlightcontroller.core.module.FloodlightModuleException; import net.floodlightcontroller.core.module.IFloodlightModule; import net.floodlightcontroller.core.module.IFloodlightService; import net.floodlightcontroller.storage.IStorageSourceService; import org.projectfloodlight.openflow.protocol.OFControllerRole; import org.projectfloodlight.openflow.protocol.OFMessage; import org.projectfloodlight.openflow.protocol.OFPortDesc; import org.projectfloodlight.openflow.protocol.OFRoleReply; import org.projectfloodlight.openflow.protocol.OFType; import org.projectfloodlight.openflow.types.DatapathId; import org.sdnplatform.sync.IStoreClient; import org.sdnplatform.sync.IStoreListener; import org.sdnplatform.sync.ISyncService; import org.sdnplatform.sync.ISyncService.Scope; import org.sdnplatform.sync.error.SyncException; import org.sdnplatform.sync.internal.rpc.IRPCListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class FT implements IOFMessageListener, IFloodlightModule, IStoreListener<String>, IOFSwitchListener, IRPCListener { private ISyncService syncService; private IStoreClient<String, String> storeFT; protected static Logger logger = LoggerFactory.getLogger(FT.class); protected static IOFSwitchService switchService; private String controllerId; @Override public String getName() { // TODO Auto-generated method stub return FT.class.getSimpleName(); } @Override public boolean isCallbackOrderingPrereq(OFType type, String name) { // TODO Auto-generated method stub return false; } @Override public boolean isCallbackOrderingPostreq(OFType type, String name) { // TODO Auto-generated method stub return false; } @Override public Collection<Class<? extends IFloodlightService>> getModuleServices() { // TODO Auto-generated method stub return null; } @Override public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() { // TODO Auto-generated method stub return null; } @Override public Collection<Class<? extends IFloodlightService>> getModuleDependencies() { // TODO Auto-generated method stub Collection<Class<? extends IFloodlightService>> l = new ArrayList<Class<? extends IFloodlightService>>(); l.add(IStorageSourceService.class); l.add(ISyncService.class); l.add(IOFSwitchService.class); return l; } @Override public void init(FloodlightModuleContext context) throws FloodlightModuleException { // TODO Auto-generated method stub this.syncService = context.getServiceImpl(ISyncService.class); switchService = context.getServiceImpl(IOFSwitchService.class); Map<String, String> configParams = context.getConfigParams(FloodlightProvider.class); controllerId = configParams.get("controllerId"); } @Override public void startUp(FloodlightModuleContext context) throws FloodlightModuleException { switchService.addOFSwitchListener(this); syncService.addRPCListener(this); try { this.syncService.registerStore("FT_Switches", Scope.GLOBAL); this.storeFT = this.syncService .getStoreClient("FT_Switches", String.class, String.class); this.storeFT.addStoreListener(this); } catch (SyncException e) { throw new FloodlightModuleException("Error while setting up sync service", e); } } @Override public net.floodlightcontroller.core.IListener.Command receive( IOFSwitch sw, OFMessage msg, FloodlightContext cntx) { // TODO Auto-generated method stub return null; } @Override public void keysModified(Iterator<String> keys, org.sdnplatform.sync.IStoreListener.UpdateType type) { // TODO Auto-generated method stub while(keys.hasNext()){ String k = keys.next(); try { /*logger.debug("keysModified: Key:{}, Value:{}, Type: {}", new Object[] { k, storeClient.get(k).getValue().toString(), type.name()} );*/ if(type.name().equals("REMOTE")){ String swIds = storeFT.get(k).getValue(); logger.debug("REMOTE: NodeId:{}, Switches:{}", k, swIds); } } catch (SyncException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } @Override public void switchAdded(DatapathId switchId) { // TODO Auto-generated method stub } @Override public void switchRemoved(DatapathId switchId) { // TODO Auto-generated method stub String activeSwitches = getActiveSwitchesAndUpdateSyncInfo(); logger.debug("Switch REMOVED: {}, Syncing: {}", switchId, activeSwitches); } @Override public void switchActivated(DatapathId switchId) { // TODO Auto-generated method stub String activeSwitches = getActiveSwitchesAndUpdateSyncInfo(); logger.debug("Switch ACTIVATED: {}, Syncing: {}", switchId, activeSwitches); } @Override public void switchPortChanged(DatapathId switchId, OFPortDesc port, PortChangeType type) { // TODO Auto-generated method stub logger.debug("Switch Port CHANGED: {}", switchId); } @Override public void switchChanged(DatapathId switchId) { // TODO Auto-generated method stub String activeSwitches = getActiveSwitchesAndUpdateSyncInfo(); logger.debug("Switch CHANGED: {}, Syncing: {}", switchId, activeSwitches); } @Override public void switchDeactivated(DatapathId switchId) { // TODO Auto-generated method stub String activeSwitches = getActiveSwitchesAndUpdateSyncInfo(); logger.debug("Switch DEACTIVATED: {}, Syncing: {}", switchId, activeSwitches); } public String getActiveSwitchesAndUpdateSyncInfo(){ String activeSwitches = ""; if(switchService == null) return ""; Iterator<DatapathId> itDpid = switchService.getAllSwitchDpids().iterator(); while (itDpid.hasNext()) { DatapathId dpid = itDpid.next(); try{ if(switchService.getActiveSwitch(dpid).isActive()){ activeSwitches += dpid; if(itDpid.hasNext()) activeSwitches += ","; } } catch(NullPointerException npe){ return ""; } } if(activeSwitches.equals("")) return ""; try { this.storeFT.put(controllerId, activeSwitches); return activeSwitches; } catch (SyncException e) { e.printStackTrace(); return ""; } } public void setSwitchRole(OFControllerRole role, String swId){ IOFSwitch sw = switchService.getActiveSwitch(DatapathId.of(swId)); OFRoleReply reply=null; UtilDurable utilDurable = new UtilDurable(); reply = utilDurable.setSwitchRole(sw, role); if(reply!=null){ logger.info("DEFINED {} as {}, reply.getRole:{}!", new Object[]{ sw.getId(), role, reply.getRole()}); } else logger.info("Reply NULL!"); } @Override public void disconnectedNode(Short nodeId) { // TODO Auto-generated method stub String swIds=null; try { swIds = storeFT.get(""+nodeId).getValue(); logger.debug("Switches managed by nodeId:{}, Switches:{}", nodeId, swIds); } catch (SyncException e) { e.printStackTrace(); } if(swIds != null){ String swId[] = swIds.split(","); for (int i = 0; i < swId.length; i++) { setSwitchRole(OFControllerRole.ROLE_MASTER, swId[i]); } } } @Override public void connectedNode(Short nodeId) { // TODO Auto-generated method stub String activeSwicthes = getActiveSwitchesAndUpdateSyncInfo(); logger.debug("NodeID:{} connected, sending my Switches: {}", nodeId, activeSwicthes); } } |