From b58aa00371805767ad561d12fabd2a912a062ee6 Mon Sep 17 00:00:00 2001 From: Vishal Thapar Date: Tue, 28 Apr 2015 00:05:48 +0530 Subject: [PATCH 1/1] Interfacemgr: Listener for NodeConnector events 1. Added listener for NodeConnector DCNs 2. Added openflowplugin to features.xml 3. Corrected dependency for model-flow-service 4. Added code for interfaces update/delete Change-Id: If2391f3ca96589870fbc33bd0b9d09e19daf09b1 Signed-off-by: Vishal Thapar --- features/src/main/features/features.xml | 18 ++-- interfacemgr/interfacemgr-impl/pom.xml | 3 +- .../IfmNodeConnectorListener.java | 81 ++++++++++++++++ .../interfacemgr/InterfaceManager.java | 94 ++++++++++++++++--- .../interfacemgr/InterfacemgrProvider.java | 5 + 5 files changed, 179 insertions(+), 22 deletions(-) create mode 100644 interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmNodeConnectorListener.java diff --git a/features/src/main/features/features.xml b/features/src/main/features/features.xml index d87ef722..d710d320 100644 --- a/features/src/main/features/features.xml +++ b/features/src/main/features/features.xml @@ -18,7 +18,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html odl-yangtools-models odl-openflowplugin-nsf-model mvn:org.opendaylight.vpnservice/model-bgp/{{VERSION}} - mvn:org.opendaylight.vpnservice/vpnmanager-api/${vpnmanager.version} + mvn:org.opendaylight.vpnservice/vpnmanager-api/${vpnmanager.version} mvn:org.opendaylight.vpnservice/nexthopmgr-api/${nexthopmgr.version} mvn:org.opendaylight.vpnservice/idmanager-api/${idmanager.version} mvn:org.opendaylight.vpnservice/fibmanager-api/${fibmanager.version} @@ -27,28 +27,30 @@ and is available at http://www.eclipse.org/legal/epl-v10.html odl-mdsal-broker odl-vpnservice-api + odl-openflowplugin-southbound + odl-openflowplugin-flow-services mvn:org.opendaylight.vpnservice/bgpmanager-api/${project.version} - mvn:org.opendaylight.vpnservice/bgpmanager-impl/${project.version} - mvn:org.opendaylight.vpnservice/mdsalutil-api/${interfacemgr.version} - mvn:org.opendaylight.vpnservice/mdsalutil-impl/${interfacemgr.version} + mvn:org.opendaylight.vpnservice/bgpmanager-impl/${project.version} + mvn:org.opendaylight.vpnservice/mdsalutil-api/${interfacemgr.version} + mvn:org.opendaylight.vpnservice/mdsalutil-impl/${interfacemgr.version} mvn:org.opendaylight.vpnservice/vpnmanager-impl/${vpnmanager.version} mvn:org.opendaylight.vpnservice/interfacemgr-api/${interfacemgr.version} mvn:org.opendaylight.vpnservice/interfacemgr-impl/${interfacemgr.version} mvn:org.opendaylight.vpnservice/nexthopmgr-impl/${nexthopmgr.version} mvn:org.opendaylight.vpnservice/idmanager-impl/${idmanager.version} mvn:org.opendaylight.vpnservice/fibmanager-impl/${fibmanager.version} - + wrap:mvn:org.apache.thrift/libthrift/0.9.1$overwrite=merge&Bundle-Version=0.9.1&Export-Package=*;-noimport:=true;version="0.9.1" - mvn:org.opendaylight.vpnservice/bgpmanager-impl/${project.version}/xml/config - mvn:org.opendaylight.vpnservice/mdsalutil-impl/${interfacemgr.version}/xml/config + mvn:org.opendaylight.vpnservice/bgpmanager-impl/${project.version}/xml/config + mvn:org.opendaylight.vpnservice/mdsalutil-impl/${interfacemgr.version}/xml/config mvn:org.opendaylight.vpnservice/vpnmanager-impl/${vpnmanager.version}/xml/config mvn:org.opendaylight.vpnservice/interfacemgr-impl/${interfacemgr.version}/xml/config mvn:org.opendaylight.vpnservice/nexthopmgr-impl/${nexthopmgr.version}/xml/config mvn:org.opendaylight.vpnservice/idmanager-impl/${idmanager.version}/xml/config mvn:org.opendaylight.vpnservice/fibmanager-impl/${fibmanager.version}/xml/config - + odl-vpnservice-impl diff --git a/interfacemgr/interfacemgr-impl/pom.xml b/interfacemgr/interfacemgr-impl/pom.xml index 9c90c127..6fcdf059 100644 --- a/interfacemgr/interfacemgr-impl/pom.xml +++ b/interfacemgr/interfacemgr-impl/pom.xml @@ -27,8 +27,9 @@ and is available at http://www.eclipse.org/legal/epl-v10.html ${project.version} - org.opendaylight.controller.model + org.opendaylight.openflowplugin.model model-flow-service + 0.1.0-SNAPSHOT org.opendaylight.yangtools.model diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmNodeConnectorListener.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmNodeConnectorListener.java new file mode 100644 index 00000000..ef3653ea --- /dev/null +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmNodeConnectorListener.java @@ -0,0 +1,81 @@ +package org.opendaylight.vpnservice.interfacemgr; + +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; + +import java.util.Iterator; +import java.util.List; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.DataChangeListener; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.opendaylight.vpnservice.AbstractDataChangeListener; + +public class IfmNodeConnectorListener extends AbstractDataChangeListener implements AutoCloseable{ + private static final Logger LOG = LoggerFactory.getLogger(IfmNodeConnectorListener.class); + private ListenerRegistration listenerRegistration; + private final DataBroker broker; + private InterfaceManager ifManager; + + public IfmNodeConnectorListener(final DataBroker db) { + super(NodeConnector.class); + broker = db; + registerListener(db); + } + + public IfmNodeConnectorListener(final DataBroker dataBroker, InterfaceManager interfaceManager) { + this(dataBroker); + ifManager = interfaceManager; + } + + private void registerListener(final DataBroker db) { + try { + listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL, + getWildCardPath(), IfmNodeConnectorListener.this, DataChangeScope.SUBTREE); + } catch (final Exception e) { + LOG.error("IfmNodeConnectorListener: DataChange listener registration fail!", e); + throw new IllegalStateException("IfmNodeConnectorListener: registration Listener failed.", e); + } + } + + private InstanceIdentifier getWildCardPath() { + return InstanceIdentifier.create(Nodes.class).child(Node.class).child(NodeConnector.class); + } + + @Override + public void close() throws Exception { + if (listenerRegistration != null) { + try { + listenerRegistration.close(); + } catch (final Exception e) { + LOG.error("Error when cleaning up DataChangeListener.", e); + } + listenerRegistration = null; + } + LOG.info("IfmNodeConnectorListener Closed"); + } + + @Override + protected void add(InstanceIdentifier identifier, NodeConnector node) { + LOG.trace("NodeConnectorAdded: key: " + identifier + ", value=" + node ); + ifManager.processPortAdd(node); + } + + @Override + protected void remove(InstanceIdentifier identifier, NodeConnector del) { + LOG.trace("NodeConnectorRemoved: key: " + identifier + ", value=" + del ); + ifManager.processPortDelete(del); + } + + @Override + protected void update(InstanceIdentifier identifier, NodeConnector original, NodeConnector update) { + LOG.trace("NodeConnectorUpdated: key: " + identifier + ", original=" + original + ", update=" + update ); + ifManager.processPortUpdate(original, update); + } + +} diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfaceManager.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfaceManager.java index 3ba00f57..768656d7 100644 --- a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfaceManager.java +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfaceManager.java @@ -7,8 +7,10 @@ */ package org.opendaylight.vpnservice.interfacemgr; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL3tunnel; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder; import java.math.BigInteger; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter32; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter64; @@ -78,7 +80,7 @@ public class InterfaceManager extends AbstractDataChangeListener impl } LOG.info("Interface Manager Closed"); } - + private void registerListener(final DataBroker db) { try { listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, @@ -108,7 +110,7 @@ public class InterfaceManager extends AbstractDataChangeListener impl private InstanceIdentifier buildStateInterfaceId(String interfaceName) { //TODO Make this generic and move to AbstractDataChangeListener or Utils. - InstanceIdentifierBuilder idBuilder = + InstanceIdentifierBuilder idBuilder = InstanceIdentifier.builder(InterfacesState.class) .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.class, new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(interfaceName)); @@ -123,7 +125,7 @@ public class InterfaceManager extends AbstractDataChangeListener impl if(port.isPresent()) { Interface interf = port.get(); NodeConnector nodeConn = getNodeConnectorFromInterface(interf); - updateInterfaceState(interf, nodeConn); + updateInterfaceState(identifier, interf, nodeConn); /* TODO: * 1. Get interface-id from id manager * 2. Update interface-state with following: @@ -137,7 +139,8 @@ public class InterfaceManager extends AbstractDataChangeListener impl } } - private void updateInterfaceState(Interface interf, NodeConnector nodeConn) { + private void updateInterfaceState(InstanceIdentifier identifier, + Interface interf, NodeConnector nodeConn) { /* Update InterfaceState * 1. Get interfaces-state Identifier * 2. Add interface to interfaces-state/interface @@ -152,8 +155,9 @@ public class InterfaceManager extends AbstractDataChangeListener impl Optional stateIf = read(LogicalDatastoreType.OPERATIONAL, id); org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface stateIface; + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder ifaceBuilder = + new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder(); if(!stateIf.isPresent()) { - org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder ifaceBuilder = new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder(); // TODO: Get interface-id from IdManager ifaceBuilder.setAdminStatus((interf.isEnabled()) ? org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus.Up : org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus.Down); @@ -162,11 +166,37 @@ public class InterfaceManager extends AbstractDataChangeListener impl ifaceBuilder.setKey(getStateInterfaceKeyFromName(interf.getName())); //ifaceBuilder.setStatistics(createStatistics(interf.getName(), nodeConn)); stateIface = ifaceBuilder.build(); - LOG.trace("updating OPERATIONAL data store with stateIface {} and id {}", stateIface, id); + LOG.trace("Adding stateIface {} and id {} to OPERATIONAL DS", stateIface, id); asyncWrite(LogicalDatastoreType.OPERATIONAL, id, stateIface, DEFAULT_CALLBACK); + } else { + if(interf.isEnabled() != null) { + ifaceBuilder.setAdminStatus((interf.isEnabled()) ? org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus.Up : + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus.Down); + } + if(interf.getType() != null) { + ifaceBuilder.setType(interf.getType()); + } + + stateIface = ifaceBuilder.build(); + LOG.trace("updating OPERATIONAL data store with stateIface {} and id {}", stateIface, id); + asyncUpdate(LogicalDatastoreType.OPERATIONAL, id, stateIface, DEFAULT_CALLBACK); } } + /* + private void setAugmentations( + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder ifaceBuilder, + InstanceIdentifier identifier, Interface interf) { + // TODO Add code for all augmentations + InstanceIdentifier ifL3TunnelPath = identifier.augmentation(IfL3tunnel.class); + Optional l3Tunnel = read(LogicalDatastoreType.CONFIGURATION, ifL3TunnelPath); + String ifName = interf.getName(); + if(l3Tunnel.isPresent()) { + l3Tunnel.get(); + } + } + */ + private Statistics createStatistics(String name, NodeConnector nodeConn) { Counter64 init64 = new Counter64(new BigInteger("0000000000000000")); Counter32 init32 = new Counter32((long) 0); @@ -186,6 +216,7 @@ public class InterfaceManager extends AbstractDataChangeListener impl private NodeConnector getNodeConnectorFromInterface(Interface interf) { NodeConnectorId ncId = interf.getAugmentation(BaseIds.class).getOfPortId(); + //TODO: Replace with MDSAL Util method NodeId nodeId = new NodeId(ncId.getValue().substring(0,ncId.getValue().lastIndexOf(":"))); InstanceIdentifier ncIdentifier = InstanceIdentifier.builder(Nodes.class) .child(Node.class, new NodeKey(nodeId)) @@ -201,12 +232,14 @@ public class InterfaceManager extends AbstractDataChangeListener impl } private void delInterface(final InstanceIdentifier identifier, - final Interface del) { - InstanceIdentifier id = buildId(identifier); - Optional port = read(LogicalDatastoreType.CONFIGURATION, id); - if(port.isPresent()) { - Interface interf = port.get(); - // TODO: Update operational data + final Interface delInterface) { + InstanceIdentifier id = + buildStateInterfaceId(delInterface.getName()); + Optional stateIf = + read(LogicalDatastoreType.OPERATIONAL, id); + if(!stateIf.isPresent()) { + LOG.trace("deleting interfaces:state OPERATIONAL data store with id {}", id); + asyncRemove(LogicalDatastoreType.OPERATIONAL, id, DEFAULT_CALLBACK); } } @@ -257,4 +290,39 @@ public class InterfaceManager extends AbstractDataChangeListener impl tx.put(datastoreType, path, data, true); Futures.addCallback(tx.submit(), callback); } + + private void asyncUpdate(LogicalDatastoreType datastoreType, + InstanceIdentifier path, T data, FutureCallback callback) { + WriteTransaction tx = broker.newWriteOnlyTransaction(); + tx.merge(datastoreType, path, data, true); + Futures.addCallback(tx.submit(), callback); + } + + private void asyncRemove(LogicalDatastoreType datastoreType, + InstanceIdentifier path, FutureCallback callback) { + WriteTransaction tx = broker.newWriteOnlyTransaction(); + tx.delete(datastoreType, path); + Futures.addCallback(tx.submit(), callback); + } + + public void processPortAdd(NodeConnector port) { + String strPortId = port.getId().getValue(); + FlowCapableNodeConnector ofPort = port.getAugmentation(FlowCapableNodeConnector.class); + LOG.debug("PortAdd: PortId { "+strPortId+"} PortName {"+ofPort.getName()+"}"); + } + + public void processPortUpdate(NodeConnector oldPort, NodeConnector update) { + String oldPortId = oldPort.getId().getValue(); + FlowCapableNodeConnector oldOfPort = oldPort.getAugmentation(FlowCapableNodeConnector.class); + String strPortId = update.getId().getValue(); + FlowCapableNodeConnector ofPort = update.getAugmentation(FlowCapableNodeConnector.class); + LOG.debug("PortUpdate: { "+strPortId+", "+ofPort.getName()+"}"); + } + + public void processPortDelete(NodeConnector port) { + String strPortId = port.getId().getValue(); + FlowCapableNodeConnector ofPort = port.getAugmentation(FlowCapableNodeConnector.class); + LOG.debug("PortDelete: PortId { "+strPortId+"} PortName {"+ofPort.getName()+"}"); + } + } diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfacemgrProvider.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfacemgrProvider.java index ab30a083..8127e928 100644 --- a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfacemgrProvider.java +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfacemgrProvider.java @@ -19,6 +19,7 @@ public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable private static final Logger LOG = LoggerFactory.getLogger(InterfacemgrProvider.class); private InterfaceManager interfaceManager; + private IfmNodeConnectorListener ifmNcListener; @Override public void onSessionInitiated(ProviderContext session) { @@ -26,15 +27,19 @@ public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable try { final DataBroker dataBroker = session.getSALService(DataBroker.class); interfaceManager = new InterfaceManager(dataBroker); + ifmNcListener = new IfmNodeConnectorListener(dataBroker, interfaceManager); } catch (Exception e) { LOG.error("Error initializing services", e); } + //TODO: Make this debug + LOG.info("Interfacemgr services initiated"); } @Override public void close() throws Exception { LOG.info("InterfacemgrProvider Closed"); interfaceManager.close(); + ifmNcListener.close(); } @Override -- 2.36.6