/* ONF SampleTap Software License Copyright ©2014 Open Networking Foundation This ONF SampleTap software is 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 original license at http://www.apache.org/licenses/LICENSE-2.0 and also in the main directory of the source distribution. Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. End of ONF SampleTap Software License */ package org.opendaylight.controller.samples.onftappingapp; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.net.UnknownHostException; import javax.transaction.NotSupportedException; import org.slf4j.Marker; import org.slf4j.MarkerFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.log4j.BasicConfigurator; import org.apache.log4j.PropertyConfigurator; import com.mongodb.BasicDBObject; import com.mongodb.BasicDBObjectBuilder; import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.DBCursor; import com.mongodb.DBObject; import com.mongodb.MongoClient; import org.bson.types.ObjectId; import org.opendaylight.controller.forwardingrulesmanager.FlowEntry; import org.opendaylight.controller.forwardingrulesmanager.IForwardingRulesManager; import org.opendaylight.controller.sal.core.Node; import org.opendaylight.controller.sal.core.NodeConnector; import org.opendaylight.controller.sal.core.UpdateType; import org.opendaylight.controller.sal.reader.NodeDescription; import org.opendaylight.controller.sal.utils.Status; import org.opendaylight.controller.samples.onftappingapp.internal.ONFTappingAppImpl; public class TappingApp { private static Logger logger = LoggerFactory.getLogger(ONFTappingAppImpl.class); // We use fatal in our application so get a marker for FATAL static Marker fatal = MarkerFactory.getMarker("FATAL"); // Application global variables private static Properties applicationProps = new Properties(System.getProperties()); private static String mongoDBUsername = ""; private static String mongoDBPassword = ""; private static String wwwRootdir = ""; private final String appName; private final String hostname; private final String version = "1.0"; private boolean captureARP = false; private static int mongoDBPort = 27017; // Default MongoDB Port private MongoClient mongoClient; // Our MongoDB (Client) Connector private static DB database; // Our handle to MongoDB database // Instantiate the class that implements the application logic for pushing flows into ODL private TappingAppLogic tappingAppLogic = new TappingAppLogic(this); private ONFTappingAppImpl onfTappingAppImpl = null; // A Map<DataPathDescString, OPFSwitch> of unassigned OPF switches Map<String, OPFSwitch> unassignedOPFSwitchMap = new HashMap<String, OPFSwitch>(); // A Map<DataPathDescString, OPFSwitch> of assigned OPF switches Map<String, OPFSwitch> assignedOPFSwitchMap = new HashMap<String, OPFSwitch>(); // The ruleDB is a Map of Nodes to an ArrayList of FlowEntries. The index into the list is the port number private Map<Node, List<FlowEntry>> rulesDB = new HashMap<Node, List<FlowEntry>>(); // Return codes from the programming of the perHost rules into the switch public enum RulesProgrammingReturnCode { SUCCESS, FAILED_FEW_SWITCHES, FAILED_ALL_SWITCHES, FAILED_WRONG_PARAMS } // Constructor public TappingApp(String appName, String hostname, ONFTappingAppImpl onfTappingAppImpl) throws DBAuthenticationException, DatabaseConnectException { this.appName = appName; this.hostname = hostname; this.onfTappingAppImpl = onfTappingAppImpl; // Configure the logging system PropertyConfigurator.configure("log4j.properties"); BasicConfigurator.configure(); // Announce that the application has been launched logger.info("Tapping App: " + this.getName() + " version: " + this.getVersion()); // Load application configuration from the configuration file in CLASSPATH try { loadConfigurationFromFile(); } catch (IOException e) { logger.error(fatal, "Unable to load ONS Tapping Application configuration file"); logger.debug("Exception:", e); return; } // Set the mongo DB port if it is specified in the configuration file if (System.getProperties().containsKey("MongoDBPort")) setMongoDBPort(Integer.getInteger("MongoDBPort")); try { // MongoDB username and password are loaded from the application's configuration file connectToDatabase(mongoDBUsername, mongoDBPassword); } catch (DBAuthenticationException authException) { logger.error("Unable to connect to database " + authException.toString()); throw authException; } catch (DatabaseConnectException dbException) { logger.error("Unable to connect to database " + dbException.toString()); throw dbException; } // TODO - remove after integration //this.purgeObjectModelFromDatabase(); // TODO - remove after integration // Make stuff up for the GUI integration // makeFakeOPFSwitches(); } // Class destructor - call on shutdown public void close() { try { saveConfigurationToFile(); } catch (IOException e) { logger.error("Unable to save ONS Tapping Application configuration file"); logger.debug("Exception:", e); } } public static int getMongoDBPort() { return mongoDBPort; } public void setMongoDBPort(int i_mongoDBPort) { mongoDBPort = i_mongoDBPort; } public static DB getDatabase() { return database; } // Getters and setters public String getName() { return appName; } public String getHostname() { return hostname; } public String getVersion() { return version; } public boolean getCaptureARP() { return captureARP; } public void setCaptureARP(boolean captureARP) { this.captureARP = captureARP; logger.info("ARP Capture was " + (captureARP ? "Enabled" : "Disabled")); } public static String getWwwRootdir() { return wwwRootdir; } private void loadConfigurationFromFile() throws IOException { // now load properties from last invocation FileInputStream in = new FileInputStream("ONSTappingApp.config"); applicationProps.load(in); in.close(); // Store the application properties in the system properties System.setProperties(applicationProps); mongoDBUsername = applicationProps.getProperty("MongoDBUsername"); mongoDBPassword = applicationProps.getProperty("MongoDBPassword"); wwwRootdir = applicationProps.getProperty("www-rootdir"); logger.info("MongoDB credentials: username '" + mongoDBUsername + "' password '" + mongoDBPassword + "'"); logger.info("WWW Root Dir: " + wwwRootdir); } // Store the application properties to the configuration file private static void saveConfigurationToFile() throws IOException { FileOutputStream out = new FileOutputStream("ONSTappingApp.config"); Properties properties = new Properties(); properties.setProperty("MongoDBUsername", mongoDBUsername); properties.setProperty("MongoDBPassword", mongoDBPassword); String mongoPort = Integer.toString(TappingApp.getMongoDBPort()); properties.setProperty("MongoDBPort", mongoPort); properties.store(out, "Settings for the ONS Tapping Application"); out.close(); } public void connectToDatabase(String dbUsername, String dbPassword) throws DatabaseConnectException, DBAuthenticationException { try { mongoClient = new MongoClient("localhost", mongoDBPort); database = mongoClient.getDB(DatabaseNames.getDatabaseName()); // If the username and password are set then authenticate against the DB if (dbUsername.isEmpty() || dbPassword.isEmpty()) { logger.info("MongoDB username or password are not set, so database authentication is not used"); } else { boolean auth = database.authenticate(dbUsername, dbPassword.toCharArray()); if (!auth) { throw new DBAuthenticationException(); } } logger.info("Connected to configuration database " + database.toString()); } catch (UnknownHostException e) { logger.error("Error while connecting to Database", e); throw new DatabaseConnectException(); } } public void purgeObjectModelFromDatabase() { DBCollection tpTable = database.getCollection(DatabaseNames.getTapPolicyTableName()); tpTable.drop(); DBCollection mcTable = database.getCollection(DatabaseNames.getMatchCriteriaTableName()); mcTable.drop(); DBCollection seTable = database.getCollection(DatabaseNames.getSwitchEntryTableName()); seTable.drop(); DBCollection nhsTable = database.getCollection(DatabaseNames.getNextHopSwitchTableName()); nhsTable.drop(); DBCollection pcTable = database.getCollection(DatabaseNames.getPortChainTableName()); pcTable.drop(); DBCollection cdTable = database.getCollection(DatabaseNames.getCaptureDevTableName()); cdTable.drop(); DBCollection logTable = database.getCollection(DatabaseNames.getLoggerTableName()); logTable.drop(); } // Return a list containing all the Tap Policies by loading them from the database public List<TapPolicy> getAllTapPolicies() { DBCollection tpTable = database.getCollection(DatabaseNames.getTapPolicyTableName()); DBCursor cursor = tpTable.find(); List<TapPolicy> tapPolicyList = new ArrayList<TapPolicy>(cursor.size()); try { while(cursor.hasNext()) { // Get the object from the database DBObject tapPolicyObj = cursor.next(); // Construct a new tap policy from the DBobject and add it to list tapPolicyList.add(new TapPolicy(tapPolicyObj)); } } catch (NotFoundException e) { logger.error("Object referenced by Tap Policy cannot be found", e); } finally { cursor.close(); } return tapPolicyList; } // // Return a list containing all the Match Criteria by loading them from the database public List<MatchCriteria> getAllMatchCriteria() { DBCollection mcTable = database.getCollection(DatabaseNames.getMatchCriteriaTableName()); DBCursor cursor = mcTable.find(); List<MatchCriteria> matchCriteriaList = new ArrayList<MatchCriteria>(cursor.size()); try { while(cursor.hasNext()) { DBObject matchCriteriaObj = cursor.next(); MatchCriteria matchCriteria = new MatchCriteria(matchCriteriaObj); matchCriteriaList.add(matchCriteria); } } finally { cursor.close(); } return matchCriteriaList; } // Return a list containing all the SwitchEntries public List<SwitchEntry> getAllSwitchEntries() { DBCollection seTable = database.getCollection(DatabaseNames.getSwitchEntryTableName()); DBCursor cursor = seTable.find(); List<SwitchEntry> switchEntryList = new ArrayList<SwitchEntry>(cursor.size()); try { while(cursor.hasNext()) { DBObject switchEntryObj = cursor.next(); SwitchEntry switchEntry = new SwitchEntry(switchEntryObj, this); // Add the new SwitchEntry to the list switchEntryList.add(switchEntry); } } finally { cursor.close(); } return switchEntryList; } private void makeFakeOPFSwitches() { OPFSwitch opfSwitch1 = new OPFSwitch(); opfSwitch1.setIPAddress("10.2.34.2"); opfSwitch1.setDescription("Fake Switch 1"); opfSwitch1.setMACAddress("aa:bb:cc:dd:ee:11"); opfSwitch1.setMFRDescription("WTL Fake Switch"); opfSwitch1.setHardwareDesc("Fake hardware"); opfSwitch1.setSoftwareDesc("Fake software"); opfSwitch1.setSerialNumber("ABCDEFG"); opfSwitch1.setDataPathDesc("FGHD-JIVS-6DF1S-KLSAQ"); // Simulate a 24 port switch List<PortDescription> fakePortDescList1 = new ArrayList<PortDescription>(); for (int port = 0; port < 24; port++) { fakePortDescList1.add(new PortDescription("Port " + port, "11:22:33:44:aa:bb", port)); } opfSwitch1.setPortDescList(fakePortDescList1); // Add the OPFSwitch to the map unassignedOPFSwitchMap.put(opfSwitch1.getDataPathDesc(), opfSwitch1); OPFSwitch opfSwitch2 = new OPFSwitch(); //ObjectId oid2 = new ObjectId(); //opfSwitch2.setObjectId(oid2.toString()); opfSwitch2.setIPAddress("10.2.15.143"); opfSwitch2.setDescription("Fake Switch 2"); opfSwitch2.setMACAddress("aa:bb:11:22:f4:1c"); opfSwitch2.setMFRDescription("WTL Fake Switch"); opfSwitch2.setHardwareDesc("Fake hardware"); opfSwitch2.setSoftwareDesc("Fake software"); opfSwitch2.setSerialNumber("ZXCVBNK"); opfSwitch2.setDataPathDesc("JDSS-IODS-8FD8D-LKODQ"); // Simulate a 24 port switch List<PortDescription> fakePortDescList2 = new ArrayList<PortDescription>(); for (int port = 0; port < 24; port++) { fakePortDescList2.add(new PortDescription("Port " + port, "bb:1c:f3:ac:12:ea", port)); } opfSwitch2.setPortDescList(fakePortDescList2); // Add the OPF Switch to the map unassignedOPFSwitchMap.put(opfSwitch2.getDataPathDesc(), opfSwitch2); } // Return a list containing all the unassigned OPFSwitch objects public List<OPFSwitch> getAllUnassignedSwitchEntries() { logger.info("Getting App Unassigned Switch Entries"); logger.info("Unassigned Map " + this.unassignedOPFSwitchMap); logger.info("Assigned Map " + this.assignedOPFSwitchMap); // Clone the Map into a list List<OPFSwitch> unassignedOPFSwitchList = new ArrayList<OPFSwitch>(unassignedOPFSwitchMap.values()); return unassignedOPFSwitchList; } // Return a list containing all the NextHopSwitches public List<NextHopSwitch> getAllNextHopSwitches() { DBCollection nhsTable = database.getCollection(DatabaseNames.getNextHopSwitchTableName()); DBCursor cursor = nhsTable.find(); List<NextHopSwitch> nextHopSwitchList = new ArrayList<NextHopSwitch>(cursor.size()); try { while(cursor.hasNext()) { DBObject nhsObj = cursor.next(); NextHopSwitch nhs = new NextHopSwitch(nhsObj); // Add the new SwitchEntry to the list nextHopSwitchList.add(nhs); } } finally { cursor.close(); } return nextHopSwitchList; } // Return a list containing all the Port Chain objects public List<PortChain> getAllPortChains() { DBCollection pcTable = database.getCollection(DatabaseNames.getPortChainTableName()); DBCursor cursor = pcTable.find(); List<PortChain> portChainList = new ArrayList<PortChain>(cursor.size()); try { while(cursor.hasNext()) { DBObject portChainObj = cursor.next(); // Construct a new port chain from the DB object PortChain portChain = new PortChain(portChainObj); // Add the new port chain to the list portChainList.add(portChain); } } finally { cursor.close(); } return portChainList; } // Return a list containing all the Capture Devices public List<CaptureDev> getAllCaptureDevices() { DBCollection pcTable = database.getCollection(DatabaseNames.getCaptureDevTableName()); DBCursor cursor = pcTable.find(); List<CaptureDev> captureDevList = new ArrayList<CaptureDev>(cursor.size()); while(cursor.hasNext()) { DBObject captureDevObj = cursor.next(); // Construct a new CaptureDev from the document CaptureDev captureDev = new CaptureDev(captureDevObj); // Add it to the list captureDevList.add(captureDev); } return captureDevList; } // Returns a summary list of the Tap Policies that have been defined public List<TapPolicySummary> getTapPolicySummaries() { List<TapPolicySummary> summaryList = new ArrayList<TapPolicySummary>(); DBCollection table = database.getCollection(DatabaseNames.getTapPolicyTableName()); // Run a query to look for all the Tap Policies DBCursor cursor = table.find(); while (cursor.hasNext()) { DBObject doc = cursor.next(); TapPolicySummary summary = new TapPolicySummary((String) doc.get("_id").toString(), (String) doc.get("name"), (String) doc.get("description"), (Boolean) doc.get("enabled")); summaryList.add(summary); } return summaryList; } public void assignSwitch(String OPFSwitchId, String switchEntryId) throws NotFoundException, OPFSwitchNotFoundException, OPFSwitchIsAssignedException { // Look for the OPF Switch in the assigned list OPFSwitch opfSwitch = getAssignedOPFSwitchById(OPFSwitchId); if (opfSwitch != null) throw new OPFSwitchIsAssignedException(); // Look for the OPF Switch in the unassigned list opfSwitch = getUnAssignedOPFSwitchById(OPFSwitchId); if (opfSwitch == null) throw new OPFSwitchNotFoundException(); // We found it. Does it think it is already assigned? if (opfSwitch.getAssigned() == true) { // This OPFSwitch is already assigned throw new OPFSwitchIsAssignedException(); } // Look for the SwitchEntry by id SwitchEntry switchEntry = getSwitchEntryById(switchEntryId); logger.info("SwitchEntry " + switchEntry); // Finally, we can assign the OPF switch to the switch entry switchEntry.assignOPFSwitch(opfSwitch); // Update the database modifySwitchEntry(switchEntryId, switchEntry); // Move the OPFSwitch from the unassigned to the assigned map assignOPFSwitch(OPFSwitchId, opfSwitch); logger.info("Assigned OPFSwitch " + opfSwitch.getSerialNumber() + " at IP address " + opfSwitch.getIPAddressStr() + " to SwitchEntry with ID " + switchEntryId); // Send the flows to the switch // TODO need to look up the node here so we can send the flows //this.switchChanged(UpdateType.CHANGED, node); } // Move the OPFSwitch from the unassigned to the assigned map private void assignOPFSwitch(String OPFSwitchId, OPFSwitch opfSwitch) { logger.info("Assigning OPF Switch " + opfSwitch); this.unassignedOPFSwitchMap.remove(OPFSwitchId); this.assignedOPFSwitchMap.put(OPFSwitchId, opfSwitch); } // Move the OPFSwitch from the assigned to the unassigned map private void unassignOPFSwitch(String OPFSwitchId, OPFSwitch opfSwitch) { logger.info("Unassigning OPF Switch " + opfSwitch); this.assignedOPFSwitchMap.remove(OPFSwitchId); this.unassignedOPFSwitchMap.put(OPFSwitchId, opfSwitch); } public void unassignSwitch(String OPFSwitchId, String switchEntryId) throws NotFoundException, OPFSwitchNotFoundException, OPFSwitchIsNotAssignedException { // Look for the OPF Switch in the unassigned list OPFSwitch opfSwitch = getUnAssignedOPFSwitchById(OPFSwitchId); if (opfSwitch != null) throw new OPFSwitchIsNotAssignedException(); // Look for the OPF Switch in the assigned list opfSwitch = getAssignedOPFSwitchById(OPFSwitchId); if (opfSwitch == null) throw new OPFSwitchNotFoundException(); // We found it. Does it think it is already unassigned? if (opfSwitch.getAssigned() == false) { // This OPFSwitch is already assigned throw new OPFSwitchIsNotAssignedException(); } // Move the OPFSwitch from the assigned to the unassigned map unassignOPFSwitch(OPFSwitchId, opfSwitch); // Look for the SwitchEntry by id SwitchEntry switchEntry = getSwitchEntryById(switchEntryId); // Finally, we can un-assign the OPF switch from the switch entry switchEntry.unassignOPFSwitch(opfSwitch); // Update the database modifySwitchEntry(switchEntryId, switchEntry); logger.info("Unassigned OPFSwitch " + opfSwitch.getSerialNumber() + " at IP address " + opfSwitch.getIPAddressStr() + " from " + switchEntryId); } // Add a new policy to the system. public void addTapPolicy(TapPolicy tapPolicy) throws DuplicateEntryException { // Check whether there is an existing policy with the same name if (tapPolicyExistsByName(tapPolicy.getName())) throw new DuplicateEntryException(); // Get the tap policy table DBCollection table = database.getCollection(DatabaseNames.getTapPolicyTableName()); // Create a document containing the new tap policy BasicDBObject document = tapPolicy.getAsDocument(); // Add the new tap policy document to the tap policy table table.insert(document); // Get the object ID from mongo and update it in the tap policy object ObjectId objectId = document.getObjectId("_id"); tapPolicy.setObjectId(objectId.toString()); logger.info("Added tap policy " + tapPolicy.getName() + " object ID " + tapPolicy.getObjectId()); // Notify the application that the tap policy changed // tappingAppLogic.NotifyConfigChange(DBTableChangeEnum.TAP_POLICY, tapPolicy.getObjectId()); } // Delete the TapPolicy with the specified objectId public void deleteTapPolicy(String objectId) throws NotFoundException { DBCollection table = database.getCollection(DatabaseNames.getTapPolicyTableName()); // Create a query to look for the existing TapPolicy by ID BasicDBObject searchQuery = new BasicDBObject(); searchQuery.put("_id", new ObjectId(objectId)); DBObject dbObj = table.findOne(searchQuery); if (dbObj == null) throw new NotFoundException(); // We are deleting this tapPolicy, so remove references to other objects TapPolicy.removeObjectReferences(dbObj); // Remove the TapPolicy from the database table.remove(searchQuery); logger.info("Removed tap policy " + (String) dbObj.get("name")); // Notify the application that the tap policy changed // TODO - add objectID // tappingAppLogic.NotifyConfigChange(DBTableChangeEnum.TAP_POLICY); } // Return true if the database contains a TapPolicy with the specified name private boolean tapPolicyExistsByName(String name) { DBCollection table = database.getCollection(DatabaseNames.getTapPolicyTableName()); // Run a query to look for the TapPolicy name BasicDBObject searchQuery = new BasicDBObject(); searchQuery.put("name", name); DBObject dbObj = table.findOne(searchQuery); return (dbObj != null) ? true : false; } public void modifyTapPolicy(final String tapPolicyId, TapPolicy tapPolicy) throws NotFoundException { DBCollection table = database.getCollection(DatabaseNames.getTapPolicyTableName()); // Create a query to look for the existing TapPolicy by ID BasicDBObject searchQuery = new BasicDBObject(); searchQuery.put("_id", new ObjectId(tapPolicyId)); // Check whether the policy exists DBObject dbObj = table.findOne(searchQuery); if (dbObj == null) throw new NotFoundException(); // Create a document containing the new tap policy BasicDBObject newDocument = tapPolicy.getAsDocument(); BasicDBObject updateObj = new BasicDBObject(); updateObj.put("$set", newDocument); // Update the document in the database table.update(searchQuery, updateObj); logger.info("Updated tap policy id " + tapPolicyId); } // Add a new match criteria to the system public void addMatchCriteria(MatchCriteria matchCriteria) throws DuplicateEntryException { // Check whether there is an existing match criteria with the same name if (matchCriteriaExistsByName(matchCriteria.getName())) throw new DuplicateEntryException(); // Get the match criteria table DBCollection table = database.getCollection(DatabaseNames.getMatchCriteriaTableName()); // Create a document containing the new match criteria BasicDBObject document = matchCriteria.getAsDocument(); // Add the new tap policy document to the MatchCriteria table table.insert(document); // Get the object ID from mongo and update it in the MatchCriteria object ObjectId objectId = document.getObjectId("_id"); matchCriteria.setObjectId(objectId.toString()); logger.info("Added match criteria " + matchCriteria.getName() + " object ID " + matchCriteria.getObjectId()); // tappingAppLogic.NotifyConfigChange(DBTableChangeEnum.MATCH_CRITERIA, matchCriteria.getObjectId()); } private boolean matchCriteriaExistsByName(String name) { DBCollection table = database.getCollection(DatabaseNames.getMatchCriteriaTableName()); // Run a query to look for the Match Criteria name BasicDBObject searchQuery = new BasicDBObject(); searchQuery.put("name", name); DBObject dbObj = table.findOne(searchQuery); return (dbObj != null) ? true : false; } public void deleteMatchCriteria(final String objectId) throws NotFoundException, ObjectInUseException { DBCollection table = database.getCollection(DatabaseNames.getMatchCriteriaTableName()); // Create a query to look for the existing TapPolicy by ID BasicDBObject searchQuery = new BasicDBObject(); searchQuery.put("_id", new ObjectId(objectId)); DBObject dbObj = table.findOne(searchQuery); if (dbObj == null) throw new NotFoundException(); if ((long) dbObj.get("refCount") != 0) { throw new ObjectInUseException(); } // Remove the Match Criteria from the database table.remove(searchQuery); logger.info("Removed match criteria " + (String) dbObj.get("name")); } public void modifyMatchCriteria(final String matchCriteriaId, MatchCriteria matchCriteria) throws NotFoundException { DBCollection table = database.getCollection(DatabaseNames.getMatchCriteriaTableName()); logger.info("Match Criteria enabled " + matchCriteria.getEnabled()); // Create a query to look for the existing TapPolicy by ID BasicDBObject searchQuery = new BasicDBObject(); searchQuery.put("_id", new ObjectId(matchCriteriaId)); // Check whether the policy exists DBObject dbObj = table.findOne(searchQuery); if (dbObj == null) throw new NotFoundException(); // Create a document containing the new tap policy BasicDBObject newDocument = matchCriteria.getAsDocument(); BasicDBObject updateObj = new BasicDBObject(); updateObj.put("$set", newDocument); // Update the document in the database table.update(searchQuery, updateObj); logger.info("Updated match criteria id " + matchCriteriaId); } public void addSwitchEntry(SwitchEntry switchEntry) throws DuplicateEntryException, NotSupportedException { // We aren't supporting this mode yet if (switchEntry.getTappingMode() == TappingModeEnum.NORMAL) { throw new NotSupportedException("Normal Mode is not suppored"); } // Check whether there is an existing switch entry with the same name if (switchEntryExistsByName(switchEntry.getName())) throw new DuplicateEntryException(); // Get the match criteria table DBCollection table = database.getCollection(DatabaseNames.getSwitchEntryTableName()); // Create a document containing the new match criteria BasicDBObject document = switchEntry.getAsDocument(); // Add the new tap policy document to the tap policy table table.insert(document); // Get the object ID from mongo and update it in the switch entry object ObjectId objectId = document.getObjectId("_id"); switchEntry.setObjectId(objectId.toString()); logger.info("Added Switch Entry " + switchEntry.getName() + " object ID " + switchEntry.getObjectId()); } public void modifySwitchEntry(final String switchEntryId, SwitchEntry switchEntry) throws NotFoundException { DBCollection table = database.getCollection(DatabaseNames.getSwitchEntryTableName()); // Create a query to look for the existing SwitchEntry by ID BasicDBObject searchQuery = new BasicDBObject(); searchQuery.put("_id", new ObjectId(switchEntryId)); // Check whether the switchEntry exists DBObject dbObj = table.findOne(searchQuery); if (dbObj == null) throw new NotFoundException(); // Create a document containing the new switch Entry BasicDBObject newDocument = switchEntry.getAsDocument(); BasicDBObject updateObj = new BasicDBObject(); updateObj.put("$set", newDocument); // Update the document in the database table.update(searchQuery, updateObj); logger.info("Updated SwitchEntry id " + switchEntryId); } // Delete the SwitchEntry with the specified objectId public void deleteSwitchEntry(String objectId) throws NotFoundException, ObjectInUseException { DBCollection table = database.getCollection(DatabaseNames.getSwitchEntryTableName()); // Create a query to look for the existing SwitchEntry by ID BasicDBObject searchQuery = new BasicDBObject(); searchQuery.put("_id", new ObjectId(objectId)); DBObject dbObj = table.findOne(searchQuery); if (dbObj == null) throw new NotFoundException(); if ((long) dbObj.get("refCount") != 0) { throw new ObjectInUseException(); } // Get the existing portChain String switchName = (String) dbObj.get("name"); // Remove the PortChain from the database table.remove(searchQuery); logger.info("Removed switch " + switchName); // Notify the application that the port chaun changed // TODO - add objectID // tappingAppLogic.NotifyConfigChange(DBTableChangeEnum.SWITCH_ENTRY); } private boolean switchEntryExistsByName(String switchName) { DBCollection table = database.getCollection(DatabaseNames.getSwitchEntryTableName()); // Run a query to look for the SwitchEntry name BasicDBObject searchQuery = new BasicDBObject(); searchQuery.put("name", switchName); DBObject dbObj = table.findOne(searchQuery); return (dbObj != null) ? true : false; } public SwitchEntry findSwitchByDataPathId(final String switchId) throws NotFoundException { DBCollection table = database.getCollection(DatabaseNames.getSwitchEntryTableName()); // Create a query to look for the existing SwitchEntry by ID BasicDBObject searchQuery = new BasicDBObject(); searchQuery.put("OPFSwitchDatapath", switchId); DBObject dbObj = table.findOne(searchQuery); if (dbObj == null) throw new NotFoundException(); SwitchEntry switchEntry = null; switchEntry = new SwitchEntry(dbObj, this); return switchEntry; } public void addNextHopSwitch(NextHopSwitch nextHopSwitch) throws DuplicateEntryException { // Check whether there is an existing next hop switch with the same name if (nextHopSwitchExistsByName(nextHopSwitch.getName())) throw new DuplicateEntryException(); // Get the match criteria table DBCollection table = database.getCollection(DatabaseNames.getNextHopSwitchTableName()); // Create a document containing the new match criteria BasicDBObject document = nextHopSwitch.getAsDocument(); // Add the new tap policy document to the tap policy table table.insert(document); // Get the object ID from mongo and update it in the switch entry object ObjectId objectId = document.getObjectId("_id"); nextHopSwitch.setObjectId(objectId.toString()); logger.info("Added Next Hop Switch " + nextHopSwitch.getName() + " object ID " + nextHopSwitch.getObjectId()); } public void modifyNextHopSwitch(final String nhsId, NextHopSwitch nextHopSwitch) throws NotFoundException { DBCollection table = database.getCollection(DatabaseNames.getNextHopSwitchTableName()); // Create a query to look for the existing NextHopSwitch by ID BasicDBObject searchQuery = new BasicDBObject(); searchQuery.put("_id", new ObjectId(nhsId)); // Check whether the nextHopSwitch exists DBObject dbObj = table.findOne(searchQuery); if (dbObj == null) throw new NotFoundException(); // Create a document containing the new nextHopSwitch BasicDBObject newDocument = nextHopSwitch.getAsDocument(); BasicDBObject updateObj = new BasicDBObject(); updateObj.put("$set", newDocument); // Update the document in the database table.update(searchQuery, updateObj); logger.info("Updated NextHopSwitch id " + nhsId); } // Delete the NextHopSwitch with the specified objectId public void deleteNextHopSwitch(String objectId) throws NotFoundException { DBCollection table = database.getCollection(DatabaseNames.getNextHopSwitchTableName()); // Create a query to look for the existing NextHopSwitch by ID BasicDBObject searchQuery = new BasicDBObject(); searchQuery.put("_id", new ObjectId(objectId)); DBObject dbObj = table.findOne(searchQuery); if (dbObj == null) throw new NotFoundException(); // Get the existing nextHopSwitch name String nhsName = (String) dbObj.get("name"); // Remove the nextHopSwitch from the database table.remove(searchQuery); logger.info("Removed Next Hop Switch " + nhsName); // Notify the application that the capture device changed // TODO - add objectID // tappingAppLogic.NotifyConfigChange(DBTableChangeEnum.NEXT_HOP_SWITCH; } private boolean nextHopSwitchExistsByName(String switchName) { DBCollection table = database.getCollection(DatabaseNames.getSwitchEntryTableName()); // Run a query to look for the SwitchEntry name BasicDBObject searchQuery = new BasicDBObject(); searchQuery.put("name", switchName); DBObject dbObj = table.findOne(searchQuery); return (dbObj != null) ? true : false; } public void addCaptureDevice(CaptureDev captureDev) throws DuplicateEntryException { // Check whether there is an existing capture device with the same name if (captureDeviceExistsByName(captureDev.getName())) throw new DuplicateEntryException(); // Get the match criteria table DBCollection table = database.getCollection(DatabaseNames.getCaptureDevTableName()); // Create a document containing the new match criteria BasicDBObject document = captureDev.getAsDocument(); // Add the new tap policy document to the tap policy table table.insert(document); // Get the object ID from mongo and update it in the switch entry object ObjectId objectId = document.getObjectId("_id"); captureDev.setObjectId(objectId.toString()); logger.info("Added Next Hop Switch " + captureDev.getName() + " object ID " + captureDev.getObjectId()); } private boolean captureDeviceExistsByName(String name) { DBCollection table = database.getCollection(DatabaseNames.getCaptureDevTableName()); // Run a query to look for the SwitchEntry name BasicDBObject searchQuery = new BasicDBObject(); searchQuery.put("name", name); DBObject dbObj = table.findOne(searchQuery); return (dbObj != null) ? true : false; } public void modifyCaptureDev(final String captureDevId, CaptureDev captureDev) throws NotFoundException { DBCollection table = database.getCollection(DatabaseNames.getCaptureDevTableName()); // Create a query to look for the existing CaptureDev by ID BasicDBObject searchQuery = new BasicDBObject(); searchQuery.put("_id", new ObjectId(captureDevId)); // Check whether the CaptureDev exists DBObject dbObj = table.findOne(searchQuery); if (dbObj == null) throw new NotFoundException(); // Create a document containing the new switch Entry BasicDBObject newDocument = captureDev.getAsDocument(); BasicDBObject updateObj = new BasicDBObject(); updateObj.put("$set", newDocument); // Update the document in the database table.update(searchQuery, updateObj); logger.info("Updated CaptureDev id " + captureDevId); } // Delete the CaptureDev with the specified objectId public void deleteCaptureDev(String objectId) throws NotFoundException, ObjectInUseException { DBCollection table = database.getCollection(DatabaseNames.getCaptureDevTableName()); // Create a query to look for the existing CaptureDev by ID BasicDBObject searchQuery = new BasicDBObject(); searchQuery.put("_id", new ObjectId(objectId)); DBObject dbObj = table.findOne(searchQuery); if (dbObj == null) throw new NotFoundException(); if ((long) dbObj.get("refCount") != 0) { throw new ObjectInUseException(); } // Get the existing captureDev String captureDevName = (String) dbObj.get("name"); // Remove the captureDev from the database table.remove(searchQuery); logger.info("Removed Capture Device " + captureDevName); // Notify the application that the capture device changed // TODO - add objectID // tappingAppLogic.NotifyConfigChange(DBTableChangeEnum.CAPTURE_DEVICE); } public void addPortChain(PortChain portChain) throws DuplicateEntryException { // Check whether there is an existing port chain with the same name if (portChainExistsByName(portChain.getName())) throw new DuplicateEntryException(); // Get the match criteria table DBCollection table = database.getCollection(DatabaseNames.getPortChainTableName()); // Create a document containing the new match criteria BasicDBObject document = portChain.getAsDocument(); // Add the new tap policy document to the tap policy table table.insert(document); // Get the object ID from mongo and update it in the switch entry object ObjectId objectId = document.getObjectId("_id"); portChain.setObjectId(objectId.toString()); logger.info("Added Port Chain " + portChain.getName() + " object ID " + portChain.getObjectId()); } private boolean portChainExistsByName(String name) { DBCollection table = database.getCollection(DatabaseNames.getPortChainTableName()); // Run a query to look for the PortChain name BasicDBObject searchQuery = new BasicDBObject(); searchQuery.put("name", name); DBObject dbObj = table.findOne(searchQuery); return (dbObj != null) ? true : false; } public void modifyPortChain(final String portChainId, PortChain portChain) throws NotFoundException { DBCollection table = database.getCollection(DatabaseNames.getPortChainTableName()); // Create a query to look for the existing PortChain by ID BasicDBObject searchQuery = new BasicDBObject(); searchQuery.put("_id", new ObjectId(portChainId)); // Check whether the PortChain exists DBObject dbObj = table.findOne(searchQuery); if (dbObj == null) throw new NotFoundException(); // Create a document containing the new portChain BasicDBObject newDocument = portChain.getAsDocument(); BasicDBObject updateObj = new BasicDBObject(); updateObj.put("$set", newDocument); // Update the document in the database table.update(searchQuery, updateObj); logger.info("Updated PortChain ID " + portChainId); } // Delete the PortChain with the specified objectId public void deletePortChain(String objectId) throws NotFoundException, ObjectInUseException { DBCollection table = database.getCollection(DatabaseNames.getPortChainTableName()); // Create a query to look for the existing TapPolicy by ID BasicDBObject searchQuery = new BasicDBObject(); searchQuery.put("_id", new ObjectId(objectId)); DBObject dbObj = table.findOne(searchQuery); if (dbObj == null) throw new NotFoundException(); if ((long) dbObj.get("refCount") != 0) { throw new ObjectInUseException(); } // Get the existing PortChain String portChainName = (String) dbObj.get("name"); // Remove the PortChain from the database table.remove(searchQuery); logger.info("Removed Port Chain " + portChainName); // Notify the application that the port chaun changed // TODO - add objectID // tappingAppLogic.NotifyConfigChange(DBTableChangeEnum.PORT_CHAIN); } public List<LoggedMessage> loadLoggedMessagesFromDatabase() { DBCollection logTable = database.getCollection(DatabaseNames.getLoggerTableName()); DBCursor cursor = logTable.find(); List<LoggedMessage> loggedMessageList = processLogMessageCursor(cursor); cursor.close(); return loggedMessageList; } public List<LoggedMessage> loadLoggedMessagesFromDatabase(final Date startDate, final Date endDate) { DBCollection logTable = database.getCollection(DatabaseNames.getLoggerTableName()); // Create a query to look for log entries after the start date BasicDBObject searchQuery = new BasicDBObject(); searchQuery.put("timestamp", BasicDBObjectBuilder.start("$gte", startDate).add("$lte", endDate).get()); DBCursor cursor = logTable.find(searchQuery); List<LoggedMessage> loggedMessageList = processLogMessageCursor(cursor); cursor.close(); return loggedMessageList; } public List<LoggedMessage> loadLoggedMessagesFromDatabase(final Date startDate) { DBCollection logTable = database.getCollection(DatabaseNames.getLoggerTableName()); // Create a query to look for log entries after the start date BasicDBObject searchQuery = new BasicDBObject(); searchQuery.put("timestamp", new BasicDBObject("$gte", startDate)); DBCursor cursor = logTable.find(searchQuery); List<LoggedMessage> loggedMessageList = processLogMessageCursor(cursor); cursor.close(); return loggedMessageList; } private List<LoggedMessage> processLogMessageCursor(DBCursor cursor) { List<LoggedMessage> loggedMessageList = new ArrayList<LoggedMessage>(cursor.size()); while(cursor.hasNext()) { DBObject logObj = cursor.next(); LoggedMessage logMsg = new LoggedMessage(); ObjectId oid = (ObjectId) logObj.get("_id"); logMsg.setObjectId(oid.toString()); logMsg.setTimestamp((Date) logObj.get("timestamp")); logMsg.setLogLevel(LoggingLevelEnum.getEnum((String) logObj.get("level"))); logMsg.setThreadId((String) logObj.get("thread")); logMsg.setMessage((String) logObj.get("message")); logMsg.setFileName((String) logObj.get("fileName")); logMsg.setMethodName((String) logObj.get("method")); logMsg.setLineNumber(Integer.parseInt((String) logObj.get("lineNumber"))); // get these fields from the "host" sub-document DBObject hostObj = (DBObject) logObj.get("host"); logMsg.setHostname((String) hostObj.get("name")); logMsg.setHostIP((String) hostObj.get("ip")); // Add the message to the list loggedMessageList.add(logMsg); } return loggedMessageList; } public List<PortStatus> getPortStatus(String switchId) { // Get the switch info from ODL SwitchInfo switchInfo = getSwitchInfo(switchId); List<PortStatus> portStatusList = new ArrayList<PortStatus>(switchInfo.numPorts); for (int port = 0; port < switchInfo.numPorts; port++) { LinkStateEnum portState = switchInfo.portStateList.get(port); boolean live = ((port % 3 == 0) ? true : false); boolean blocked = ((port % 10 == 0) ? true : false); PortTypeEnum type = PortTypeEnum.NETWORK_DEVICE; if (port == 22) type = PortTypeEnum.CAPTURE_DEVICE; if ((port == 10) || (port == 11)) type = PortTypeEnum.PORT_CHAIN; portStatusList.add(new PortStatus(port, type, portState, blocked, live)); } return portStatusList; } public List<PortStatistics> getPortStatistics(String switchId) { // Get the switch statistics from ODL SwitchInfo switchInfo = getSwitchInfo(switchId); List<PortStatistics> portStatisticsList = new ArrayList<PortStatistics>(switchInfo.numPorts); for (int port = 0; port < switchInfo.numPorts; port++) { PortStatistics portStatistics = switchInfo.portStatisticsList.get(port); portStatisticsList.add(portStatistics); } return portStatisticsList; } private SwitchInfo getSwitchInfo(String switchId) { // Note switch ID is not used yet. Eventually plumb this into ODL SwitchInfo switchInfo = new SwitchInfo(); return switchInfo; } public TapPolicy getTapPolicyById(String tapPolicyId) throws NotFoundException { DBCollection table = database.getCollection(DatabaseNames.getTapPolicyTableName()); // Create a query to look for the existing TapPolicy by ID BasicDBObject searchQuery = new BasicDBObject(); searchQuery.put("_id", new ObjectId(tapPolicyId)); // Check whether the policy exists DBObject dbObj = table.findOne(searchQuery); if (dbObj == null) throw new NotFoundException(); // Construct a new tap policy from the DBobject and add it to list TapPolicy tapPolicy = new TapPolicy(dbObj); return tapPolicy; } public MatchCriteria getMatchCriteriaById(String matchCriteriaId) throws NotFoundException { DBCollection table = database.getCollection(DatabaseNames.getMatchCriteriaTableName()); // Create a query to look for the existing MatchCriteria by ID BasicDBObject searchQuery = new BasicDBObject(); searchQuery.put("_id", new ObjectId(matchCriteriaId)); // Check whether the policy exists DBObject dbObj = table.findOne(searchQuery); if (dbObj == null) throw new NotFoundException(); // Construct a new match criteria from the DBobject and add it to list MatchCriteria matchCriteria = new MatchCriteria(dbObj); return matchCriteria; } public SwitchEntry getSwitchEntryById(String switchId) throws NotFoundException { DBCollection table = database.getCollection(DatabaseNames.getSwitchEntryTableName()); // Create a query to look for the existing SwitchEntry by ID BasicDBObject searchQuery = new BasicDBObject(); searchQuery.put("_id", new ObjectId(switchId)); // Check whether the policy exists DBObject dbObj = table.findOne(searchQuery); if (dbObj == null) throw new NotFoundException(); // Construct a new switch entry from the DBobject and return it SwitchEntry switchEntry = new SwitchEntry(dbObj, this); logger.info("SwitchEntry " + switchEntry); return switchEntry; } public PortChain getPortChainById(String portChainId) throws NotFoundException { DBCollection table = database.getCollection(DatabaseNames.getPortChainTableName()); // Create a query to look for the existing PortChain by ID BasicDBObject searchQuery = new BasicDBObject(); searchQuery.put("_id", new ObjectId(portChainId)); // Check whether the port chain exists DBObject dbObj = table.findOne(searchQuery); if (dbObj == null) throw new NotFoundException(); // Construct a new port chain from the DBobject and return it PortChain portChain = new PortChain(dbObj); return portChain; } public static CaptureDev getCaptureDevById(String captureDevId) throws NotFoundException { DBCollection table = database.getCollection(DatabaseNames.getCaptureDevTableName()); // Create a query to look for the existing CaptureDev by ID BasicDBObject searchQuery = new BasicDBObject(); searchQuery.put("_id", new ObjectId(captureDevId)); // Check whether the captureDev exists DBObject dbObj = table.findOne(searchQuery); if (dbObj == null) throw new NotFoundException(); // Construct a caprture dev from the DBobject and return it CaptureDev captureDev = new CaptureDev(dbObj); return captureDev; } public OPFSwitch getUnAssignedOPFSwitchById(String oPFSwitchDataPath) { OPFSwitch opfSwitch = unassignedOPFSwitchMap.get(oPFSwitchDataPath); return opfSwitch; } public OPFSwitch getAssignedOPFSwitchById(String oPFSwitchDataPath) { OPFSwitch opfSwitch = assignedOPFSwitchMap.get(oPFSwitchDataPath); return opfSwitch; } private void runGetAllObjectsUnitTest() { List<TapPolicy> tapPolicyList = this.getAllTapPolicies(); for(TapPolicy tp : tapPolicyList) { logger.info(tp.toString()); System.out.println(tp.toString()); } List<MatchCriteria> matchCriteriaList = this.getAllMatchCriteria(); for(MatchCriteria mc : matchCriteriaList) { logger.info(mc.toString()); System.out.println(mc.toString()); } List<SwitchEntry> switchEntryList = this.getAllSwitchEntries(); for(SwitchEntry se : switchEntryList) { logger.info(se.toString()); System.out.println(se.toString()); } List<NextHopSwitch> nextHopSwitchList = this.getAllNextHopSwitches(); for(NextHopSwitch nhs : nextHopSwitchList) { logger.info(nhs.toString()); System.out.println(nhs.toString()); } List<CaptureDev> captureDevList = this.getAllCaptureDevices(); for(CaptureDev cd : captureDevList) { logger.info(cd.toString()); System.out.println(cd.toString()); } List<PortChain> portChains = this.getAllPortChains(); for (PortChain pc : portChains) { logger.info(pc.toString()); } } private void runLogMessageUnitTest() { List<LoggedMessage> logMessages = this.loadLoggedMessagesFromDatabase(); for(LoggedMessage lm : logMessages) { logger.info("Log Message " + lm); System.out.println("Log Messsage " + lm); } } // Called from ODL when a switch is added/modified/removed public void switchChanged(UpdateType type, Node node) { logger.info("TappingApp::switchChanged"); this.tappingAppLogic.switchChanged(type, node); } public List<TapPolicy> getTapPoliciesForSwitch(SwitchEntry switchEntry) { DBCollection table = database.getCollection(DatabaseNames.getTapPolicyTableName()); List<TapPolicy> tapPoliciesForSwitch = new ArrayList<TapPolicy>(); logger.info("Searching for Tap Policies for switch with ID " + switchEntry.getObjectId()); BasicDBObject searchQuery = new BasicDBObject(); ObjectId switchId = new ObjectId(switchEntry.getObjectId()); searchQuery.put("switchAndPort.switchEntryId", switchId); DBCursor cursor = table.find(searchQuery); logger.info("Query result set contains "+ cursor.count() + "Tap Policies"); try { while(cursor.hasNext()) { TapPolicy tapPolicy; try { tapPolicy = new TapPolicy(cursor.next()); tapPoliciesForSwitch.add(tapPolicy); logger.info("Tap Policy " + tapPolicy); } catch (NotFoundException e) { logger.warn("Cannot find tap policy"); } } } finally { cursor.close(); } return tapPoliciesForSwitch; } // A new switch connected to ODL. We add it to the list of unassigned switches public OPFSwitch createOPFSwitch(Node node) { logger.info("TappingAppLogic::createOPFSwitch"); final String switchId = node.getNodeIDString(); // Get the OPFSwith populated with values from the Node/NodeDescriptor OPFSwitch opfSwitch = null; try { opfSwitch = this.getOPFSwitchFromNode(node); } catch (InternalError e) { logger.warn("Unable to get information about OPFSwitch from the Node"); return opfSwitch; } if (opfSwitch != null) { // TODO -get this somehow opfSwitch.setIPAddress("127.0.0.1"); opfSwitch.setDataPathDesc(switchId); // Simulate a 24 port switch List<PortDescription> fakePortDescList = new ArrayList<PortDescription>(); for (int port = 0; port < 24; port++) { fakePortDescList.add(new PortDescription("Port " + port, "11:22:33:44:aa:bb", port)); } opfSwitch.setPortDescList(fakePortDescList); logger.info("Adding ONF Switch entry to unassignedOPFSwitchMap " + opfSwitch); logger.info("Map Key is " + opfSwitch.getDataPathDesc()); // Add the OPFSwitch to the map this.unassignedOPFSwitchMap.put(opfSwitch.getDataPathDesc(), opfSwitch); List<OPFSwitch> foo = this.getAllUnassignedSwitchEntries(); logger.info("Added switch " + switchId + " to the unrecognied switch list"); logger.info("Unassigned Map " + unassignedOPFSwitchMap); logger.info("Unassigned list " + foo); } return opfSwitch; } public void removeOPFSwitch(Node node) { final String switchId = node.getNodeIDString(); logger.info("Removing OPF switch ID " + switchId); // Look for the switch in the unassigned Map OPFSwitch opfSwitch = this.unassignedOPFSwitchMap.get(switchId); if (opfSwitch != null) { this.unassignedOPFSwitchMap.remove(switchId); logger.info("Removed unassigned OPF Switch " + switchId); } else { // Look for the switch in the assigned Map opfSwitch = this.assignedOPFSwitchMap.get(switchId); if (opfSwitch != null) { this.assignedOPFSwitchMap.remove(switchId); } else { logger.warn("Attempt to remove nonexistent OPF Switch " + switchId); } } } // // Temporary code just until we can hook up the GUI // public void bindSwitchEntryToOPF(String opfSwitchId) throws InternalError { // // SwitchEntry switchEntry = null; // try { // switchEntry = findSwitchByDataPathId(opfSwitchId); // } catch (NotFoundException e) { // logger.info("Can't find switch with ID " + opfSwitchId); // } // // if (switchEntry == null ) { // logger.info("Creating new SwitchEntry"); // // SwitchEntry newSwitchEntry = new SwitchEntry(); // newSwitchEntry.setName("OVS Switch 1: br_int"); // newSwitchEntry.setTappingMode(TappingModeEnum.TAPAGGR); // // // Add the new switch entry to the system // try { // this.addSwitchEntry(newSwitchEntry); // } catch (DuplicateEntryException e1) { // logger.error("Internal Error: Duplicate SwitchEntry", e1); // throw new InternalError("Internal Error: Duplicate SwitchEntry but can't find it"); // } // // logger.info("SwitchEntry Added " + newSwitchEntry); // // // Assign the OPF Switch to the new SwitchEntry // try { // this.assignSwitch(opfSwitchId, newSwitchEntry.getObjectId()); // } catch (NotFoundException e) { // logger.error("SwitchEntry Not Found", e); // } catch (OPFSwitchNotFoundException e) { // logger.error("OPF Switch Not Found, e"); // } catch (OPFSwitchIsAssignedException e) { // logger.error("OPFSwitch is already assigned", e); // } // // // this.tappingAppLogic.createDemoObjects(newSwitchEntry); // } // } // Return an OPFSwitch object populated with values from the NodeDescriptor public OPFSwitch getOPFSwitchFromNode(Node node) throws InternalError { if (this.onfTappingAppImpl.getStatisticsManager() == null) { logger.warn("ONFTappingAppImpl.StatisticsManager is null"); throw new InternalError(); } NodeDescription nodeDesc = this.onfTappingAppImpl.getStatisticsManager().getNodeDescription(node); if (nodeDesc == null){ logger.warn("Node Description is null"); throw new InternalError(); } else logger.info("NodeDesc " + nodeDesc); return new OPFSwitch(nodeDesc, node.getNodeIDString()); } // Check the assigned and unassigned switch maps public OPFSwitch getOPFSwitchById(String opfSwitchId) { // See if we have an existing entry for this OPF Switch OPFSwitch opfSwitch = this.getAssignedOPFSwitchById(opfSwitchId); if (opfSwitch == null) opfSwitch = this.getUnAssignedOPFSwitchById(opfSwitchId); return opfSwitch; } // Add the FlowRules to the ruleMap (in-memory database). // Rules are installed into the switch by InstallSwitchRules public void installFlowRules(List<FlowEntry> flowRules, Node node) { // Add the rules to the rule map (key is the node) this.rulesDB.put(node, flowRules); Set<Node> switchesToProgram = new HashSet<Node>(); // Add the switch to the set of switches to program switchesToProgram.add(node); // And now send them to the switch this.pushFlowRulesToSwitch(switchesToProgram); } // Routine that fetches the switch rules from the rulesDB and installs them into // the switch hardware. The one having the same match rules will be // overwritten silently. // // @return a return code to indicate the result of programming the switch private RulesProgrammingReturnCode pushFlowRulesToSwitch(Set<Node> switchesToProgram) { logger.info("pushFlowRulesToSwitch"); if (switchesToProgram == null) { logger.info("No switches to program"); logger.info("Leaving installSwitchRules. Return code is: " + RulesProgrammingReturnCode.FAILED_WRONG_PARAMS); return RulesProgrammingReturnCode.FAILED_WRONG_PARAMS; } // Get the Forwarding Rules Manager from ODL (via the Impl) IForwardingRulesManager forwardinRulesMgr = this.onfTappingAppImpl.getForwardingRulesManager(); if (forwardinRulesMgr == null) { logger.warn("Cannot install flow ... Fowarding Rules Mananger is null"); return RulesProgrammingReturnCode.FAILED_ALL_SWITCHES; } RulesProgrammingReturnCode returnCode = RulesProgrammingReturnCode.SUCCESS; // Now program every switch logger.info("Inside pushFlowRulesToSwitch. There are " + switchesToProgram.size() + " switches to program"); // Program each switch ... for (Node swId : switchesToProgram) { List<FlowEntry> flowEntryList = this.rulesDB.get(swId); if (flowEntryList == null) { logger.info("Flow entry list is null"); continue; } logger.info("Inside installSwitchRules. There are " + flowEntryList.size() + " flows"); for (FlowEntry flowEntry : flowEntryList) { if (flowEntry != null) { logger.info("Installing flowEntry " + flowEntry.toString()); // Populate the Policy field now logger.info("Installing flow " + flowEntry + " using the ForwardingManager"); Status poStatus = forwardinRulesMgr.modifyOrAddFlowEntry(flowEntry); logger.info("FowardingManager returned " + poStatus); if (!poStatus.isSuccess()) { logger.error("Failed to install policy: " + flowEntry.getGroupName() + " (" + poStatus.getDescription() + ")"); returnCode = RulesProgrammingReturnCode.FAILED_FEW_SWITCHES; // Remove the entry from the DB, it was not installed! this.rulesDB.remove(swId); } else { logger.debug("Successfully installed policy " + flowEntry.toString() + " on switch " + swId); } } else { logger.error("Cannot find a policy for SW:({}))", swId); } } } logger.info("Leaving installSwitchRules. Return code is: " + returnCode); return returnCode; } // Get the set of NodeConnectors for a node (requires acces to the SwitchManager public Set<NodeConnector> getODLNodeConnectors(Node node) { // Get the set of nodeConnectors Set<NodeConnector> ports = this.onfTappingAppImpl.getSwitchManager().getNodeConnectors(node); Iterator<NodeConnector> portIt = ports.iterator(); // List<NodeConnector> portsArray = new ArrayList<NodeConnector>(); while (portIt.hasNext()) { logger.info("NodeConnector " + portIt.next()); //portsArray.add(portIt.next()); } return ports; //return this.onfTappingAppImpl.getSwitchManager().getNodeConnectors(node); // .getPhysicalNodeConnectors(node); } }