org.opendaylight.controller.samples.onftappingapp.MatchCriteria.java Source code

Java tutorial

Introduction

Here is the source code for org.opendaylight.controller.samples.onftappingapp.MatchCriteria.java

Source

/* 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.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.bson.types.ObjectId;

import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import com.mongodb.WriteResult;

import org.opendaylight.controller.forwardingrulesmanager.FlowEntry;
import org.opendaylight.controller.sal.action.Action;
import org.opendaylight.controller.sal.core.Node;
import org.opendaylight.controller.sal.flowprogrammer.Flow;
import org.opendaylight.controller.sal.match.Match;
import org.opendaylight.controller.samples.onftappingapp.internal.ONFTappingAppImpl;

public class MatchCriteria {

    private long referenceCount = 0;
    private String objectId = "";
    private String name = "";
    private boolean enabled = true;
    private boolean reflexive;
    private int priority;

    // Values to match
    List<MatchField> matchFieldList = new ArrayList<MatchField>();

    private static Logger logger = LoggerFactory.getLogger(ONFTappingAppImpl.class);

    public MatchCriteria() {
        this.referenceCount = 0;
    }

    // Copy constructor
    public MatchCriteria(MatchCriteria matchCriteria) {
        this.objectId = matchCriteria.getObjectId();
        this.name = matchCriteria.getName();
        this.enabled = matchCriteria.getEnabled();
        this.reflexive = matchCriteria.getReflexive();
        this.priority = matchCriteria.getPriority();

        this.matchFieldList = new ArrayList<MatchField>(matchCriteria.getFields());
    }

    public MatchCriteria(DBObject matchCriteriaObj) {

        this.setName((String) matchCriteriaObj.get("name"));
        this.setReferenceCount((long) matchCriteriaObj.get("refCount"));

        ObjectId oid = (ObjectId) matchCriteriaObj.get("_id");
        this.setObjectId(oid.toString());
        this.setEnabled((Boolean) matchCriteriaObj.get("enabled"));
        this.setReflexive((Boolean) matchCriteriaObj.get("reflexive"));
        this.setPriority((int) matchCriteriaObj.get("priority"));

        BasicDBList mfList = (BasicDBList) matchCriteriaObj.get("matchFields");
        BasicDBObject[] mfArray = mfList.toArray(new BasicDBObject[0]);
        for (BasicDBObject dbObj : mfArray) {
            MatchField matchField = new MatchField();
            matchField.setType(dbObj.getString("type"));
            matchField.setValue(dbObj.getString("value"));
            // Add the match field to the match criteria
            this.addMatchField(matchField);
        }
    }

    public long getReferenceCount() {
        return this.referenceCount;
    }

    public void setReferenceCount(final long refCount) {
        this.referenceCount = refCount;
    }

    public String getObjectId() {
        return this.objectId;
    }

    public void setObjectId(String objId) {
        this.objectId = objId;
    }

    public boolean isReflexive() {
        return reflexive;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean getEnabled() {
        return this.enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    public boolean getReflexive() {
        return this.reflexive;
    }

    public int getPriority() {
        return priority;
    }

    public void setPriority(int priority) {
        this.priority = priority;
    }

    public void setReflexive(boolean reflexive1) {
        this.reflexive = reflexive1;
    }

    public List<MatchField> getFields() {
        List<MatchField> cloneList = new ArrayList<MatchField>(matchFieldList.size());

        Iterator<MatchField> it = matchFieldList.iterator();

        while (it.hasNext()) {
            MatchField matchField = it.next();
            cloneList.add(matchField);
        }

        return cloneList;
    }

    // Construct the match criteria fields from a list of MatchField key/value pairs
    public void addMatchField(MatchField matchField) {
        logger.info(matchField.toString());

        // Copy the match criteria into the map and set the bit mask to indicate it is part of the match
        switch (matchField.getType()) {
        case MatchField.UNDEFINED:
            // Ignored
            break;

        case MatchField.ETH_TYPE:
        case MatchField.IP_PROTO:
        case MatchField.IP_TOS:
        case MatchField.VLAN_TAG:
        case MatchField.SOURCE_IP:
        case MatchField.SOURCE_MAC:
        case MatchField.DEST_IP:
        case MatchField.DEST_MAC:
        case MatchField.PROTO_SVC:
        case MatchField.PROTO_PORT:
            matchFieldList.add(matchField);
            break;

        default:
            logger.warn("Unhandled Match Field Type " + matchField.getType());
            break;
        }
    }

    // Construct the match criteria fields from a list of MatchField key/value pairs
    public void setFields(List<MatchField> matchFields) {
        Iterator<MatchField> it = matchFields.iterator();

        while (it.hasNext()) {
            MatchField matchField = it.next();
            addMatchField(matchField);
        }
    }

    public String toString() {
        String objString;

        objString = "Match Criteria: Object ID: " + getObjectId() + " Name:" + getName();

        Iterator<MatchField> it = matchFieldList.iterator();
        while (it.hasNext()) {
            MatchField matchField = it.next();
            objString += ", " + matchField.toString();
        }

        return objString;
    }

    public BasicDBObject getAsDocument() {
        BasicDBObject document = new BasicDBObject();

        document.put("refCount", this.getReferenceCount());
        document.put("name", this.getName());
        document.put("enabled", this.getEnabled());
        document.put("reflexive", this.getReflexive());
        document.put("priority", this.getPriority());

        List<Object> matchFieldsDoc = new BasicDBList();
        for (int i = 0; i < matchFieldList.size(); i++) {
            MatchField matchField = matchFieldList.get(i);
            matchFieldsDoc.add(matchField.getAsDocument());
        }
        document.put("matchFields", matchFieldsDoc);

        return document;
    }

    public static boolean adjustReferenceCount(final ReferenceCountEnum adjType, String matchCriteriaId)
            throws NotFoundException {

        DB database = TappingApp.getDatabase();
        DBCollection table = database.getCollection(DatabaseNames.getMatchCriteriaTableName());

        // Look for the Match Criteria object by object ID in the database
        BasicDBObject searchQuery = new BasicDBObject();
        ObjectId id = new ObjectId(matchCriteriaId);
        searchQuery.put("_id", id);
        DBObject dbObj = table.findOne(searchQuery);

        if (dbObj == null)
            throw new NotFoundException();

        // create an increment query
        DBObject modifier = new BasicDBObject("refCount", (adjType == ReferenceCountEnum.DECREMENT) ? -1 : 1);
        DBObject incQuery = new BasicDBObject("$inc", modifier);

        // increment a counter value atomically
        WriteResult result = table.update(searchQuery, incQuery);
        return (result != null) ? true : false;
    }

    public void generateFlowRules(List<FlowEntry> flowRules, List<Action> actions, Node node) {

        // Add a Match for the set of MatchFields in the MatchCriteria
        List<MatchField> matchFields = this.getFields();

        // OpenDaylight Match object
        Match match = new Match();

        for (MatchField matchField : matchFields) {
            try {
                logger.info("MatchField " + matchField);

                // Get the OpenDaylight Match object for this match field
                matchField.addODLMatch(match);
            } catch (UnknownHostException e) {
                logger.info("Unable to resolve hostname for a MatchField used by MatchCritera " + this.getName());
            } catch (IllegalArgumentException e) {
                logger.info("Cannot create flow from " + matchField + " used by MatchCriteria " + this.getName()
                        + ": Illegal Argument");
            }
        }

        Flow flow = new Flow(match, actions);
        // Install the flows permanently (no timeouts)
        flow.setIdleTimeout((short) 0);
        flow.setHardTimeout((short) 0);

        // Set the priority based on the user input
        flow.setPriority((short) this.getPriority());

        if (this.isReflexive()) {
            logger.info("MatchCriteria is reflexive ... adding reverse flow");
            // TODO -- add this here
        }

        FlowEntry flowEntry = new FlowEntry("ONFTappingApp", this.getName(), flow, node);
        flowRules.add(flowEntry);
    }
}