/* 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.Iterator;
import java.util.List;
import javax.naming.OperationNotSupportedException;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import org.apache.log4j.Logger;
import org.bson.types.ObjectId;
import org.opendaylight.controller.forwardingrulesmanager.FlowEntry;
import org.opendaylight.controller.sal.action.Action;
import org.opendaylight.controller.sal.core.Node;
public class TapPolicy {
private String objectId = "";
private String name = "";
private String description = "";
private boolean enabled = false;
// Specifies the criteria used to match this policy
List<String> matchCriteriaIdList = new ArrayList<String>();
List<String> captureDevIdList = new ArrayList<String>();
List<String> portChainIdList = new ArrayList<String>();
// Stores the SwitchAndPort objects defined for this policy
List<SwitchAndPort> switchAndPortList = new ArrayList<SwitchAndPort>();
private static final Logger logger = Logger.getLogger(TappingApp.class);
// Construct an empty object
public TapPolicy() {
}
public TapPolicy(String objectId, String name, String description, boolean enabled) {
this.objectId = objectId;
setName(name);
setDescription(description);
setEnabled(enabled);
}
// Construct from a database object
public TapPolicy(DBObject tapPolicyObj) throws NotFoundException {
ObjectId oid = (ObjectId) tapPolicyObj.get("_id");
this.setObjectId(oid.toString());
this.setName((String) tapPolicyObj.get("name"));
this.setDescription((String) tapPolicyObj.get("description"));
this.setEnabled((Boolean) tapPolicyObj.get("enabled"));
BasicDBList mcList = (BasicDBList) tapPolicyObj.get("matchCriteria");
Iterator<Object> mcListIt = mcList.iterator();
while (mcListIt.hasNext()) {
String matchCriteriaId = (String) mcListIt.next();
this.addMatchCriteria(matchCriteriaId);
}
BasicDBList swAndPortList = (BasicDBList) tapPolicyObj.get("switchAndPort");
Iterator<Object> swAndPortListIt = swAndPortList.iterator();
while (swAndPortListIt.hasNext()) {
DBObject sapObj = (DBObject) swAndPortListIt.next();
SwitchAndPort switchAndPort = new SwitchAndPort(sapObj);
this.addSwitchAndPort(switchAndPort);
}
BasicDBList cdList = (BasicDBList) tapPolicyObj.get("captureDev");
Iterator<Object> cdListIt = cdList.iterator();
while (cdListIt.hasNext()) {
String captureDevId = (String) cdListIt.next();
this.addCaptureDev(captureDevId);
}
BasicDBList pcList = (BasicDBList) tapPolicyObj.get("portChain");
Iterator<Object> pcListIt = pcList.iterator();
while (pcListIt.hasNext()) {
String portChainId = (String) pcListIt.next();
this.addPortChain(portChainId);
}
}
// Copy constructor
public TapPolicy(TapPolicy tapPolicy) {
this.objectId = tapPolicy.getObjectId();
this.name = tapPolicy.getName();
this.description = tapPolicy.getDescription();
this.enabled = tapPolicy.isEnabled();
this.matchCriteriaIdList = new ArrayList<String>(tapPolicy.getMatchCriteriaIdList());
this.captureDevIdList = new ArrayList<String>(tapPolicy.getCaptureDevList());
this.portChainIdList = new ArrayList<String>(tapPolicy.getPortChainList());
this.switchAndPortList = new ArrayList<SwitchAndPort>(tapPolicy.getSwitchAndPortList());
}
// Getters and setters
public String getObjectId() {
return objectId;
}
public void setObjectId(String objectId) {
this.objectId = objectId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enable) {
this.enabled = enable;
}
public void addMatchCriteria(final MatchCriteria matchCriteria) throws NotFoundException {
this.addMatchCriteria(matchCriteria.getObjectId());
}
public void addMatchCriteria(final String matchCriteriaId) throws NotFoundException {
// Increment the reference count
MatchCriteria.adjustReferenceCount(ReferenceCountEnum.INCREMENT, matchCriteriaId);
// Add the match criteria to this policy's list
this.matchCriteriaIdList.add(matchCriteriaId);
}
public void removeMatchCriteria(String matchCriteriaId) throws NotFoundException{
// Decrement the reference count
MatchCriteria.adjustReferenceCount(ReferenceCountEnum.DECREMENT, matchCriteriaId);
// Remove the match criteria to this policy's list
this.matchCriteriaIdList.remove(matchCriteriaId);
}
public List<String> getMatchCriteriaIdList() {
List<String> cloneList = new ArrayList<String>(matchCriteriaIdList.size());
Iterator<String> it = matchCriteriaIdList.iterator();
while (it.hasNext()) {
String matchCriteriaId = it.next();
cloneList.add(matchCriteriaId);
}
return cloneList;
}
public void addSwitchAndPort(final SwitchAndPort switchAndPort) throws NotFoundException {
// Get the Switch ID from the SwitchAndPort
String switchEntryId = switchAndPort.getSwitchIdStr();
// Increment the reference count on the SwitchEntry
SwitchEntry.adjustReferenceCount(ReferenceCountEnum.INCREMENT, switchEntryId);
// Add the switch entry to this policy's list
this.switchAndPortList.add(switchAndPort);
}
public void removeSwitchAndPort(SwitchAndPort switchAndPort) throws NotFoundException {
// Get the Switch ID from the SwitchAndPort
String switchEntryId = switchAndPort.getSwitchIdStr();
// Decrement the reference count
SwitchEntry.adjustReferenceCount(ReferenceCountEnum.DECREMENT, switchEntryId);
// Remove the SwitchAndPort from this policy's list
this.switchAndPortList.remove(switchAndPort);
}
public List<SwitchAndPort> getSwitchAndPortList () {
List<SwitchAndPort> cloneList = new ArrayList<SwitchAndPort>(switchAndPortList.size());
for (SwitchAndPort switchAndPort : switchAndPortList) {
// Copy the SwitchAndPort objects into the cloned list
cloneList.add(switchAndPort.clone());
}
return cloneList;
}
public void addCaptureDev(CaptureDev captureDev) throws NotFoundException {
this.addCaptureDev(captureDev.getObjectId());
}
public void addCaptureDev(String captureDevId) throws NotFoundException {
// Increment the reference count
CaptureDev.adjustReferenceCount(ReferenceCountEnum.INCREMENT, captureDevId);
// Add the match criteria to this policy's list
this.captureDevIdList.add(captureDevId);
}
public void removeCaptureDev(String captureDevId) throws NotFoundException {
// Decrement the reference count
CaptureDev.adjustReferenceCount(ReferenceCountEnum.DECREMENT, captureDevId);
// Remove the match criteria to this policy's list
this.captureDevIdList.remove(captureDevId);
}
public List<String> getCaptureDevList() {
List<String> cloneList = new ArrayList<String>(captureDevIdList.size());
Iterator<String> it = captureDevIdList.iterator();
while (it.hasNext()) {
String captureDevId = it.next();
cloneList.add(captureDevId);
}
return cloneList;
}
public void addPortChain(PortChain portChain) throws NotFoundException {
this.addPortChain(portChain.getObjectId());
}
public void addPortChain(final String portChainId) throws NotFoundException {
// Increment the reference count
PortChain.adjustReferenceCount(ReferenceCountEnum.INCREMENT, portChainId);
// Add the port chain to this policy's list
this.portChainIdList.add(portChainId);
}
public void removePortChain(String portChainId) throws NotFoundException {
// Decrement the reference count
PortChain.adjustReferenceCount(ReferenceCountEnum.DECREMENT, portChainId);
// Remove the match criteria to this policy's list
this.portChainIdList.remove(portChainId);
}
public List<String> getPortChainList() {
List<String> cloneList = new ArrayList<String>(portChainIdList.size());
Iterator<String> it = portChainIdList.iterator();
while (it.hasNext()) {
String portChainId = it.next();
cloneList.add(portChainId);
}
return cloneList;
}
// Return a summary of the Tap Policy object (for the GUI)
public TapPolicySummary getSummary() {
TapPolicySummary summary = new TapPolicySummary(getObjectId(), getName(), getDescription(), isEnabled());
return summary;
}
public BasicDBObject getAsDocument() {
BasicDBObject document = new BasicDBObject();
document.put("name", getName());
document.put("description", getDescription());
document.put("enabled", isEnabled());
document.put("creationDate", new Date());
// Add Match Criteria ID list Sub-document
BasicDBList matchCriteriaListDoc = new BasicDBList();
for (int i = 0; i < matchCriteriaIdList.size(); i++) {
String matchCriteriaId = matchCriteriaIdList.get(i);
matchCriteriaListDoc.add(matchCriteriaId);
}
document.put("matchCriteria", matchCriteriaListDoc);
// Add SwitchAndPort Sub-document
BasicDBList switchAndPortListDoc = new BasicDBList();
for (SwitchAndPort switchAndPort : switchAndPortList) {
switchAndPortListDoc.add(switchAndPort.getAsDocument());
}
document.put("switchAndPort", switchAndPortListDoc);
// Add Capture Device Sub-document
BasicDBList captureDevListDoc = new BasicDBList();
for (int i = 0; i < captureDevIdList.size(); i++) {
String captureDevId = captureDevIdList.get(i);
captureDevListDoc.add(captureDevId);
}
document.put("captureDev", captureDevListDoc);
// Add Port Chain Sub-document
BasicDBList portChainListDoc = new BasicDBList();
for (int i = 0; i < portChainIdList.size(); i++) {
String portChainId = portChainIdList.get(i);
portChainListDoc.add(portChainId);
}
document.put("portChain", portChainListDoc);
return document;
}
public String toString() {
String objString = "Tap Policy: Object ID: " + getObjectId() + " Name: " + name + " Description: " + description + " enabled: " + enabled;
return objString;
}
// Remove object references for this TapPolicy referred to by the tapPolicyDBObj
public static void removeObjectReferences(DBObject tapPolicyDBObj) throws NotFoundException {
BasicDBList mcList = (BasicDBList) tapPolicyDBObj.get("matchCriteria");
Iterator<Object> mcListIt = mcList.iterator();
while (mcListIt.hasNext()) {
String matchCriteriaId = (String) mcListIt.next();
// Decrement the reference count in the database object
MatchCriteria.adjustReferenceCount(ReferenceCountEnum.DECREMENT, matchCriteriaId);
}
BasicDBList seList = (BasicDBList) tapPolicyDBObj.get("switchEntries");
Iterator<Object> seListIt = seList.iterator();
while (seListIt.hasNext()) {
String switchEntryId = (String) seListIt.next();
// Decrement the reference count in the database object
SwitchEntry.adjustReferenceCount(ReferenceCountEnum.DECREMENT, switchEntryId);
}
BasicDBList cdList = (BasicDBList) tapPolicyDBObj.get("captureDev");
Iterator<Object> cdListIt = cdList.iterator();
while (cdListIt.hasNext()) {
String captureDevId = (String) cdListIt.next();
// Decrement the reference count in the database object
CaptureDev.adjustReferenceCount(ReferenceCountEnum.DECREMENT, captureDevId);
}
BasicDBList pcList = (BasicDBList) tapPolicyDBObj.get("portChain");
Iterator<Object> pcListIt = pcList.iterator();
while (pcListIt.hasNext()) {
String portChainId = (String) pcListIt.next();
// Decrement the reference count in the database object
PortChain.adjustReferenceCount(ReferenceCountEnum.DECREMENT, portChainId);
}
}
public List<Action> generateActionList(Node node, TappingAppLogic tappingAppLogic) throws NotFoundException {
List<Action> actions = new ArrayList<Action>();
for (String captureDevId : this.getCaptureDevList()) {
CaptureDev captureDev = null;
try {
captureDev = TappingApp.getCaptureDevById(captureDevId);
} catch (NotFoundException e) {
logger.warn("Can't find CaptureDev with ID " + captureDevId);
}
if (captureDev.isEnabled()) {
// Only generate actions for CaptureDevices that are enabled
captureDev.generateActionList(actions, node, tappingAppLogic, this);
}
else
logger.info("CaptureDev " + this.getName() + " is disabled");
}
logger.info("Generated " + actions.size() + " actions");
return actions;
}
Node getODLSwitchById(String switchId) throws OperationNotSupportedException {
logger.info("TapPolicy:getODLSwitchById is not implemented");
throw new OperationNotSupportedException();
}
public void createFlowRules(Node node, List<FlowEntry> flowRules, TappingAppLogic tappingAppLogic) throws NotFoundException, InconsistentDatabaseException {
// Generate the list of actions for this policy
List<Action> actionList = this.generateActionList(node, tappingAppLogic);
// Iterate over the match criteria for this policy
for (String matchCriteriaId : this.getMatchCriteriaIdList()) {
try {
MatchCriteria matchCriteria = tappingAppLogic.getMatchCriteriaById(matchCriteriaId);
// Only include MatchCriteria that are enabled
if (matchCriteria.getEnabled() == true) {
// Generate the flow rules for this switch
matchCriteria.generateFlowRules(flowRules, actionList, node);
}
else {
logger.info("MatchCriteria " + matchCriteria.getName() + " is disabled");
}
} catch (NotFoundException e) {
// logger.info("Can't find MatchCriteria " + matchCriteriaId);
throw new InconsistentDatabaseException("Can't find Match Criteria " + matchCriteriaId);
}
}
logger.info("Generated " + flowRules.size() + " rules for switch " + node.getNodeIDString());
}
}