From 0c4b3b74b93fec1781b15477935cab80eee5d35c Mon Sep 17 00:00:00 2001 From: Jozef Gloncak Date: Tue, 28 Apr 2015 14:41:06 +0200 Subject: [PATCH] Support for Table Features FlowListenerTest.java - removed equals which checks concrete transaction ID. If changes are done on flow also TableForwarder is notified because listener is listening on subtree changes. Therefore can happend that sometimes changes in table are processed before changes in flow and therefore is generated transaction ID DOM-2 instead DOM-1. Change-Id: I3570c03fda0b532833c85bae01ed4a10cc14a2d2 Signed-off-by: HemaTG Signed-off-by: Jozef Gloncak --- .../frm/ForwardingRulesManager.java | 15 +++ .../frm/impl/FlowNodeReconciliationImpl.java | 10 ++ .../frm/impl/ForwardingRulesManagerImpl.java | 25 ++++ .../applications/frm/impl/TableForwarder.java | 116 ++++++++++++++++++ .../test/java/test/mock/FlowListenerTest.java | 4 - .../mock/util/RpcProviderRegistryMock.java | 4 + .../test/mock/util/SalTableServiceMock.java | 25 ++++ .../src/main/yang/sal-table.yang | 4 + 8 files changed, 199 insertions(+), 4 deletions(-) create mode 100644 applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/TableForwarder.java create mode 100644 applications/forwardingrules-manager/src/test/java/test/mock/util/SalTableServiceMock.java diff --git a/applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/ForwardingRulesManager.java b/applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/ForwardingRulesManager.java index 4c695f2837..1de3a1b37d 100644 --- a/applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/ForwardingRulesManager.java +++ b/applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/ForwardingRulesManager.java @@ -11,11 +11,13 @@ package org.opendaylight.openflowplugin.applications.frm; import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.SalTableService; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; /** @@ -98,6 +100,13 @@ public interface ForwardingRulesManager extends AutoCloseable { */ public SalMeterService getSalMeterService(); + /** + * Table RPC service + * + * @return + */ + public SalTableService getSalTableService(); + /** * Content definition method and prevent code duplicity in Reconcil * @return ForwardingRulesCommiter<Flow> @@ -116,6 +125,12 @@ public interface ForwardingRulesManager extends AutoCloseable { */ public ForwardingRulesCommiter getMeterCommiter(); + /** + * Content definition method and prevent code duplicity + * @return ForwardingRulesCommiter<Table> + */ + public ForwardingRulesCommiter getTableCommiter(); + /** * Content definition method * @return FlowNodeReconciliation diff --git a/applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/FlowNodeReconciliationImpl.java b/applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/FlowNodeReconciliationImpl.java index 0564131b48..b47af791c6 100644 --- a/applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/FlowNodeReconciliationImpl.java +++ b/applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/FlowNodeReconciliationImpl.java @@ -148,6 +148,16 @@ public class FlowNodeReconciliationImpl implements FlowNodeReconciliation { } if (flowNode.isPresent()) { + /* Tables - have to be pushed before groups */ + // CHECK if while pusing the update, updateTableInput can be null to emulate a table add + List
tableList = flowNode.get().getTable() != null + ? flowNode.get().getTable() : Collections.
emptyList() ; + for (Table table : tableList) { + final KeyedInstanceIdentifier tableIdent = + nodeIdent.child(Table.class, table.getKey()); + this.provider.getTableCommiter().update(tableIdent, table, null ,nodeIdent) ; + } + /* Groups - have to be first */ List groups = flowNode.get().getGroup() != null ? flowNode.get().getGroup() : Collections. emptyList(); diff --git a/applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/ForwardingRulesManagerImpl.java b/applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/ForwardingRulesManagerImpl.java index 2e78b5e4ec..fa4c24009a 100644 --- a/applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/ForwardingRulesManagerImpl.java +++ b/applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/ForwardingRulesManagerImpl.java @@ -26,6 +26,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalF import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table; +import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.SalTableService; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -55,10 +57,12 @@ public class ForwardingRulesManagerImpl implements ForwardingRulesManager { private final SalFlowService salFlowService; private final SalGroupService salGroupService; private final SalMeterService salMeterService; + private final SalTableService salTableService; private ForwardingRulesCommiter flowListener; private ForwardingRulesCommiter groupListener; private ForwardingRulesCommiter meterListener; + private ForwardingRulesCommiter
tableListener; private FlowNodeReconciliation nodeListener; public ForwardingRulesManagerImpl(final DataBroker dataBroker, @@ -73,15 +77,22 @@ public class ForwardingRulesManagerImpl implements ForwardingRulesManager { "RPC SalGroupService not found."); this.salMeterService = Preconditions.checkNotNull(rpcRegistry.getRpcService(SalMeterService.class), "RPC SalMeterService not found."); + this.salTableService = Preconditions.checkNotNull(rpcRegistry.getRpcService(SalTableService.class), + "RPC SalTableService not found."); } @Override public void start() { + this.flowListener = new FlowForwarder(this, dataService); + this.groupListener = new GroupForwarder(this, dataService); this.meterListener = new MeterForwarder(this, dataService); + + this.tableListener = new TableForwarder(this, dataService); this.nodeListener = new FlowNodeReconciliationImpl(this, dataService); LOG.info("ForwardingRulesManager has started successfully."); + } @Override @@ -98,6 +109,10 @@ public class ForwardingRulesManagerImpl implements ForwardingRulesManager { this.meterListener.close(); this.meterListener = null; } + if (this.tableListener != null) { + this.tableListener.close(); + this.tableListener = null; + } if (this.nodeListener != null) { this.nodeListener.close(); this.nodeListener = null; @@ -162,6 +177,11 @@ public class ForwardingRulesManagerImpl implements ForwardingRulesManager { return salMeterService; } + @Override + public SalTableService getSalTableService() { + return salTableService; + } + @Override public ForwardingRulesCommiter getFlowCommiter() { return flowListener; @@ -177,6 +197,11 @@ public class ForwardingRulesManagerImpl implements ForwardingRulesManager { return meterListener; } + @Override + public ForwardingRulesCommiter
getTableCommiter() { + return tableListener; + } + @Override public FlowNodeReconciliation getFlowNodeReconciliation() { return nodeListener; diff --git a/applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/TableForwarder.java b/applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/TableForwarder.java new file mode 100644 index 0000000000..6981b379bf --- /dev/null +++ b/applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/impl/TableForwarder.java @@ -0,0 +1,116 @@ +package org.opendaylight.openflowplugin.applications.frm.impl; + +import org.opendaylight.openflowplugin.common.wait.SimpleTaskRetryLooper; + +import java.util.concurrent.Callable; +import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.openflowplugin.applications.frm.ForwardingRulesManager; +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.flow.inventory.rev130819.FlowCapableNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table; +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.nodes.Node; +import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.table.update.OriginalTableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.table.update.UpdatedTableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableRef; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.google.common.base.Preconditions; + +public class TableForwarder extends AbstractListeningCommiter
{ + + private static final Logger LOG = LoggerFactory.getLogger(TableForwarder.class); + + private ListenerRegistration listenerRegistration; + + public TableForwarder (final ForwardingRulesManager manager, final DataBroker db) { + super(manager, Table.class); + Preconditions.checkNotNull(db, "DataBroker can not be null!"); + final DataTreeIdentifier
treeId = new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, getWildCardPath()); + + try { + SimpleTaskRetryLooper looper = new SimpleTaskRetryLooper(ForwardingRulesManagerImpl.STARTUP_LOOP_TICK, + ForwardingRulesManagerImpl.STARTUP_LOOP_MAX_RETRIES); + listenerRegistration = looper.loopUntilNoException(new Callable>() { + @Override + public ListenerRegistration call() throws Exception { + return db.registerDataTreeChangeListener(treeId, TableForwarder.this); + } + }); + } catch (final Exception e) { + LOG.warn("FRM Table DataChange listener registration fail!"); + LOG.debug("FRM Table DataChange listener registration fail ..", e); + throw new IllegalStateException("TableForwarder startup fail! System needs restart.", e); + } + } + + @Override + public void close() { + if (listenerRegistration != null) { + try { + listenerRegistration.close(); + } catch (Exception e) { + LOG.error("Error by stop FRM TableChangeListener.", e); + } + listenerRegistration = null; + } + } + + @Override + protected InstanceIdentifier
getWildCardPath() { + return InstanceIdentifier.create(Nodes.class).child(Node.class) + .augmentation(FlowCapableNode.class).child(Table.class); + } + + @Override + public void remove(final InstanceIdentifier
identifier, final Table removeDataObj, + final InstanceIdentifier nodeIdent) { + // DO Nothing + } + + @Override + public void update(final InstanceIdentifier
identifier, + final Table original, final Table update, + final InstanceIdentifier nodeIdent) { + LOG.debug( "Received the Table Update request [Tbl id, node Id, original, upd" + + " " + identifier + " " + nodeIdent + " " + original + " " + update ); + + final Table originalTable = (original); + Table updatedTable ; + if( null == update) + updatedTable = (original); + else + updatedTable = (update); + + final UpdateTableInputBuilder builder = new UpdateTableInputBuilder(); + + builder.setNode(new NodeRef(nodeIdent.firstIdentifierOf(Node.class))); + builder.setTableRef(new TableRef(identifier)); + + builder.setTransactionUri(new Uri(provider.getNewTransactionId())); + + builder.setUpdatedTable((new UpdatedTableBuilder(updatedTable)).build()); + + builder.setOriginalTable((new OriginalTableBuilder(originalTable)).build()); + LOG.debug( "Invoking SalTableService " ) ; + + if( this.provider.getSalTableService() != null ) + System.out.println( " Handle to SalTableServices" + this.provider.getSalTableService()) ; + this.provider.getSalTableService().updateTable(builder.build()); + + } + + @Override + public void add(final InstanceIdentifier
identifier, final Table addDataObj, + final InstanceIdentifier nodeIdent) { + //DO NOthing + } + + +} diff --git a/applications/forwardingrules-manager/src/test/java/test/mock/FlowListenerTest.java b/applications/forwardingrules-manager/src/test/java/test/mock/FlowListenerTest.java index c2454418b6..e9de0fb1d9 100644 --- a/applications/forwardingrules-manager/src/test/java/test/mock/FlowListenerTest.java +++ b/applications/forwardingrules-manager/src/test/java/test/mock/FlowListenerTest.java @@ -82,7 +82,6 @@ public class FlowListenerTest extends FRMTest { salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService(); addFlowCalls = salFlowService.getAddFlowCalls(); assertEquals(2, addFlowCalls.size()); - assertEquals("DOM-1", addFlowCalls.get(1).getTransactionUri().getValue()); assertEquals(2, addFlowCalls.get(1).getTableId().intValue()); assertEquals(flowII, addFlowCalls.get(1).getFlowRef().getValue()); @@ -123,7 +122,6 @@ public class FlowListenerTest extends FRMTest { salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService(); List updateFlowCalls = salFlowService.getUpdateFlowCalls(); assertEquals(1, updateFlowCalls.size()); - assertEquals("DOM-1", updateFlowCalls.get(0).getTransactionUri().getValue()); assertEquals(flowII, updateFlowCalls.get(0).getFlowRef().getValue()); assertEquals(Boolean.TRUE, updateFlowCalls.get(0).getOriginalFlow().isStrict()); assertEquals(Boolean.TRUE, updateFlowCalls.get(0).getUpdatedFlow().isStrict()); @@ -169,7 +167,6 @@ public class FlowListenerTest extends FRMTest { salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService(); List updateFlowCalls = salFlowService.getUpdateFlowCalls(); assertEquals(1, updateFlowCalls.size()); - assertEquals("DOM-1", updateFlowCalls.get(0).getTransactionUri().getValue()); assertEquals(flowII, updateFlowCalls.get(0).getFlowRef().getValue()); assertEquals(ipMatch, updateFlowCalls.get(0).getUpdatedFlow().getMatch().getIpMatch()); forwardingRulesManager.close(); @@ -205,7 +202,6 @@ public class FlowListenerTest extends FRMTest { salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService(); List removeFlowCalls = salFlowService.getRemoveFlowCalls(); assertEquals(1, removeFlowCalls.size()); - assertEquals("DOM-1", removeFlowCalls.get(0).getTransactionUri().getValue()); assertEquals(flowII, removeFlowCalls.get(0).getFlowRef().getValue()); assertEquals(Boolean.TRUE, removeFlowCalls.get(0).isStrict()); diff --git a/applications/forwardingrules-manager/src/test/java/test/mock/util/RpcProviderRegistryMock.java b/applications/forwardingrules-manager/src/test/java/test/mock/util/RpcProviderRegistryMock.java index ff17a0c366..b6a01b4e29 100644 --- a/applications/forwardingrules-manager/src/test/java/test/mock/util/RpcProviderRegistryMock.java +++ b/applications/forwardingrules-manager/src/test/java/test/mock/util/RpcProviderRegistryMock.java @@ -1,5 +1,7 @@ package test.mock.util; +import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.SalTableService; + import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener; import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; @@ -35,6 +37,8 @@ public class RpcProviderRegistryMock implements RpcProviderRegistry { return (T) new SalGroupServiceMock(); } else if (serviceInterface.equals(SalMeterService.class)) { return (T) new SalMeterServiceMock(); + } else if (serviceInterface.equals(SalTableService.class)) { + return (T) new SalTableServiceMock(); } else { return null; } diff --git a/applications/forwardingrules-manager/src/test/java/test/mock/util/SalTableServiceMock.java b/applications/forwardingrules-manager/src/test/java/test/mock/util/SalTableServiceMock.java new file mode 100644 index 0000000000..52b94d7872 --- /dev/null +++ b/applications/forwardingrules-manager/src/test/java/test/mock/util/SalTableServiceMock.java @@ -0,0 +1,25 @@ +package test.mock.util; + +import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableOutput; + +import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.SalTableService; +import org.opendaylight.yangtools.yang.common.RpcResult; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Future; + +public class SalTableServiceMock implements SalTableService { + private List updateTableInput = new ArrayList<>(); + + + public List getUpdateTableInput() { + return updateTableInput; + } + + @Override + public Future> updateTable(UpdateTableInput input) { + updateTableInput.add(input); + return null; + } +} diff --git a/model/model-flow-service/src/main/yang/sal-table.yang b/model/model-flow-service/src/main/yang/sal-table.yang index a40529bef4..e8b45ace1a 100644 --- a/model/model-flow-service/src/main/yang/sal-table.yang +++ b/model/model-flow-service/src/main/yang/sal-table.yang @@ -28,6 +28,10 @@ module sal-table { description "Configuring openflow table."; input { + uses tr:transaction-metadata; + leaf table-ref { + type table-type:table-ref; + } uses table-update; uses tr:transaction-aware; } -- 2.36.6