X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=mdsalutil%2Fmdsalutil-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fvpnservice%2Fmdsalutil%2Finternal%2FMDSALManager.java;h=08a1e657334ac684750cdb0917ebb5307f55a455;hb=HEAD;hp=cbd11417094067237c769d68b98ba8c1f4661f3f;hpb=485583fa27099ac706dffeae850dd0f6b48714ca;p=vpnservice.git diff --git a/mdsalutil/mdsalutil-impl/src/main/java/org/opendaylight/vpnservice/mdsalutil/internal/MDSALManager.java b/mdsalutil/mdsalutil-impl/src/main/java/org/opendaylight/vpnservice/mdsalutil/internal/MDSALManager.java index cbd11417..08a1e657 100644 --- a/mdsalutil/mdsalutil-impl/src/main/java/org/opendaylight/vpnservice/mdsalutil/internal/MDSALManager.java +++ b/mdsalutil/mdsalutil-impl/src/main/java/org/opendaylight/vpnservice/mdsalutil/internal/MDSALManager.java @@ -13,6 +13,8 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import org.opendaylight.vpnservice.mdsalutil.ActionInfo; import org.opendaylight.vpnservice.mdsalutil.ActionType; @@ -40,12 +42,15 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.N import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService; +import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.opendaylight.vpnservice.mdsalutil.*; import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.DataChangeListener; +import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.controller.md.sal.common.api.data.OptimisticLockFailedException; import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; @@ -62,8 +67,11 @@ public class MDSALManager implements AutoCloseable { private DataBroker m_dataBroker; private PacketProcessingService m_packetProcessingService; + private ListenerRegistration groupListenerRegistration; + private ListenerRegistration flowListenerRegistration; private ConcurrentMap flowMap = new ConcurrentHashMap(); private ConcurrentMap groupMap = new ConcurrentHashMap (); + private ExecutorService executorService = Executors.newSingleThreadExecutor(); /** * Writes the flows and Groups to the MD SAL DataStore @@ -77,14 +85,39 @@ public class MDSALManager implements AutoCloseable { public MDSALManager(final DataBroker db, PacketProcessingService pktProcService) { m_dataBroker = db; m_packetProcessingService = pktProcService; + registerListener(db); s_logger.info( "MDSAL Manager Initialized ") ; } @Override public void close() throws Exception { + groupListenerRegistration.close(); + flowListenerRegistration.close(); s_logger.info("MDSAL Manager Closed"); } + private void registerListener(DataBroker db) { + try { + flowListenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL, getWildCardFlowPath(), + new FlowListener(), + DataChangeScope.SUBTREE); + groupListenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL, getWildCardGroupPath(), + new GroupListener(), + DataChangeScope.SUBTREE); + } catch (final Exception e) { + s_logger.error("GroupEventHandler: DataChange listener registration fail!", e); + throw new IllegalStateException("GroupEventHandler: registration Listener failed.", e); + } + } + + private InstanceIdentifier getWildCardGroupPath() { + return InstanceIdentifier.create(Nodes.class).child(Node.class).augmentation(FlowCapableNode.class).child(Group.class); + } + + private InstanceIdentifier getWildCardFlowPath() { + return InstanceIdentifier.create(Nodes.class).child(Node.class).augmentation(FlowCapableNode.class).child(Table.class).child(Flow.class); + } + public void installFlow(FlowEntity flowEntity) { try { @@ -231,7 +264,8 @@ public class MDSALManager implements AutoCloseable { public CheckedFuture removeFlowNew(BigInteger dpnId, Flow flowEntity) { s_logger.debug("Remove flow {}",flowEntity); Node nodeDpn = buildDpnNode(dpnId); - FlowKey flowKey = new FlowKey(new FlowId(flowEntity.getId())); + //FlowKey flowKey = new FlowKey(new FlowId(flowEntity.getId())); + FlowKey flowKey = new FlowKey(flowEntity.getId()); InstanceIdentifier flowInstanceId = InstanceIdentifier.builder(Nodes.class) .child(Node.class, nodeDpn.getKey()).augmentation(FlowCapableNode.class) .child(Table.class, new TableKey(flowEntity.getTableId())).child(Flow.class, flowKey).build(); @@ -417,4 +451,75 @@ public class MDSALManager implements AutoCloseable { } } + class GroupListener extends AbstractDataChangeListener { + + public GroupListener() { + super(Group.class); + } + + @Override + protected void remove(InstanceIdentifier identifier, Group del) { + BigInteger dpId = getDpnFromString(identifier.firstKeyOf(Node.class, NodeKey.class).getId().getValue()); + executeNotifyTaskIfRequired(dpId, del); + } + + private void executeNotifyTaskIfRequired(BigInteger dpId, Group group) { + GroupInfoKey groupKey = new GroupInfoKey(dpId, group.getGroupId().getValue()); + Runnable notifyTask = groupMap.remove(groupKey); + if (notifyTask == null) { + return; + } + executorService.execute(notifyTask); + } + + @Override + protected void update(InstanceIdentifier identifier, Group original, Group update) { + BigInteger dpId = getDpnFromString(identifier.firstKeyOf(Node.class, NodeKey.class).getId().getValue()); + executeNotifyTaskIfRequired(dpId, update); + } + + @Override + protected void add(InstanceIdentifier identifier, Group add) { + BigInteger dpId = getDpnFromString(identifier.firstKeyOf(Node.class, NodeKey.class).getId().getValue()); + executeNotifyTaskIfRequired(dpId, add); + } + } + + class FlowListener extends AbstractDataChangeListener { + + public FlowListener() { + super(Flow.class); + } + + @Override + protected void remove(InstanceIdentifier identifier, Flow del) { + BigInteger dpId = getDpnFromString(identifier.firstKeyOf(Node.class, NodeKey.class).getId().getValue()); + notifyTaskIfRequired(dpId, del); + } + + private void notifyTaskIfRequired(BigInteger dpId, Flow flow) { + FlowInfoKey flowKey = new FlowInfoKey(dpId, flow.getTableId(), flow.getMatch(), flow.getId().getValue()); + Runnable notifyTask = flowMap.remove(flowKey); + if (notifyTask == null) { + return; + } + executorService.execute(notifyTask); + } + + @Override + protected void update(InstanceIdentifier identifier, Flow original, Flow update) { + } + + @Override + protected void add(InstanceIdentifier identifier, Flow add) { + BigInteger dpId = getDpnFromString(identifier.firstKeyOf(Node.class, NodeKey.class).getId().getValue()); + notifyTaskIfRequired(dpId, add); + } + } + + private BigInteger getDpnFromString(String dpnString) { + String[] split = dpnString.split(":"); + return new BigInteger(split[1]); + } + }