net.onrc.openvirtex.util.OVXFlowManager.java Source code

Java tutorial

Introduction

Here is the source code for net.onrc.openvirtex.util.OVXFlowManager.java

Source

/*******************************************************************************
 * Copyright 2014 Open Networking 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
 *
 * 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.
 ******************************************************************************/
package net.onrc.openvirtex.util;

import java.math.BigInteger;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import net.onrc.openvirtex.elements.host.Host;
import net.onrc.openvirtex.exceptions.DroppedMessageException;
import net.onrc.openvirtex.exceptions.IndexOutOfBoundException;
import net.onrc.openvirtex.util.BitSetIndex.IndexType;

import org.apache.commons.lang.ArrayUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.google.common.collect.HashBiMap;

public class OVXFlowManager {
    static Logger log = LogManager.getLogger(OVXFlowManager.class.getName());

    private final HashBiMap<Integer, BigInteger> flowValues;
    private final BitSetIndex flowCounter;
    private final Integer tenantId;
    private Collection<Host> hostList;

    public OVXFlowManager(Integer tenantId, Collection<Host> hostList) {
        this.flowValues = HashBiMap.create();
        this.flowCounter = new BitSetIndex(IndexType.FLOW_COUNTER);
        this.tenantId = tenantId;
        this.hostList = hostList;
    }

    public Integer storeFlowValues(final byte[] srcMac, final byte[] dstMac) throws IndexOutOfBoundException {
        // TODO: Optimize flow numbers
        final BigInteger dualMac = new BigInteger(ArrayUtils.addAll(srcMac, dstMac));
        Integer flowId = this.flowValues.inverse().get(dualMac);
        if (flowId == null) {
            flowId = this.flowCounter.getNewIndex();
            log.debug("virtual net = {}: save flowId = {} that is associated to {} {}", this.tenantId, flowId,
                    MACAddress.valueOf(srcMac).toString(), MACAddress.valueOf(dstMac).toString());
            this.flowValues.put(flowId, dualMac);
        }
        return flowId;
    }

    public LinkedList<MACAddress> getFlowValues(final Integer flowId) {
        final LinkedList<MACAddress> macList = new LinkedList<MACAddress>();
        final BigInteger dualMac = this.flowValues.get(flowId);
        if (dualMac != null) {
            final MACAddress srcMac = MACAddress.valueOf(dualMac.shiftRight(48).longValue());
            final MACAddress dstMac = MACAddress.valueOf(dualMac.longValue());
            macList.add(srcMac);
            macList.add(dstMac);
        }
        return macList;
    }

    public Integer getFlowId(final byte[] srcMac, final byte[] dstMac) throws DroppedMessageException {
        final BigInteger dualMac = new BigInteger(ArrayUtils.addAll(srcMac, dstMac));
        final Integer flowId = this.flowValues.inverse().get(dualMac);
        if (flowId != null && flowId != 0) {
            log.debug("virtual net = {}: retrieving flowId {} that is associated to {} {}", this.tenantId, flowId,
                    MACAddress.valueOf(srcMac).toString(), MACAddress.valueOf(dstMac).toString());
            return flowId;
        }
        throw new DroppedMessageException("virtual net =  " + this.tenantId
                + ": unable to retrive the flowId associated to these mac addresses: "
                + MACAddress.valueOf(srcMac).toString() + "-" + MACAddress.valueOf(dstMac).toString()
                + ". Dropping message!");
    }

    /**
     * Gets list of all registered MAC addresses in this virtual network.
     */
    private List<MACAddress> getMACList() {
        final List<MACAddress> result = new LinkedList<MACAddress>();
        for (final Host host : this.hostList) {
            result.add(host.getMac());
        }
        return result;
    }

    public void boot() throws IndexOutOfBoundException {
        final List<MACAddress> macList = this.getMACList();
        for (final MACAddress srcMac : macList) {
            this.storeFlowValues(srcMac.toBytes(), MACAddress.valueOf("ff:ff:ff:ff:ff:ff").toBytes());
            for (final MACAddress dstMac : macList) {
                if (srcMac.toLong() != dstMac.toLong()) {
                    this.storeFlowValues(srcMac.toBytes(), dstMac.toBytes());
                }
            }
        }
    }
}