From: Tony Tkacik Date: Mon, 14 Oct 2013 16:56:43 +0000 (+0200) Subject: MD-SAL RuntimeDataProvider for Forwarding Rules X-Git-Tag: jenkins-controller-bulk-release-prepare-only-2-1~622 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=97b0b3751318c5ad1f680ed3ef7701b0434fde7d MD-SAL RuntimeDataProvider for Forwarding Rules Change-Id: I0eac10ec50c9f4a4e95a0d9542842078ef8c7422 Signed-off-by: Tony Tkacik --- diff --git a/opendaylight/md-sal/flow-management-compatibility/pom.xml b/opendaylight/md-sal/flow-management-compatibility/pom.xml new file mode 100644 index 0000000000..5c24baa650 --- /dev/null +++ b/opendaylight/md-sal/flow-management-compatibility/pom.xml @@ -0,0 +1,89 @@ + + 4.0.0 + + org.opendaylight.controller + sal-parent + 1.0-SNAPSHOT + + flow-management-compatibility + bundle + + scm:git:ssh://git.opendaylight.org:29418/controller.git + scm:git:ssh://git.opendaylight.org:29418/controller.git + https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL + + + + + + org.apache.felix + maven-bundle-plugin + true + + + Forwarding Rules Manager Adapter for MD-SAL + + + + + org.eclipse.xtend + xtend-maven-plugin + + + maven-clean-plugin + + + + + + + org.opendaylight.controller + sal-common-util + 1.0-SNAPSHOT + + + org.opendaylight.controller + sal-binding-api + 1.0-SNAPSHOT + + + org.slf4j + slf4j-api + + + com.google.guava + guava + + + junit + junit + test + + + org.mockito + mockito-all + test + + + org.eclipse.xtend + org.eclipse.xtend.lib + + + org.opendaylight.controller.model + model-flow-management + 1.0-SNAPSHOT + + + org.opendaylight.controller + forwardingrulesmanager + 0.4.1-SNAPSHOT + + + org.opendaylight.controller + sal-compability + 1.0-SNAPSHOT + + + + diff --git a/opendaylight/md-sal/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FRMRuntimeDataProvider.xtend b/opendaylight/md-sal/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FRMRuntimeDataProvider.xtend new file mode 100644 index 0000000000..58248590a1 --- /dev/null +++ b/opendaylight/md-sal/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FRMRuntimeDataProvider.xtend @@ -0,0 +1,165 @@ +package org.opendaylight.controller.md.frm.compatibility + +import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier +import org.opendaylight.yangtools.yang.binding.DataObject +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.DataCommitHandler.DataCommitTransaction +import org.opendaylight.controller.sal.binding.api.data.DataProviderService +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowKey +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 +import org.opendaylight.controller.md.sal.common.api.data.DataChangeListener +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.FlowsBuilder +import org.opendaylight.controller.forwardingrulesmanager.IForwardingRulesManager +import static com.google.common.base.Preconditions.*; +import static extension org.opendaylight.controller.md.frm.compatibility.FlowConfigMapping.*; +import static extension org.opendaylight.controller.sal.compability.NodeMapping.*; +import org.opendaylight.controller.sal.common.util.Arguments +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem +import org.opendaylight.yangtools.yang.common.RpcResult +import org.opendaylight.controller.forwardingrulesmanager.FlowConfig +import java.util.HashSet +import org.opendaylight.controller.sal.common.util.Rpcs +import java.util.Collections +import org.opendaylight.yangtools.yang.common.RpcError + +class FRMRuntimeDataProvider implements RuntimeDataProvider, DataCommitHandler, DataObject> { + + static val FLOWS_PATH = InstanceIdentifier.builder().node(Flows).toInstance; + + @Property + var DataProviderService dataService; + + @Property + var DataChangeListener changeListener; + + @Property + var IForwardingRulesManager manager; + + FlowManagementReader configuration = new ConfigurationReader(); + + def init() { + //dataService.registerDataChangeListener(FLOWS_PATH, changeListener); + dataService.registerCommitHandler(FLOWS_PATH, this); + } + + override readConfigurationData(InstanceIdentifier path) { + return readFrom(configuration, path); + } + + override DataObject readOperationalData(InstanceIdentifier path) { + return readFrom(configuration, path); + } + + def DataObject readFrom(FlowManagementReader store, InstanceIdentifier path) { + if (FLOWS_PATH == path) { + return store.readAllFlows(); + } + if (FLOWS_PATH.contains(path)) { + return store.readFlow(path.toFlowKey()); + } + return null; + } + + override FlowCommitTransaction requestCommit( + DataModification modification) { + return new FlowCommitTransaction(this,modification); + } + + def toFlowKey(InstanceIdentifier identifier) { + checkNotNull(identifier) + val item = Arguments.checkInstanceOf(identifier.path.get(1),IdentifiableItem); + val key = Arguments.checkInstanceOf(item.key,FlowKey) + return key; + } + + def RpcResult finish(FlowCommitTransaction transaction) { + for(flw: transaction.toRemove) { + manager.removeStaticFlow(flw.name,flw.node) + } + + for(flw: transaction.toUpdate) { + manager.removeStaticFlow(flw.name,flw.node); + manager.addStaticFlow(flw); + } + + return Rpcs.getRpcResult(true,null,Collections.emptySet()) + } + + def RpcResult rollback(FlowCommitTransaction transaction) { + // NOOP: We did not changed any state. + } + +} + +class ConfigurationReader implements FlowManagementReader { + + @Property + var IForwardingRulesManager manager; + + override Flows readAllFlows() { + val it = new FlowsBuilder(); + flow = manager.staticFlows.map[ + toConfigurationFlow(); + ] + return it.build(); + } + + override readFlow(FlowKey key) { + val flowCfg = manager.getStaticFlow(key.id,key.node.toADNode()); + return flowCfg.toConfigurationFlow; + } +} + +public static class FlowCommitTransaction implements DataCommitTransaction, DataObject> { + + @Property + val DataModification, DataObject> modification; + + @Property + val FRMRuntimeDataProvider flowManager; + + @Property + val toAdd = new HashSet(); + + @Property + var Iterable toUpdate + + @Property + var Iterable toRemove + + + new(FRMRuntimeDataProvider flowManager,DataModification, DataObject> modification) { + super(); + _flowManager = flowManager; + _modification = modification; + processModification(); + } + + override finish() throws IllegalStateException { + return flowManager.finish(this); + } + + override rollback() throws IllegalStateException +{ + return flowManager.rollback(this); + } + + def processModification() { + val updated = modification.updatedConfigurationData.entrySet; + + val _toUpdate = updated.filter[key.isFlowPath].map[ + return (value as Flow).toFlowConfig + ] + toUpdate = _toUpdate as Iterable + + + val _toRemove = modification.removedConfigurationData.filter[isFlowPath].map[ + toFlowConfig + ] + toRemove = _toRemove as Iterable + + } +} diff --git a/opendaylight/md-sal/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowConfigMapping.xtend b/opendaylight/md-sal/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowConfigMapping.xtend new file mode 100644 index 0000000000..602b626452 --- /dev/null +++ b/opendaylight/md-sal/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowConfigMapping.xtend @@ -0,0 +1,61 @@ +package org.opendaylight.controller.md.frm.compatibility + +import org.opendaylight.controller.forwardingrulesmanager.FlowConfig +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowBuilder + +import static extension org.opendaylight.controller.sal.compability.NodeMapping.* +import static org.opendaylight.controller.sal.compability.MDFlowMapping.* +import static org.opendaylight.controller.sal.compability.ToSalConversionsUtils.* + +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowKey +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem +import org.opendaylight.yangtools.yang.binding.Identifiable + +class FlowConfigMapping { + + static def toConfigurationFlow(FlowConfig sourceCfg) { + val it = new FlowBuilder(); + val source = flowAdded(sourceCfg.flow); + + action = source.action; + cookie = source.cookie; + hardTimeout = source.hardTimeout + idleTimeout = source.idleTimeout + match = source.match + node = source.node + key = new FlowKey(sourceCfg.name, node) + return it.build(); + } + + static def toFlowConfig(Flow sourceCfg) { + val flow = toFlow(sourceCfg); + val it = new FlowConfig; + name = sourceCfg.key.id + node = sourceCfg.node.toADNode(); + + return it + } + + static def toFlowConfig(InstanceIdentifier identifier) { + val it = new FlowConfig() + val FlowKey key = ((identifier.path.get(2) as IdentifiableItem).key) + name = key.id; + node = key.node.toADNode(); + + return it; + } + + static def boolean isFlowPath(InstanceIdentifier path) { + if(path.path.size < 2) return false; + if (path.path.get(2) instanceof IdentifiableItem) { + val IdentifiableItem> item = path.path.get(2) as IdentifiableItem>; + val Identifiable key = item.key; + if (key instanceof FlowKey) { + return true; + } + } + return false; + } +} diff --git a/opendaylight/md-sal/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowManagementReader.java b/opendaylight/md-sal/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowManagementReader.java new file mode 100644 index 0000000000..61566d7aa3 --- /dev/null +++ b/opendaylight/md-sal/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowManagementReader.java @@ -0,0 +1,13 @@ +package org.opendaylight.controller.md.frm.compatibility; + +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.Flows; +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.FlowKey; + +public interface FlowManagementReader { + + Flows readAllFlows(); + + Flow readFlow(FlowKey key); + +} diff --git a/opendaylight/md-sal/model/model-flow-management/src/main/yang/flow-config.yang b/opendaylight/md-sal/model/model-flow-management/src/main/yang/flow-config.yang index da8e914fe7..5e6b59a018 100644 --- a/opendaylight/md-sal/model/model-flow-management/src/main/yang/flow-config.yang +++ b/opendaylight/md-sal/model/model-flow-management/src/main/yang/flow-config.yang @@ -20,7 +20,7 @@ module flow-management { container flows { list flow { - key "id"; + key "id node"; leaf id { type string; diff --git a/opendaylight/md-sal/pom.xml b/opendaylight/md-sal/pom.xml index 54fd037411..60e5a3daf8 100644 --- a/opendaylight/md-sal/pom.xml +++ b/opendaylight/md-sal/pom.xml @@ -39,6 +39,7 @@ sal-connector-api sal-rest-connector + flow-management-compatibility