<tag>HEAD</tag>
</scm>
<artifactId>arphandler</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<packaging>bundle</packaging>
<build>
<configuration>
<instructions>
<Import-Package>
+ org.opendaylight.controller.sal.packet.address,
org.opendaylight.controller.connectionmanager,
org.opendaylight.controller.sal.connection,
org.opendaylight.controller.sal.core,
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${hosttracker.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
-
/*
* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
import org.opendaylight.controller.clustering.services.IClusterContainerServices;
import org.opendaylight.controller.clustering.services.IClusterServices;
import org.opendaylight.controller.connectionmanager.IConnectionManager;
+import org.opendaylight.controller.hosttracker.HostIdFactory;
+import org.opendaylight.controller.hosttracker.IHostId;
import org.opendaylight.controller.hosttracker.IfHostListener;
import org.opendaylight.controller.hosttracker.IfIptoHost;
import org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector;
private BlockingQueue<ARPCacheEvent> ARPCacheEvents = new LinkedBlockingQueue<ARPCacheEvent>();
private Thread cacheEventHandler;
private boolean stopping = false;
+
/*
* A cluster allocated cache. Used for synchronizing ARP request/reply
- * events across all cluster controllers. To raise an event, we put() a specific
- * event object (as key) and all nodes handle it in the entryUpdated callback.
+ * events across all cluster controllers. To raise an event, we put() a
+ * specific event object (as key) and all nodes handle it in the
+ * entryUpdated callback.
*
* In case of ARPReply, we put true value to send replies to any requestors
* by calling generateAndSendReply
*/
private ConcurrentMap<ARPEvent, Boolean> arpRequestReplyEvent;
- void setConnectionManager(IConnectionManager cm){
+ void setConnectionManager(IConnectionManager cm) {
this.connectionManager = cm;
}
- void unsetConnectionManager(IConnectionManager cm){
- if (this.connectionManager == cm){
+ void unsetConnectionManager(IConnectionManager cm) {
+ if (this.connectionManager == cm) {
connectionManager = null;
}
}
- void setClusterContainerService(IClusterContainerServices s){
+ void setClusterContainerService(IClusterContainerServices s) {
this.clusterContainerService = s;
}
}
}
- protected void sendARPReply(NodeConnector p, byte[] sMAC, InetAddress sIP,
- byte[] tMAC, InetAddress tIP) {
+ protected void sendARPReply(NodeConnector p, byte[] sMAC, InetAddress sIP, byte[] tMAC, InetAddress tIP) {
byte[] senderIP = sIP.getAddress();
byte[] targetIP = tIP.getAddress();
- ARP arp = createARP(ARP.REPLY,sMAC,senderIP,tMAC,targetIP);
+ ARP arp = createARP(ARP.REPLY, sMAC, senderIP, tMAC, targetIP);
Ethernet ethernet = createEthernet(sMAC, tMAC, arp);
// Make sure that the host is a legitimate member of this subnet
if (!subnet.hasNodeConnector(p)) {
- log.debug("{} showing up on {} does not belong to {}",
- new Object[] { sourceIP, p, subnet });
+ log.debug("{} showing up on {} does not belong to {}", new Object[] { sourceIP, p, subnet });
return;
}
}
/*
- * OpCode != request -> ARP Reply. If there are hosts (in
- * arpRequestors) waiting for the ARP reply for this sourceIP, it's
- * time to generate the reply and send it to these hosts.
+ * OpCode != request -> ARP Reply. If there are hosts (in arpRequestors)
+ * waiting for the ARP reply for this sourceIP, it's time to generate
+ * the reply and send it to these hosts.
*
* If sourceIP==targetIP, it is a Gratuitous ARP. If there are hosts (in
* arpRequestors) waiting for the ARP reply for this sourceIP, it's time
*/
if (pkt.getOpCode() != ARP.REQUEST || sourceIP.equals(targetIP)) {
- // Raise a reply event so that any waiting requestors will be sent a reply
- // the true value indicates we should generate replies to requestors across the cluster
+ // Raise a reply event so that any waiting requestors will be sent a
+ // reply
+ // the true value indicates we should generate replies to requestors
+ // across the cluster
log.trace("Received ARP reply packet from {}, reply to all requestors.", sourceIP);
arpRequestReplyEvent.put(new ARPReply(sourceIP, sourceMAC), true);
return;
}
/*
- * ARP Request Handling:
- * If targetIP is the IP of the subnet, reply with ARP REPLY
- * If targetIP is a known host, PROXY ARP (by sending ARP REPLY) on behalf of known target hosts.
- * For unknown target hosts, generate and send an ARP request to ALL switches/ports using
- * the IP address defined in the subnet as source address
+ * ARP Request Handling: If targetIP is the IP of the subnet, reply with
+ * ARP REPLY If targetIP is a known host, PROXY ARP (by sending ARP
+ * REPLY) on behalf of known target hosts. For unknown target hosts,
+ * generate and send an ARP request to ALL switches/ports using the IP
+ * address defined in the subnet as source address
*/
/*
* If target IP is gateway IP, Send ARP reply
*/
if ((targetIP.equals(subnet.getNetworkAddress()))
&& (NetUtils.isBroadcastMACAddr(targetMAC) || Arrays.equals(targetMAC, getControllerMAC()))) {
- if (connectionManager.getLocalityStatus(p.getNode()) == ConnectionLocality.LOCAL){
- if (log.isTraceEnabled()){
+ if (connectionManager.getLocalityStatus(p.getNode()) == ConnectionLocality.LOCAL) {
+ if (log.isTraceEnabled()) {
log.trace("Received local ARP req. for default gateway. Replying with controller MAC: {}",
HexEncode.bytesToHexString(getControllerMAC()));
}
return;
}
-
- HostNodeConnector host = hostTracker.hostQuery(targetIP);
+ // Hosttracker hosts db key implementation
+ IHostId id = HostIdFactory.create(targetIP, null);
+ HostNodeConnector host = hostTracker.hostQuery(id);
// unknown host, initiate ARP request
if (host == null) {
// add the requestor to the list so that we can replay the reply
arpRequestors.put(targetIP, requestorSet);
}
requestorSet.add(requestor);
- countDownTimers.put(targetIP, (short) 2); // reset timeout to 2sec
+ countDownTimers.put(targetIP, (short) 2); // reset timeout to
+ // 2sec
}
- //Raise a bcast request event, all controllers need to send one
+ // Raise a bcast request event, all controllers need to send one
log.trace("Sending a bcast ARP request for {}", targetIP);
arpRequestReplyEvent.put(new ARPRequest(targetIP, subnet), false);
} else {
/*
- * Target host known (across the cluster), send ARP REPLY make sure that targetMAC
- * matches the host's MAC if it is not broadcastMAC
+ * Target host known (across the cluster), send ARP REPLY make sure
+ * that targetMAC matches the host's MAC if it is not broadcastMAC
*/
if (NetUtils.isBroadcastMACAddr(targetMAC) || Arrays.equals(host.getDataLayerAddressBytes(), targetMAC)) {
log.trace("Received ARP req. for known host {}, sending reply...", targetIP);
if (connectionManager.getLocalityStatus(p.getNode()) == ConnectionLocality.LOCAL) {
- sendARPReply(p,
- host.getDataLayerAddressBytes(),
- host.getNetworkAddress(),
- pkt.getSenderHardwareAddress(),
- sourceIP);
+ sendARPReply(p, host.getDataLayerAddressBytes(), host.getNetworkAddress(),
+ pkt.getSenderHardwareAddress(), sourceIP);
} else {
- arpRequestReplyEvent.put(new ARPReply(
- p,
- host.getNetworkAddress(),
- host.getDataLayerAddressBytes(),
- sourceIP,
- pkt.getSenderHardwareAddress()), false);
+ arpRequestReplyEvent.put(new ARPReply(p, host.getNetworkAddress(), host.getDataLayerAddressBytes(),
+ sourceIP, pkt.getSenderHardwareAddress()), false);
}
} else {
/*
- * Target MAC has been changed. For now, discard it.
- * TODO: We may need to send unicast ARP REQUEST on behalf of
- * the target back to the sender to trigger the sender to update
- * its table
+ * Target MAC has been changed. For now, discard it. TODO: We
+ * may need to send unicast ARP REQUEST on behalf of the target
+ * back to the sender to trigger the sender to update its table
*/
}
}
}
/**
- * Send a broadcast ARP Request to the switch/ ports using
- * the networkAddress of the subnet as sender IP
- * the controller's MAC as sender MAC
- * the targetIP as the target Network Address
+ * Send a broadcast ARP Request to the switch/ ports using the
+ * networkAddress of the subnet as sender IP the controller's MAC as sender
+ * MAC the targetIP as the target Network Address
*/
protected void sendBcastARPRequest(InetAddress targetIP, Subnet subnet) {
log.trace("sendBcatARPRequest targetIP:{} subnet:{}", targetIP, subnet);
}
byte[] targetHardwareAddress = new byte[] { (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 };
- //TODO: should use IBroadcastHandler instead
+ // TODO: should use IBroadcastHandler instead
for (NodeConnector p : nodeConnectors) {
- //filter out any non-local or internal ports
- if (!(connectionManager.getLocalityStatus(p.getNode()) == ConnectionLocality.LOCAL) || topologyManager.isInternal(p)) {
+ // filter out any non-local or internal ports
+ if (!(connectionManager.getLocalityStatus(p.getNode()) == ConnectionLocality.LOCAL)
+ || topologyManager.isInternal(p)) {
continue;
}
log.trace("Sending toward nodeConnector:{}", p);
/**
* Send a unicast ARP Request to the known host on a specific switch/port as
- * defined in the host.
- * The sender IP is the networkAddress of the subnet
+ * defined in the host. The sender IP is the networkAddress of the subnet
* The sender MAC is the controller's MAC
*/
protected void sendUcastARPRequest(HostNodeConnector host, Subnet subnet) {
Subnet subnet = null;
if (switchManager != null) {
- subnet = switchManager.getSubnetByNetworkAddress(host
- .getNetworkAddress());
+ subnet = switchManager.getSubnetByNetworkAddress(host.getNetworkAddress());
}
if (subnet == null) {
log.debug("can't find subnet matching {}", host.getNetworkAddress());
return;
}
- if (connectionManager.getLocalityStatus(host.getnodeconnectorNode()) == ConnectionLocality.LOCAL){
+ if (connectionManager.getLocalityStatus(host.getnodeconnectorNode()) == ConnectionLocality.LOCAL) {
log.trace("Send a ucast ARP req. to: {}", host);
sendUcastARPRequest(host, subnet);
} else {
}
/**
- * An IP packet is punted to the controller, this means that the
- * destination host is not known to the controller.
- * Need to discover it by sending a Broadcast ARP Request
+ * An IP packet is punted to the controller, this means that the destination
+ * host is not known to the controller. Need to discover it by sending a
+ * Broadcast ARP Request
*
* @param pkt
* @param p
InetAddress dIP = NetUtils.getInetAddress(pkt.getDestinationAddress());
if (dIP == null) {
- return;
+ return;
}
// try to find a matching subnet
}
// see if we know about the host
- HostNodeConnector host = hostTracker.hostFind(dIP);
+ // Hosttracker hosts db key implementation
+ IHostId id = HostIdFactory.create(dIP, null);
+ HostNodeConnector host = hostTracker.hostFind(id);
if (host == null) {
// if we don't, know about the host, try to find it
- log.trace("Punted IP pkt to {}, sending bcast ARP event...",
- dIP);
+ log.trace("Punted IP pkt to {}, sending bcast ARP event...", dIP);
/*
* unknown destination host, initiate bcast ARP request
*/
arpRequestReplyEvent.put(new ARPRequest(dIP, subnet), false);
- } else if (routing == null ||
- routing.getRoute(p.getNode(), host.getnodeconnectorNode()) != null) {
- /* if IRouting is available, make sure that this packet can get it's
+ } else if (routing == null || routing.getRoute(p.getNode(), host.getnodeconnectorNode()) != null) {
+ /*
+ * if IRouting is available, make sure that this packet can get it's
* destination normally before teleporting it there. If it's not
* available, then assume it's reachable.
*
log.trace("forwarding punted IP pkt to {} received at {}", dIP, p);
- /* if we know where the host is and there's a path from where this
+ /*
+ * if we know where the host is and there's a path from where this
* packet was punted to where the host is, then deliver it to the
- * host for now */
+ * host for now
+ */
NodeConnector nc = host.getnodeConnector();
// re-encode the Ethernet packet (the parent of the IPv4 packet)
rp.setOutgoingNodeConnector(nc);
this.dataPacketService.transmitDataPacket(rp);
} else {
- log.trace("ignoring punted IP pkt to {} because there is no route from {}",
- dIP, p);
+ log.trace("ignoring punted IP pkt to {} because there is no route from {}", dIP, p);
}
}
allocateCaches();
retrieveCaches();
+
}
@SuppressWarnings({ "unchecked" })
private void retrieveCaches() {
- ConcurrentMap<?,?> map;
+ ConcurrentMap<?, ?> map;
- if (this.clusterContainerService == null){
+ if (this.clusterContainerService == null) {
log.error("Cluster service unavailable, can't retieve ARPHandler caches!");
return;
}
map = clusterContainerService.getCache(ARP_EVENT_CACHE_NAME);
- if (map != null){
+ if (map != null) {
this.arpRequestReplyEvent = (ConcurrentMap<ARPEvent, Boolean>) map;
} else {
log.error("Cache allocation failed for {}", ARP_EVENT_CACHE_NAME);
}
private void allocateCaches() {
- if (clusterContainerService == null){
+ if (clusterContainerService == null) {
nonClusterObjectCreate();
log.error("Clustering service unavailable. Allocated non-cluster caches for ARPHandler.");
return;
}
- try{
+ try {
clusterContainerService.createCache(ARP_EVENT_CACHE_NAME,
EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
- } catch (CacheConfigException e){
+ } catch (CacheConfigException e) {
log.error("ARPHandler cache configuration invalid!");
- } catch (CacheExistException e){
+ } catch (CacheExistException e) {
log.debug("ARPHandler cache exists, skipped allocation.");
}
}
- private void nonClusterObjectCreate(){
+ private void nonClusterObjectCreate() {
arpRequestReplyEvent = new ConcurrentHashMap<ARPEvent, Boolean>();
}
+
/**
- * Function called by the dependency manager when at least one
- * dependency become unsatisfied or when the component is shutting
- * down because for example bundle is being stopped.
+ * Function called by the dependency manager when at least one dependency
+ * become unsatisfied or when the component is shutting down because for
+ * example bundle is being stopped.
*
*/
void destroy() {
}
/**
- * Function called by dependency manager after "init ()" is called
- * and after the services provided by the class are registered in
- * the service registry
+ * Function called by dependency manager after "init ()" is called and after
+ * the services provided by the class are registered in the service registry
*
*/
void start() {
}
/**
- * Function called by the dependency manager before the services
- * exported by the component are unregistered, this will be
- * followed by a "destroy ()" calls
+ * Function called by the dependency manager before the services exported by
+ * the component are unregistered, this will be followed by a "destroy ()"
+ * calls
*
*/
- void stop(){
+ void stop() {
}
void stopping() {
handlePuntedIPPacket((IPv4) nextPak, inPkt.getIncomingNodeConnector());
} else if (nextPak instanceof ARP) {
log.trace("Handle ARP packet: {}", formattedPak);
- handleARPPacket((Ethernet) formattedPak, (ARP) nextPak, inPkt
- .getIncomingNodeConnector());
+ handleARPPacket((Ethernet) formattedPak, (ARP) nextPak, inPkt.getIncomingNodeConnector());
}
}
return PacketResult.IGNORED;
}
- private ARP createARP(short opCode, byte[] senderMacAddress, byte[] senderIP, byte[] targetMacAddress, byte[] targetIP) {
- ARP arp = new ARP();
- arp.setHardwareType(ARP.HW_TYPE_ETHERNET);
- arp.setProtocolType(EtherTypes.IPv4.shortValue());
- arp.setHardwareAddressLength((byte) 6);
- arp.setProtocolAddressLength((byte) 4);
- arp.setOpCode(opCode);
- arp.setSenderHardwareAddress(senderMacAddress) ;
- arp.setSenderProtocolAddress(senderIP);
- arp.setTargetHardwareAddress(targetMacAddress);
- arp.setTargetProtocolAddress(targetIP);
- return arp;
+ private ARP createARP(short opCode, byte[] senderMacAddress, byte[] senderIP, byte[] targetMacAddress,
+ byte[] targetIP) {
+ ARP arp = new ARP();
+ arp.setHardwareType(ARP.HW_TYPE_ETHERNET);
+ arp.setProtocolType(EtherTypes.IPv4.shortValue());
+ arp.setHardwareAddressLength((byte) 6);
+ arp.setProtocolAddressLength((byte) 4);
+ arp.setOpCode(opCode);
+ arp.setSenderHardwareAddress(senderMacAddress);
+ arp.setSenderProtocolAddress(senderIP);
+ arp.setTargetHardwareAddress(targetMacAddress);
+ arp.setTargetProtocolAddress(targetIP);
+ return arp;
}
private Ethernet createEthernet(byte[] sourceMAC, byte[] targetMAC, ARP arp) {
// Clean up ARP event cache
try {
- if (clusterContainerService.amICoordinator() && ! arpRequestReplyEvent.isEmpty()){
+ if (clusterContainerService.amICoordinator() && !arpRequestReplyEvent.isEmpty()) {
arpRequestReplyEvent.clear();
}
- } catch (Exception e){
+ } catch (Exception e) {
log.warn("ARPHandler: A cluster member failed to clear event cache.");
}
}
private void generateAndSendReply(InetAddress sourceIP, byte[] sourceMAC) {
if (log.isTraceEnabled()) {
log.trace("generateAndSendReply called with params sourceIP:{} sourceMAC:{}", sourceIP,
- HexEncode.bytesToHexString(sourceMAC));
+ HexEncode.bytesToHexString(sourceMAC));
}
Set<HostNodeConnector> hosts = arpRequestors.remove(sourceIP);
if ((hosts == null) || hosts.isEmpty()) {
countDownTimers.remove(sourceIP);
for (HostNodeConnector host : hosts) {
if (log.isTraceEnabled()) {
- log.trace("Sending ARP Reply with src {}/{}, target {}/{}",
- new Object[] {
- HexEncode.bytesToHexString(sourceMAC),
- sourceIP,
- HexEncode.bytesToHexString(host.getDataLayerAddressBytes()),
- host.getNetworkAddress() });
+ log.trace(
+ "Sending ARP Reply with src {}/{}, target {}/{}",
+ new Object[] { HexEncode.bytesToHexString(sourceMAC), sourceIP,
+ HexEncode.bytesToHexString(host.getDataLayerAddressBytes()), host.getNetworkAddress() });
}
- if (connectionManager.getLocalityStatus(host.getnodeconnectorNode()) == ConnectionLocality.LOCAL){
- sendARPReply(host.getnodeConnector(),
- sourceMAC,
- sourceIP,
- host.getDataLayerAddressBytes(),
+ if (connectionManager.getLocalityStatus(host.getnodeconnectorNode()) == ConnectionLocality.LOCAL) {
+ sendARPReply(host.getnodeConnector(), sourceMAC, sourceIP, host.getDataLayerAddressBytes(),
host.getNetworkAddress());
} else {
/*
- * In the remote event a requestor moved to another
- * controller it may turn out it now we need to send
- * the ARP reply from a different controller, this
- * cover the case
+ * In the remote event a requestor moved to another controller
+ * it may turn out it now we need to send the ARP reply from a
+ * different controller, this cover the case
*/
arpRequestReplyEvent.put(
- new ARPReply(
- host.getnodeConnector(),
- sourceIP,
- sourceMAC,
- host.getNetworkAddress(),
- host.getDataLayerAddressBytes()), false);
+ new ARPReply(host.getnodeConnector(), sourceIP, sourceMAC, host.getNetworkAddress(), host
+ .getDataLayerAddressBytes()), false);
}
}
}
-
@Override
public void entryUpdated(ARPEvent key, Boolean new_value, String cacheName, boolean originLocal) {
log.trace("Got and entryUpdated for cacheName {} key {} isNew {}", cacheName, key, new_value);
public void entryCreated(ARPEvent key, String cacheName, boolean originLocal) {
// nothing to do
}
+
@Override
public void entryDeleted(ARPEvent key, String cacheName, boolean originLocal) {
// nothing to do
}
- private void enqueueARPCacheEvent (ARPEvent event, boolean new_value) {
+ private void enqueueARPCacheEvent(ARPEvent event, boolean new_value) {
try {
ARPCacheEvent cacheEvent = new ARPCacheEvent(event, new_value);
if (!ARPCacheEvents.contains(cacheEvent)) {
}
/*
- * this thread monitors the connectionEvent queue for new incoming events from
+ * this thread monitors the connectionEvent queue for new incoming events
+ * from
*/
private class ARPCacheEventHandler implements Runnable {
@Override
log.trace("Trigger and ARP Broadcast Request upon receipt of {}", req);
sendBcastARPRequest(req.getTargetIP(), req.getSubnet());
- //If unicast and local, send reply
+ // If unicast and local, send reply
} else if (connectionManager.getLocalityStatus(req.getHost().getnodeconnectorNode()) == ConnectionLocality.LOCAL) {
log.trace("ARPCacheEventHandler - sendUcatARPRequest upon receipt of {}", req);
sendUcastARPRequest(req.getHost(), req.getSubnet());
}
} else if (event instanceof ARPReply) {
ARPReply rep = (ARPReply) event;
- // New reply received by controller, notify all awaiting requestors across the cluster
+ // New reply received by controller, notify all awaiting
+ // requestors across the cluster
if (ev.isNewReply()) {
log.trace("Trigger a generateAndSendReply in response to {}", rep);
generateAndSendReply(rep.getTargetIP(), rep.getTargetMac());
- // Otherwise, a specific reply. If local, send out.
+ // Otherwise, a specific reply. If local, send out.
} else if (connectionManager.getLocalityStatus(rep.getPort().getNode()) == ConnectionLocality.LOCAL) {
log.trace("ARPCacheEventHandler - sendUcatARPReply locally in response to {}", rep);
- sendARPReply(rep.getPort(),
- rep.getSourceMac(),
- rep.getSourceIP(),
- rep.getTargetMac(),
+ sendARPReply(rep.getPort(), rep.getSourceMac(), rep.getSourceIP(), rep.getTargetMac(),
rep.getTargetIP());
}
}
<yangtools.binding.version>0.6.0-SNAPSHOT</yangtools.binding.version>
<!--versions for bits of the controller -->
<controller.version>0.4.1-SNAPSHOT</controller.version>
+ <hosttracker.version>0.5.1-SNAPSHOT</hosttracker.version>
+ <arphandler.version>0.5.1-SNAPSHOT</arphandler.version>
+ <forwarding.staticrouting>0.5.1-SNAPSHOT</forwarding.staticrouting>
+ <samples.loadbalancer>0.5.1-SNAPSHOT</samples.loadbalancer>
<config.version>0.2.3-SNAPSHOT</config.version>
<netconf.version>0.2.3-SNAPSHOT</netconf.version>
<mdsal.version>1.0-SNAPSHOT</mdsal.version>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${hosttracker.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwarding.staticrouting</artifactId>
- <version>${controller.version}</version>
+ <version>${forwarding.staticrouting}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>arphandler</artifactId>
- <version>${controller.version}</version>
+ <version>${arphandler.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker</artifactId>
- <version>${controller.version}</version>
+ <version>${hosttracker.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker.implementation</artifactId>
- <version>${controller.version}</version>
+ <version>${hosttracker.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>samples.loadbalancer</artifactId>
- <version>${controller.version}</version>
+ <version>${samples.loadbalancer}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
#netconf.tls.keystore=
#netconf.tls.keystore.password=
-netconf.config.persister.storageAdapterClass=org.opendaylight.controller.netconf.persist.impl.NoOpStorageAdapter
+netconf.config.persister.storageAdapterClass=org.opendaylight.controller.config.persist.storage.file.FileStorageAdapter
+fileStorage=configuration/controller.config
+numberOfBackups=1
yangstore.blacklist=.*controller.model.*
# Set Default start level for framework
# Logging configuration for Tomcat-JUL logging
java.util.logging.config.file=configuration/tomcat-logging.properties
+
+#Hosttracker hostsdb key scheme setting
+hosttracker.keyscheme=IP
--- /dev/null
+//START OF CONFIG-LAST
+<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+<modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:schema-service-singleton</type>
+ <name>yang-schema-service</name>
+ </module>
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:hash-map-data-store</type>
+ <name>hash-map-data-store</name>
+ </module>
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-broker-impl</type>
+ <name>dom-broker</name>
+ <data-store xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-data-store</type>
+ <name>ref_hash-map-data-store</name>
+ </data-store>
+ </module>
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-broker-impl</type>
+ <name>binding-broker-impl</name>
+ <notification-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
+ <name>ref_binding-notification-broker</name>
+ </notification-service>
+ <data-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
+ <name>ref_binding-data-broker</name>
+ </data-broker>
+ </module>
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:runtime-generated-mapping</type>
+ <name>runtime-mapping-singleton</name>
+ </module>
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-notification-broker</type>
+ <name>binding-notification-broker</name>
+ </module>
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-data-broker</type>
+ <name>binding-data-broker</name>
+ <dom-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
+ <name>ref_dom-broker</name>
+ </dom-broker>
+ <mapping-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding:binding-dom-mapping-service</type>
+ <name>ref_runtime-mapping-singleton</name>
+ </mapping-service>
+ </module>
+</modules>
+<services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <service>
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
+ <instance>
+ <name>ref_yang-schema-service</name>
+ <provider>/config/modules/module[name='schema-service-singleton']/instance[name='yang-schema-service']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
+ <instance>
+ <name>ref_binding-notification-broker</name>
+ <provider>/config/modules/module[name='binding-notification-broker']/instance[name='binding-notification-broker']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-data-store</type>
+ <instance>
+ <name>ref_hash-map-data-store</name>
+ <provider>/config/modules/module[name='hash-map-data-store']/instance[name='hash-map-data-store']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
+ <instance>
+ <name>ref_binding-broker-impl</name>
+ <provider>/config/modules/module[name='binding-broker-impl']/instance[name='binding-broker-impl']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding-impl:binding-dom-mapping-service</type>
+ <instance>
+ <name>ref_runtime-mapping-singleton</name>
+ <provider>/config/modules/module[name='runtime-generated-mapping']/instance[name='runtime-mapping-singleton']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
+ <instance>
+ <name>ref_dom-broker</name>
+ <provider>/config/modules/module[name='dom-broker-impl']/instance[name='dom-broker']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
+ <instance>
+ <name>ref_binding-data-broker</name>
+ <provider>/config/modules/module[name='binding-data-broker']/instance[name='binding-data-broker']</provider>
+ </instance>
+ </service>
+</services>
+</data>
+
+//END OF SNAPSHOT
+urn:opendaylight:l2:types?module=opendaylight-l2-types&revision=2013-08-27
+urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&revision=2013-10-28
+urn:opendaylight:params:xml:ns:yang:controller:threadpool?module=threadpool&revision=2013-04-09
+urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom?module=opendaylight-md-sal-dom&revision=2013-10-28
+urn:opendaylight:params:xml:ns:yang:controller:config?module=config&revision=2013-04-05
+urn:ietf:params:netconf:capability:candidate:1.0
+urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&revision=2010-10-04
+urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor?module=netty-event-executor&revision=2013-11-12
+urn:ietf:params:xml:ns:yang:rpc-context?module=rpc-context&revision=2013-06-17
+urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl?module=opendaylight-sal-binding-broker-impl&revision=2013-10-28
+urn:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&revision=2010-09-24
+urn:ietf:params:netconf:capability:rollback-on-error:1.0
+urn:ietf:params:xml:ns:yang:ietf-yang-types?module=ietf-yang-types&revision=2010-09-24
+urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl?module=threadpool-impl&revision=2013-04-05
+urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&revision=2013-10-28
+urn:opendaylight:params:xml:ns:yang:controller:logback:config?module=config-logging&revision=2013-07-16
+urn:opendaylight:yang:extension:yang-ext?module=yang-ext&revision=2013-07-09
+urn:opendaylight:params:xml:ns:yang:iana?module=iana&revision=2013-08-16
+urn:opendaylight:params:xml:ns:yang:controller:md:sal:common?module=opendaylight-md-sal-common&revision=2013-10-28
+urn:opendaylight:params:xml:ns:yang:ieee754?module=ieee754&revision=2013-08-19
+//END OF CONFIG
<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>commons.opendaylight</artifactId>
- <version>1.4.1-SNAPSHOT</version>
- <relativePath>../../commons/opendaylight</relativePath>
- </parent>
- <scm>
- <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
- <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
- <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main</url>
- <tag>HEAD</tag>
- </scm>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>commons.opendaylight</artifactId>
+ <version>1.4.1-SNAPSHOT</version>
+ <relativePath>../../commons/opendaylight</relativePath>
+ </parent>
+ <scm>
+ <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+ <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+ <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main</url>
+ <tag>HEAD</tag>
+ </scm>
- <artifactId>forwarding.staticrouting</artifactId>
- <version>0.4.1-SNAPSHOT</version>
- <packaging>bundle</packaging>
+ <artifactId>forwarding.staticrouting</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ <packaging>bundle</packaging>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Import-Package>
- org.opendaylight.controller.sal.utils,
- org.opendaylight.controller.sal.core,
- org.opendaylight.controller.configuration,
- org.opendaylight.controller.forwardingrulesmanager,
- org.opendaylight.controller.hosttracker,
- org.opendaylight.controller.hosttracker.hostAware,
- org.opendaylight.controller.clustering.services,
- org.opendaylight.controller.sal.packet,
- org.opendaylight.controller.sal.routing,
- org.opendaylight.controller.topologymanager,
- org.eclipse.osgi.framework.console,
- org.osgi.framework,
- org.slf4j,
- org.apache.felix.dm,
- org.apache.commons.lang3.builder
- </Import-Package>
- <Export-Package>
- org.opendaylight.controller.forwarding.staticrouting
- </Export-Package>
- <Bundle-Activator>
- org.opendaylight.controller.forwarding.staticrouting.internal.Activator
- </Bundle-Activator>
- </instructions>
- <manifestLocation>${project.basedir}/META-INF</manifestLocation>
- </configuration>
- </plugin>
- </plugins>
- </build>
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>topologymanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>forwardingrulesmanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>hosttracker</artifactId>
- <version>0.4.1-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>configuration</artifactId>
- <version>0.4.1-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
- </dependency>
- </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>${bundle.plugin.version}</version>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>
+ org.opendaylight.controller.sal.packet.address,
+ org.opendaylight.controller.sal.utils,
+ org.opendaylight.controller.sal.core,
+ org.opendaylight.controller.configuration,
+ org.opendaylight.controller.forwardingrulesmanager,
+ org.opendaylight.controller.hosttracker,
+ org.opendaylight.controller.hosttracker.hostAware,
+ org.opendaylight.controller.clustering.services,
+ org.opendaylight.controller.sal.packet,
+ org.opendaylight.controller.sal.routing,
+ org.opendaylight.controller.topologymanager,
+ org.eclipse.osgi.framework.console,
+ org.osgi.framework,
+ org.slf4j,
+ org.apache.felix.dm,
+ org.apache.commons.lang3.builder
+ </Import-Package>
+ <Export-Package>
+ org.opendaylight.controller.forwarding.staticrouting
+ </Export-Package>
+ <Bundle-Activator>
+ org.opendaylight.controller.forwarding.staticrouting.internal.Activator
+ </Bundle-Activator>
+ </instructions>
+ <manifestLocation>${project.basedir}/META-INF</manifestLocation>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>topologymanager</artifactId>
+ <version>0.4.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>forwardingrulesmanager</artifactId>
+ <version>0.4.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>hosttracker</artifactId>
+ <version>${hosttracker.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>configuration</artifactId>
+ <version>0.4.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
</project>
-
/*
* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
import org.opendaylight.controller.forwarding.staticrouting.IStaticRoutingAware;
import org.opendaylight.controller.forwarding.staticrouting.StaticRoute;
import org.opendaylight.controller.forwarding.staticrouting.StaticRouteConfig;
+import org.opendaylight.controller.hosttracker.HostIdFactory;
+import org.opendaylight.controller.hosttracker.IHostId;
import org.opendaylight.controller.hosttracker.IfIptoHost;
import org.opendaylight.controller.hosttracker.IfNewHostNotify;
import org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector;
/**
* Static Routing feature provides the bridge between SDN and Non-SDN networks.
*/
-public class StaticRoutingImplementation implements IfNewHostNotify,
- IForwardingStaticRouting, IObjectReader, IConfigurationContainerAware {
- private static Logger log = LoggerFactory
- .getLogger(StaticRoutingImplementation.class);
+public class StaticRoutingImplementation implements IfNewHostNotify, IForwardingStaticRouting, IObjectReader,
+ IConfigurationContainerAware {
+ private static Logger log = LoggerFactory.getLogger(StaticRoutingImplementation.class);
private static String ROOT = GlobalConstants.STARTUPHOME.toString();
ConcurrentMap<String, StaticRoute> staticRoutes;
ConcurrentMap<String, StaticRouteConfig> staticRouteConfigs;
}
@Override
- public Object readObject(ObjectInputStream ois)
- throws FileNotFoundException, IOException, ClassNotFoundException {
+ public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException {
// Perform the class deserialization locally, from inside the package
// where the class is defined
return ois.readObject();
@SuppressWarnings("unchecked")
private void loadConfiguration() {
ObjectReader objReader = new ObjectReader();
- ConcurrentMap<String, StaticRouteConfig> confList = (ConcurrentMap<String, StaticRouteConfig>) objReader
- .read(this, staticRoutesFileName);
+ ConcurrentMap<String, StaticRouteConfig> confList = (ConcurrentMap<String, StaticRouteConfig>) objReader.read(
+ this, staticRoutesFileName);
if (confList == null) {
return;
}
}
-
private Status saveConfig() {
return saveConfigInternal();
}
Status status;
ObjectWriter objWriter = new ObjectWriter();
- status = objWriter.write(
- new ConcurrentHashMap<String, StaticRouteConfig>(
- staticRouteConfigs), staticRoutesFileName);
+ status = objWriter.write(new ConcurrentHashMap<String, StaticRouteConfig>(staticRouteConfigs),
+ staticRoutesFileName);
if (status.isSuccess()) {
return status;
}
@SuppressWarnings("deprecation")
- private void allocateCaches() {
+ private void allocateCaches() {
if (this.clusterContainerService == null) {
- log
- .info("un-initialized clusterContainerService, can't create cache");
+ log.info("un-initialized clusterContainerService, can't create cache");
return;
}
try {
- clusterContainerService.createCache(
- "forwarding.staticrouting.routes", EnumSet
- .of(IClusterServices.cacheMode.TRANSACTIONAL));
- clusterContainerService.createCache(
- "forwarding.staticrouting.configs", EnumSet
- .of(IClusterServices.cacheMode.TRANSACTIONAL));
+ clusterContainerService.createCache("forwarding.staticrouting.routes",
+ EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
+ clusterContainerService.createCache("forwarding.staticrouting.configs",
+ EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
} catch (CacheExistException cee) {
- log
- .error("\nCache already exists - destroy and recreate if needed");
+ log.error("\nCache already exists - destroy and recreate if needed");
} catch (CacheConfigException cce) {
log.error("\nCache configuration invalid - check cache mode");
}
@SuppressWarnings({ "unchecked", "deprecation" })
private void retrieveCaches() {
if (this.clusterContainerService == null) {
- log
- .info("un-initialized clusterContainerService, can't retrieve cache");
+ log.info("un-initialized clusterContainerService, can't retrieve cache");
return;
}
try {
ra.staticRouteUpdate(s, update);
} catch (Exception e) {
- log.error("",e);
+ log.error("", e);
}
}
}
@Override
public Object call() throws Exception {
- if (!added
- || (staticRoute.getType() == StaticRoute.NextHopType.SWITCHPORT)) {
+ if (!added || (staticRoute.getType() == StaticRoute.NextHopType.SWITCHPORT)) {
notifyStaticRouteUpdate(staticRoute, added);
} else {
InetAddress nh = staticRoute.getNextHopAddress();
- HostNodeConnector host = hostTracker.hostQuery(nh);
+ // HostTracker hosts db key scheme implementation
+ IHostId id = HostIdFactory.create(nh, null);
+ HostNodeConnector host = hostTracker.hostQuery(id);
if (host == null) {
log.debug("Next hop {} is not present, try to discover it", nh.getHostAddress());
- Future<HostNodeConnector> future = hostTracker.discoverHost(nh);
+ Future<HostNodeConnector> future = hostTracker.discoverHost(id);
if (future != null) {
try {
host = future.get();
public StaticRoute getBestMatchStaticRoute(InetAddress ipAddress) {
ByteBuffer bblongestPrefix = null;
try {
- bblongestPrefix = ByteBuffer.wrap(InetAddress.getByName("0.0.0.0")
- .getAddress());
+ bblongestPrefix = ByteBuffer.wrap(InetAddress.getByName("0.0.0.0").getAddress());
} catch (Exception e) {
return null;
}
return status;
}
if (staticRouteConfigs.get(config.getName()) != null) {
- return new Status(StatusCode.CONFLICT,
- "A valid Static Route configuration with this name " +
- "already exists. Please use a different name");
+ return new Status(StatusCode.CONFLICT, "A valid Static Route configuration with this name "
+ + "already exists. Please use a different name");
}
// Update database
for (Map.Entry<String, StaticRoute> entry : staticRoutes.entrySet()) {
if (entry.getValue().compareTo(sRoute) == 0) {
- return new Status(StatusCode.CONFLICT,
- "This conflicts with an existing Static Route " +
- "Configuration. Please check the configuration " +
- "and try again");
+ return new Status(StatusCode.CONFLICT, "This conflicts with an existing Static Route "
+ + "Configuration. Please check the configuration " + "and try again");
}
}
staticRoutes.put(config.getName(), sRoute);
checkAndUpdateListeners(name, sRoute, false);
return new Status(StatusCode.SUCCESS, null);
}
- return new Status(StatusCode.NOTFOUND,
- "Static Route with name " + name + " is not found");
+ return new Status(StatusCode.NOTFOUND, "Static Route with name " + name + " is not found");
}
void setClusterContainerService(IClusterContainerServices s) {
containerName = "";
}
- staticRoutesFileName = ROOT + "staticRouting_" + containerName
- + ".conf";
+ staticRoutesFileName = ROOT + "staticRouting_" + containerName + ".conf";
- log.debug("forwarding.staticrouting starting on container {}",
- containerName);
+ log.debug("forwarding.staticrouting starting on container {}", containerName);
allocateCaches();
retrieveCaches();
this.executor = Executors.newFixedThreadPool(1);
}
/*
- * Slow probe to identify any gateway that might have silently appeared
- * after the Static Routing Configuration.
+ * Slow probe to identify any gateway that might have silently appeared
+ * after the Static Routing Configuration.
*/
gatewayProbeTimer = new Timer();
gatewayProbeTimer.schedule(new TimerTask() {
public void run() {
for (Map.Entry<String, StaticRoute> s : staticRoutes.entrySet()) {
StaticRoute route = s.getValue();
- if ((route.getType() == StaticRoute.NextHopType.IPADDRESS)
- && route.getHost() == null) {
+ if ((route.getType() == StaticRoute.NextHopType.IPADDRESS) && route.getHost() == null) {
checkAndUpdateListeners(s.getKey(), route, true);
}
}
}
}, 60 * 1000, 60 * 1000);
+
}
/**
- * Function called by the dependency manager when at least one
- * dependency become unsatisfied or when the component is shutting
- * down because for example bundle is being stopped.
+ * Function called by the dependency manager when at least one dependency
+ * become unsatisfied or when the component is shutting down because for
+ * example bundle is being stopped.
*
*/
void destroy() {
- log.debug("Destroy all the Static Routing Rules given we are "
- + "shutting down");
+ log.debug("Destroy all the Static Routing Rules given we are " + "shutting down");
gatewayProbeTimer.cancel();
}
/**
- * Function called by dependency manager after "init ()" is called
- * and after the services provided by the class are registered in
- * the service registry
+ * Function called by dependency manager after "init ()" is called and after
+ * the services provided by the class are registered in the service registry
*
*/
void start() {
}
/**
- * Function called by the dependency manager before the services
- * exported by the component are unregistered, this will be
- * followed by a "destroy ()" calls
+ * Function called by the dependency manager before the services exported by
+ * the component are unregistered, this will be followed by a "destroy ()"
+ * calls
*
*/
void stop() {
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${hosttracker.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${hosttracker.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${hosttracker.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${hosttracker.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>commons.opendaylight</artifactId>
- <version>1.4.1-SNAPSHOT</version>
- <relativePath>../../commons/opendaylight</relativePath>
- </parent>
- <scm>
- <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
- <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
- <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main</url>
- <tag>HEAD</tag>
- </scm>
- <artifactId>hosttracker</artifactId>
- <version>0.4.1-SNAPSHOT</version>
- <packaging>bundle</packaging>
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>commons.opendaylight</artifactId>
+ <version>1.4.1-SNAPSHOT</version>
+ <relativePath>../../commons/opendaylight</relativePath>
+ </parent>
+ <scm>
+ <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+ <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+ <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main</url>
+ <tag>HEAD</tag>
+ </scm>
+ <artifactId>hosttracker</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ <packaging>bundle</packaging>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Export-Package>
- org.opendaylight.controller.hosttracker,
- org.opendaylight.controller.hosttracker.hostAware
- </Export-Package>
- <Import-Package>
- org.opendaylight.controller.sal.core,
- org.opendaylight.controller.sal.utils,
- org.opendaylight.controller.topologymanager,
- org.opendaylight.controller.sal.packet.address,
- org.opendaylight.controller.switchmanager,
- org.opendaylight.controller.clustering.services,
- javax.xml.bind.annotation,
- javax.xml.bind,
- org.apache.felix.dm,
- org.apache.commons.lang3.builder,
- org.osgi.service.component,
- org.slf4j,
- org.eclipse.osgi.framework.console,
- org.osgi.framework
- </Import-Package>
- </instructions>
- <manifestLocation>${project.basedir}/META-INF</manifestLocation>
- </configuration>
- </plugin>
- </plugins>
- </build>
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>topologymanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>switchmanager</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>clustering.services</artifactId>
- <version>0.4.1-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- <version>0.5.1-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </dependency>
- </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>${bundle.plugin.version}</version>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Export-Package>
+ org.opendaylight.controller.hosttracker,
+ org.opendaylight.controller.hosttracker.hostAware
+ </Export-Package>
+ <Import-Package>
+ org.opendaylight.controller.sal.core,
+ org.opendaylight.controller.sal.utils,
+ org.opendaylight.controller.topologymanager,
+ org.opendaylight.controller.sal.packet.address,
+ org.opendaylight.controller.switchmanager,
+ org.opendaylight.controller.clustering.services,
+ javax.xml.bind.annotation,
+ javax.xml.bind,
+ org.apache.felix.dm,
+ org.apache.commons.lang3.builder,
+ org.osgi.service.component,
+ org.slf4j,
+ org.eclipse.osgi.framework.console,
+ org.osgi.framework
+ </Import-Package>
+ </instructions>
+ <manifestLocation>${project.basedir}/META-INF</manifestLocation>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>topologymanager</artifactId>
+ <version>0.4.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>switchmanager</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>clustering.services</artifactId>
+ <version>0.4.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal</artifactId>
+ <version>0.5.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ </dependencies>
</project>
+
--- /dev/null
+/*
+ * Copyright IBM Corporation, 2013. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.hosttracker;
+
+import java.net.InetAddress;
+
+import org.opendaylight.controller.sal.packet.address.DataLinkAddress;
+
+/*
+ * Class used to generate a key based on the scheme choosen for hostsdb storage in hosttracker.
+ * @author Deepak Udapudi
+ */
+public class HostIdFactory {
+ public static final String DEFAULT_IP_KEY_SCHEME = "IP";
+ public static final String IP_MAC_KEY_SCHEME = "IP+MAC";
+ private static String scheme = null;
+ static {
+ scheme = System.getProperty("hosttracker.keyscheme");
+ }
+
+ public static String getScheme() {
+ return scheme;
+ }
+
+ public static IHostId create(InetAddress ip, DataLinkAddress mac) {
+ IHostId ipHostId = new IPHostId(ip);
+ if (scheme != null) {
+ switch (scheme) {
+
+ case DEFAULT_IP_KEY_SCHEME:
+ return ipHostId;
+ case IP_MAC_KEY_SCHEME:
+ IHostId ipMacHostId = new IPMacHostId(ip, mac);
+ return ipMacHostId;
+ default:
+ return ipHostId;
+
+ }
+ }
+ return ipHostId;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright IBM Corporation, 2013. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.hosttracker;
+
+import java.io.Serializable;
+
+/*
+ * Marker interface used by the key classes for their implementation
+ * @author Deepak Udapudi
+ */
+
+public interface IHostId extends Serializable {
+
+}
--- /dev/null
+/*
+ * Copyright IBM Corporation, 2013. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.hosttracker;
+
+import java.io.Serializable;
+import java.net.InetAddress;
+
+/*
+ * IP only key class implementation using the marker interface IHostId
+ * @author Deepak Udapudi
+ */
+
+public class IPHostId implements IHostId, Serializable {
+ private static final long serialVersionUID = 1L;
+ private InetAddress ipAddress;
+
+ public InetAddress getIpAddress() {
+ return ipAddress;
+ }
+
+ public void setIpAddress(InetAddress ipAddress) {
+ this.ipAddress = ipAddress;
+ }
+
+ public IPHostId(InetAddress ipAddress) {
+ super();
+ this.ipAddress = ipAddress;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((ipAddress == null) ? 0 : ipAddress.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ IPHostId other = (IPHostId) obj;
+ if (ipAddress == null) {
+ if (other.ipAddress != null)
+ return false;
+ } else if (!ipAddress.equals(other.ipAddress))
+ return false;
+ return true;
+ }
+
+ public static IHostId fromIP(InetAddress addr) {
+ return new IPHostId(addr);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright IBM Corporation, 2013. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.hosttracker;
+
+import java.io.Serializable;
+import java.net.InetAddress;
+
+/*
+ * IP + Mac key class implementation using the marker interface IHostId
+ * @author Deepak Udapudi
+ */
+
+import org.opendaylight.controller.sal.packet.address.DataLinkAddress;
+
+public class IPMacHostId implements IHostId, Serializable {
+
+ private static final long serialVersionUID = 1L;
+ private InetAddress ipAddress;
+ private DataLinkAddress macAddr;
+
+ public IPMacHostId(InetAddress ipAddress, DataLinkAddress macAddr) {
+ super();
+ this.ipAddress = ipAddress;
+ this.macAddr = macAddr;
+ }
+
+ public InetAddress getIpAddress() {
+ return ipAddress;
+ }
+
+ public void setIpAddress(InetAddress ipAddress) {
+ this.ipAddress = ipAddress;
+ }
+
+ public DataLinkAddress getMacAddr() {
+ return macAddr;
+ }
+
+ public void setMacAddr(DataLinkAddress macAddr) {
+ this.macAddr = macAddr;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((ipAddress == null) ? 0 : ipAddress.hashCode());
+ result = prime * result + ((macAddr == null) ? 0 : macAddr.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ IPMacHostId other = (IPMacHostId) obj;
+ if (ipAddress == null) {
+ if (other.ipAddress != null)
+ return false;
+ } else if (!ipAddress.equals(other.ipAddress))
+ return false;
+ if (macAddr == null) {
+ if (other.macAddr != null)
+ return false;
+ } else if (!macAddr.equals(other.macAddr))
+ return false;
+ return true;
+ }
+
+ public static IHostId fromIPAndMac(InetAddress ip, DataLinkAddress mac) {
+ return new IPMacHostId(ip, mac);
+ }
+
+}
* statically through Northbound APIs. If a binding is unknown, then an ARP
* request is initiated immediately to discover the host.
*
- * @param networkAddress
- * IP Address of the Host encapsulated in class InetAddress
+ * @param id
+ * IP address and Mac Address combination encapsulated in IHostId
+ * interface
* @return {@link org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector}
* Class that contains the Host info such as its MAC address, Switch
* ID, port, VLAN. If Host is not found, returns NULL
*/
- public HostNodeConnector hostFind(InetAddress networkAddress);
+ public HostNodeConnector hostFind(IHostId id);
+
+ /**
+ * Applications call this interface methods to determine IP address to MAC
+ * binding and its connectivity to an OpenFlow switch in term of Node, Port,
+ * and VLAN. These bindings are learned dynamically as well as can be added
+ * statically through Northbound APIs. If a binding is unknown, then an ARP
+ * request is initiated immediately to discover the host.
+ *
+ * @param addr
+ * IP address of the host
+ * @return {@link org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector}
+ * Class that contains the Host info such as its MAC address, Switch
+ * ID, port, VLAN. If Host is not found, returns NULL
+ */
+ public HostNodeConnector hostFind(InetAddress addr);
/**
* Checks the local Host Database to see if a Host has been learned for a
- * given IP address.
+ * given IP address and Mac combination using the HostId.
*
- * @param networkAddress
- * IP Address of the Host encapsulated in class InetAddress
+ * @param id
+ * IP address and Mac Address combination encapsulated in IHostId
+ * interface
+ * @return {@link org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector}
+ * Class that contains the Host info such as its MAC address, Switch
+ * ID, port, VLAN. If Host is not found, returns NULL
+ *
+ */
+ public HostNodeConnector hostQuery(IHostId id);
+
+ /**
+ * Checks the local Host Database to see if a Host has been learned for a
+ * given IP address and Mac combination using the HostId.
+ *
+ * @param addr
+ * IP address of the Host
* @return {@link org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector}
* Class that contains the Host info such as its MAC address, Switch
* ID, port, VLAN. If Host is not found, returns NULL
*
*/
- public HostNodeConnector hostQuery(InetAddress networkAddress);
+ public HostNodeConnector hostQuery(InetAddress addr);
/**
- * Initiates an immediate discovery of the Host for a given IP address. This
+ * Initiates an immediate discovery of the Host for a given Host id. This
* provides for the calling applications to block on the host discovery.
*
- * @param networkAddress
- * IP address encapsulated in InetAddress class
+ * @param id
+ * IP address and Mac Address combination encapsulated in IHostId
+ * interface
+ * @return Future
+ * {@link org.opendaylight.controller.hosttracker.HostTrackerCallable}
+ */
+ public Future<HostNodeConnector> discoverHost(IHostId id);
+
+ /**
+ * Initiates an immediate discovery of the Host for a given Host id. This
+ * provides for the calling applications to block on the host discovery.
+ *
+ * @param addr
+ * IP address of the host
* @return Future
* {@link org.opendaylight.controller.hosttracker.HostTrackerCallable}
*/
- public Future<HostNodeConnector> discoverHost(InetAddress networkAddress);
+ public Future<HostNodeConnector> discoverHost(InetAddress addr);
/**
* Returns the Network Hierarchy for a given Host. This API is typically
* used by applications like Hadoop for Rack Awareness functionality.
*
- * @param IP
- * address of the Host encapsulated in InetAddress class
+ * @param id
+ * IP address and Mac Address combination encapsulated in IHostId
+ * interface
* @return List of String ArrayList containing the Hierarchies.
*/
- public List<List<String>> getHostNetworkHierarchy(InetAddress hostAddress);
+ public List<List<String>> getHostNetworkHierarchy(IHostId id);
+
+ /**
+ * Returns the Network Hierarchy for a given Host. This API is typically
+ * used by applications like Hadoop for Rack Awareness functionality.
+ *
+ * @param addr
+ * IP address of the host
+ * @return List of String ArrayList containing the Hierarchies.
+ */
+ public List<List<String>> getHostNetworkHierarchy(InetAddress addr);
/**
* Returns all the the Hosts either learned dynamically or added statically
* @return The status object as described in {@code Status} indicating the
* result of this action.
*/
- public Status addStaticHost(String networkAddress, String dataLayerAddress,
- NodeConnector nc, String vlan);
+ public Status addStaticHost(String networkAddress, String dataLayerAddress, NodeConnector nc, String vlan);
/**
* Allows the deletion of statically learned Host
* result of this action.
*/
public Status removeStaticHost(String networkAddress);
+
+ /**
+ * Allows the deletion of statically learned Host
+ *
+ * @param networkAddress
+ * @param macAddress
+ * @return The status object as described in {@code Status} indicating the
+ * result of this action.
+ */
+ public Status removeStaticHostUsingIPAndMac(String networkAddress, String macAddress);
}
<relativePath>../../commons/opendaylight</relativePath>
</parent>
<artifactId>hosttracker.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<packaging>bundle</packaging>
<scm>
<connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${hosttracker.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
import org.opendaylight.controller.clustering.services.ICacheUpdateAware;
import org.opendaylight.controller.clustering.services.IClusterContainerServices;
import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.hosttracker.HostIdFactory;
+import org.opendaylight.controller.hosttracker.IHostId;
+import org.opendaylight.controller.hosttracker.IPHostId;
+import org.opendaylight.controller.hosttracker.IPMacHostId;
import org.opendaylight.controller.hosttracker.IfHostListener;
import org.opendaylight.controller.hosttracker.IfIptoHost;
import org.opendaylight.controller.hosttracker.IfNewHostNotify;
* removed the database
*/
+/***
+ *
+ * HostTracker db key scheme implementation support. Support has been added for
+ * IP only or IP + MAC scheme as of now. User can use either of the schemes
+ * based on the configuration done in config.ini file. By default IP only key
+ * scheme is choosen. The attribute to be set in config.ini is
+ * hosttracker.keyscheme. It could have a value of 0 or 1 as of now. 0 is for IP
+ * only scheme. 1 is for IP + MAC scheme.
+ *
+ *
+ */
+
public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAware, IInventoryListener,
- ITopologyManagerAware, ICacheUpdateAware<InetAddress, HostNodeConnector>, CommandProvider {
+ ITopologyManagerAware, ICacheUpdateAware<IHostId, HostNodeConnector>, CommandProvider {
static final String ACTIVE_HOST_CACHE = "hosttracker.ActiveHosts";
static final String INACTIVE_HOST_CACHE = "hosttracker.InactiveHosts";
private static final Logger logger = LoggerFactory.getLogger(HostTracker.class);
protected final Set<IHostFinder> hostFinder = new CopyOnWriteArraySet<IHostFinder>();;
- protected ConcurrentMap<InetAddress, HostNodeConnector> hostsDB;
+ protected ConcurrentMap<IHostId, HostNodeConnector> hostsDB;
/*
* Following is a list of hosts which have been requested by NB APIs to be
* added, but either the switch or the port is not sup, so they will be
protected boolean stopping;
private static boolean hostRefresh = true;
private static int hostRetryCount = 5;
+ private String keyScheme = null;
+
private static class ARPPending {
- protected InetAddress hostIP;
+ protected IHostId hostId;
protected short sent_count;
protected HostTrackerCallable hostTrackerCallable;
- public InetAddress getHostIP() {
- return hostIP;
+ public IHostId getHostId() {
+ return hostId;
}
public short getSent_count() {
return hostTrackerCallable;
}
- public void setHostIP(InetAddress networkAddr) {
- this.hostIP = networkAddr;
+ public void setHostId(IHostId id) {
+ this.hostId = id;
}
public void setSent_count(short count) {
// This list contains the hosts for which ARP requests are being sent
// periodically
- ConcurrentMap<InetAddress, ARPPending> ARPPendingList;
+ ConcurrentMap<IHostId, ARPPending> ARPPendingList;
/*
* This list below contains the hosts which were initially in ARPPendingList
* above, but ARP response didn't come from there hosts after multiple
*
* We can't recover from condition 3 above
*/
- ConcurrentMap<InetAddress, ARPPending> failedARPReqList;
+ ConcurrentMap<IHostId, ARPPending> failedARPReqList;
public HostTracker() {
}
/* ARP Refresh Timer to go off every 5 seconds to implement ARP aging */
arpRefreshTimer = new Timer();
arpRefreshTimer.schedule(new ARPRefreshHandler(), 5000, 5000);
+ keyScheme = HostIdFactory.getScheme();
logger.debug("startUp: Caches created, timers started");
}
return;
}
logger.debug("Retrieving cache for HostTrackerAH");
- hostsDB = (ConcurrentMap<InetAddress, HostNodeConnector>) this.clusterContainerService
- .getCache(ACTIVE_HOST_CACHE);
+ hostsDB = (ConcurrentMap<IHostId, HostNodeConnector>) this.clusterContainerService.getCache(ACTIVE_HOST_CACHE);
if (hostsDB == null) {
logger.error("Cache couldn't be retrieved for HostTracker");
}
}
public void nonClusterObjectCreate() {
- hostsDB = new ConcurrentHashMap<InetAddress, HostNodeConnector>();
+ hostsDB = new ConcurrentHashMap<IHostId, HostNodeConnector>();
inactiveStaticHosts = new ConcurrentHashMap<NodeConnector, HostNodeConnector>();
- ARPPendingList = new ConcurrentHashMap<InetAddress, ARPPending>();
- failedARPReqList = new ConcurrentHashMap<InetAddress, ARPPending>();
+ ARPPendingList = new ConcurrentHashMap<IHostId, ARPPending>();
+ failedARPReqList = new ConcurrentHashMap<IHostId, ARPPending>();
}
public void shutDown() {
}
private boolean hostExists(HostNodeConnector host) {
- HostNodeConnector lhost = hostsDB.get(host.getNetworkAddress());
+ IHostId id = HostIdFactory.create(host.getNetworkAddress(), host.getDataLayerAddress());
+ HostNodeConnector lhost = hostsDB.get(id);
return host.equals(lhost);
}
- private HostNodeConnector getHostFromOnActiveDB(InetAddress networkAddress) {
- return hostsDB.get(networkAddress);
+ private HostNodeConnector getHostFromOnActiveDB(IHostId id) {
+ return hostsDB.get(id);
}
- private Entry<NodeConnector, HostNodeConnector> getHostFromInactiveDB(InetAddress networkAddress) {
+ private Entry<NodeConnector, HostNodeConnector> getHostFromInactiveDB(IHostId id) {
for (Entry<NodeConnector, HostNodeConnector> entry : inactiveStaticHosts.entrySet()) {
- if (entry.getValue().equalsByIP(networkAddress)) {
- logger.debug("getHostFromInactiveDB(): Inactive Host found for IP:{} ", networkAddress.getHostAddress());
+ HostNodeConnector hnc = entry.getValue();
+ IHostId cmpId = HostIdFactory.create(hnc.getNetworkAddress(), hnc.getDataLayerAddress());
+ if (cmpId.equals(id)) {
+ logger.debug("getHostFromInactiveDB(): Inactive Host found for ID:{} ", decodeIPFromId(id));
return entry;
}
}
- logger.debug("getHostFromInactiveDB() Inactive Host Not found for IP: {}", networkAddress.getHostAddress());
+ logger.debug("getHostFromInactiveDB() Inactive Host Not found for ID: {}", decodeIPFromId(id));
return null;
}
- private void removeHostFromInactiveDB(InetAddress networkAddress) {
+ private void removeHostFromInactiveDB(IHostId id) {
NodeConnector nodeConnector = null;
for (Entry<NodeConnector, HostNodeConnector> entry : inactiveStaticHosts.entrySet()) {
- if (entry.getValue().equalsByIP(networkAddress)) {
+ HostNodeConnector hnc = entry.getValue();
+ IHostId cmpId = HostIdFactory.create(hnc.getNetworkAddress(), hnc.getDataLayerAddress());
+ if (cmpId.equals(id)) {
nodeConnector = entry.getKey();
break;
}
}
if (nodeConnector != null) {
inactiveStaticHosts.remove(nodeConnector);
- logger.debug("removeHostFromInactiveDB(): Host Removed for IP: {}", networkAddress.getHostAddress());
+ logger.debug("removeHostFromInactiveDB(): Host Removed for IP: {}", decodeIPFromId(id));
return;
}
- logger.debug("removeHostFromInactiveDB(): Host Not found for IP: {}", networkAddress.getHostAddress());
+ logger.debug("removeHostFromInactiveDB(): Host Not found for IP: {}", decodeIPFromId(id));
}
protected boolean hostMoved(HostNodeConnector host) {
- if (hostQuery(host.getNetworkAddress()) != null) {
+ IHostId id = HostIdFactory.create(host.getNetworkAddress(), host.getDataLayerAddress());
+ if (hostQuery(id) != null) {
return true;
}
return false;
}
@Override
- public HostNodeConnector hostQuery(InetAddress networkAddress) {
- return hostsDB.get(networkAddress);
+ public HostNodeConnector hostQuery(IHostId id) {
+ return hostsDB.get(id);
}
@Override
- public Future<HostNodeConnector> discoverHost(InetAddress networkAddress) {
+ public Future<HostNodeConnector> discoverHost(IHostId id) {
if (executor == null) {
logger.debug("discoverHost: Null executor");
return null;
}
- Callable<HostNodeConnector> worker = new HostTrackerCallable(this, networkAddress);
+ Callable<HostNodeConnector> worker = new HostTrackerCallable(this, id);
Future<HostNodeConnector> submit = executor.submit(worker);
return submit;
}
@Override
- public HostNodeConnector hostFind(InetAddress networkAddress) {
+ public HostNodeConnector hostFind(IHostId id) {
/*
* Sometimes at boot with containers configured in the startup we hit
* this path (from TIF) when hostFinder has not been set yet Caller
return null;
}
- HostNodeConnector host = hostQuery(networkAddress);
+ HostNodeConnector host = hostQuery(id);
if (host != null) {
- logger.debug("hostFind(): Host found for IP: {}", networkAddress.getHostAddress());
+ logger.debug("hostFind(): Host found for IP: {}", id);
return host;
}
/* Add this host to ARPPending List for any potential retries */
- addToARPPendingList(networkAddress);
- logger.debug("hostFind(): Host Not Found for IP: {}, Inititated Host Discovery ...",
- networkAddress.getHostAddress());
+ addToARPPendingList(id);
+ logger.debug("hostFind(): Host Not Found for IP: {}, Inititated Host Discovery ...", id);
/* host is not found, initiate a discovery */
for (IHostFinder hf : hostFinder) {
- hf.find(networkAddress);
+ InetAddress addr = decodeIPFromId(id);
+ hf.find(addr);
}
return null;
}
@Override
public Set<HostNodeConnector> getActiveStaticHosts() {
Set<HostNodeConnector> list = new HashSet<HostNodeConnector>();
- for (Entry<InetAddress, HostNodeConnector> entry : hostsDB.entrySet()) {
+ for (Entry<IHostId, HostNodeConnector> entry : hostsDB.entrySet()) {
HostNodeConnector host = entry.getValue();
if (host.isStaticHost()) {
list.add(host);
return list;
}
- private void addToARPPendingList(InetAddress networkAddr) {
+ private void addToARPPendingList(IHostId id) {
ARPPending arphost = new ARPPending();
- arphost.setHostIP(networkAddr);
+ arphost.setHostId(id);
arphost.setSent_count((short) 1);
- ARPPendingList.put(networkAddr, arphost);
- logger.debug("Host Added to ARPPending List, IP: {}", networkAddr);
+ ARPPendingList.put(id, arphost);
+ logger.debug("Host Added to ARPPending List, IP: {}", decodeIPFromId(id));
+
}
- public void setCallableOnPendingARP(InetAddress networkAddr, HostTrackerCallable callable) {
+ public void setCallableOnPendingARP(IHostId id, HostTrackerCallable callable) {
ARPPending arphost;
- for (Entry<InetAddress, ARPPending> entry : ARPPendingList.entrySet()) {
+ for (Entry<IHostId, ARPPending> entry : ARPPendingList.entrySet()) {
arphost = entry.getValue();
- if (arphost.getHostIP().equals(networkAddr)) {
+ if (arphost.getHostId().equals(id)) {
arphost.setHostTrackerCallable(callable);
}
}
}
- private void processPendingARPReqs(InetAddress networkAddr) {
+ private void processPendingARPReqs(IHostId id) {
ARPPending arphost;
- if ((arphost = ARPPendingList.remove(networkAddr)) != null) {
+ if ((arphost = ARPPendingList.remove(id)) != null) {
// Remove the arphost from ARPPendingList as it has been learned now
- logger.debug("Host Removed from ARPPending List, IP: {}", networkAddr);
+ logger.debug("Host Removed from ARPPending List, IP: {}", id);
HostTrackerCallable htCallable = arphost.getHostTrackerCallable();
if (htCallable != null) {
htCallable.wakeup();
* It could have been a host from the FailedARPReqList
*/
- if (failedARPReqList.containsKey(networkAddr)) {
- failedARPReqList.remove(networkAddr);
- logger.debug("Host Removed from FailedARPReqList List, IP: {}", networkAddr);
+ if (failedARPReqList.containsKey(id)) {
+ failedARPReqList.remove(id);
+ logger.debug("Host Removed from FailedARPReqList List, IP: {}", decodeIPFromId(id));
}
}
// Learn a new Host
private void learnNewHost(HostNodeConnector host) {
+ IHostId id = HostIdFactory.create(host.getNetworkAddress(), host.getDataLayerAddress());
host.initArpSendCountDown();
- HostNodeConnector rHost = hostsDB.putIfAbsent(host.getNetworkAddress(), host);
+ HostNodeConnector rHost = hostsDB.putIfAbsent(id, host);
if (rHost != null) {
// Another host is already learned for this IP address, replace it
- replaceHost(host.getNetworkAddress(), rHost, host);
+ replaceHost(id, rHost, host);
} else {
logger.debug("New Host Learned: MAC: {} IP: {}", HexEncode.bytesToHexString(host
.getDataLayerAddressBytes()), host.getNetworkAddress().getHostAddress());
}
}
- private void replaceHost(InetAddress networkAddr, HostNodeConnector removedHost, HostNodeConnector newHost) {
+ private void replaceHost(IHostId id, HostNodeConnector removedHost, HostNodeConnector newHost) {
// Ignore ARP messages from internal nodes
NodeConnector newHostNc = newHost.getnodeConnector();
boolean newHostIsInternal = topologyManager.isInternal(newHostNc);
newHost.initArpSendCountDown();
- if (hostsDB.replace(networkAddr, removedHost, newHost)) {
+ if (hostsDB.replace(id, removedHost, newHost)) {
logger.debug("Host move occurred: Old Host IP:{}, New Host IP: {}", removedHost.getNetworkAddress()
.getHostAddress(), newHost.getNetworkAddress().getHostAddress());
logger.debug("Old Host MAC: {}, New Host MAC: {}",
/*
* Host replacement has failed, do the recovery
*/
- hostsDB.put(networkAddr, newHost);
+ hostsDB.put(id, newHost);
logger.error("Host replacement failed. Overwrite the host. Repalced Host: {}, New Host: {}", removedHost,
newHost);
}
notifyHostLearnedOrRemoved(removedHost, false);
notifyHostLearnedOrRemoved(newHost, true);
if (!newHost.isStaticHost()) {
- processPendingARPReqs(networkAddr);
+ processPendingARPReqs(id);
}
}
// Remove known Host
- private void removeKnownHost(InetAddress key) {
+ private void removeKnownHost(IHostId key) {
HostNodeConnector host = hostsDB.get(key);
if (host != null) {
logger.debug("Removing Host: IP:{}", host.getNetworkAddress().getHostAddress());
hostsDB.remove(key);
} else {
- logger.error("removeKnownHost(): Host for IP address {} not found in hostsDB", key.getHostAddress());
+ logger.error("removeKnownHost(): Host for IP address {} not found in hostsDB", decodeIPFromId(key));
}
}
public void run() {
HostNodeConnector removedHost = null;
InetAddress networkAddr = host.getNetworkAddress();
-
+ IHostId id = HostIdFactory.create(networkAddr, host.getDataLayerAddress());
/* Check for Host Move case */
if (hostMoved(host)) {
/*
* location parameters with new information, and notify the
* applications listening to host move.
*/
- removedHost = hostsDB.get(networkAddr);
+
+ removedHost = hostsDB.get(id);
if (removedHost != null) {
- replaceHost(networkAddr, removedHost, host);
+ replaceHost(id, removedHost, host);
return;
} else {
logger.error("Host to be removed not found in hostsDB");
learnNewHost(host);
/* check if there is an outstanding request for this host */
- processPendingARPReqs(networkAddr);
+ processPendingARPReqs(id);
notifyHostLearnedOrRemoved(host, true);
}
}
logger.debug("Received for Host: IP {}, MAC {}, {}", host.getNetworkAddress().getHostAddress(),
HexEncode.bytesToHexString(host.getDataLayerAddressBytes()), host);
if (hostExists(host)) {
- HostNodeConnector existinghost = hostsDB.get(host.getNetworkAddress());
+ IHostId id = HostIdFactory.create(host.getNetworkAddress(), host.getDataLayerAddress());
+ HostNodeConnector existinghost = hostsDB.get(id);
existinghost.initArpSendCountDown();
// Update the host
- hostsDB.put(host.getNetworkAddress(), existinghost);
+
+ hostsDB.put(id, existinghost);
+ logger.debug("hostListener returned without adding the host");
return;
}
new NotifyHostThread(host).start();
* Switch-Ids as String).
*/
@Override
- public List<List<String>> getHostNetworkHierarchy(InetAddress hostAddress) {
- HostNodeConnector host = hostQuery(hostAddress);
+ public List<List<String>> getHostNetworkHierarchy(IHostId id) {
+ HostNodeConnector host = hostQuery(id);
if (host == null) {
return null;
}
public void subnetNotify(Subnet sub, boolean add) {
logger.debug("Received subnet notification: {} add={}", sub, add);
if (add) {
- for (Entry<InetAddress, ARPPending> entry : failedARPReqList.entrySet()) {
+ for (Entry<IHostId, ARPPending> entry : failedARPReqList.entrySet()) {
ARPPending arphost;
arphost = entry.getValue();
if (hostFinder == null) {
logger.warn("ARPHandler Services are not available on subnet addition");
continue;
}
- logger.debug("Sending the ARP from FailedARPReqList fors IP: {}", arphost.getHostIP().getHostAddress());
+ logger.debug("Sending the ARP from FailedARPReqList fors IP: {}", decodeIPFromId(arphost.getHostId()));
for (IHostFinder hf : hostFinder) {
- hf.find(arphost.getHostIP());
+ hf.find(decodeIPFromId(arphost.getHostId()));
}
}
}
/* This routine runs every 4 seconds */
logger.trace("Number of Entries in ARP Pending/Failed Lists: ARPPendingList = {}, failedARPReqList = {}",
ARPPendingList.size(), failedARPReqList.size());
- for (Entry<InetAddress, ARPPending> entry : ARPPendingList.entrySet()) {
+ for (Entry<IHostId, ARPPending> entry : ARPPendingList.entrySet()) {
arphost = entry.getValue();
- if (hostsDB.containsKey(arphost.getHostIP())) {
+ if (hostsDB.containsKey(arphost.getHostId())) {
// this host is already learned, shouldn't be in
// ARPPendingList
// Remove it and continue
- logger.warn("Learned Host {} found in ARPPendingList", arphost.getHostIP());
+ logger.warn("Learned Host {} found in ARPPendingList", decodeIPFromId(arphost.getHostId()));
ARPPendingList.remove(entry.getKey());
continue;
}
continue;
}
for (IHostFinder hf : hostFinder) {
- hf.find(arphost.getHostIP());
+ hf.find(decodeIPFromId(arphost.getHostId()));
}
arphost.sent_count++;
- logger.debug("ARP Sent from ARPPending List, IP: {}", arphost.getHostIP().getHostAddress());
+ logger.debug("ARP Sent from ARPPending List, IP: {}", decodeIPFromId(arphost.getHostId()));
} else if (arphost.getSent_count() >= hostRetryCount) {
/*
* ARP requests have been sent without receiving a reply,
*/
ARPPendingList.remove(entry.getKey());
logger.debug("ARP reply not received after multiple attempts, removing from Pending List IP: {}",
- arphost.getHostIP().getHostAddress());
+ decodeIPFromId(arphost.getHostId()));
/*
* Add this host to a different list which will be processed
* on link up events
*/
- logger.debug("Adding the host to FailedARPReqList IP: {}", arphost.getHostIP().getHostAddress());
+ logger.debug("Adding the host to FailedARPReqList IP: {}", decodeIPFromId(arphost.getHostId()));
failedARPReqList.put(entry.getKey(), arphost);
} else {
logger.error("ARPRefreshHandler(): hostsDB is not allocated yet:");
return;
}
- for (Entry<InetAddress, HostNodeConnector> entry : hostsDB.entrySet()) {
+ for (Entry<IHostId, HostNodeConnector> entry : hostsDB.entrySet()) {
HostNodeConnector host = entry.getValue();
if (host.isStaticHost()) {
/* this host was learned via API3, don't age it out */
HostNodeConnector host = null;
try {
host = new HostNodeConnector(dataLayerAddress, networkAddr, nc, vlan);
+ IHostId id = HostIdFactory.create(networkAddr, new EthernetAddress(dataLayerAddress));
if (hostExists(host)) {
// This host is already learned either via ARP or through a
// northbound request
return new Status(StatusCode.SUCCESS);
}
- if (hostsDB.get(networkAddr) != null) {
+ if (hostsDB.get(id) != null) {
// There is already a host with this IP address (but behind
// a different (switch, port, vlan) tuple. Return an error
return new Status(StatusCode.CONFLICT, "Host with this IP already exists.");
*/
if (switchManager.isNodeConnectorEnabled(nc)) {
learnNewHost(host);
- processPendingARPReqs(networkAddr);
+ processPendingARPReqs(id);
notifyHostLearnedOrRemoved(host, true);
} else {
inactiveStaticHosts.put(nc, host);
return new Status(StatusCode.BADREQUEST, "Host already exists");
}
+ IHostId id = HostIdFactory.create(networkAddr, new EthernetAddress(dataLayerAddress));
+
if ((tobeUpdatedHost = hostsDB.get(networkAddr)) != null) {
- if (hostsDB.replace(networkAddr, tobeUpdatedHost, host)) {
+ if (hostsDB.replace(id, tobeUpdatedHost, host)) {
logger.debug("Host replaced from hostsDB. Old host: {} New Host: {}", tobeUpdatedHost, host);
notifyHostLearnedOrRemoved(tobeUpdatedHost, false);
notifyHostLearnedOrRemoved(host, true);
* otherwise
*/
- public Status removeStaticHostReq(InetAddress networkAddress) {
+ public Status removeStaticHostReq(InetAddress networkAddress, DataLinkAddress mac) {
// Check if host is in active hosts database
- HostNodeConnector host = getHostFromOnActiveDB(networkAddress);
+ IHostId id = HostIdFactory.create(networkAddress, mac);
+ HostNodeConnector host = getHostFromOnActiveDB(id);
if (host != null) {
// Validation check
if (!host.isStaticHost()) {
}
// Remove and notify
notifyHostLearnedOrRemoved(host, false);
- removeKnownHost(networkAddress);
+ removeKnownHost(id);
return new Status(StatusCode.SUCCESS, null);
}
// Check if host is in inactive hosts database
- Entry<NodeConnector, HostNodeConnector> entry = getHostFromInactiveDB(networkAddress);
+ Entry<NodeConnector, HostNodeConnector> entry = getHostFromInactiveDB(id);
if (entry != null) {
host = entry.getValue();
// Validation check
if (!host.isStaticHost()) {
return new Status(StatusCode.FORBIDDEN, "Host " + networkAddress.getHostName() + " is not static");
}
- this.removeHostFromInactiveDB(networkAddress);
+ this.removeHostFromInactiveDB(id);
return new Status(StatusCode.SUCCESS, null);
}
switch (type) {
case REMOVED:
logger.debug("Received removed node {}", node);
- for (Entry<InetAddress, HostNodeConnector> entry : hostsDB.entrySet()) {
+ for (Entry<IHostId, HostNodeConnector> entry : hostsDB.entrySet()) {
HostNodeConnector host = entry.getValue();
if (host.getnodeconnectorNode().equals(node)) {
logger.debug("Node: {} is down, remove from Hosts_DB", node);
@Override
public Status removeStaticHost(String networkAddress) {
try {
+ if ((keyScheme != null) && (!keyScheme.equals(HostIdFactory.DEFAULT_IP_KEY_SCHEME))) {
+ return new Status(StatusCode.NOTALLOWED, "Host DB Key scheme used is not IP only scheme.");
+ }
InetAddress address = InetAddress.getByName(networkAddress);
- return removeStaticHostReq(address);
+ return removeStaticHostReq(address, null);
} catch (UnknownHostException e) {
logger.debug("Invalid IP Address when trying to remove host", e);
return new Status(StatusCode.BADREQUEST, "Invalid IP Address when trying to remove host");
}
}
+ @Override
+ public Status removeStaticHostUsingIPAndMac(String networkAddress, String macAddress) {
+ try {
+ if ((keyScheme != null) && (keyScheme.equals(HostIdFactory.DEFAULT_IP_KEY_SCHEME))) {
+ return new Status(StatusCode.NOTALLOWED, "Host DB Key scheme used is not IP only scheme.");
+ }
+ InetAddress address = InetAddress.getByName(networkAddress);
+ DataLinkAddress mac = new EthernetAddress(HexEncode.bytesFromHexString(macAddress));
+ return removeStaticHostReq(address, mac);
+ } catch (UnknownHostException e) {
+ logger.debug("Invalid IP Address when trying to remove host", e);
+ return new Status(StatusCode.BADREQUEST, "Invalid IP Address when trying to remove host");
+ } catch (ConstructionException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ return new Status(StatusCode.BADREQUEST, "Invalid Input parameters have been passed.");
+ }
+ }
+
+ private InetAddress decodeIPFromId(IHostId id) {
+ if ((keyScheme != null) && (keyScheme.equals(HostIdFactory.DEFAULT_IP_KEY_SCHEME))) {
+ IPHostId ipId = (IPHostId) id;
+ return (ipId.getIpAddress());
+ } else if ((keyScheme != null) && (keyScheme.equals(HostIdFactory.IP_MAC_KEY_SCHEME))) {
+ IPMacHostId ipMacId = (IPMacHostId) id;
+ return (ipMacId.getIpAddress());
+ }
+ return null;
+ }
+
+ private DataLinkAddress decodeMacFromId(IHostId id) {
+ if ((keyScheme != null) && (!keyScheme.equals(HostIdFactory.DEFAULT_IP_KEY_SCHEME))) {
+ IPMacHostId ipMacId = (IPMacHostId) id;
+ return (ipMacId.getMacAddr());
+ }
+
+ return null;
+ }
+
private void handleNodeConnectorStatusUp(NodeConnector nodeConnector) {
ARPPending arphost;
HostNodeConnector host = null;
logger.trace("handleNodeConnectorStatusUp {}", nodeConnector);
- for (Entry<InetAddress, ARPPending> entry : failedARPReqList.entrySet()) {
+ for (Entry<IHostId, ARPPending> entry : failedARPReqList.entrySet()) {
arphost = entry.getValue();
- logger.trace("Sending the ARP from FailedARPReqList fors IP: {}", arphost.getHostIP().getHostAddress());
+ logger.trace("Sending the ARP from FailedARPReqList fors IP: {}", arphost.getHostId());
if (hostFinder == null) {
logger.warn("ARPHandler is not available at interface up");
logger.warn("Since this event is missed, host(s) connected to interface {} may not be discovered",
// Use hostFinder's "probe" method
try {
byte[] dataLayerAddress = NetUtils.getBroadcastMACAddr();
- host = new HostNodeConnector(dataLayerAddress, arphost.getHostIP(), nodeConnector, (short) 0);
+ host = new HostNodeConnector(dataLayerAddress, decodeIPFromId(arphost.getHostId()), nodeConnector,
+ (short) 0);
for (IHostFinder hf : hostFinder) {
hf.probe(host);
}
} catch (ConstructionException e) {
logger.debug("HostNodeConnector couldn't be created for Host: {}, NodeConnector: {}",
- arphost.getHostIP(), nodeConnector);
+ arphost.getHostId(), nodeConnector);
logger.error("", e);
}
}
if (host != null) {
inactiveStaticHosts.remove(nodeConnector);
learnNewHost(host);
- processPendingARPReqs(host.getNetworkAddress());
+ IHostId id = HostIdFactory.create(host.getNetworkAddress(), host.getDataLayerAddress());
+ processPendingARPReqs(id);
notifyHostLearnedOrRemoved(host, true);
}
}
private void handleNodeConnectorStatusDown(NodeConnector nodeConnector) {
logger.trace("handleNodeConnectorStatusDown {}", nodeConnector);
- for (Entry<InetAddress, HostNodeConnector> entry : hostsDB.entrySet()) {
+ for (Entry<IHostId, HostNodeConnector> entry : hostsDB.entrySet()) {
HostNodeConnector host = entry.getValue();
if (host.getnodeConnector().equals(nodeConnector)) {
logger.debug(" NodeConnector: {} is down, remove from Hosts_DB", nodeConnector);
this.containerName = "";
}
startUp();
+
+ logger.debug("key Scheme in hosttracker is {}", keyScheme);
}
/**
}
@Override
- public void entryCreated(InetAddress key, String cacheName, boolean originLocal) {
+ public void entryCreated(IHostId key, String cacheName, boolean originLocal) {
if (originLocal) {
return;
}
}
@Override
- public void entryUpdated(InetAddress key, HostNodeConnector new_value, String cacheName, boolean originLocal) {
+ public void entryUpdated(IHostId key, HostNodeConnector new_value, String cacheName, boolean originLocal) {
}
@Override
- public void entryDeleted(InetAddress key, String cacheName, boolean originLocal) {
+ public void entryDeleted(IHostId key, String cacheName, boolean originLocal) {
}
private void registerWithOSGIConsole() {
public void _dumpPendingARPReqList(CommandInterpreter ci) {
ARPPending arphost;
- for (Entry<InetAddress, ARPPending> entry : ARPPendingList.entrySet()) {
+ for (Entry<IHostId, ARPPending> entry : ARPPendingList.entrySet()) {
arphost = entry.getValue();
- ci.println(arphost.getHostIP().toString());
+ ci.println(arphost.getHostId().toString());
}
}
public void _dumpFailedARPReqList(CommandInterpreter ci) {
ARPPending arphost;
- for (Entry<InetAddress, ARPPending> entry : failedARPReqList.entrySet()) {
+ for (Entry<IHostId, ARPPending> entry : failedARPReqList.entrySet()) {
arphost = entry.getValue();
- ci.println(arphost.getHostIP().toString());
+ ci.println(arphost.getHostId().toString());
}
}
+
+ @Override
+ public HostNodeConnector hostFind(InetAddress addr) {
+ IHostId id = HostIdFactory.create(addr, null);
+ return (hostFind(id));
+ }
+
+ @Override
+ public HostNodeConnector hostQuery(InetAddress addr) {
+ IHostId id = HostIdFactory.create(addr, null);
+ return (hostQuery(id));
+ }
+
+ @Override
+ public Future<HostNodeConnector> discoverHost(InetAddress addr) {
+ IHostId id = HostIdFactory.create(addr, null);
+ return discoverHost(id);
+ }
+
+ @Override
+ public List<List<String>> getHostNetworkHierarchy(InetAddress addr) {
+ IHostId id = HostIdFactory.create(addr, null);
+ return getHostNetworkHierarchy(id);
+ }
}
* find a host in HostTracker's database and want to discover the host
* in the same thread without being called by a callback function.
*/
-import java.net.InetAddress;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
+import org.opendaylight.controller.hosttracker.IHostId;
import org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector;
+/**
+ *
+ *
+ */
public class HostTrackerCallable implements Callable<HostNodeConnector> {
- InetAddress trackedHost;
+ //host id which could be ip or a combination of ip + mac based on the scheme chosen.
+ IHostId trackedHost;
HostTracker hostTracker;
protected CountDownLatch latch;
- public HostTrackerCallable(HostTracker tracker, InetAddress inet) {
+ public HostTrackerCallable(HostTracker tracker, IHostId inet) {
trackedHost = inet;
hostTracker = tracker;
latch = new CountDownLatch(1);
\r
import java.net.InetAddress;\r
import java.net.UnknownHostException;\r
+\r
import junit.framework.TestCase;\r
\r
import org.junit.Assert;\r
import org.junit.Test;\r
+import org.opendaylight.controller.hosttracker.IHostId;\r
+import org.opendaylight.controller.hosttracker.IPHostId;\r
\r
public class HostTrackerTest extends TestCase {\r
\r
Assert.assertFalse(hostTracker == null);\r
\r
InetAddress hostIP = InetAddress.getByName("192.168.0.8");\r
+ IHostId id = IPHostId.fromIP(hostIP);\r
\r
HostTrackerCallable htCallable = new HostTrackerCallable(hostTracker,\r
- hostIP);\r
- Assert.assertTrue(htCallable.trackedHost.equals(hostIP));\r
+ id);\r
+ Assert.assertTrue(htCallable.trackedHost.equals(id));\r
Assert.assertTrue(htCallable.hostTracker.equals(hostTracker));\r
\r
long count = htCallable.latch.getCount();\r
Assert.assertFalse(hostTracker == null);\r
\r
InetAddress hostIP_1 = InetAddress.getByName("192.168.0.8");\r
+ IHostId id1 = IPHostId.fromIP(hostIP_1);\r
InetAddress hostIP_2 = InetAddress.getByName("192.168.0.18");\r
- hostTracker.discoverHost(hostIP_1);\r
- hostTracker.discoverHost(hostIP_2);\r
+ IHostId id2 = IPHostId.fromIP(hostIP_2);\r
+ hostTracker.discoverHost(id1);\r
+ hostTracker.discoverHost(id2);\r
hostTracker.nonClusterObjectCreate();\r
}\r
\r
</scm>
<artifactId>hosttracker.integrationtest</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>0.5.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${hosttracker.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${hosttracker.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>arphandler</artifactId>
- <version>0.4.1-SNAPSHOT</version>
+ <version>${arphandler.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.opendaylight.controller.hosttracker.IHostId;
+import org.opendaylight.controller.hosttracker.IPHostId;
import org.opendaylight.controller.hosttracker.IfIptoHost;
import org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector;
import org.opendaylight.controller.sal.core.Node;
import org.osgi.framework.ServiceReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
//import org.opendaylight.controller.hosttracker.*;
@RunWith(PaxExam.class)
private IfIptoHost hosttracker = null;
private IInventoryListener invtoryListener = null;
+
// Configure the OSGi container
@Configuration
public Option[] config() {
st = this.hosttracker.addStaticHost("192.168.0.13", "11:22:33:44:55:77", nc1_2, "0");
Assert.assertFalse(st.isSuccess());
-
this.invtoryListener.notifyNodeConnector(nc1_1, UpdateType.ADDED, null);
// check all host list
Status st = this.hosttracker.addStaticHost("192.168.0.8", "11:22:33:44:55:66", nc1_1, null);
st = this.hosttracker.addStaticHost("192.168.0.13", "11:22:33:44:55:77", nc1_2, "");
- HostNodeConnector hnc_1 = this.hosttracker.hostFind(InetAddress.getByName("192.168.0.8"));
+ IHostId id1 = IPHostId.fromIP(InetAddress.getByName("192.168.0.8"));
+ HostNodeConnector hnc_1 = this.hosttracker.hostFind(id1);
assertNull(hnc_1);
this.invtoryListener.notifyNodeConnector(nc1_1, UpdateType.ADDED, null);
- hnc_1 = this.hosttracker.hostFind(InetAddress.getByName("192.168.0.8"));
+ IHostId id2 = IPHostId.fromIP(InetAddress.getByName("192.168.0.8"));
+ hnc_1 = this.hosttracker.hostFind(id2);
+
assertNotNull(hnc_1);
}
<build>
<plugins>
-
<plugin>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-maven-plugin</artifactId>
--- /dev/null
+/**
+* Generated file
+
+* Generated from: yang module name: opendaylight-sal-binding-broker-impl yang module local name: binding-broker-impl
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Wed Nov 20 17:33:01 CET 2013
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.md.sal.binding.impl;
+
+import org.opendaylight.controller.sal.binding.impl.BindingAwareBrokerImpl;
+import org.osgi.framework.BundleContext;
+
+/**
+*
+*/
+public final class BindingBrokerImplModule extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractBindingBrokerImplModule
+{
+
+ private BundleContext bundleContext;
+
+ public BindingBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public BindingBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, BindingBrokerImplModule oldModule, java.lang.AutoCloseable oldInstance) {
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ public void validate(){
+ super.validate();
+ // Add custom validation for module attributes here.
+ }
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+ BindingAwareBrokerImpl broker = new BindingAwareBrokerImpl(getBundleContext());
+ broker.setDataBroker(getDataBrokerDependency());
+ broker.setNotifyBroker(getNotificationServiceDependency());
+ broker.start();
+ return broker;
+ }
+
+ public BundleContext getBundleContext() {
+ return bundleContext;
+ }
+
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+}
--- /dev/null
+/**
+* Generated file
+
+* Generated from: yang module name: opendaylight-sal-binding-broker-impl yang module local name: binding-broker-impl
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Wed Nov 20 17:33:01 CET 2013
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.md.sal.binding.impl;
+
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
+import org.opendaylight.controller.config.spi.Module;
+import org.osgi.framework.BundleContext;
+
+/**
+*
+*/
+public class BindingBrokerImplModuleFactory extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractBindingBrokerImplModuleFactory
+{
+
+
+ @Override
+ public Module createModule(String instanceName, DependencyResolver dependencyResolver, BundleContext bundleContext) {
+ BindingBrokerImplModule module = (BindingBrokerImplModule) super.createModule(instanceName, dependencyResolver, bundleContext);
+ module.setBundleContext(bundleContext);
+ return module;
+ }
+
+ @Override
+ public Module createModule(String instanceName, DependencyResolver dependencyResolver,
+ DynamicMBeanWithInstance old, BundleContext bundleContext) throws Exception {
+ BindingBrokerImplModule module = (BindingBrokerImplModule) super.createModule(instanceName, dependencyResolver, old, bundleContext);
+ module.setBundleContext(bundleContext);
+ return module;
+ }
+
+}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.config.yang.md.sal.binding.impl;
-
-import org.opendaylight.controller.sal.binding.impl.BindingAwareBrokerImpl;
-import org.osgi.framework.BundleContext;
-
-import com.google.common.base.Preconditions;
-
-/**
-*
-*/
-public final class BindingBrokerImplSingletonModule extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractBindingBrokerImplSingletonModule
-{
-
- private BundleContext bundleContext;
-
- public BindingBrokerImplSingletonModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
- super(identifier, dependencyResolver);
- }
-
- public BindingBrokerImplSingletonModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, BindingBrokerImplSingletonModule oldModule, java.lang.AutoCloseable oldInstance) {
- super(identifier, dependencyResolver, oldModule, oldInstance);
- }
-
- @Override
- public void validate() {
- super.validate();
- Preconditions.checkNotNull(getBundleContext());
- }
-
-
- @Override
- public boolean canReuseInstance(AbstractBindingBrokerImplSingletonModule oldModule) {
- return true;
- }
-
-
- public java.lang.AutoCloseable createInstance() {
- BindingAwareBrokerImpl broker = new BindingAwareBrokerImpl(getBundleContext());
- broker.start();
- return broker;
- }
-
- public BundleContext getBundleContext() {
- return bundleContext;
- }
-
- public void setBundleContext(BundleContext bundleContext) {
- this.bundleContext = bundleContext;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.config.yang.md.sal.binding.impl;
-
-import org.opendaylight.controller.config.api.DependencyResolver;
-import org.opendaylight.controller.config.api.DependencyResolverFactory;
-import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
-import org.opendaylight.controller.config.api.ModuleIdentifier;
-import org.opendaylight.controller.config.spi.Module;
-import org.osgi.framework.BundleContext;
-
-import java.util.Collections;
-import java.util.Set;
-
-/**
-*
-*/
-public class BindingBrokerImplSingletonModuleFactory extends
- org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractBindingBrokerImplSingletonModuleFactory {
-
- private static final String SINGLETON_NAME = "binding-broker-singleton";
- public static ModuleIdentifier SINGLETON_IDENTIFIER = new ModuleIdentifier(NAME, SINGLETON_NAME);
-
- @Override
- public Module createModule(String instanceName, DependencyResolver dependencyResolver, BundleContext bundleContext) {
- throw new UnsupportedOperationException("Only default instance supported.");
- }
-
- @Override
- public Module createModule(String instanceName, DependencyResolver dependencyResolver,
- DynamicMBeanWithInstance old, BundleContext bundleContext) throws Exception {
- Module instance = super.createModule(instanceName, dependencyResolver, old, bundleContext);
- ((BindingBrokerImplSingletonModule)instance).setBundleContext(bundleContext);
- return instance;
- }
-
- @Override
- public Set<BindingBrokerImplSingletonModule> getDefaultModules(DependencyResolverFactory dependencyResolverFactory,
- BundleContext bundleContext) {
-
- DependencyResolver dependencyResolver = dependencyResolverFactory
- .createDependencyResolver(SINGLETON_IDENTIFIER);
- BindingBrokerImplSingletonModule instance = new BindingBrokerImplSingletonModule(SINGLETON_IDENTIFIER,
- dependencyResolver);
- instance.setBundleContext(bundleContext);
-
- return Collections.singleton(instance);
- }
-
-}
--- /dev/null
+/**
+ * Generated file
+
+ * Generated from: yang module name: opendaylight-sal-binding-broker-impl yang module local name: binding-data-broker
+ * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+ * Generated at: Wed Nov 20 17:33:01 CET 2013
+ *
+ * Do not modify this file unless it is present under src/main directory
+ */
+package org.opendaylight.controller.config.yang.md.sal.binding.impl;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+
+import org.opendaylight.controller.md.sal.common.impl.routing.AbstractDataReadRouter;
+import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentDataServiceConnector;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentMappingService;
+import org.opendaylight.controller.sal.core.api.Broker;
+import org.opendaylight.controller.sal.core.api.data.DataProviderService;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.osgi.framework.BundleContext;
+
+import com.google.common.util.concurrent.MoreExecutors;
+
+/**
+*
+*/
+public final class DataBrokerImplModule extends
+ org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractDataBrokerImplModule {
+
+ private BundleContext bundleContext;
+
+ public DataBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+ org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public DataBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+ org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
+ DataBrokerImplModule oldModule, java.lang.AutoCloseable oldInstance) {
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ public void validate() {
+ super.validate();
+ }
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+ DataBrokerImpl dataBindingBroker = new DataBrokerImpl();
+
+ // FIXME: obtain via dependency management
+ ExecutorService executor = Executors.newCachedThreadPool();
+ ExecutorService listeningExecutor = MoreExecutors.listeningDecorator(executor);
+ dataBindingBroker.setExecutor(listeningExecutor);
+
+
+
+ Broker domBroker = getDomBrokerDependency();
+ BindingIndependentMappingService mappingService = getMappingServiceDependency();
+
+ if (domBroker != null && mappingService != null) {
+ BindingIndependentDataServiceConnector runtimeMapping = new BindingIndependentDataServiceConnector();
+ runtimeMapping.setMappingService(mappingService);
+ runtimeMapping.setBaDataService(dataBindingBroker);
+ domBroker.registerProvider(runtimeMapping, getBundleContext());
+ }
+
+ return dataBindingBroker;
+ }
+
+ public BundleContext getBundleContext() {
+ return bundleContext;
+ }
+
+ public void setBundleContext(BundleContext bundleContext2) {
+ this.bundleContext = bundleContext2;
+ }
+}
--- /dev/null
+/**
+* Generated file
+
+* Generated from: yang module name: opendaylight-sal-binding-broker-impl yang module local name: binding-data-broker
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Wed Nov 20 17:33:01 CET 2013
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.md.sal.binding.impl;
+
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
+import org.opendaylight.controller.config.spi.Module;
+import org.osgi.framework.BundleContext;
+
+/**
+*
+*/
+public class DataBrokerImplModuleFactory extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractDataBrokerImplModuleFactory
+{
+
+ @Override
+ public Module createModule(String instanceName, DependencyResolver dependencyResolver, BundleContext bundleContext) {
+ DataBrokerImplModule module = (DataBrokerImplModule) super.createModule(instanceName, dependencyResolver, bundleContext);
+ module.setBundleContext(bundleContext);
+ return module;
+ }
+
+ @Override
+ public Module createModule(String instanceName, DependencyResolver dependencyResolver,
+ DynamicMBeanWithInstance old, BundleContext bundleContext) throws Exception {
+ DataBrokerImplModule module = (DataBrokerImplModule) super.createModule(instanceName, dependencyResolver, old, bundleContext);
+ module.setBundleContext(bundleContext);
+ return module;
+ }
+
+}
--- /dev/null
+/**
+* Generated file
+
+* Generated from: yang module name: opendaylight-sal-binding-broker-impl yang module local name: binding-notification-broker
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Wed Nov 20 17:33:01 CET 2013
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.md.sal.binding.impl;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+
+import org.opendaylight.controller.sal.binding.impl.NotificationBrokerImpl;
+
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+
+/**
+*
+*/
+public final class NotificationBrokerImplModule extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractNotificationBrokerImplModule
+{
+
+ public NotificationBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public NotificationBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, NotificationBrokerImplModule oldModule, java.lang.AutoCloseable oldInstance) {
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ public void validate(){
+ super.validate();
+ // Add custom validation for module attributes here.
+ }
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+ ExecutorService executor = Executors.newFixedThreadPool(5);
+ ListeningExecutorService listeningExecutor = MoreExecutors.listeningDecorator(executor);
+ NotificationBrokerImpl broker = new NotificationBrokerImpl(listeningExecutor);
+ return broker;
+ }
+}
--- /dev/null
+/**
+* Generated file
+
+* Generated from: yang module name: opendaylight-sal-binding-broker-impl yang module local name: binding-notification-broker
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Wed Nov 20 17:33:01 CET 2013
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.md.sal.binding.impl;
+
+/**
+*
+*/
+public class NotificationBrokerImplModuleFactory extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractNotificationBrokerImplModuleFactory
+{
+
+
+}
--- /dev/null
+/**
+* Generated file
+
+* Generated from: yang module name: opendaylight-sal-binding-broker-impl yang module local name: binding-rpc-broker
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Wed Nov 20 17:33:01 CET 2013
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.md.sal.binding.impl;
+
+/**
+*
+*/
+public final class RpcBrokerImplModule extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractRpcBrokerImplModule
+{
+
+ public RpcBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public RpcBrokerImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, RpcBrokerImplModule oldModule, java.lang.AutoCloseable oldInstance) {
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ public void validate(){
+ super.validate();
+ // Add custom validation for module attributes here.
+ }
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+ //TODO:implement
+ throw new java.lang.UnsupportedOperationException("Unimplemented stub method");
+ }
+}
--- /dev/null
+/**
+* Generated file
+
+* Generated from: yang module name: opendaylight-sal-binding-broker-impl yang module local name: binding-rpc-broker
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Wed Nov 20 17:33:01 CET 2013
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.md.sal.binding.impl;
+
+/**
+*
+*/
+public class RpcBrokerImplModuleFactory extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractRpcBrokerImplModuleFactory
+{
+
+
+}
--- /dev/null
+/**
+* Generated file
+
+* Generated from: yang module name: opendaylight-sal-binding-broker-impl yang module local name: runtime-generated-mapping
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Wed Nov 20 18:20:19 CET 2013
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.md.sal.binding.impl;
+
+import javassist.ClassPool;
+
+import org.opendaylight.controller.sal.binding.dom.serializer.impl.RuntimeGeneratedMappingServiceImpl;
+import org.osgi.framework.BundleContext;
+
+import com.google.common.base.Preconditions;
+
+/**
+*
+*/
+public final class RuntimeMappingModule extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractRuntimeMappingModule
+{
+
+ private BundleContext bundleContext;
+
+ public RuntimeMappingModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public RuntimeMappingModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, RuntimeMappingModule oldModule, java.lang.AutoCloseable oldInstance) {
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ public void validate(){
+ super.validate();
+ Preconditions.checkNotNull(bundleContext);
+ // Add custom validation for module attributes here.
+ }
+
+ @Override
+ public boolean canReuseInstance(AbstractRuntimeMappingModule oldModule) {
+ return true;
+ }
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+ RuntimeGeneratedMappingServiceImpl service = new RuntimeGeneratedMappingServiceImpl();
+ ClassPool pool = new ClassPool(); // Should be default singleton
+ service.setPool(pool);
+ service.start(getBundleContext());
+ return service;
+ }
+
+ private BundleContext getBundleContext() {
+ return bundleContext;
+ }
+
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+}
--- /dev/null
+/**
+* Generated file
+
+* Generated from: yang module name: opendaylight-sal-binding-broker-impl yang module local name: runtime-generated-mapping
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Wed Nov 20 18:20:19 CET 2013
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.md.sal.binding.impl;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.DependencyResolverFactory;
+import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.spi.Module;
+import org.osgi.framework.BundleContext;
+
+/**
+*
+*/
+public class RuntimeMappingModuleFactory extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractRuntimeMappingModuleFactory
+{
+
+
+ private static RuntimeMappingModule SINGLETON = null;
+ private static ModuleIdentifier IDENTIFIER = new ModuleIdentifier(NAME, "runtime-mapping-singleton");
+
+ @Override
+ public Module createModule(String instanceName, DependencyResolver dependencyResolver, BundleContext bundleContext) {
+ throw new UnsupportedOperationException("Only default instance supported");
+ }
+
+ @Override
+ public Module createModule(String instanceName, DependencyResolver dependencyResolver,
+ DynamicMBeanWithInstance old, BundleContext bundleContext) throws Exception {
+ RuntimeMappingModule module = (RuntimeMappingModule) super.createModule(instanceName, dependencyResolver, old, bundleContext);
+ module.setBundleContext(bundleContext);
+ return module;
+ }
+
+ @Override
+ public Set<RuntimeMappingModule> getDefaultModules(DependencyResolverFactory dependencyResolverFactory,
+ BundleContext bundleContext) {
+ if(SINGLETON == null) {
+ DependencyResolver dependencyResolver = dependencyResolverFactory.createDependencyResolver(IDENTIFIER);
+ SINGLETON = new RuntimeMappingModule(IDENTIFIER , dependencyResolver);
+ SINGLETON.setBundleContext(bundleContext);
+ }
+
+
+ return Collections.singleton(SINGLETON);
+ }
+
+}
}
- override getRoute(InstanceIdentifier nodeInstance) {
+ override getRoute(InstanceIdentifier<? extends Object> nodeInstance) {
val ret = routes.get(nodeInstance);
if(ret !== null) {
return ret;
@SuppressWarnings("rawtypes")
override updateRoute(InstanceIdentifier<? extends Object> path, S service) {
- routes.put(path as InstanceIdentifier,service);
+ routes.put(path as InstanceIdentifier<? extends DataObject>,service);
}
}
\ No newline at end of file
import org.opendaylight.yangtools.yang.binding.RpcService
import javassist.CtClass
-import static com.google.common.base.Preconditions.*
import javassist.CtMethod
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
import org.opendaylight.yangtools.yang.binding.annotations.RoutingContext
}
override <T extends RpcService> getRouterFor(Class<T> iface) {
- val contexts = new HashSet<Class<? extends BaseIdentity>>
-
- val instance = <RpcRouterCodegenInstance<T>>withClassLoader(iface.classLoader) [ |
+ val instance = <RpcRouterCodegenInstance<T>>withClassLoaderAndLock(iface.classLoader,lock) [ |
val supertype = iface.asCtClass
val metadata = supertype.rpcMetadata;
val targetCls = createClass(iface.routerName, supertype) [
]
val finalClass = targetCls.toClass(iface.classLoader, iface.protectionDomain)
return new RuntimeGeneratedInvokerPrototype(supportedNotification,
- finalClass as Class<? extends org.opendaylight.controller.sal.binding.api.NotificationListener>);
+ finalClass as Class<? extends org.opendaylight.controller.sal.binding.api.NotificationListener<?>>);
}
protected def resolveInvokerClass(Class<? extends NotificationListener> class1) {
- val invoker = invokerClasses.get(class1);
- if (invoker !== null) {
- return invoker;
- }
- val newInvoker = generateListenerInvoker(class1);
- invokerClasses.put(class1, newInvoker);
- return newInvoker
+ return <RuntimeGeneratedInvokerPrototype>withClassLoaderAndLock(class1.classLoader,lock) [|
+ val invoker = invokerClasses.get(class1);
+ if (invoker !== null) {
+ return invoker;
+ }
+ val newInvoker = generateListenerInvoker(class1);
+ invokerClasses.put(class1, newInvoker);
+ return newInvoker
+
+ ]
}
}
val NotificationListener delegate;
@Property
- var org.opendaylight.controller.sal.binding.api.NotificationListener invocationProxy;
+ var org.opendaylight.controller.sal.binding.api.NotificationListener<Notification> invocationProxy;
@Property
var RuntimeGeneratedInvokerPrototype prototype;
new(NotificationListener delegate, RuntimeGeneratedInvokerPrototype prototype) {
_delegate = delegate;
_prototype = prototype;
- _invocationProxy = prototype.protoClass.newInstance;
+ _invocationProxy = prototype.protoClass.newInstance as org.opendaylight.controller.sal.binding.api.NotificationListener<Notification>;
RuntimeCodeHelper.setDelegate(_invocationProxy, delegate);
}
val Set<Class<? extends Notification>> supportedNotifications;
@Property
- val Class<? extends org.opendaylight.controller.sal.binding.api.NotificationListener> protoClass;
+ val Class<? extends org.opendaylight.controller.sal.binding.api.NotificationListener<?>> protoClass;
}
package class RpcServiceMetadata {
void onBindingClassCaptured(Class<?> cls);
+ void onBindingClassProcessed(Class<?> cls);
}
}
}
- public static void setClassToCaseMap(Class<? extends BindingCodec> codec,
- Map<Class,BindingCodec> classToCaseRawCodec) {
+ public static void setClassToCaseMap(Class<? extends BindingCodec<?,?>> codec,
+ Map<Class<?>,BindingCodec<?,?>> classToCaseRawCodec) {
Field instanceIdField;
try {
instanceIdField = codec.getField(CLASS_TO_CASE_MAP);
}
- public static void setCompositeNodeToCaseMap(Class<? extends BindingCodec> codec,
- Map<CompositeNode,BindingCodec> compositeToCase) {
+ public static void setCompositeNodeToCaseMap(Class<? extends BindingCodec<?,?>> codec,
+ Map<CompositeNode,BindingCodec<?,?>> compositeToCase) {
Field instanceIdField;
try {
instanceIdField = codec.getField(COMPOSITE_TO_CASE);
}
public static void setAugmentationCodec(Class<? extends BindingCodec<Map<QName, Object>, Object>> dataCodec,
- BindingCodec augmentableCodec) {
+ BindingCodec<?,?> augmentableCodec) {
Field instanceIdField;
try {
instanceIdField = dataCodec.getField(AUGMENTATION_CODEC);
+ void onClassProcessed(Class<?> cl);
+
void onCodecCreated(Class<?> codec);
void onValueCodecCreated(Class<?> valueClass,Class<?> valueCodec);
void onChoiceCodecCreated(Class<?> choiceClass,Class<? extends BindingCodec<Map<QName, Object>,Object>> choiceCodec);
return new NodeIdentifier(QName.create(previousQname,qname.localName));
}
+ @SuppressWarnings("rawtypes")
private def dispatch PathArgument serializePathArgument(IdentifiableItem argument, QName previousQname) {
val Map<QName,Object> predicates = new HashMap();
val type = argument.type;
return new NodeIdentifierWithPredicates(QName.create(previousQname,qname.localName),predicates);
}
- def resolveQname(Class class1) {
+ def resolveQname(Class<?> class1) {
val qname = classToQName.get(class1);
if(qname !== null) {
return qname;
val qnameField = class1.getField("QNAME");
val qnameValue = qnameField.get(null) as QName;
classToQName.put(class1,qnameValue);
+ return qnameValue;
}
}
\ No newline at end of file
import org.opendaylight.yangtools.yang.binding.Augmentation;
import org.opendaylight.yangtools.yang.binding.BindingCodec;
import org.opendaylight.yangtools.yang.binding.DataContainer;
+import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.Identifier;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
ReferencedTypeImpl typeref = new ReferencedTypeImpl(type.getPackageName(), type.getName());
@SuppressWarnings("rawtypes")
WeakReference<Class> weakRef = typeToClass.get(typeref);
+ if(weakRef == null) {
+ LOG.error("Could not find loaded class for path: {} and type: {}",path,typeref.getFullyQualifiedName());
+ }
return weakRef.get();
}
@Override
@SuppressWarnings("rawtypes")
public void bindingClassEncountered(Class cls) {
+
ConcreteType typeRef = Types.typeForClass(cls);
+ if(typeToClass.containsKey(typeRef)) {
+ return;
+ }
+ LOG.info("Binding Class {} encountered.",cls);
WeakReference<Class> weakRef = new WeakReference<>(cls);
typeToClass.put(typeRef, weakRef);
+ if(DataObject.class.isAssignableFrom(cls)) {
+ @SuppressWarnings({"unchecked","unused"})
+ Object cdc = getCodecForDataObject((Class<? extends DataObject>) cls);
+ }
+ }
+
+ @Override
+ public void onClassProcessed(Class<?> cls) {
+ ConcreteType typeRef = Types.typeForClass(cls);
+ if(typeToClass.containsKey(typeRef)) {
+ return;
+ }
+ LOG.info("Binding Class {} encountered.",cls);
+ WeakReference<Class> weakRef = new WeakReference<>((Class) cls);
+ typeToClass.put(typeRef, weakRef);
}
private DataSchemaNode getSchemaNode(List<QName> path) {
ReferencedTypeImpl typeref = new ReferencedTypeImpl(caseNode.getValue().getPackageName(), caseNode
.getValue().getName());
ChoiceCaseNode node = (ChoiceCaseNode) SchemaContextUtil.findDataSchemaNode(module, caseNode.getKey());
+ if (node == null) {
+ LOG.error("YANGTools Bug: SchemaNode for {}, with path {} was not found in context.",
+ typeref.getFullyQualifiedName(), caseNode.getKey());
+ continue;
+ }
+
@SuppressWarnings("rawtypes")
ChoiceCaseCodecImpl value = new ChoiceCaseCodecImpl(node);
typeToCaseNodes.putIfAbsent(typeref, value);
BindingCodec<Map<QName, Object>, Object> delegate = newInstanceOf(choiceCodec);
ChoiceCodecImpl<?> newCodec = new ChoiceCodecImpl(delegate);
choiceCodecs.put(choiceClass, newCodec);
- CodecMapping.setClassToCaseMap(choiceCodec, (Map<Class, BindingCodec>) classToCaseRawCodec);
+ CodecMapping.setClassToCaseMap(choiceCodec, (Map<Class<?>, BindingCodec<?, ?>>) classToCaseRawCodec);
CodecMapping.setCompositeNodeToCaseMap(choiceCodec, newCodec.getCompositeToCase());
}
public BindingCodec get(Object key) {
if (key instanceof Class) {
Class cls = (Class) key;
- bindingClassEncountered(cls);
+ //bindingClassEncountered(cls);
ChoiceCaseCodecImpl caseCodec = getCaseCodecFor(cls);
return caseCodec.getDelegate();
}
this.choiceCases = choiceCases;
}
- @Override
- public Set<java.util.Map.Entry<CompositeNode, BindingCodec>> entrySet() {
- return null;
- }
-
@Override
public BindingCodec get(Object key) {
if (false == (key instanceof CompositeNode)) {
}
return null;
}
+
+
}
/**
* Key type
*/
@SuppressWarnings("rawtypes")
- private static abstract class MapFacadeBase<T> implements Map<T, BindingCodec> {
+ private static abstract class MapFacadeBase<T> implements Map<T, BindingCodec<?, ?>> {
@Override
public boolean containsKey(Object key) {
}
@Override
- public Collection<BindingCodec> values() {
+ public Collection<BindingCodec<?, ?>> values() {
return null;
}
}
@Override
- public BindingCodec<Map<QName, Object>, Object> put(T key, BindingCodec value) {
+ public BindingCodec<Map<QName, Object>, Object> put(T key, BindingCodec<?,?> value) {
throw notModifiable();
}
@Override
- public void putAll(Map<? extends T, ? extends BindingCodec> m) {
+ public void putAll(Map<? extends T, ? extends BindingCodec<?, ?>> m) {
throw notModifiable();
}
}
@Override
- public Set<java.util.Map.Entry<T, BindingCodec>> entrySet() {
+ public Set<java.util.Map.Entry<T, BindingCodec<?, ?>>> entrySet() {
+ // TODO Auto-generated method stub
return null;
}
import java.util.AbstractMap.SimpleEntry
import org.opendaylight.yangtools.yang.model.api.SchemaPath
import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil
-import java.util.ArrayList
-import org.opendaylight.yangtools.yang.common.QName
import org.opendaylight.yangtools.yang.binding.DataContainer
-import static com.google.common.base.Preconditions.*;
-import java.util.List
-import org.opendaylight.yangtools.yang.data.api.Node
-import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
-import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl
-import org.opendaylight.yangtools.concepts.Delegator
import java.util.concurrent.ConcurrentMap
import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
-import org.opendaylight.yangtools.yang.binding.BindingCodec
import com.google.common.collect.HashMultimap
import com.google.common.util.concurrent.SettableFuture
import java.util.concurrent.Future
import org.opendaylight.controller.sal.binding.dom.serializer.api.ValueWithQName
import org.opendaylight.controller.sal.binding.dom.serializer.api.DataContainerCodec
import org.opendaylight.yangtools.binding.generator.util.Types
+import org.osgi.framework.BundleContext
+import java.util.Hashtable
+import org.osgi.framework.ServiceRegistration
-class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingService, SchemaServiceListener {
+class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingService, SchemaServiceListener, AutoCloseable {
@Property
ClassPool pool;
val promisedTypeDefinitions = HashMultimap.<Type, SettableFuture<GeneratedTypeBuilder>>create;
val promisedSchemas = HashMultimap.<Type, SettableFuture<SchemaNode>>create;
+
+ ServiceRegistration<SchemaServiceListener> listenerRegistration
override onGlobalContextUpdated(SchemaContext arg0) {
recreateBindingContext(arg0);
val ret = transformer.deserialize(node)?.value as DataObject;
return ret;
}
+
+ override fromDataDom(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry) {
+ return registry.instanceIdentifierCodec.deserialize(entry);
+ }
private def void updateBindingFor(Map<SchemaPath, GeneratedTypeBuilder> map, SchemaContext module) {
for (entry : map.entrySet) {
}
}
- public def void start() {
+ public def void start(BundleContext ctx) {
binding = new TransformerGenerator(pool);
registry = new LazyGeneratedCodecRegistry()
registry.generator = binding
binding.typeToDefinition = typeToDefinition
binding.typeToSchemaNode = typeToSchemaNode
binding.typeDefinitions = typeDefinitions
-
+ if(ctx !== null) {
+ listenerRegistration = ctx.registerService(SchemaServiceListener,this,new Hashtable<String,String>());
+ }
}
private def getTypeDefinition(Type type) {
}
promisedSchemas.removeAll(builder);
}
+
+ override close() throws Exception {
+ listenerRegistration?.unregister();
+ }
+
}
return withClassLoaderAndLock(inputType.classLoader, lock) [ |
val ret = getGeneratedClass(inputType)
if (ret !== null) {
+ listener.onClassProcessed(inputType);
return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
}
val ref = Types.typeForClass(inputType)
val typeSpecBuilder = typeToDefinition.get(ref)
val typeSpec = typeSpecBuilder.toInstance();
val newret = generateTransformerFor(inputType, typeSpec, node);
+ listener.onClassProcessed(inputType);
return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
]
}
val typeSpecBuilder = typeToDefinition.get(ref)
val typeSpec = typeSpecBuilder.toInstance();
val newret = generateAugmentationTransformerFor(inputType, typeSpec, node);
+ listener.onClassProcessed(inputType);
return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
]
}
]
}
- private def Class getGeneratedClass(Class<? extends Object> cls) {
+ private def Class<?> getGeneratedClass(Class<? extends Object> cls) {
try {
return loadClassWithTCCL(cls.codecClassName)
if (transformer !== null) {
return transformer;
}
- val valueTransformer = generateValueTransformer(cls, type);
- return valueTransformer;
+ return withClassLoaderAndLock(cls.classLoader,lock) [|
+ val valueTransformer = generateValueTransformer(cls, type);
+ return valueTransformer;
+ ]
}
private def generateKeyTransformerFor(Class<? extends Object> inputType, GeneratedType typeSpec, ListSchemaNode node) {
try {
- log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
+ //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
val properties = typeSpec.allProperties;
val ctCls = createClass(inputType.codecClassName) [
//staticField(Map,"AUGMENTATION_SERIALIZERS");
_resultName = QNAME;
}
java.util.List _childNodes = new java.util.ArrayList();
- «inputType.name» value = («inputType.name») $2;
+ «inputType.resolvedName» value = («inputType.name») $2;
«FOR key : node.keyDefinition»
«val propertyName = key.getterName»
«val keyDef = node.getDataChildByName(key)»
«val property = properties.get(propertyName)»
«deserializeProperty(keyDef, property, propertyName)»;
«ENDFOR»
- «inputType.name» _value = new «inputType.name»(«node.keyDefinition.keyConstructorList»);
+ «inputType.resolvedName» _value = new «inputType.name»(«node.keyDefinition.keyConstructorList»);
return _value;
}
'''
}
}
- private def Class<? extends BindingCodec<Object, Object>> generateCaseCodec(Class inputType, GeneratedType type,
+ private def Class<? extends BindingCodec<Object, Object>> generateCaseCodec(Class<?> inputType, GeneratedType type,
ChoiceCaseNode node) {
try {
- log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
+ //log.info("Generating DOM Codec for {} with {}, TCCL is: {}", inputType, inputType.classLoader,Thread.currentThread.contextClassLoader)
val ctCls = createClass(type.codecClassName) [
//staticField(Map,"AUGMENTATION_SERIALIZERS");
implementsType(BINDING_CODEC)
«QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
java.util.List _childNodes = new java.util.ArrayList();
«type.resolvedName» value = («type.resolvedName») $2;
- «transformDataContainerBody(type.allProperties, node)»
+ «transformDataContainerBody(type,type.allProperties, node)»
return ($r) _childNodes;
}
'''
}
private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateTransformerFor(
- Class inputType, GeneratedType typeSpec, SchemaNode node) {
+ Class<?> inputType, GeneratedType typeSpec, SchemaNode node) {
try {
- log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
+ //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
val ctCls = createClass(typeSpec.codecClassName) [
//staticField(Map,"AUGMENTATION_SERIALIZERS");
staticQNameField(inputType);
}
private def Class<? extends BindingCodec<Map<QName, Object>, Object>> generateAugmentationTransformerFor(
- Class inputType, GeneratedType type, AugmentationSchema node) {
+ Class<?> inputType, GeneratedType type, AugmentationSchema node) {
try {
- log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
+ //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
val properties = type.allProperties
val ctCls = createClass(type.codecClassName) [
//staticField(Map,"AUGMENTATION_SERIALIZERS");
return null;
}
java.util.Map _compositeNode = (java.util.Map) $2;
- ////System.out.println(_localQName + " " + _compositeNode);
+ //System.out.println(_localQName + " " + _compositeNode);
«type.builderName» _builder = new «type.builderName»();
«FOR child : node.childNodes»
«val signature = properties.getFor(child)»
}
private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateTransformerFor(
- Class inputType, GeneratedType typeSpec, ChoiceNode node) {
+ Class<?> inputType, GeneratedType typeSpec, ChoiceNode node) {
try {
- log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
+ //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
val ctCls = createClass(typeSpec.codecClassName) [
//staticField(Map,"AUGMENTATION_SERIALIZERS");
//staticQNameField(inputType);
return null;
}
java.util.Map.Entry _input = new «SimpleEntry.name»($1,_baValue);
- return (java.util.List) _codec.serialize(_input);
+ Object _ret = _codec.serialize(_input);
+ //System.out.println("«typeSpec.name»#toDomStatic: " + _ret);
+ return («List.name») _ret;
}
'''
]
return null;
}
java.util.Map _compositeNode = (java.util.Map) $2;
- ////System.out.println(_localQName + " " + _compositeNode);
+ //System.out.println(_localQName + " " + _compositeNode);
«type.builderName» _builder = new «type.builderName»();
«deserializeDataNodeContainerBody(type, node)»
«deserializeAugmentations»
String propertyName) '''
java.util.List _dom_«propertyName» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.
localName»"));
- ////System.out.println("«propertyName»#deCode"+_dom_«propertyName»);
+ //System.out.println("«propertyName»#deCode"+_dom_«propertyName»);
java.util.List «propertyName» = new java.util.ArrayList();
if(_dom_«propertyName» != null) {
java.util.List _serialized = new java.util.ArrayList();
boolean _hasNext = _iterator.hasNext();
while(_hasNext) {
Object _listItem = _iterator.next();
- ////System.out.println(" item" + _listItem);
+ //System.out.println(" item" + _listItem);
Object _value = «type.actualTypeArguments.get(0).serializer.resolvedName».fromDomStatic(_localQName,_listItem);
- ////System.out.println(" value" + _value);
+ //System.out.println(" value" + _value);
«propertyName».add(_value);
_hasNext = _iterator.hasNext();
}
}
- ////System.out.println(" list" + «propertyName»);
+ //System.out.println(" list" + «propertyName»);
'''
private def dispatch CharSequence deserializeProperty(LeafListSchemaNode schema, ParameterizedType type,
val returnType = typeSpec.valueReturnType;
if (returnType == null) {
-
val ctCls = createDummyImplementation(inputType, typeSpec);
val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
}
+ var hasBinding = false;
+ try {
+ val bindingCodecClass = loadClassWithTCCL(BINDING_CODEC.name);
+ hasBinding = bindingCodecClass !== null;
+ } catch (ClassNotFoundException e) {
+ hasBinding = false;
+ }
+ val hasYangBinding = hasBinding
val ctCls = createClass(typeSpec.codecClassName) [
//staticField(Map,"AUGMENTATION_SERIALIZERS");
- implementsType(BINDING_CODEC)
- staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
- implementsType(BindingDeserializer.asCtClass)
+ if(hasYangBinding) {
+ implementsType(BINDING_CODEC)
+ staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec)
+ implementsType(BindingDeserializer.asCtClass)
+ }
method(Object, "toDomValue", Object) [
modifiers = PUBLIC + FINAL + STATIC
body = '''
{
- ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
+ //System.out.println("«inputType.simpleName»#toDomValue: "+$1);
if($1 == null) {
return null;
}
«typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
- ////System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
+ //System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
«returnType.resolvedName» _value = _encapsulatedValue.getValue();
- ////System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_value);
+ //System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_value);
Object _domValue = «serializeValue(returnType, "_value")»;
return _domValue;
}
modifiers = PUBLIC + FINAL + STATIC
body = '''
{
- ////System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
+ //System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
if($1 == null) {
return null;
return null;
}
- private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
+ private def dispatch Class<?> generateValueTransformer(
Class<?> inputType, Enumeration typeSpec) {
try {
- log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
+ //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
val ctCls = createClass(typeSpec.codecClassName) [
//staticField(Map,"AUGMENTATION_SERIALIZERS");
- implementsType(BINDING_CODEC)
+ //implementsType(BINDING_CODEC)
+
method(Object, "toDomValue", Object) [
modifiers = PUBLIC + FINAL + STATIC
body = '''
val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
log.info("DOM Codec for {} was generated {}", inputType, ret)
- return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
+ return ret;
} catch (CodeGenerationException e) {
throw new CodeGenerationException("Cannot compile Transformator for " + inputType, e);
} catch (Exception e) {
«QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
java.util.List _childNodes = new java.util.ArrayList();
«type.resolvedName» value = («type.resolvedName») $2;
- «transformDataContainerBody(type.allProperties, node)»
+ «transformDataContainerBody(type,type.allProperties, node)»
«serializeAugmentations»
return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
}
«QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
java.util.List _childNodes = new java.util.ArrayList();
«type.resolvedName» value = («type.resolvedName») $2;
- «transformDataContainerBody(type.allProperties, node)»
+ «transformDataContainerBody(type,type.allProperties, node)»
«serializeAugmentations»
return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
}
«QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
java.util.List _childNodes = new java.util.ArrayList();
«type.resolvedName» value = («type.resolvedName») $2;
- «transformDataContainerBody(type.allProperties, node)»
+ «transformDataContainerBody(type,type.allProperties, node)»
«serializeAugmentations»
return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
}
}
'''
- private def transformDataContainerBody(Map<String, Type> properties, DataNodeContainer node) {
+ private def transformDataContainerBody(Type type,Map<String, Type> properties, DataNodeContainer node) {
val ret = '''
«FOR child : node.childNodes.filter[!augmenting]»
«var signature = properties.getFor(child)»
- //System.out.println("«signature.key»" + value.«signature.key»());
+ //System.out.println("«type.name»#«signature.key»" + value.«signature.key»());
«serializeProperty(child, signature.value, signature.key)»
«ENDFOR»
'''
return '''«typeSpec.resolvedName»$Broker$Codec$DOM'''
}
- private def codecClassName(Class typeSpec) {
+ private def codecClassName(Class<?> typeSpec) {
return '''«typeSpec.name»$Broker$Codec$DOM'''
}
- private def dispatch HashMap<String, Type> getAllProperties(GeneratedType type) {
+ private def HashMap<String, Type> getAllProperties(GeneratedType type) {
val ret = new HashMap<String, Type>();
type.collectAllProperties(ret);
return ret;
return type.asCtClass.name;
}
- def String getResolvedName(Class type) {
+ def String getResolvedName(Class<?> type) {
return type.asCtClass.name;
}
def CtClass asCtClass(Type type) {
- val name = type.fullyQualifiedName
val cls = loadClassWithTCCL(type.fullyQualifiedName)
return cls.asCtClass;
}
import java.util.concurrent.Executors
import java.util.Collections
import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.controller.sal.binding.impl.connect.dom.ConnectorActivator
+import java.util.concurrent.locks.ReentrantLock
+import java.util.concurrent.Callable
+import java.util.WeakHashMap
+import javax.annotation.concurrent.GuardedBy
class BindingAwareBrokerImpl implements BindingAwareBroker, AutoCloseable {
private static val log = LoggerFactory.getLogger(BindingAwareBrokerImpl)
-
private InstanceIdentifier<? extends DataObject> root = InstanceIdentifier.builder().toInstance();
- private val clsPool = ClassPool.getDefault()
- private var RuntimeCodeGenerator generator;
-
+ private static val clsPool = ClassPool.getDefault()
+ public static var RuntimeCodeGenerator generator;
/**
* Map of all Managed Direct Proxies
*
*
*/
- private val Map<Class<? extends RpcService>, RpcRouter<? extends RpcService>> rpcRouters = new ConcurrentHashMap();
+ private val Map<Class<? extends RpcService>, RpcRouter<? extends RpcService>> rpcRouters = new WeakHashMap();
@Property
- private var NotificationBrokerImpl notifyBroker
-
+ private var NotificationProviderService notifyBroker
+
@Property
- private var DataBrokerImpl dataBroker
-
+ private var DataProviderService dataBroker
+
@Property
var BundleContext brokerBundleContext
-
+
ServiceRegistration<NotificationProviderService> notifyProviderRegistration
-
+
ServiceRegistration<NotificationService> notifyConsumerRegistration
-
+
ServiceRegistration<DataProviderService> dataProviderRegistration
-
+
ServiceRegistration<DataBrokerService> dataConsumerRegistration
-
- ConnectorActivator connectorActivator
-
-
+
+ private val proxyGenerationLock = new ReentrantLock;
+
+ private val routerGenerationLock = new ReentrantLock;
+
public new(BundleContext bundleContext) {
_brokerBundleContext = bundleContext;
}
initGenerator();
val executor = Executors.newCachedThreadPool;
+
// Initialization of notificationBroker
log.info("Starting MD-SAL: Binding Aware Notification Broker");
- notifyBroker = new NotificationBrokerImpl(executor);
- notifyBroker.invokerFactory = generator.invokerFactory;
log.info("Starting MD-SAL: Binding Aware Data Broker");
- dataBroker = new DataBrokerImpl();
- dataBroker.executor = executor;
- val brokerProperties = newProperties();
-
-
log.info("Starting MD-SAL: Binding Aware Data Broker");
- notifyProviderRegistration = brokerBundleContext.registerService(NotificationProviderService, notifyBroker,
- brokerProperties)
- notifyConsumerRegistration = brokerBundleContext.registerService(NotificationService, notifyBroker, brokerProperties)
- dataProviderRegistration = brokerBundleContext.registerService(DataProviderService, dataBroker, brokerProperties)
- dataConsumerRegistration = brokerBundleContext.registerService(DataBrokerService, dataBroker, brokerProperties)
-
- connectorActivator = new ConnectorActivator(dataBroker,brokerBundleContext);
- connectorActivator.start();
log.info("MD-SAL: Binding Aware Broker Started");
}
* If proxy class does not exist for supplied service class it will be generated automatically.
*/
private def <T extends RpcService> getManagedDirectProxy(Class<T> service) {
-
var RpcProxyContext existing = null
+
if ((existing = managedProxies.get(service)) != null) {
return existing.proxy
}
- val proxyInstance = generator.getDirectProxyFor(service)
- val rpcProxyCtx = new RpcProxyContext(proxyInstance.class)
- val properties = new Hashtable<String, String>()
- rpcProxyCtx.proxy = proxyInstance as RpcService
-
- properties.salServiceType = SAL_SERVICE_TYPE_CONSUMER_PROXY
- rpcProxyCtx.registration = brokerBundleContext.registerService(service, rpcProxyCtx.proxy as T, properties)
- managedProxies.put(service, rpcProxyCtx)
- return rpcProxyCtx.proxy
+ return withLock(proxyGenerationLock) [ |
+ val maybeProxy = managedProxies.get(service);
+ if (maybeProxy !== null) {
+ return maybeProxy.proxy;
+ }
+
+
+ val proxyInstance = generator.getDirectProxyFor(service)
+ val rpcProxyCtx = new RpcProxyContext(proxyInstance.class)
+ val properties = new Hashtable<String, String>()
+ rpcProxyCtx.proxy = proxyInstance as RpcService
+ properties.salServiceType = SAL_SERVICE_TYPE_CONSUMER_PROXY
+ rpcProxyCtx.registration = brokerBundleContext.registerService(service, rpcProxyCtx.proxy as T, properties)
+ managedProxies.put(service, rpcProxyCtx)
+ return rpcProxyCtx.proxy
+ ]
+ }
+
+ private static def <T> T withLock(ReentrantLock lock, Callable<T> method) {
+ try {
+ lock.lock();
+ val ret = method.call;
+ return ret;
+ } finally {
+ lock.unlock();
+ }
}
/**
val osgiReg = context.bundleContext.registerService(type, service, properties);
proxy.delegate = service;
- return new RpcServiceRegistrationImpl<T>(type, service, osgiReg,this);
+ return new RpcServiceRegistrationImpl<T>(type, service, osgiReg, this);
}
def <T extends RpcService> RoutedRpcRegistration<T> registerRoutedRpcImplementation(Class<T> type, T service,
}
// We created Router
- val newRouter = generator.getRouterFor(type);
- checkState(newRouter !== null);
- rpcRouters.put(type, newRouter);
-
- // We create / update Direct Proxy for router
- val proxy = getManagedDirectProxy(type);
- proxy.delegate = newRouter.invocationProxy
- return newRouter;
+ return withLock(routerGenerationLock) [ |
+ val maybeRouter = rpcRouters.get(type);
+ if (maybeRouter !== null) {
+ return maybeRouter as RpcRouter<T>;
+ }
+
+ val newRouter = generator.getRouterFor(type);
+ checkState(newRouter !== null);
+ rpcRouters.put(type, newRouter);
+ // We create / update Direct Proxy for router
+ val proxy = getManagedDirectProxy(type);
+ proxy.delegate = newRouter.invocationProxy
+ return newRouter;
+ ]
}
// Updating internal structure of registration
routingTable.updateRoute(path, registration.instance)
+
// Update routing table / send announce to message bus
-
val success = paths.put(context, path);
}
routingTable.removeRoute(path)
}
}
-
+
protected def <T extends RpcService> void unregisterRpcService(RpcServiceRegistrationImpl<T> registration) {
val type = registration.serviceType;
-
+
val proxy = managedProxies.get(type);
- if(proxy.proxy.delegate === registration.instance) {
+ if (proxy.proxy.delegate === registration.instance) {
proxy.proxy.delegate = null;
}
}
-
+
def createDelegate(Class<? extends RpcService> type) {
getManagedDirectProxy(type);
}
-
+
def getRpcRouters() {
return Collections.unmodifiableMap(rpcRouters);
}
-
+
override close() {
dataConsumerRegistration.unregister()
dataProviderRegistration.unregister()
notifyConsumerRegistration.unregister()
notifyProviderRegistration.unregister()
}
-
+
}
class RoutedRpcRegistrationImpl<T extends RpcService> extends AbstractObjectRegistration<T> implements RoutedRpcRegistration<T> {
checkClosed()
broker.unregisterPath(this, context, path);
}
-
+
override getServiceType() {
return router.serviceType;
}
}
}
-class RpcServiceRegistrationImpl<T extends RpcService> extends AbstractObjectRegistration<T> implements RpcRegistration<T> {
+
+class RpcServiceRegistrationImpl<T extends RpcService> extends AbstractObjectRegistration<T> implements RpcRegistration<T> {
val ServiceRegistration<T> osgiRegistration;
private var BindingAwareBrokerImpl broker;
-
+
@Property
val Class<T> serviceType;
- public new(Class<T> type, T service, ServiceRegistration<T> osgiReg,BindingAwareBrokerImpl broker) {
+ public new(Class<T> type, T service, ServiceRegistration<T> osgiReg, BindingAwareBrokerImpl broker) {
super(service);
this._serviceType = type;
this.osgiRegistration = osgiReg;
- this.broker= broker;
+ this.broker = broker;
}
override protected removeRegistration() {
broker.unregisterRpcService(this);
broker = null;
}
-
+
}
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicLong;
import org.opendaylight.controller.md.sal.common.api.data.DataReader;
import org.opendaylight.controller.md.sal.common.impl.service.AbstractDataBroker;
public class DataBrokerImpl extends AbstractDataBroker<InstanceIdentifier<? extends DataObject>, DataObject, DataChangeListener> implements
- DataProviderService {
+ DataProviderService, AutoCloseable {
+
+
+ private final AtomicLong nextTransaction = new AtomicLong();
+
public DataBrokerImpl() {
setDataReadRouter(new BindingAwareDataReaderRouter());
}
@Override
public DataTransactionImpl beginTransaction() {
- return new DataTransactionImpl(this);
+ String transactionId = "BA-" + nextTransaction.getAndIncrement();
+ return new DataTransactionImpl(transactionId,this);
}
@Override
+ @Deprecated
public <T extends DataRoot> T getData(DataStoreIdentifier store, Class<T> rootType) {
- // TODO Auto-generated method stub
- return null;
+ throw new UnsupportedOperationException("Deprecated");
}
@Override
+ @Deprecated
public <T extends DataRoot> T getData(DataStoreIdentifier store, T filter) {
- // TODO Auto-generated method stub
- return null;
+ throw new UnsupportedOperationException("Deprecated");
}
@Override
+ @Deprecated
public <T extends DataRoot> T getCandidateData(DataStoreIdentifier store, Class<T> rootType) {
- // TODO Auto-generated method stub
- return null;
+ throw new UnsupportedOperationException("Deprecated");
}
@Override
+ @Deprecated
public <T extends DataRoot> T getCandidateData(DataStoreIdentifier store, T filter) {
- // TODO Auto-generated method stub
- return null;
+ throw new UnsupportedOperationException("Deprecated");
}
@Override
+ @Deprecated
public RpcResult<DataRoot> editCandidateData(DataStoreIdentifier store, DataRoot changeSet) {
- // TODO Auto-generated method stub
- return null;
+ throw new UnsupportedOperationException("Deprecated");
}
@Override
+ @Deprecated
public Future<RpcResult<Void>> commit(DataStoreIdentifier store) {
- // TODO Auto-generated method stub
- return null;
+ throw new UnsupportedOperationException("Deprecated");
}
@Override
+ @Deprecated
public DataObject getData(InstanceIdentifier<? extends DataObject> data) {
- // TODO Auto-generated method stub
- return null;
+ throw new UnsupportedOperationException("Deprecated");
}
@Override
+ @Deprecated
public DataObject getConfigurationData(InstanceIdentifier<?> data) {
- // TODO Auto-generated method stub
- return null;
+ throw new UnsupportedOperationException("Deprecated");
}
@Override
+ @Deprecated
public void registerChangeListener(InstanceIdentifier<? extends DataObject> path, DataChangeListener changeListener) {
- // TODO Auto-generated method stub
-
+ throw new UnsupportedOperationException("Deprecated");
}
@Override
+ @Deprecated
public void unregisterChangeListener(InstanceIdentifier<? extends DataObject> path,
DataChangeListener changeListener) {
- // TODO Auto-generated method stub
-
+ throw new UnsupportedOperationException("Deprecated");
}
-
+ @Override
+ public void close() throws Exception {
+
+ }
}
\ No newline at end of file
- public DataTransactionImpl(DataBrokerImpl dataBroker) {
- super(dataBroker);
+ public DataTransactionImpl(Object identifier,DataBrokerImpl dataBroker) {
+ super(identifier,dataBroker);
}
@Override
import org.slf4j.LoggerFactory
import java.util.concurrent.Callable
-class NotificationBrokerImpl implements NotificationProviderService {
+class NotificationBrokerImpl implements NotificationProviderService, AutoCloseable {
val Multimap<Class<? extends Notification>, NotificationListener<?>> listeners;
@Property
var ExecutorService executor;
- @Property
- var RuntimeCodeGenerator generator;
-
- @Property
- var NotificationInvokerFactory invokerFactory;
-
new(ExecutorService executor) {
listeners = HashMultimap.create()
this.executor = executor;
override registerNotificationListener(
org.opendaylight.yangtools.yang.binding.NotificationListener listener) {
- val invoker = invokerFactory.invokerFor(listener);
+ val invoker = BindingAwareBrokerImpl.generator.invokerFactory.invokerFor(listener);
for (notifyType : invoker.supportedNotifications) {
listeners.put(notifyType, invoker.invocationProxy)
}
listeners.remove(notifyType, reg.invoker.invocationProxy)
}
}
+
+ override close() {
+ //FIXME: implement properly.
+ }
+
}
class GenericNotificationRegistration<T extends Notification> extends AbstractObjectRegistration<NotificationListener<T>> implements ListenerRegistration<NotificationListener<T>> {
override call() {
try {
+ log.info("Delivering notification {} to {}",notification,listener);
listener.onNotification(notification);
+ log.info("Notification delivered {} to {}",notification,listener);
} catch (Exception e) {
log.error("Unhandled exception thrown by listener: {}", listener, e);
}
package org.opendaylight.controller.sal.binding.impl.connect.dom;
+import java.util.Collection;
import java.util.Collections;
+import java.util.Map;
import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
-import org.opendaylight.controller.config.api.jmx.CommitStatus;
+import org.opendaylight.controller.md.sal.common.api.RegistrationListener;
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
-import org.opendaylight.controller.md.sal.common.api.data.DataModification;
-import org.opendaylight.controller.md.sal.common.api.data.DataReader;
import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandlerRegistration;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider;
import org.opendaylight.controller.sal.common.util.Rpcs;
-import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
+import org.opendaylight.controller.sal.core.api.Provider;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
+import org.opendaylight.yangtools.concepts.Registration;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.RpcError;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-
-import com.google.common.base.Preconditions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class BindingIndependentDataServiceConnector implements //
RuntimeDataProvider, //
- DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> {
+ Provider {
+
+ private final Logger LOG = LoggerFactory.getLogger(BindingIndependentDataServiceConnector.class);
private static final InstanceIdentifier<? extends DataObject> ROOT = InstanceIdentifier.builder().toInstance();
+ private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier ROOT_BI = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+ .builder().toInstance();
+
private BindingIndependentMappingService mappingService;
- private DataBrokerService biDataService;
+ private org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService;
private DataProviderService baDataService;
+ private ConcurrentMap<Object, BindingToDomTransaction> domOpenedTransactions = new ConcurrentHashMap<>();
+ private ConcurrentMap<Object, DomToBindingTransaction> bindingOpenedTransactions = new ConcurrentHashMap<>();
+
+ private BindingToDomCommitHandler bindingToDomCommitHandler = new BindingToDomCommitHandler();
+ private DomToBindingCommitHandler domToBindingCommitHandler = new DomToBindingCommitHandler();
+
+ private Registration<DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject>> baCommitHandlerRegistration;
+
+ private Registration<DataCommitHandler<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode>> biCommitHandlerRegistration;
+
@Override
public DataObject readOperationalData(InstanceIdentifier<? extends DataObject> path) {
- // TODO Auto-generated method stub
org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
CompositeNode result = biDataService.readOperationalData(biPath);
return mappingService.dataObjectFromDataDom(path, result);
return mappingService.dataObjectFromDataDom(path, result);
}
- @Override
- public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> requestCommit(
- DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
-
- DataModificationTransaction translated = translateTransaction(modification);
- return new WrappedTransaction(translated, modification);
- }
-
- private DataModificationTransaction translateTransaction(
+ private DataModificationTransaction createBindingToDomTransaction(
DataModification<InstanceIdentifier<? extends DataObject>, DataObject> source) {
DataModificationTransaction target = biDataService.beginTransaction();
for (Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry : source.getUpdatedConfigurationData()
.toDataDom(entry);
target.putOperationalData(biEntry.getKey(), biEntry.getValue());
}
- for(InstanceIdentifier<? extends DataObject> entry : source.getRemovedConfigurationData()) {
+ for (InstanceIdentifier<? extends DataObject> entry : source.getRemovedConfigurationData()) {
org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biEntry = mappingService.toDataDom(entry);
target.removeConfigurationData(biEntry);
}
- for(InstanceIdentifier<? extends DataObject> entry : source.getRemovedOperationalData()) {
+ for (InstanceIdentifier<? extends DataObject> entry : source.getRemovedOperationalData()) {
org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biEntry = mappingService.toDataDom(entry);
target.removeOperationalData(biEntry);
}
return target;
}
- private class WrappedTransaction implements
+ private org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction createDomToBindingTransaction(
+ DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> source) {
+ org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction target = baDataService
+ .beginTransaction();
+ for (Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> entry : source
+ .getUpdatedConfigurationData().entrySet()) {
+ InstanceIdentifier<?> baKey = mappingService.fromDataDom(entry.getKey());
+ DataObject baData = mappingService.dataObjectFromDataDom(baKey, entry.getValue());
+ target.putConfigurationData(baKey, baData);
+ }
+ for (Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> entry : source
+ .getUpdatedOperationalData().entrySet()) {
+ InstanceIdentifier<?> baKey = mappingService.fromDataDom(entry.getKey());
+ DataObject baData = mappingService.dataObjectFromDataDom(baKey, entry.getValue());
+ target.putOperationalData(baKey, baData);
+ }
+ for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry : source.getRemovedConfigurationData()) {
+ InstanceIdentifier<?> baEntry = mappingService.fromDataDom(entry);
+ target.removeConfigurationData(baEntry);
+ }
+ for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry : source.getRemovedOperationalData()) {
+ InstanceIdentifier<?> baEntry = mappingService.fromDataDom(entry);
+ target.removeOperationalData(baEntry);
+ }
+ return target;
+ }
+
+ public org.opendaylight.controller.sal.core.api.data.DataProviderService getBiDataService() {
+ return biDataService;
+ }
+
+ public void setBiDataService(org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService) {
+ this.biDataService = biDataService;
+ }
+
+ public DataProviderService getBaDataService() {
+ return baDataService;
+ }
+
+ public void setBaDataService(DataProviderService baDataService) {
+ this.baDataService = baDataService;
+ }
+
+ public void start() {
+ baDataService.registerDataReader(ROOT, this);
+ baCommitHandlerRegistration = baDataService.registerCommitHandler(ROOT, bindingToDomCommitHandler);
+ biCommitHandlerRegistration = biDataService.registerCommitHandler(ROOT_BI, domToBindingCommitHandler);
+ baDataService.registerCommitHandlerListener(domToBindingCommitHandler);
+ }
+
+ public void setMappingService(BindingIndependentMappingService mappingService) {
+ this.mappingService = mappingService;
+ }
+
+ @Override
+ public Collection<ProviderFunctionality> getProviderFunctionality() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public void onSessionInitiated(ProviderSession session) {
+ setBiDataService(session.getService(org.opendaylight.controller.sal.core.api.data.DataProviderService.class));
+ start();
+ }
+
+ private class DomToBindingTransaction implements
+ DataCommitTransaction<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> {
+
+ private final org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction backing;
+ private final DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> modification;
+
+ public DomToBindingTransaction(
+ org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction backing,
+ DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> modification) {
+ super();
+ this.backing = backing;
+ this.modification = modification;
+ bindingOpenedTransactions.put(backing.getIdentifier(), this);
+ }
+
+ @Override
+ public DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> getModification() {
+ return modification;
+ }
+
+ @Override
+ public RpcResult<Void> rollback() throws IllegalStateException {
+ // backing.cancel();
+ return Rpcs.<Void> getRpcResult(true, null, Collections.<RpcError> emptySet());
+ }
+
+ @Override
+ public RpcResult<Void> finish() throws IllegalStateException {
+ Future<RpcResult<TransactionStatus>> result = backing.commit();
+ try {
+ RpcResult<TransactionStatus> baResult = result.get();
+ return Rpcs.<Void> getRpcResult(baResult.isSuccessful(), null, baResult.getErrors());
+ } catch (InterruptedException e) {
+ throw new IllegalStateException("", e);
+ } catch (ExecutionException e) {
+ throw new IllegalStateException("", e);
+ }
+ }
+ }
+
+ private class BindingToDomTransaction implements
DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> {
private DataModificationTransaction backing;
private DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification;
- public WrappedTransaction(DataModificationTransaction backing,
+ public BindingToDomTransaction(DataModificationTransaction backing,
DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
this.backing = backing;
this.modification = modification;
+ domOpenedTransactions.put(backing.getIdentifier(), this);
}
@Override
public RpcResult<Void> finish() throws IllegalStateException {
Future<RpcResult<TransactionStatus>> result = backing.commit();
try {
- RpcResult<TransactionStatus> biresult = result.get();
+ RpcResult<TransactionStatus> biResult = result.get();
+ return Rpcs.<Void> getRpcResult(biResult.isSuccessful(), null, biResult.getErrors());
} catch (InterruptedException e) {
throw new IllegalStateException("", e);
} catch (ExecutionException e) {
throw new IllegalStateException("", e);
+ } finally {
+ domOpenedTransactions.remove(backing.getIdentifier());
}
- return Rpcs.<Void> getRpcResult(true, null, Collections.<RpcError> emptySet());
}
@Override
public RpcResult<Void> rollback() throws IllegalStateException {
- // backing.cancel();
+ domOpenedTransactions.remove(backing.getIdentifier());
return Rpcs.<Void> getRpcResult(true, null, Collections.<RpcError> emptySet());
}
-
}
- public DataBrokerService getBiDataService() {
- return biDataService;
- }
+ private class BindingToDomCommitHandler implements
+ DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> {
- public void setBiDataService(DataBrokerService biDataService) {
- this.biDataService = biDataService;
- }
+ @Override
+ public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> requestCommit(
+ DataModification<InstanceIdentifier<? extends DataObject>, DataObject> bindingTransaction) {
- public DataProviderService getBaDataService() {
- return baDataService;
- }
+ /**
+ * Transaction was created as DOM transaction, in that case we do
+ * not need to forward it back.
+ */
+ if (bindingOpenedTransactions.containsKey(bindingTransaction.getIdentifier())) {
- public void setBaDataService(DataProviderService baDataService) {
- this.baDataService = baDataService;
+ return CommitHandlersTransactions.allwaysSuccessfulTransaction(bindingTransaction);
+ }
+ DataModificationTransaction domTransaction = createBindingToDomTransaction(bindingTransaction);
+ BindingToDomTransaction wrapped = new BindingToDomTransaction(domTransaction, bindingTransaction);
+ LOG.info("Forwarding Binding Transaction: {} as DOM Transaction: {} .", bindingTransaction.getIdentifier(),
+ domTransaction.getIdentifier());
+ return wrapped;
+ }
}
- public void start() {
- baDataService.registerDataReader(ROOT, this);
- baDataService.registerCommitHandler(ROOT, this);
- }
+ private class DomToBindingCommitHandler implements //
+ RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier<?>, DataObject>>, //
+ DataCommitHandler<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> {
- public void setMappingService(BindingIndependentMappingService mappingService) {
- this.mappingService = mappingService;
- }
+ @Override
+ public void onRegister(DataCommitHandlerRegistration<InstanceIdentifier<?>, DataObject> registration) {
+
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath = mappingService.toDataDom(registration.getPath());
+ // FIXME: do registration based on only active commit handlers.
+
+ }
+ @Override
+ public void onUnregister(DataCommitHandlerRegistration<InstanceIdentifier<?>, DataObject> registration) {
+ // NOOP for now
+ // FIXME: do registration based on only active commit handlers.
+ }
+
+ public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> requestCommit(
+ DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> domTransaction) {
+ Object identifier = domTransaction.getIdentifier();
+
+ /**
+ * We checks if the transcation was originated in this mapper. If it
+ * was originated in this mapper we are returing allways success
+ * commit hanlder to prevent creating loop in two-phase commit and
+ * duplicating data.
+ */
+ if (domOpenedTransactions.containsKey(identifier)) {
+ return CommitHandlersTransactions.allwaysSuccessfulTransaction(domTransaction);
+ }
+
+ org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction baTransaction = createDomToBindingTransaction(domTransaction);
+ DomToBindingTransaction forwardedTransaction = new DomToBindingTransaction(baTransaction, domTransaction);
+ LOG.info("Forwarding DOM Transaction: {} as Binding Transaction: {}.", domTransaction.getIdentifier(),
+ baTransaction.getIdentifier());
+ return forwardedTransaction;
+ }
+ }
}
org.opendaylight.yangtools.yang.data.api.InstanceIdentifier toDataDom(InstanceIdentifier<? extends DataObject> path);
DataObject dataObjectFromDataDom(InstanceIdentifier<? extends DataObject> path, CompositeNode result);
-
-
+
+ InstanceIdentifier<?> fromDataDom(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry);
+
}
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+import java.util.Collections;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
+import org.opendaylight.controller.sal.common.util.Rpcs;
+import org.opendaylight.yangtools.concepts.Path;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+public class CommitHandlersTransactions {
+
+ private static class AllwaysSuccessfulTransaction<P,D> implements DataCommitTransaction<P, D> {
+
+ private final DataModification<P, D> modification;
+
+ public AllwaysSuccessfulTransaction(DataModification<P, D> modification) {
+ this.modification = modification;
+ }
+ @Override
+ public RpcResult<Void> rollback() throws IllegalStateException {
+ return Rpcs.<Void>getRpcResult(true, null, Collections.<RpcError>emptyList());
+ }
+ @Override
+ public RpcResult<Void> finish() throws IllegalStateException {
+ return Rpcs.<Void>getRpcResult(true, null, Collections.<RpcError>emptyList());
+ }
+
+ @Override
+ public DataModification<P, D> getModification() {
+ return modification;
+ }
+ }
+
+
+ public static final <P extends Path<P>,D> AllwaysSuccessfulTransaction<P, D> allwaysSuccessfulTransaction(DataModification<P, D> modification) {
+ return new AllwaysSuccessfulTransaction<>(modification);
+ }
+}
+++ /dev/null
-package org.opendaylight.controller.sal.binding.impl.connect.dom;
-
-import java.util.Collection;
-import java.util.Collections;
-
-import javassist.ClassPool;
-
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
-import org.opendaylight.controller.sal.binding.dom.serializer.impl.RuntimeGeneratedMappingServiceImpl;
-import org.opendaylight.controller.sal.binding.dom.serializer.impl.TransformerGenerator;
-import org.opendaylight.controller.sal.core.api.Broker;
-import org.opendaylight.controller.sal.core.api.Provider;
-import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
-import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
-import org.opendaylight.controller.sal.core.api.model.SchemaService;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.util.tracker.ServiceTracker;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
-
-public class ConnectorActivator implements Provider, ServiceTrackerCustomizer<Broker, Broker> {
-
- BindingIndependentDataServiceConnector dataConnector;
- BindingIndependentMappingService mappingService;
-
- private final DataProviderService baDataService;
- private BundleContext context;
-
- private ServiceTracker<Broker, Broker> brokerTracker;
-
- public ConnectorActivator(DataProviderService dataService, BundleContext context) {
- baDataService = dataService;
- this.context = context;
- brokerTracker = new ServiceTracker<>(context, Broker.class, this);
- }
-
- @Override
- public Collection<ProviderFunctionality> getProviderFunctionality() {
- return Collections.emptySet();
- }
-
- @Override
- public void onSessionInitiated(ProviderSession session) {
-
- RuntimeGeneratedMappingServiceImpl mappingImpl = new RuntimeGeneratedMappingServiceImpl();
- mappingImpl.setPool(new ClassPool());
- SchemaService schemaService = (session.getService(SchemaService.class));
- ClassPool pool = new ClassPool();
- mappingImpl.setBinding(new TransformerGenerator(pool));
- mappingImpl.start();
- schemaService.registerSchemaServiceListener(mappingImpl);
- mappingService = mappingImpl;
- dataConnector = new BindingIndependentDataServiceConnector();
- dataConnector.setBaDataService(baDataService);
- dataConnector.setBiDataService(session.getService(DataBrokerService.class));
- dataConnector.setMappingService(mappingService);
- dataConnector.start();
- }
-
- @Override
- public Broker addingService(ServiceReference<Broker> reference) {
- Broker br= context.getService(reference);
- br.registerProvider(this, context);
- return br;
- }
-
- @Override
- public void modifiedService(ServiceReference<Broker> reference, Broker service) {
- // NOOP
- }
-
- @Override
- public void removedService(ServiceReference<Broker> reference, Broker service) {
- // NOOP
- }
-
- public void start() {
- brokerTracker.open();
- }
-}
--- /dev/null
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.yangtools.concepts.Path;
+
+import com.google.common.util.concurrent.JdkFutureAdapters;
+
+public final class DataModificationTracker<P extends Path<P>,D> {
+
+ ConcurrentMap<Object, DataModification<P,D>> trackedTransactions = new ConcurrentHashMap<>();
+
+
+ public void startTrackingModification(DataModification<P,D> modification) {
+ trackedTransactions.putIfAbsent(modification.getIdentifier(), modification);
+
+
+ }
+
+ public boolean containsIdentifier(Object identifier) {
+ return trackedTransactions.containsKey(identifier);
+ }
+}
--- /dev/null
+package org.opendaylight.controller.sal.binding.spi;
+
+import org.opendaylight.yangtools.yang.binding.BaseIdentity;
+import org.opendaylight.yangtools.yang.binding.RpcService;
+
+public interface RpcRoutingContext<C extends BaseIdentity,S extends RpcService> {
+
+ Class<C> getContextType();
+ Class<S> getServiceType();
+}
namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl";
prefix "binding-impl";
- import config { prefix config; revision-date 2013-04-05; }
- import opendaylight-md-sal-binding {prefix sal;}
+ import config { prefix config; revision-date 2013-04-05; }
+ import opendaylight-md-sal-binding {prefix sal;}
+ import opendaylight-md-sal-dom {prefix dom;}
+ import opendaylight-md-sal-common {prefix common;}
description
"Service definition for Binding Aware MD-SAL.";
"Initial revision";
}
- identity binding-broker-impl-singleton {
+ identity binding-dom-mapping-service {
+ base config:service-type;
+ config:java-class "org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentMappingService";
+ }
+
+
+ identity binding-broker-impl {
base config:module-type;
config:provided-service sal:binding-broker-osgi-registry;
- config:java-name-prefix BindingBrokerImplSingleton;
+ config:java-name-prefix BindingBrokerImpl;
+ }
+
+ identity binding-data-broker {
+ base config:module-type;
+ config:provided-service sal:binding-data-broker;
+ config:provided-service sal:binding-data-consumer-broker;
+ config:java-name-prefix DataBrokerImpl;
}
-
- grouping rpc-routing-table {
-
+ identity binding-rpc-broker {
+ base config:module-type;
+ config:provided-service sal:binding-rpc-registry;
+ config:java-name-prefix RpcBrokerImpl;
+ }
+
+ identity binding-notification-broker {
+ base config:module-type;
+ config:provided-service sal:binding-notification-service;
+ config:provided-service sal:binding-notification-subscription-service;
+ config:java-name-prefix NotificationBrokerImpl;
}
+ identity runtime-generated-mapping {
+ base config:module-type;
+ config:provided-service binding-dom-mapping-service;
+ config:java-name-prefix RuntimeMapping;
+ }
- grouping rpc-router {
- leaf module {
- type string;
+ augment "/config:modules/config:module/config:configuration" {
+ case binding-broker-impl {
+ when "/config:modules/config:module/config:type = 'binding-broker-impl'";
+
+ /*
+ container rpc-registry {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity sal:binding-rpc-registry;
+ }
+ }
+ }*/
+
+ container data-broker {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity sal:binding-data-broker;
+ }
+ }
+ }
+
+ container notification-service {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity sal:binding-notification-service;
+ }
+ }
+ }
}
- container routing-tables {
- list routing-table {
- uses rpc-routing-table;
+ }
+
+ augment "/config:modules/config:module/config:configuration" {
+ case binding-data-broker {
+ when "/config:modules/config:module/config:type = 'binding-data-broker'";
+ container dom-broker {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity dom:dom-broker-osgi-registry;
+ }
+ }
}
+ container mapping-service {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity binding-dom-mapping-service;
+ }
+ }
+ }
}
}
+
+ augment "/config:modules/config:module/config:state" {
+ case runtime-generated-mapping {
+ when "/config:modules/config:module/config:type = 'runtime-generated-mapping'";
+ }
+ }
augment "/config:modules/config:module/config:state" {
- case binding-broker-impl-singleton {
- when "/config:modules/config:module/config:type = 'binding-broker-impl-singleton'";
-
- container rpc-routers {
- list rpc-router {
- uses rpc-router;
- }
- }
+ case binding-data-broker {
+ when "/config:modules/config:module/config:type = 'binding-data-broker'";
+ uses common:data-state;
+ }
+ }
+ augment "/config:modules/config:module/config:state" {
+ case binding-rpc-broker {
+ when "/config:modules/config:module/config:type = 'binding-rpc-broker'";
+ uses common:rpc-state;
+ }
+ }
+ augment "/config:modules/config:module/config:state" {
+ case binding-notification-broker {
+ when "/config:modules/config:module/config:type = 'binding-notification-broker'";
+ uses common:notification-state;
}
}
}
\ No newline at end of file
import com.google.common.util.concurrent.MoreExecutors;
public abstract class AbstractDataServiceTest {
- protected DataBrokerService biDataService;
+ protected org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService;
protected DataProviderService baDataService;
/**
mappingService = mappingServiceImpl;
File pathname = new File("target/gen-classes-debug");
//System.out.println("Generated classes are captured in " + pathname.getAbsolutePath());
- mappingServiceImpl.start();
+ mappingServiceImpl.start(null);
//mappingServiceImpl.getBinding().setClassFileCapturePath(pathname);
connectorServiceImpl = new BindingIndependentDataServiceConnector();
package org.opendaylight.controller.sal.binding.test.bugfix;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
+
+
import org.junit.Test;
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopMplsAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopMplsActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodesBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;