
org.coos.messaging.routing.TopologyMap Maven / Gradle / Ivy
/**
* COOS - Connected Objects Operating System (www.connectedobjects.org).
*
* Copyright (C) 2009 Telenor ASA and Tellu AS. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*
* You may also contact one of the following for additional information:
* Telenor ASA, Snaroyveien 30, N-1331 Fornebu, Norway (www.telenor.no)
* Tellu AS, Hagalokkveien 13, N-1383 Asker, Norway (www.tellu.no)
*/
package org.coos.messaging.routing;
import org.coos.messaging.util.Log;
import org.coos.messaging.util.LogFactory;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author Knut Eilif Husa, Tellu AS Topology map of the COOS network
*/
public class TopologyMap {
private String routerUuid;
private Map curLinkCosts = new ConcurrentHashMap();
private List listeners = new LinkedList();
private long notificationInterval = 200;
private long maxAge = 200;
private Timer timer = new Timer();
private boolean dirty = false;
private final Log logger = LogFactory.getLog(this.getClass());
public TopologyMap(String routerUri) {
this.routerUuid = routerUri;
}
public TopologyMap(String routerUuid, long notificationInterval, long maxAge) {
this.routerUuid = routerUuid;
this.notificationInterval = notificationInterval;
this.maxAge = maxAge;
}
public void update(Vector linkCosts) { // Todo optimize serialization of
// linkCosts
// System.out.println("Updating topology map router: " + routerUri);
for (int i = 0; i < linkCosts.size(); i++) {
LinkCost linkCost = (LinkCost) linkCosts.elementAt(i);
LinkCost currentCost = curLinkCosts.get(linkCost.getKey());
if (currentCost != null) {
if (!linkCost.getLinkId().equals(currentCost.getLinkId())) {
// New link
LinkCost lc = new LinkCost(linkCost);
this.curLinkCosts.put(linkCost.getKey(), lc);
dirty = true;
} else {
// check change in cost to trigger a recalculation of
// optimal paths
for (String qos : currentCost.getQoSClasses()) {
int curCost = currentCost.getCost(qos);
int candCost = linkCost.getCost(qos);
if (curCost != candCost) {
dirty = true;
break;
}
}
for (String qos : linkCost.getQoSClasses()) {
// check change in cost
int curCost = currentCost.getCost(qos);
int candCost = linkCost.getCost(qos);
if (curCost != candCost) {
dirty = true;
break;
}
}
// check change in alias to trigger a recalculation of
// optimal paths
// Not necessary, but else we need to call a separate
// interface to deal with this
for (String alias : currentCost.getAliases()) {
if (!linkCost.getAliases().contains(alias)) {
dirty = true;
break;
}
}
for (String alias : linkCost.getAliases()) {
if (!currentCost.getAliases().contains(alias)) {
dirty = true;
break;
}
}
LinkCost lc = new LinkCost(linkCost);
this.curLinkCosts.put(linkCost.getKey(), lc);
}
} else {
LinkCost lc = new LinkCost(linkCost);
this.curLinkCosts.put(linkCost.getKey(), lc);
dirty = true;
}
}
if (dirty) {
// Call listeners
for (int j = 0; j < listeners.size(); j++) {
TopologyMapListener listener = listeners.get(j);
listener.notifyChanged(TopologyMap.this);
}
// remove infinitePaths after listeners have had a chance to react
// on infinite path links
Iterator iter = curLinkCosts.values().iterator();
while (iter.hasNext()) {
LinkCost linkCost = iter.next();
if (!linkCost.isLink()) {
logger.trace("Removing link: " + linkCost.getKey() + " from topologyMap");
iter.remove();
}
}
dirty = false;
}
}
public void update(LinkCost linkCost) {
Vector arg = new Vector();
arg.addElement(linkCost);
update(arg);
}
public List getAliases(String uuid) {
List res = new LinkedList();
for (LinkCost lc : curLinkCosts.values()) {
if (lc.getToUuid().equals(uuid) && !lc.getAliases().isEmpty()) {
res.addAll(lc.getAliases());
}
}
return res;
}
public void addListener(TopologyMapListener listener) {
listeners.add(listener);
}
public void removeListener(TopologyMapListener listener) {
listeners.add(listener);
}
public String getRouterUuid() {
return routerUuid;
}
public boolean isNeighbourNode(String uuid) {
return isNeighbourNode(routerUuid, uuid);
}
public boolean isNeighbourNode(String fromUuid, String toUuid) {
StringBuffer buf = new StringBuffer();
buf.append(fromUuid);
buf.append(",");
buf.append(toUuid);
return curLinkCosts.get(buf.toString()) != null;
}
public Set getNodeUuids() {
// return new HashSet(nodeUris);
HashSet nodeUuid = new HashSet();
for (LinkCost lc : curLinkCosts.values()) {
nodeUuid.add(lc.getFromUuid());
nodeUuid.add(lc.getToUuid());
}
return nodeUuid;
}
public LinkCost getLinkCost(String fromUuid, String toUuid) {
StringBuffer buf = new StringBuffer();
buf.append(fromUuid);
buf.append(",");
buf.append(toUuid);
LinkCost lc = curLinkCosts.get(buf.toString());
if (lc != null) {
return lc;
} else {
return new LinkCost(fromUuid, toUuid, "-1", LinkCost.MAX_VALUE);
}
}
public LinkCost getLinkCost(String toUuid) {
return getLinkCost(routerUuid, toUuid);
}
public void start() {
timer = new Timer();
timer.schedule(new NotificationTask(), 0, notificationInterval);
}
public void stop() {
if (timer != null) {
timer.cancel();
}
}
private class NotificationTask extends TimerTask {
public void run() {
// Check for aging
for (LinkCost linkCost : curLinkCosts.values()) {
if (linkCost.getTimeStamp() + maxAge < System.currentTimeMillis()) {
linkCost.setLink(false);
dirty = true;
logger.trace("Link: " + linkCost.getKey() + " expired");
}
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy