
com.github.sdnwiselab.sdnwise.application.AbstractApplication Maven / Gradle / Ivy
Show all versions of sdn-wise-ctrl Show documentation
/*
* Copyright (C) 2015 SDN-WISE
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package com.github.sdnwiselab.sdnwise.application;
import com.github.sdnwiselab.sdnwise.adapter.AbstractAdapter;
import com.github.sdnwiselab.sdnwise.controller.AbstractController;
import com.github.sdnwiselab.sdnwise.controlplane.ControlPlaneLayer;
import com.github.sdnwiselab.sdnwise.controlplane.ControlPlaneLogger;
import com.github.sdnwiselab.sdnwise.packet.DataPacket;
import com.github.sdnwiselab.sdnwise.packet.NetworkPacket;
import static com.github.sdnwiselab.sdnwise.packet.NetworkPacket.DATA;
import com.github.sdnwiselab.sdnwise.topology.NetworkGraph;
import com.github.sdnwiselab.sdnwise.util.NodeAddress;
import java.util.Observable;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Representation of the sensor network and resolver of all the data packets
* coming from the network itself. This abstract class has two main private
* methods. managePacket and graphUpdate(abstract). The first is called when a
* request is coming from the network while the latter is called when something
* in the topology of the network changes.
*
* There are a send and a receive methods to/from the Adaptation Layer
*
* @author Sebastiano Milardo
*/
public abstract class AbstractApplication extends ControlPlaneLayer {
/**
* To avoid garbage collection of the logger.
*/
protected static final Logger LOGGER = Logger.getLogger("APP");
/**
* Incomig packets queue size.
*/
private static final int QUEUE_SIZE = 1000;
/**
* Incoming packets queue.
*/
private final ArrayBlockingQueue bQ;
/**
* Controller.
*/
private final AbstractController controller;
/**
* Creates an Application Abstract Class.
*
* @param ctrl the controller to be used
* @param lower the adapter to be used
*/
public AbstractApplication(final AbstractController ctrl,
final AbstractAdapter lower) {
super("APP", lower, null);
ControlPlaneLogger.setupLogger(getLayerShortName());
controller = ctrl;
bQ = new ArrayBlockingQueue<>(QUEUE_SIZE);
}
/**
* Gets the Network Graph of this AbstractController.
*
* @return the controller network graph.
*/
public final NetworkGraph getNetworkGraph() {
return controller.getNetworkGraph();
}
/**
* Invoked every time there is a change in the topology of the network. A
* change can be an added/removed node/link or a variation in the rssi
* between nodes. The granularity of this updates can be specified in the
* NetworkGraph class.
*/
public abstract void graphUpdate();
/**
* Invoked every time a DataPacket is received by the application.
*
* @param data incoming DataPacket.
*/
public abstract void receivePacket(final DataPacket data);
/**
* Sends a generic message to a node. The message is represented by an array
* of bytes.
*
* @param net network id of the dst node
* @param dst network address of the dst node
* @param message the content of the message to be sent
*/
public final void sendMessage(final byte net, final NodeAddress dst,
final byte[] message) {
if (message.length != 0) {
DataPacket dp = new DataPacket(net, controller.getSinkAddress(),
dst, message);
dp.setNxh(controller.getSinkAddress());
getLower().send(dp.toByteArray());
}
}
/**
* Sends a generic message to a node. The message is represented by string.
*
* @param net network id of the destination node
* @param destination network address of the destination node
* @param message the content of the message to be sent
*/
public final void sendMessage(final byte net, final NodeAddress destination,
final String message) {
if (message != null && !message.isEmpty()) {
sendMessage(net, destination, message.getBytes(UTF8_CHARSET));
}
}
@Override
public final void update(final Observable o, final Object arg) {
if (o.equals(getLower())) {
try {
bQ.put(new NetworkPacket((byte[]) arg));
} catch (InterruptedException ex) {
log(Level.SEVERE, ex.toString());
}
}
}
@Override
protected final void setupLayer() {
new Thread(new Worker()).start();
}
/**
* Extracts the packets from the incoming queue and send them to the
* receivePacket function.
*/
private class Worker implements Runnable {
@Override
public void run() {
while (true) {
try {
NetworkPacket data = bQ.take();
if (data.getTyp() == DATA) {
receivePacket(new DataPacket(data));
}
} catch (InterruptedException ex) {
log(Level.SEVERE, ex.toString());
}
}
}
}
}