Merge "BUG 274 REST response instead of NumberFormatException"
authorEd Warnicke <eaw@cisco.com>
Thu, 1 May 2014 15:17:55 +0000 (15:17 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 1 May 2014 15:17:55 +0000 (15:17 +0000)
68 files changed:
opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/ModuleFieldSerializer.java
opendaylight/config/yang-test-plugin/src/main/java/org/opendaylight/controller/config/yang/test/plugin/ProcessSources.java
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModule.java
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModuleFactory.java
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModule.java
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModuleFactory.java
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModule.java
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleFactory.java
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleUtil.java
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModule.java
opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModuleFactory.java
opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini
opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.xml
opendaylight/md-sal/compatibility/flow-management-compatibility/pom.xml
opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/ConfigurationReader.java [new file with mode: 0644]
opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FRMRuntimeDataProvider.java [new file with mode: 0644]
opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FRMRuntimeDataProvider.xtend [deleted file]
opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowCommitTransaction.java [new file with mode: 0644]
opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowConfigMapping.java [new file with mode: 0644]
opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowConfigMapping.xtend [deleted file]
opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowManagementReader.java
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyCommitHandler.java [new file with mode: 0644]
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyCommitHandler.xtend [deleted file]
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyProvider.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyTransaction.xtend [deleted file]
opendaylight/md-sal/forwardingrules-manager/pom.xml
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/AbstractChangeListener.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/AbstractTransaction.xtend [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/FRMActivator.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/FRMActivator.xtend [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowChangeListener.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowCommitHandler.xtend [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowProvider.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowProvider.xtend [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowTransaction.xtend [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowTransactionValidator.java
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupChangeListener.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupCommitHandler.xtend [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupProvider.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupProvider.xtend [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupTransaction.xtend [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupTransactionValidator.java
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterChangeListener.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterCommitHandler.xtend [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterProvider.java [new file with mode: 0644]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterProvider.xtend [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterTransaction.xtend [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterTransactionValidator.java
opendaylight/md-sal/inventory-manager/pom.xml
opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/FlowCapableInventoryProvider.java [new file with mode: 0644]
opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/FlowCapableInventoryProvider.xtend [deleted file]
opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/InventoryActivator.java [new file with mode: 0644]
opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/InventoryActivator.xtend [deleted file]
opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/InventoryMapping.java [new file with mode: 0644]
opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/InventoryMapping.xtend [deleted file]
opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/NodeChangeCommiter.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedTransaction.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/ForwardedBackwardsCompatibleDataBroker.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/SingletonHolder.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/codegen/impl/SingletonHolderTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-dom-it/pom.xml
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/ImmutableDataChangeEvent.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/SchemaAwareApplyOperation.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/osgi/NetconfSSHActivator.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/osgi/NetconfConfigUtil.java

index c0e3bc1..6211efe 100644 (file)
@@ -16,7 +16,7 @@ public class ModuleFieldSerializer {
     public static String toString(ModuleField moduleField) {
         StringBuilder builder = new StringBuilder();
         builder.append("    ");
-        builder.append("protected final "
+        builder.append("public static final "
                 + JmxAttribute.class.getCanonicalName() + " "
                 + moduleField.getName() + "JmxAttribute = new "
                 + JmxAttribute.class.getCanonicalName() + "(\""
index f2a56f2..7a20f22 100644 (file)
@@ -44,22 +44,53 @@ public class ProcessSources extends AbstractMojo{
 
         File[] sourceFiles = sourceDirectory.listFiles();
         for (File sourceFile: sourceFiles) {
-            if(sourceFile.getName().endsWith("Module.java") || sourceFile.getName().endsWith("ModuleFactory.java")) {
-                File stubFile = new File(sourceFile.getPath().replace(".java", "Stub.txt"));
-                if (stubFile.exists()) {
-                    try {
-                        rewrite(sourceFile, FileUtils.readFileToString(stubFile));
-                    } catch (IOException e) {
-                        getLog().error("Error while reading/writing to files.", e);
+            if (sourceFile.getName().endsWith(".java")) {
+                String sourceContent;
+                try {
+                    sourceContent = FileUtils.readFileToString(sourceFile);
+                } catch (IOException e) {
+                    getLog().error("Cannot read " + sourceFile.getAbsolutePath(), e);
+                    continue;
+                }
+                if (sourceFile.getName().endsWith("Module.java") || sourceFile.getName().endsWith("ModuleFactory.java")) {
+                    File stubFile = new File(sourceFile.getPath().replace(".java", "Stub.txt"));
+                    if (stubFile.exists()) {
+                        String stubContent = null;
+                        try {
+                            stubContent = FileUtils.readFileToString(stubFile);
+                        } catch (IOException e) {
+                            getLog().error("Cannot read " + stubFile.getAbsolutePath(), e);
+                        }
+                        if (stubContent != null) {
+                            sourceContent = rewriteStub(sourceContent, stubContent);
+                        }
                     }
                 }
+                // remove copyright headers as they can contain timestamp
+                sourceContent = removeCopyrights(sourceContent);
+
+                // replace the file content
+                try {
+                    FileUtils.write(sourceFile, sourceContent);
+                } catch (IOException e) {
+                    getLog().error("Cannot write " + sourceFile.getAbsolutePath(), e);
+                }
             }
+
         }
     }
 
-    private static void rewrite(File sourceFile, String replaceTODOWith) throws IOException {
-        String source = FileUtils.readFileToString(sourceFile);
-        String target = Pattern.compile("^.*TODO.*\n.*throw new java.lang.UnsupportedOperationException.*$", Pattern.MULTILINE).matcher(source).replaceFirst(replaceTODOWith);
-        FileUtils.write(sourceFile, target);
+    private static Pattern MULTILINE_COMMENT_PATTERN = Pattern.compile("/\\*.*\\*/", Pattern.MULTILINE | Pattern.DOTALL);
+    private static String removeCopyrights(String source) {
+        String target = MULTILINE_COMMENT_PATTERN.matcher(source).replaceAll("\n");
+        //FileUtils.write(sourceFile, target);
+        return target;
+    }
+
+    private static Pattern UNSUPPORTED_OP_PATTERN = Pattern.compile("^.*TODO.*\n.*throw new java.lang.UnsupportedOperationException.*$", Pattern.MULTILINE);
+
+    private static String rewriteStub(String source, String replaceTODOWith) {
+        String target = UNSUPPORTED_OP_PATTERN.matcher(source).replaceFirst(replaceTODOWith);
+        return target;
     }
 }
index 07d7438..78ac362 100644 (file)
@@ -1,10 +1,5 @@
-/*
-* 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.test.impl;
 public class DepTestImplModule extends org.opendaylight.controller.config.yang.test.impl.AbstractDepTestImplModule {
     public DepTestImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
index ae6ae67..026dd9a 100644 (file)
@@ -1,19 +1,5 @@
-/*
-* 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
-*/
-/*
-* Generated file
-*
-* Generated from: yang module name: config-test-impl yang module local name: impl-dep
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Fri Apr 25 11:50:32 CEST 2014
-*
-* Do not modify this file unless it is present under src/main directory
-*/
+
+
 package org.opendaylight.controller.config.yang.test.impl;
 public class DepTestImplModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractDepTestImplModuleFactory {
 
index a5b7f55..ddf72f3 100644 (file)
@@ -1,10 +1,5 @@
-/*
-* 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.test.impl;
 public class IdentityTestModule extends org.opendaylight.controller.config.yang.test.impl.AbstractIdentityTestModule {
     public IdentityTestModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
index 0701226..3a4348d 100644 (file)
@@ -1,19 +1,5 @@
-/*
-* 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
-*/
-/*
-* Generated file
-*
-* Generated from: yang module name: config-test-impl yang module local name: impl-identity-test
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Fri Apr 25 11:50:32 CEST 2014
-*
-* Do not modify this file unless it is present under src/main directory
-*/
+
+
 package org.opendaylight.controller.config.yang.test.impl;
 public class IdentityTestModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractIdentityTestModuleFactory {
 
index ecbf4ab..943fe3b 100644 (file)
@@ -1,10 +1,5 @@
-/*
-* 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.test.impl;
 public class NetconfTestImplModule extends org.opendaylight.controller.config.yang.test.impl.AbstractNetconfTestImplModule {
     public NetconfTestImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
index 3baee6c..587089b 100644 (file)
@@ -1,19 +1,5 @@
-/*
-* 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
-*/
-/*
-* Generated file
-*
-* Generated from: yang module name: config-test-impl yang module local name: impl-netconf
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Fri Apr 25 11:50:32 CEST 2014
-*
-* Do not modify this file unless it is present under src/main directory
-*/
+
+
 package org.opendaylight.controller.config.yang.test.impl;
 public class NetconfTestImplModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractNetconfTestImplModuleFactory {
 
index 4de9804..1d5cda0 100644 (file)
@@ -1,10 +1,5 @@
-/*
- * 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.test.impl;
 
 import com.google.common.collect.Lists;
index 9132407..7b049e7 100644 (file)
@@ -1,10 +1,5 @@
-/*
-* 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.test.impl;
 public class TestImplModule extends org.opendaylight.controller.config.yang.test.impl.AbstractTestImplModule {
     public TestImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
index 6f9118b..de9ac2f 100644 (file)
@@ -1,19 +1,5 @@
-/*
-* 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
-*/
-/*
-* Generated file
-*
-* Generated from: yang module name: config-test-impl yang module local name: impl
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Fri Apr 25 11:50:32 CEST 2014
-*
-* Do not modify this file unless it is present under src/main directory
-*/
+
+
 package org.opendaylight.controller.config.yang.test.impl;
 public class TestImplModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractTestImplModuleFactory {
 
index 9d0d6c1..234e0fe 100644 (file)
@@ -22,6 +22,8 @@ netconf.tcp.client.port=8383
 netconf.ssh.address=0.0.0.0
 netconf.ssh.port=1830
 netconf.ssh.pk.path = ./configuration/RSA.pk
+netconf.ssh.default.user = netconf
+netconf.ssh.default.password = netconf
 
 
 netconf.config.persister.active=1,2
index 619ab06..d872bfd 100644 (file)
                     <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>
-                <!-- To enable use of new in-memory datastore and new implementations
-                     of data brokers, comment out all parts of this
-                     xml which are marked with DATA-BROKER and uncomment all parts
-                     of this xml which are marked with NEW-DATA-BROKER
-                -->
-                <!-- DATA-BROKER start-->
-                <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>
-                <!-- DATA BROKER end -->
-                <!-- NEW-DATA-BROKER start -->
-                <!--
                 <module>
-                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-inmemory-data-broker</type>
-                    <name>async-data-broker</name>
-                    <schema-service>
-                        <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
-                        <name>yang-schema-service</name>
-                    </schema-service>
+                    <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>
-                -->
-                <!-- NEW-DATA-BROKER end -->
                 <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-BROKER start -->
-                    <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>
-                        <!-- to switch to the clustered data store, comment out the hash-map-data-store <name> and uncomment the cluster-data-store one -->
-                        <name>hash-map-data-store</name>
-                        <!-- <name>cluster-data-store</name> -->
-                    </data-store>
-                    <!-- DATA-BROKER end -->
-                    <!-- NEW-DATA-BROKER start -->
-                    <!--
-                    <async-data-broker>
-                        <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-async-data-broker</type>
-                        <name>async-data-broker</name>
-                    </async-data-broker>
-                    -->
-                    <!-- NEW-DATA-BROKER end -->
+                    <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-broker-impl</type>
                         <name>binding-data-broker</name>
                     </data-broker>
                 </module>
+
+                <!--
+                     Tree-based in-memory data store. This is the data store which is currently
+                     recommended for single-node deployments.
+                -->
                 <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>
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-inmemory-data-broker</type>
+                    <name>inmemory-data-broker</name>
+                    <schema-service>
+                        <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
+                        <name>yang-schema-service</name>
+                    </schema-service>
                 </module>
-                <!-- DATA-BROKER start -->
                 <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>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>runtime-mapping-singleton</name>
-                    </mapping-service>
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-broker-impl</type>
+                    <name>inmemory-dom-broker</name>
+                    <async-data-broker>
+                        <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-async-data-broker</type>
+                        <name>inmemory-data-broker</name>
+                    </async-data-broker>
                 </module>
-                <!-- DATA-BROKER end -->
-                <!-- NEW-DATA-BROKER start -->
-                <!--
                 <module>
                     <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-data-compatible-broker</type>
-                    <name>binding-data-broker</name>
+                    <name>inmemory-binding-data-broker</name>
                     <dom-async-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>dom-broker</name>
                         <name>runtime-mapping-singleton</name>
                     </binding-mapping-service>
                 </module>
-                -->
-                <!-- NEW-DATA-BROKER end -->
             </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>yang-schema-service</name>
-                        <provider>/modules/module[type='schema-service-singleton'][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>binding-notification-broker</name>
-                        <provider>/modules/module[type='binding-notification-broker'][name='binding-notification-broker']</provider>
-                    </instance>
-                </service>
-                <!-- DATA-BROKER start -->
-                <service>
-                    <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-data-store</type>
-                    <instance>
-                        <name>hash-map-data-store</name>
-                        <provider>/modules/module[type='hash-map-data-store'][name='hash-map-data-store']</provider>
-                    </instance>
-                </service>
-                <!-- DATA-BROKER end -->
-                <!-- NEW-DATA-BROKER start -->
-                <!--
-                <service>
-                    <type  xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-async-data-broker</type>
-                    <instance>
-                        <name>async-data-broker</name>
-                        <provider>/modules/module[type='dom-inmemory-data-broker'][name='async-data-broker']</provider>
-                    </instance>
-                </service>
-                -->
-                <!-- NEW-DATA-BROKER end -->
-                <service>
-                    <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
-                    <instance>
-                        <name>binding-osgi-broker</name>
-                        <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
-                    </instance>
-                </service>
-                <service>
-                    <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
-                    <instance>
-                        <name>binding-rpc-broker</name>
-                        <provider>/modules/module[type='binding-broker-impl'][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>runtime-mapping-singleton</name>
-                        <provider>/modules/module[type='runtime-generated-mapping'][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>dom-broker</name>
-                        <provider>/modules/module[type='dom-broker-impl'][name='dom-broker']</provider>
-                    </instance>
-                </service>
+                    <service>
+                        <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
+                        <instance>
+                            <name>yang-schema-service</name>
+                            <provider>/modules/module[type='schema-service-singleton'][name='yang-schema-service']</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>runtime-mapping-singleton</name>
+                            <provider>/modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton']</provider>
+                        </instance>
+                    </service>
+                    <service>
+                        <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
+                        <instance>
+                            <name>binding-notification-broker</name>
+                            <provider>/modules/module[type='binding-notification-broker'][name='binding-notification-broker']</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>binding-osgi-broker</name>
+                            <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
+                        </instance>
+                    </service>
+                    <service>
+                        <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
+                        <instance>
+                            <name>binding-rpc-broker</name>
+                            <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
+                        </instance>
+                    </service>
 
-                <service>
-                    <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
-                    <instance>
-                        <name>binding-data-broker</name>
-                        <!--  DATA-BROKER start -->
-                        <provider>/modules/module[type='binding-data-broker'][name='binding-data-broker']</provider>
-                        <!--  DATA-BROKER end -->
-                        <!-- NEW-DATA-BROKER start -->
-                        <!--
-                        <provider>/modules/module[type='binding-data-compatible-broker'][name='binding-data-broker']</provider>
-                        -->
-                        <!--  NEW-DATA-BROKER end -->
-                    </instance>
-                </service>
+                    <service>
+                        <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
+                        <instance>
+                            <name>dom-broker</name>
+                            <provider>/modules/module[type='dom-broker-impl'][name='inmemory-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>binding-data-broker</name>
+                            <provider>/modules/module[type='binding-data-compatible-broker'][name='inmemory-binding-data-broker']</provider>
+                        </instance>
+                    </service>
+
+                    <service>
+                        <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-async-data-broker</type>
+                        <instance>
+                            <name>inmemory-data-broker</name>
+                            <provider>/modules/module[type='dom-inmemory-data-broker'][name='inmemory-data-broker']</provider>
+                        </instance>
+                    </service>
             </services>
         </data>
     </configuration>
index 93ce0dd..7770c15 100644 (file)
       <groupId>com.google.guava</groupId>
       <artifactId>guava</artifactId>
     </dependency>
-    <dependency>
-      <groupId>org.eclipse.xtend</groupId>
-      <artifactId>org.eclipse.xtend.lib</artifactId>
-    </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>forwardingrulesmanager</artifactId>
           </instructions>
         </configuration>
       </plugin>
-      <plugin>
-        <groupId>org.eclipse.xtend</groupId>
-        <artifactId>xtend-maven-plugin</artifactId>
-      </plugin>
     </plugins>
   </build>
   <scm>
diff --git a/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/ConfigurationReader.java b/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/ConfigurationReader.java
new file mode 100644 (file)
index 0000000..411af28
--- /dev/null
@@ -0,0 +1,62 @@
+/**
+ * Copyright (c) 2014 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.md.frm.compatibility;
+
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.opendaylight.controller.forwardingrulesmanager.FlowConfig;
+import org.opendaylight.controller.forwardingrulesmanager.IForwardingRulesManager;
+import org.opendaylight.controller.sal.compatibility.NodeMapping;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.Flows;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.FlowsBuilder;
+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;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ConfigurationReader implements FlowManagementReader {
+
+    private final static Logger LOG = LoggerFactory.getLogger(ConfigurationReader.class);
+
+    private IForwardingRulesManager manager;
+
+    @Override
+    public Flows readAllFlows() {
+        List<FlowConfig> staticFlows = this.manager.getStaticFlows();
+        List<Flow> flowMap = new ArrayList<Flow>(staticFlows.size());
+
+        for (FlowConfig conf : staticFlows) {
+            flowMap.add(FlowConfigMapping.toConfigurationFlow(conf));
+        }
+        final FlowsBuilder flowsBuilder = new FlowsBuilder();
+        return (flowsBuilder.setFlow(flowMap)).build();
+    }
+
+    @Override
+    public Flow readFlow(final FlowKey key) {
+        try {
+            final FlowConfig flowConf =
+                    this.manager.getStaticFlow(String.valueOf(key.getId()), NodeMapping.toADNode(key.getNode()));
+            return FlowConfigMapping.toConfigurationFlow(flowConf);
+        } catch (Exception e) {
+            String errMsg = MessageFormat.format("readFlow by key {} fail", key);
+            LOG.error(errMsg, e);
+            throw new RuntimeException(errMsg, e);
+        }
+    }
+
+    public IForwardingRulesManager getManager() {
+        return this.manager;
+    }
+
+    public void setManager(final IForwardingRulesManager manager) {
+        this.manager = manager;
+    }
+}
diff --git a/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FRMRuntimeDataProvider.java b/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FRMRuntimeDataProvider.java
new file mode 100644 (file)
index 0000000..be3add1
--- /dev/null
@@ -0,0 +1,122 @@
+/**
+ * Copyright (c) 2014 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.md.frm.compatibility;
+
+import java.util.Collections;
+
+import org.opendaylight.controller.forwardingrulesmanager.FlowConfig;
+import org.opendaylight.controller.forwardingrulesmanager.IForwardingRulesManager;
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
+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.Arguments;
+import org.opendaylight.controller.sal.common.util.Rpcs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.Flows;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowKey;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.Identifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Preconditions;
+
+public class FRMRuntimeDataProvider implements RuntimeDataProvider, DataCommitHandler<InstanceIdentifier<? extends DataObject>,DataObject> {
+
+    private final static InstanceIdentifier<Flows> FLOWS_PATH = InstanceIdentifier.<Flows> builder(Flows.class).toInstance();
+
+    private final FlowManagementReader configuration = new ConfigurationReader();
+    private DataChangeListener<InstanceIdentifier<? extends DataObject>, DataObject> changeListener;
+    private DataProviderService dataService;
+    private IForwardingRulesManager manager;
+
+    public Registration<DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject>> init() {
+        return this.dataService.registerCommitHandler(FRMRuntimeDataProvider.FLOWS_PATH, this);
+    }
+
+    @Override
+    public DataObject readConfigurationData(final InstanceIdentifier<? extends DataObject> path) {
+        return this.readFrom(this.configuration, path);
+    }
+
+    @Override
+    public DataObject readOperationalData(final InstanceIdentifier<? extends DataObject> path) {
+        return this.readFrom(this.configuration, path);
+    }
+
+    public DataObject readFrom(final FlowManagementReader store, final InstanceIdentifier<? extends DataObject> path) {
+        if (Objects.equal(FRMRuntimeDataProvider.FLOWS_PATH, path)) {
+            return store.readAllFlows();
+        }
+        if (FRMRuntimeDataProvider.FLOWS_PATH.contains(path)) {
+            return store.readFlow(this.toFlowKey(path));
+        }
+        return null;
+    }
+
+    @Override
+    public FlowCommitTransaction requestCommit(final DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
+        return new FlowCommitTransaction(this, modification);
+    }
+
+    public FlowKey toFlowKey(final InstanceIdentifier<? extends DataObject> identifier) {
+        Preconditions.<InstanceIdentifier<? extends DataObject>> checkNotNull(identifier);
+
+        Iterable<PathArgument> path = identifier.getPathArguments();
+        PathArgument get = path.iterator().next();
+        final Identifier itemKey = Arguments.<IdentifiableItem> checkInstanceOf(get, IdentifiableItem.class).getKey();
+        return Arguments.<FlowKey> checkInstanceOf(itemKey, FlowKey.class);
+    }
+
+    public RpcResult<Void> finish(final FlowCommitTransaction transaction) {
+        Iterable<FlowConfig> toRemove = transaction.getToRemove();
+        for (final FlowConfig flow : toRemove) {
+            this.manager.removeStaticFlow(flow.getName(), flow.getNode());
+        }
+        Iterable<FlowConfig> toUpdate = transaction.getToUpdate();
+        for (final FlowConfig flow : toUpdate) {
+            this.manager.removeStaticFlow(flow.getName(), flow.getNode());
+            this.manager.addStaticFlow(flow);
+        }
+        return Rpcs.<Void> getRpcResult(true, null, Collections.<RpcError> emptySet());
+    }
+
+    public RpcResult<Void> rollback(final FlowCommitTransaction transaction) {
+        return null;
+    }
+
+    public DataProviderService getDataService() {
+        return this.dataService;
+    }
+
+    public void setDataService(final DataProviderService dataService) {
+        this.dataService = dataService;
+    }
+
+    public DataChangeListener<InstanceIdentifier<? extends DataObject>, DataObject> getChangeListener() {
+        return this.changeListener;
+    }
+
+    public void setChangeListener(final DataChangeListener<InstanceIdentifier<? extends DataObject>, DataObject> changeListener) {
+        this.changeListener = changeListener;
+    }
+
+    public IForwardingRulesManager getManager() {
+        return this.manager;
+    }
+
+    public void setManager(final IForwardingRulesManager manager) {
+        this.manager = manager;
+    }
+}
diff --git a/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FRMRuntimeDataProvider.xtend b/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FRMRuntimeDataProvider.xtend
deleted file mode 100644 (file)
index 2d4e7d2..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (c) 2014 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.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.compatibility.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<InstanceIdentifier<? extends DataObject>, DataObject> {
-
-    static val FLOWS_PATH = InstanceIdentifier.builder(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<? extends DataObject> path) {
-        return readFrom(configuration, path);
-    }
-
-    override DataObject readOperationalData(InstanceIdentifier<? extends DataObject> path) {
-        return readFrom(configuration, path);
-    }
-
-    def DataObject readFrom(FlowManagementReader store, InstanceIdentifier<? extends DataObject> 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<? extends DataObject> identifier) {
-        checkNotNull(identifier)
-        val item = Arguments.checkInstanceOf(identifier.path.get(1),IdentifiableItem);
-        val key = Arguments.checkInstanceOf(item.key,FlowKey)
-        return key;
-    }
-    
-    def RpcResult<Void> 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.<Void>getRpcResult(true,null,Collections.<RpcError>emptySet())
-    }
-    
-    def RpcResult<Void> 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(String.valueOf(key.id), key.node.toADNode());
-        return flowCfg.toConfigurationFlow;
-    }
-}
-
-public static class FlowCommitTransaction implements DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> {
-
-    @Property
-    val DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification;
-
-    @Property
-    val FRMRuntimeDataProvider flowManager;
-    
-    @Property
-    val toAdd = new HashSet<FlowConfig>();
-    
-    @Property
-    var Iterable<FlowConfig> toUpdate
-    
-    @Property
-    var Iterable<FlowConfig> toRemove
-    
-
-    new(FRMRuntimeDataProvider flowManager,DataModification<InstanceIdentifier<? extends DataObject>, 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<FlowConfig>
-        
-        
-        val _toRemove = modification.removedConfigurationData.filter[isFlowPath].map[
-             toFlowConfig
-        ]
-        toRemove = _toRemove as Iterable<FlowConfig>
-        
-    }
-}
diff --git a/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowCommitTransaction.java b/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowCommitTransaction.java
new file mode 100644 (file)
index 0000000..bf0050d
--- /dev/null
@@ -0,0 +1,99 @@
+/**
+ * Copyright (c) 2014 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.md.frm.compatibility;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.opendaylight.controller.forwardingrulesmanager.FlowConfig;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+public class FlowCommitTransaction implements DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> {
+
+    private final DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification;
+    private final HashSet<FlowConfig> toAdd = new HashSet<FlowConfig>();
+    private final FRMRuntimeDataProvider flowManager;
+    private Iterable<FlowConfig> toUpdate;
+    private Iterable<FlowConfig> toRemove;
+
+    public FlowCommitTransaction(
+            final FRMRuntimeDataProvider flowManager,
+            final DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
+        this.flowManager = flowManager;
+        this.modification = modification;
+        this.processModification();
+    }
+
+    @Override
+    public RpcResult<Void> finish() throws IllegalStateException {
+        return this.flowManager.finish(this);
+    }
+
+    @Override
+    public RpcResult<Void> rollback() throws IllegalStateException {
+        return this.flowManager.rollback(this);
+    }
+
+    public void processModification() {
+        final Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> updated =
+                this.modification.getUpdatedConfigurationData().entrySet();
+        final List<FlowConfig> forUpdate = new ArrayList<FlowConfig>(updated.size());
+
+        if (updated != null && !(updated.isEmpty())) {
+            for (Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry : updated) {
+                if (FlowConfigMapping.isFlowPath(entry.getKey())) {
+                    forUpdate.add(FlowConfigMapping.toFlowConfig((Flow) entry.getValue()));
+                }
+            }
+        }
+        this.toUpdate = Collections.unmodifiableCollection(forUpdate);
+
+        final Set<InstanceIdentifier<? extends DataObject>> removedConfigurationData =
+                this.modification.getRemovedConfigurationData();
+        final List<FlowConfig> forRemove = new ArrayList<FlowConfig>(removedConfigurationData.size());
+
+        if (removedConfigurationData != null && !(removedConfigurationData.isEmpty())) {
+            for (InstanceIdentifier<? extends DataObject> data : removedConfigurationData) {
+                if (FlowConfigMapping.isFlowPath(data)) {
+                    forRemove.add(FlowConfigMapping.toFlowConfig(data));
+                }
+            }
+        }
+        this.toRemove = Collections.unmodifiableCollection(forRemove);
+    }
+
+    @Override
+    public DataModification<InstanceIdentifier<? extends DataObject>, DataObject> getModification() {
+        return this.modification;
+    }
+
+    public FRMRuntimeDataProvider getFlowManager() {
+        return this.flowManager;
+    }
+
+    public HashSet<FlowConfig> getToAdd() {
+        return this.toAdd;
+    }
+
+    public Iterable<FlowConfig> getToUpdate() {
+        return this.toUpdate;
+    }
+
+    public Iterable<FlowConfig> getToRemove() {
+        return this.toRemove;
+    }
+}
diff --git a/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowConfigMapping.java b/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowConfigMapping.java
new file mode 100644 (file)
index 0000000..58c60ec
--- /dev/null
@@ -0,0 +1,109 @@
+/**
+ * Copyright (c) 2014 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.md.frm.compatibility;
+
+import java.text.MessageFormat;
+import java.util.Iterator;
+
+import org.opendaylight.controller.forwardingrulesmanager.FlowConfig;
+import org.opendaylight.controller.sal.compatibility.MDFlowMapping;
+import org.opendaylight.controller.sal.compatibility.NodeMapping;
+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.service.rev130819.FlowAdded;
+import org.opendaylight.yangtools.yang.binding.Identifiable;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class FlowConfigMapping {
+
+    private final static Logger LOG = LoggerFactory.getLogger(FlowConfigMapping.class);
+
+    /* nodes/node/flow  -> 0 / 1 / 2  */
+    private static final int FLOW_KEY_IDENTIFIER_DEEP = 2;
+
+    public static Flow toConfigurationFlow(final FlowConfig sourceCfg) {
+        final FlowAdded source = MDFlowMapping.flowAdded(sourceCfg.getFlow());
+        final FlowBuilder flowBuilder = new FlowBuilder();
+        flowBuilder.setInstructions(source.getInstructions());
+        flowBuilder.setCookie(source.getCookie());
+        flowBuilder.setHardTimeout(source.getHardTimeout());
+        flowBuilder.setIdleTimeout(source.getIdleTimeout());
+        flowBuilder.setMatch(source.getMatch());
+        flowBuilder.setNode(source.getNode());
+
+        FlowKey flowKey =
+                new FlowKey(Long.valueOf(sourceCfg.getName()), flowBuilder.getNode());
+        flowBuilder.setKey(flowKey);
+        return flowBuilder.build();
+    }
+
+    public static FlowConfig toFlowConfig(final Flow sourceCfg) {
+        try {
+            final FlowConfig flowConfig = new FlowConfig();
+            flowConfig.setName(String.valueOf(sourceCfg.getId()));
+            flowConfig.setNode(NodeMapping.toADNode(sourceCfg.getNode()));
+            return flowConfig;
+        } catch (Exception e) {
+            String errMsg = MessageFormat.format("Convert from Flow {} to FlowConfig fail", sourceCfg);
+            LOG.error(errMsg, e);
+            throw new RuntimeException(errMsg, e);
+        }
+    }
+
+    public static FlowConfig toFlowConfig(final InstanceIdentifier<? extends Object> identifier) {
+        try {
+            PathArgument pathArg = FlowConfigMapping.getSecondPathArgumentFromPath(identifier);
+            if (pathArg != null) {
+                final FlowConfig flowConfig = new FlowConfig();
+                FlowKey key = ((IdentifiableItem<Flow, FlowKey>) pathArg).getKey();
+                flowConfig.setName(String.valueOf(key.getId()));
+                flowConfig.setNode(NodeMapping.toADNode(key.getNode()));
+                return flowConfig;
+            }
+            return null;
+        } catch (Exception e) {
+            String errMsg = MessageFormat.format("Convert from InstanceIdentifier {} to FlowConfig fail", identifier);
+            LOG.error(errMsg, e);
+            throw new RuntimeException(errMsg, e);
+        }
+    }
+
+    public static boolean isFlowPath(final InstanceIdentifier<? extends Object> path) {
+        PathArgument pathArg = FlowConfigMapping.getSecondPathArgumentFromPath(path);
+        if (pathArg == null) {
+            return false;
+        }
+        if (pathArg instanceof IdentifiableItem<?,?>) {
+            final Identifiable<?> key = ((IdentifiableItem<?, ? extends Identifiable<?>>) pathArg).getKey();
+            if ((key instanceof FlowKey)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static PathArgument getSecondPathArgumentFromPath(final InstanceIdentifier<? extends Object> path) {
+        if (path != null && path.getPathArguments() != null) {
+            Iterator<PathArgument> iterator = path.getPathArguments().iterator();
+            int deep = 0;
+            while (iterator.hasNext()) {
+                PathArgument pathArg = iterator.next();
+                if (deep == FlowConfigMapping.FLOW_KEY_IDENTIFIER_DEEP) {
+                    return pathArg;
+                }
+                deep++;
+            }
+        }
+        return null;
+    }
+}
diff --git a/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowConfigMapping.xtend b/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowConfigMapping.xtend
deleted file mode 100644 (file)
index e15b3c6..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2014 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.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.compatibility.NodeMapping.*
-import static org.opendaylight.controller.sal.compatibility.MDFlowMapping.*
-import static org.opendaylight.controller.sal.compatibility.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 source = flowAdded(sourceCfg.flow);
-        val it = new FlowBuilder();
-        instructions = source.instructions;
-        cookie = source.cookie;
-        hardTimeout = source.hardTimeout
-        idleTimeout = source.idleTimeout
-        match = source.match
-        node = source.node
-        key = new FlowKey(Long.parseLong(sourceCfg.name),node);
-        return it.build();
-    }
-
-    static def toFlowConfig(Flow sourceCfg) {
-        val it = new FlowConfig;
-        name = String.valueOf(sourceCfg.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<Flow,FlowKey>).key)
-        name = String.valueOf(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<?,? extends Identifiable<?>> item = path.path.get(2) as IdentifiableItem<?,? extends Identifiable<?>>;
-            val Identifiable<?> key = item.key;
-            if (key instanceof FlowKey) {
-                return true;
-            }
-        }
-        return false;
-    }
-}
diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyCommitHandler.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyCommitHandler.java
new file mode 100644 (file)
index 0000000..a35c3ed
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2014 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.sal.compatibility.topology;
+
+import static org.opendaylight.controller.sal.compatibility.topology.TopologyMapping.toAdEdge;
+import static org.opendaylight.controller.sal.compatibility.topology.TopologyMapping.toTopoEdgeUpdate;
+
+import java.util.Map.Entry;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader;
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.core.UpdateType;
+import org.opendaylight.controller.sal.topology.IPluginOutTopologyService;
+import org.opendaylight.controller.sal.topology.TopoEdgeUpdate;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TopologyCommitHandler implements DataChangeListener {
+    private static final Logger LOG = LoggerFactory.getLogger(TopologyCommitHandler.class);
+
+    private IPluginOutTopologyService topologyPublisher;
+
+    private final DataProviderService dataService;
+
+    public TopologyCommitHandler(final DataProviderService dataService, final IPluginOutTopologyService topologyPub) {
+        this.topologyPublisher = topologyPub;
+        this.dataService = dataService;
+    }
+
+    @Override
+    public void onDataChanged(final DataChangeEvent<InstanceIdentifier<?>, DataObject> modification) {
+        CopyOnWriteArrayList<TopoEdgeUpdate> msg = new CopyOnWriteArrayList<TopoEdgeUpdate>();
+        try {
+            TypeSafeDataReader reader = TypeSafeDataReader.forReader(dataService);
+            InstanceIdentifier<Topology> topologyPath = InstanceIdentifier.builder(NetworkTopology.class)
+                    .child(Topology.class, new TopologyKey(new TopologyId("flow:1"))).build();
+            Topology topology = reader.readOperationalData(topologyPath);
+
+            for (Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry : modification
+                    .getCreatedOperationalData().entrySet()) {
+                if (entry.getValue() instanceof Link
+                        && modification.getCreatedOperationalData().containsKey(entry.getKey())) {
+                    msg.add(toTopoEdgeUpdate(toAdEdge((Link) entry.getValue(), topology), UpdateType.ADDED, reader));
+                }
+            }
+
+            for (Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry : modification
+                    .getUpdatedOperationalData().entrySet()) {
+                if (entry.getValue() instanceof Link) {
+                    msg.add(toTopoEdgeUpdate(toAdEdge((Link) entry.getValue(), topology), UpdateType.CHANGED, reader));
+                }
+            }
+            for (InstanceIdentifier<? extends DataObject> path : modification.getRemovedOperationalData()) {
+                if (path.getTargetType() == Link.class) {
+                    Link link = (Link) modification.getOriginalOperationalData().get(path);
+                    msg.add(toTopoEdgeUpdate(toAdEdge(link, topology), UpdateType.CHANGED, reader));
+                }
+
+            }
+
+            if (topologyPublisher != null && msg != null && !msg.isEmpty()) {
+                topologyPublisher.edgeUpdate(msg);
+            }
+
+        } catch (Exception e) {
+            LOG.error("Exception caught", e);
+        }
+    }
+
+    protected IPluginOutTopologyService getTopologyPublisher() {
+        return topologyPublisher;
+    }
+
+    protected void setTopologyPublisher(final IPluginOutTopologyService topologyPublisher) {
+        this.topologyPublisher = topologyPublisher;
+    }
+
+}
diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyCommitHandler.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyCommitHandler.xtend
deleted file mode 100644 (file)
index fcf86f2..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2014 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.sal.compatibility.topology
-
-import com.google.common.collect.FluentIterable
-import java.util.concurrent.CopyOnWriteArrayList
-import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.controller.md.sal.common.api.data.DataModification
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
-import org.opendaylight.controller.sal.core.UpdateType
-import org.opendaylight.controller.sal.topology.IPluginOutTopologyService
-import org.opendaylight.controller.sal.topology.TopoEdgeUpdate
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import static extension org.opendaylight.controller.sal.compatibility.topology.TopologyMapping.*
-import org.slf4j.LoggerFactory
-
-class TopologyCommitHandler implements DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> {
-    static val LOG = LoggerFactory.getLogger(TopologyCommitHandler);
-    @Property
-    IPluginOutTopologyService topologyPublisher;
-    
-    @Property
-    DataProviderService dataService;
-    
-    new(DataProviderService dataService) {
-        _topologyPublisher = topologyPublisher
-        _dataService = dataService
-    }
-    
-    override requestCommit(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
-        val msg = new CopyOnWriteArrayList<TopoEdgeUpdate>()
-        try {
-            val reader = TypeSafeDataReader.forReader(dataService)
-            val topologyPath = InstanceIdentifier.builder(NetworkTopology).child(Topology, new TopologyKey(new TopologyId("flow:1"))).toInstance
-            val topology = reader.readOperationalData(topologyPath)
-            val adds = FluentIterable.from(modification.createdOperationalData.entrySet)
-                .filter[value instanceof Link]
-                .transform[(value as Link).toAdEdge(topology).toTopoEdgeUpdate(UpdateType.ADDED,reader)]
-                .toList
-            val updates = FluentIterable.from(modification.updatedOperationalData.entrySet)
-                .filter[!modification.createdOperationalData.containsKey(key) && (value instanceof Link)]
-                .transform[(value as Link).toAdEdge(topology).toTopoEdgeUpdate(UpdateType.ADDED,reader)] // Evidently the ADSAL does not expect edge 'CHANGED"
-                .toList
-            val removes = FluentIterable.from(modification.removedOperationalData)
-                .transform[reader.readOperationalData(it as InstanceIdentifier<DataObject>)]
-                .filter[it instanceof Link]
-                .transform[(it as Link).toAdEdge(topology).toTopoEdgeUpdate(UpdateType.REMOVED,reader)]
-                .toList
-            msg.addAll(adds)
-            msg.addAll(updates)
-            msg.addAll(removes)
-         } catch (Exception e) {
-            LOG.error("Exception caught",e)
-         }
-        return new TopologyTransaction(modification,topologyPublisher,dataService,msg)
-    }
-}
index 4aef75d..21f2b35 100644 (file)
@@ -15,10 +15,10 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey
 import org.opendaylight.yangtools.yang.binding.DataObject
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yangtools.concepts.Registration
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link
 import org.slf4j.LoggerFactory
+import org.opendaylight.yangtools.concepts.ListenerRegistration
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener
 
 class TopologyProvider implements AutoCloseable{
     static val LOG = LoggerFactory.getLogger(TopologyProvider);
@@ -30,8 +30,9 @@ class TopologyProvider implements AutoCloseable{
     @Property
     DataProviderService dataService;
     
-    Registration<DataCommitHandler<InstanceIdentifier<? extends DataObject>,DataObject>> commitHandlerRegistration;
-
+    ListenerRegistration<DataChangeListener> listenerRegistration
+    
+    
     def void start() {
 
     }
@@ -40,18 +41,17 @@ class TopologyProvider implements AutoCloseable{
             LOG.error("dataService not set");
             return;
         }
-        commitHandler = new TopologyCommitHandler(dataService)
-        commitHandler.setTopologyPublisher(topologyPublisher)
+        commitHandler = new TopologyCommitHandler(dataService,topologyPublisher);
         val InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(NetworkTopology)
             .child(Topology,new TopologyKey(new TopologyId("flow:1")))
             .child(Link)
             .toInstance();
-        commitHandlerRegistration = dataService.registerCommitHandler(path,commitHandler);
+        listenerRegistration = dataService.registerDataChangeListener(path,commitHandler);
         LOG.info("TopologyProvider started")
     }
     
     override close() throws Exception {
-        commitHandlerRegistration.close
+        listenerRegistration.close
     }
     
     def setTopologyPublisher(IPluginOutTopologyService topologyPublisher) {
diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyTransaction.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyTransaction.xtend
deleted file mode 100644 (file)
index 4de78ca..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2014 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.sal.compatibility.topology
-
-import java.util.Collections
-import java.util.List
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction
-import org.opendaylight.controller.md.sal.common.api.data.DataModification
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
-import org.opendaylight.controller.sal.topology.IPluginOutTopologyService
-import org.opendaylight.controller.sal.topology.TopoEdgeUpdate
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yangtools.yang.common.RpcResult
-import org.slf4j.LoggerFactory
-
-class TopologyTransaction implements DataCommitTransaction<InstanceIdentifier<?extends DataObject>, DataObject> {
-    static val LOG = LoggerFactory.getLogger(TopologyTransaction);
-    @Property
-    val DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification;
-    
-    @Property
-    IPluginOutTopologyService topologyPublisher;
-    
-    @Property
-    DataProviderService dataService;
-    @Property
-    List<TopoEdgeUpdate> edgeUpdates;
-    
-    new(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification,IPluginOutTopologyService topologyPublisher,
-        DataProviderService dataService,List<TopoEdgeUpdate> edgeUpdates) {
-        _modification = modification;
-        _topologyPublisher = topologyPublisher
-        _dataService = dataService
-        _edgeUpdates = edgeUpdates
-    }
-    override finish() throws IllegalStateException {
-        
-        if(topologyPublisher != null && _edgeUpdates != null && !edgeUpdates.empty) {
-            topologyPublisher.edgeUpdate(edgeUpdates)
-        }
-         
-         return new RpcResultTo()
-    }
-    
-    override getModification() {
-        return _modification;
-    }
-    
-    override rollback() throws IllegalStateException {
-        // NOOP
-    }
-}
-class RpcResultTo implements RpcResult<Void> {
-    
-    override getErrors() {
-        return Collections.emptySet
-    }
-    
-    override getResult() {
-        return null;
-    }
-    
-    override isSuccessful() {
-        return true;
-    }
-    
-}
index 919a53c..9bd63d3 100644 (file)
           </instructions>
         </configuration>
       </plugin>
-      <plugin>
-        <groupId>org.eclipse.xtend</groupId>
-        <artifactId>xtend-maven-plugin</artifactId>
-      </plugin>
     </plugins>
   </build>
 
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/AbstractChangeListener.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/AbstractChangeListener.java
new file mode 100644 (file)
index 0000000..426f4ba
--- /dev/null
@@ -0,0 +1,94 @@
+/**
+ * Copyright (c) 2014 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.frm;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * 
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ */
+public abstract class AbstractChangeListener implements DataChangeListener {
+
+    private final AtomicLong txNum = new AtomicLong();
+    private String transactionId;
+
+    @Override
+    public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> changeEvent) {
+        this.transactionId = this.newTransactionIdentifier().toString();
+
+        final Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> createdEntries = 
+                changeEvent.getCreatedConfigurationData().entrySet();
+        final Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> updatedEntries = 
+                new HashSet<Entry<InstanceIdentifier<? extends DataObject>, DataObject>>();
+
+        Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> updateConfigEntrySet = 
+                changeEvent.getUpdatedConfigurationData().entrySet();
+        updatedEntries.addAll(updateConfigEntrySet);
+        updatedEntries.removeAll(createdEntries);
+
+        final Set<InstanceIdentifier<? extends DataObject>> removeEntriesInstanceIdentifiers = 
+                changeEvent.getRemovedConfigurationData();
+
+        for (final Entry<InstanceIdentifier<? extends DataObject>, DataObject> createdEntry : createdEntries) {
+            InstanceIdentifier<? extends DataObject> c_key = createdEntry.getKey();
+            DataObject c_value = createdEntry.getValue();
+            this.add(c_key, c_value);
+        }
+
+        for (final Entry<InstanceIdentifier<?>, DataObject> updatedEntrie : updatedEntries) {
+            Map<InstanceIdentifier<? extends DataObject>, DataObject> origConfigData = 
+                    changeEvent.getOriginalConfigurationData();
+
+            InstanceIdentifier<? extends Object> u_key = updatedEntrie.getKey();
+            final DataObject originalFlow = origConfigData.get(u_key);
+            final DataObject updatedFlow = updatedEntrie.getValue();
+            this.update(u_key, originalFlow, updatedFlow);
+        }
+
+        for (final InstanceIdentifier<?> instanceId : removeEntriesInstanceIdentifiers) {
+            Map<InstanceIdentifier<? extends DataObject>, DataObject> origConfigData = 
+                    changeEvent.getOriginalConfigurationData();
+
+            final DataObject removeValue = origConfigData.get(instanceId);
+            this.remove(instanceId, removeValue);
+        }
+    }
+
+    public String getTransactionId() {
+        return this.transactionId;
+    }
+
+    private Object newTransactionIdentifier() {
+        return "DOM-" + txNum.getAndIncrement();
+    }
+
+    protected abstract void validate() throws IllegalStateException;
+
+    protected abstract void remove(
+            final InstanceIdentifier<? extends DataObject> identifier,
+            final DataObject remove);
+
+    protected abstract void update(
+            final InstanceIdentifier<? extends DataObject> identifier,
+            final DataObject original, final DataObject update);
+
+    protected abstract void add(
+            final InstanceIdentifier<? extends DataObject> identifier,
+            final DataObject add);
+}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/AbstractTransaction.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/AbstractTransaction.xtend
deleted file mode 100644 (file)
index cb1e90d..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 2014 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.frm
-
-import java.util.Collections
-import java.util.HashSet
-import java.util.Map.Entry
-import java.util.Set
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction
-import org.opendaylight.controller.md.sal.common.api.data.DataModification
-import org.opendaylight.controller.sal.common.util.Rpcs
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yangtools.yang.common.RpcError
-
-abstract class AbstractTransaction implements DataCommitTransaction<InstanceIdentifier<?extends DataObject>, DataObject> {
-        
-    @Property
-    val DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification;
-    
-    new(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
-        _modification = modification;
-    }
-    
-    def void validate() throws IllegalStateException
-    
-    override finish() throws IllegalStateException {
-        validate()
-        callRpcs();
-        return Rpcs.getRpcResult(true, null, Collections.<RpcError>emptySet());     
-    }
-    
-    override getModification() {
-        return _modification;
-    }
-    
-    override rollback() throws IllegalStateException {
-        rollbackRpcs();
-        return Rpcs.getRpcResult(true, null, Collections.<RpcError>emptySet());
-    }
-    
-    def private callRpcs() {
-        val Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> createdEntries = _modification.getCreatedConfigurationData().entrySet();
-
-        /*
-         * This little dance is because updatedEntries contains both created and modified entries
-         * The reason I created a new HashSet is because the collections we are returned are immutable.
-         */
-        val Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> updatedEntries = new HashSet<Entry<InstanceIdentifier<? extends DataObject>, DataObject>>();
-        updatedEntries.addAll(_modification.getUpdatedConfigurationData().entrySet());
-        updatedEntries.removeAll(createdEntries);
-
-        val Set<InstanceIdentifier<? extends DataObject>> removeEntriesInstanceIdentifiers = _modification.getRemovedConfigurationData();
-        for (Entry<InstanceIdentifier<? extends DataObject >, DataObject> entry : createdEntries) {
-            add(entry.key,entry.value);
-        }
-        for (Entry<InstanceIdentifier<?>, DataObject> entry : updatedEntries) {
-                val originalFlow = _modification.originalConfigurationData.get(entry.key);
-                val updatedFlow = entry.value
-                update(entry.key, originalFlow ,updatedFlow);
-        }
-
-        for (InstanceIdentifier<?> instanceId : removeEntriesInstanceIdentifiers ) {
-            val removeValue = _modification.getOriginalConfigurationData.get(instanceId);
-                remove(instanceId,removeValue);
-        }
-    }
-    
-    def void remove(InstanceIdentifier<?> identifier, DataObject remove)
-    
-    def void update(InstanceIdentifier<?> identifier, DataObject original, DataObject update)
-    
-    def void add(InstanceIdentifier<?> identifier, DataObject add)
-    
-    def private rollbackRpcs() {
-        val Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> createdEntries = _modification.getCreatedConfigurationData().entrySet();
-
-        /*
-         * This little dance is because updatedEntries contains both created and modified entries
-         * The reason I created a new HashSet is because the collections we are returned are immutable.
-         */
-        val Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> updatedEntries = new HashSet<Entry<InstanceIdentifier<? extends DataObject>, DataObject>>();
-        updatedEntries.addAll(_modification.getUpdatedConfigurationData().entrySet());
-        updatedEntries.removeAll(createdEntries);
-
-        val Set<InstanceIdentifier<? >> removeEntriesInstanceIdentifiers = _modification.getRemovedConfigurationData();
-        for (Entry<InstanceIdentifier<?>, DataObject> entry : createdEntries) {
-            remove(entry.key,entry.value); // because we are rolling back, remove what we would have added.            
-        }
-        for (Entry<InstanceIdentifier<?>, DataObject> entry : updatedEntries) {
-            val originalFlow = _modification.originalConfigurationData.get(entry.key);
-            val updatedFlow = entry.value
-            update(entry.key, updatedFlow ,originalFlow);// because we are rolling back, replace the updated with the original
-        }
-
-        for (InstanceIdentifier<?> instanceId : removeEntriesInstanceIdentifiers ) {
-            val removeValue = _modification.getOriginalConfigurationData.get(instanceId);
-            add(instanceId,removeValue);// because we are rolling back, add what we would have removed.
-        }
-    }    
-}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/FRMActivator.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/FRMActivator.java
new file mode 100644 (file)
index 0000000..929c489
--- /dev/null
@@ -0,0 +1,61 @@
+/**
+ * Copyright (c) 2014 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.frm;
+
+import org.opendaylight.controller.frm.flow.FlowProvider;
+import org.opendaylight.controller.frm.group.GroupProvider;
+import org.opendaylight.controller.frm.meter.MeterProvider;
+import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+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.meter.service.rev130918.SalMeterService;
+import org.osgi.framework.BundleContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class FRMActivator extends AbstractBindingAwareProvider {
+
+    private final static Logger LOG = LoggerFactory.getLogger(FRMActivator.class);
+
+    private static FlowProvider flowProvider = new FlowProvider(); 
+    private static GroupProvider groupProvider = new GroupProvider();
+    private static MeterProvider meterProvider = new MeterProvider();
+    
+    @Override
+    public void onSessionInitiated(final ProviderContext session) {
+        DataProviderService flowSalService = session.<DataProviderService>getSALService(DataProviderService.class);
+        FRMActivator.flowProvider.setDataService(flowSalService);
+        SalFlowService rpcFlowSalService = session.<SalFlowService>getRpcService(SalFlowService.class);
+        FRMActivator.flowProvider.setSalFlowService(rpcFlowSalService);
+        FRMActivator.flowProvider.start();
+        DataProviderService groupSalService = session.<DataProviderService>getSALService(DataProviderService.class);
+        FRMActivator.groupProvider.setDataService(groupSalService);
+        SalGroupService rpcGroupSalService = session.<SalGroupService>getRpcService(SalGroupService.class);
+        FRMActivator.groupProvider.setSalGroupService(rpcGroupSalService);
+        FRMActivator.groupProvider.start();
+        DataProviderService meterSalService = session.<DataProviderService>getSALService(DataProviderService.class);
+        FRMActivator.meterProvider.setDataService(meterSalService);
+        SalMeterService rpcMeterSalService = session.<SalMeterService>getRpcService(SalMeterService.class);
+        FRMActivator.meterProvider.setSalMeterService(rpcMeterSalService);
+        FRMActivator.meterProvider.start();
+    }
+    
+    @Override
+    protected void stopImpl(final BundleContext context) {
+        try {
+            FRMActivator.flowProvider.close();
+            FRMActivator.groupProvider.close();
+            FRMActivator.meterProvider.close();
+        } catch (Throwable e) {
+            LOG.error("Unexpected error by stopping FRMActivator", e);
+            throw new RuntimeException(e);
+        }
+    }
+  }
\ No newline at end of file
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/FRMActivator.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/FRMActivator.xtend
deleted file mode 100644 (file)
index 8ec9d79..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.frm
-
-import org.opendaylight.controller.frm.flow.FlowProvider
-import org.opendaylight.controller.frm.group.GroupProvider
-import org.opendaylight.controller.frm.meter.MeterProvider
-import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
-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.osgi.framework.BundleContext
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService
-
-class FRMActivator extends AbstractBindingAwareProvider {
-
-    static var FlowProvider provider = new FlowProvider();
-    static var GroupProvider groupProvider = new GroupProvider();
-    static var MeterProvider meterProvider = new MeterProvider();
-
-    override onSessionInitiated(ProviderContext session) {
-        provider.dataService = session.getSALService(DataProviderService)
-        provider.salFlowService = session.getRpcService(SalFlowService);
-        provider.start();
-        
-        groupProvider.dataService = session.getSALService(DataProviderService)
-        groupProvider.salGroupService = session.getRpcService(SalGroupService)
-        groupProvider.start();
-        
-        meterProvider.dataService = session.getSALService(DataProviderService)
-        meterProvider.salMeterService = session.getRpcService(SalMeterService)
-        meterProvider.start();
-    }
-
-    override protected stopImpl(BundleContext context) {
-        provider.close();
-        groupProvider.close();
-        meterProvider.close();
-    }
-
-}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowChangeListener.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowChangeListener.java
new file mode 100644 (file)
index 0000000..df086c7
--- /dev/null
@@ -0,0 +1,120 @@
+/**
+ * Copyright (c) 2014 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.frm.flow;
+
+import org.opendaylight.controller.frm.AbstractChangeListener;
+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.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowTableRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ */
+public class FlowChangeListener extends AbstractChangeListener {
+
+    private final static Logger LOG = LoggerFactory.getLogger(FlowChangeListener.class);
+
+    private final SalFlowService salFlowService;
+
+    public SalFlowService getSalFlowService() {
+        return this.salFlowService;
+    }
+    
+    public FlowChangeListener(final SalFlowService manager) {
+        this.salFlowService = manager;
+    }
+
+    @Override
+    protected void validate() throws IllegalStateException {
+        FlowTransactionValidator.validate(this);
+    }
+
+    @Override
+    protected void remove(InstanceIdentifier<? extends DataObject> identifier, DataObject removeDataObj) {
+        if ((removeDataObj instanceof Flow)) {
+            
+            final Flow flow = ((Flow) removeDataObj);
+            final InstanceIdentifier<Table> tableInstanceId = identifier.<Table> firstIdentifierOf(Table.class);
+            final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node> firstIdentifierOf(Node.class);
+            final RemoveFlowInputBuilder builder = new RemoveFlowInputBuilder(flow);
+            
+            builder.setFlowRef(new FlowRef(identifier));
+            builder.setNode(new NodeRef(nodeInstanceId));
+            builder.setFlowTable(new FlowTableRef(tableInstanceId));
+            
+            Uri uri = new Uri(this.getTransactionId());
+            builder.setTransactionUri(uri);
+            this.salFlowService.removeFlow((RemoveFlowInput) builder.build());
+            LOG.debug("Transaction {} - Removed Flow has removed flow: {}", new Object[]{uri, removeDataObj});
+        }
+    }
+
+    @Override
+    protected void update(InstanceIdentifier<? extends DataObject> identifier, DataObject original, DataObject update) {
+        if (original instanceof Flow && update instanceof Flow) {
+            
+            final Flow originalFlow = ((Flow) original);
+            final Flow updatedFlow = ((Flow) update);
+            final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node>firstIdentifierOf(Node.class);
+            final UpdateFlowInputBuilder builder = new UpdateFlowInputBuilder();
+            
+            builder.setNode(new NodeRef(nodeInstanceId));
+            builder.setFlowRef(new FlowRef(identifier));
+            
+            Uri uri = new Uri(this.getTransactionId());
+            builder.setTransactionUri(uri);
+            
+            builder.setUpdatedFlow((UpdatedFlow) (new UpdatedFlowBuilder(updatedFlow)).build());
+            builder.setOriginalFlow((OriginalFlow) (new OriginalFlowBuilder(originalFlow)).build());
+            
+            this.salFlowService.updateFlow((UpdateFlowInput) builder.build());
+            LOG.debug("Transaction {} - Update Flow has updated flow {} with {}", new Object[]{uri, original, update});
+      }
+    }
+
+    @Override
+    protected void add(InstanceIdentifier<? extends DataObject> identifier, DataObject addDataObj) {
+        if ((addDataObj instanceof Flow)) {
+            
+            final Flow flow = ((Flow) addDataObj);
+            final InstanceIdentifier<Table> tableInstanceId = identifier.<Table> firstIdentifierOf(Table.class);
+            final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node> firstIdentifierOf(Node.class);
+            final AddFlowInputBuilder builder = new AddFlowInputBuilder(flow);
+            
+            builder.setNode(new NodeRef(nodeInstanceId));
+            builder.setFlowRef(new FlowRef(identifier));
+            builder.setFlowTable(new FlowTableRef(tableInstanceId));
+            
+            Uri uri = new Uri(this.getTransactionId());
+            builder.setTransactionUri(uri);
+            this.salFlowService.addFlow((AddFlowInput) builder.build());
+            LOG.debug("Transaction {} - Add Flow has added flow: {}", new Object[]{uri, addDataObj});
+        }
+    }
+}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowCommitHandler.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowCommitHandler.xtend
deleted file mode 100644 (file)
index 188bfcd..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2014 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.frm.flow
-
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.controller.md.sal.common.api.data.DataModification
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService
-
-class FlowCommitHandler implements DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> {
-       
-    @Property
-    val SalFlowService salFlowService;
-    
-    new(SalFlowService manager) {
-        _salFlowService = manager;
-    }
-    
-    override requestCommit(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
-        return new FlowTransaction(modification,salFlowService);
-    }
-    
-}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowProvider.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowProvider.java
new file mode 100644 (file)
index 0000000..afdd628
--- /dev/null
@@ -0,0 +1,70 @@
+/**
+ * Copyright (c) 2014 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.frm.flow;
+
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+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.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.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class FlowProvider implements AutoCloseable {
+
+    private final static Logger LOG = LoggerFactory.getLogger(FlowProvider.class);
+
+    private SalFlowService salFlowService;
+    private DataProviderService dataService;
+
+    /* DataChangeListener */
+    private FlowChangeListener flowDataChangeListener;
+    ListenerRegistration<DataChangeListener> flowDataChangeListenerRegistration;
+
+    public void start() {
+        /* Build Path */
+        InstanceIdentifierBuilder<Nodes> nodesBuilder = InstanceIdentifier.<Nodes> builder(Nodes.class);
+        InstanceIdentifierBuilder<Node> nodeChild = nodesBuilder.<Node> child(Node.class);
+        InstanceIdentifierBuilder<FlowCapableNode> augmentFlowCapNode = nodeChild.<FlowCapableNode> augmentation(FlowCapableNode.class);
+        InstanceIdentifierBuilder<Table> tableChild = augmentFlowCapNode.<Table> child(Table.class);
+        InstanceIdentifierBuilder<Flow> flowChild = tableChild.<Flow> child(Flow.class);
+        final InstanceIdentifier<? extends DataObject> flowDataObjectPath = flowChild.toInstance();
+        
+        /* DataChangeListener registration */
+        this.flowDataChangeListener = new FlowChangeListener(this.salFlowService);
+        this.flowDataChangeListenerRegistration = this.dataService.registerDataChangeListener(flowDataObjectPath, flowDataChangeListener);
+        LOG.info("Flow Config Provider started.");
+    }
+
+    protected DataModificationTransaction startChange() {
+        return this.dataService.beginTransaction();
+    }
+
+    @Override
+    public void close() throws Exception {
+        if(flowDataChangeListenerRegistration != null){
+            flowDataChangeListenerRegistration.close();
+        }
+    }
+
+    public void setDataService(final DataProviderService dataService) {
+        this.dataService = dataService;
+    }
+
+    public void setSalFlowService(final SalFlowService salFlowService) {
+        this.salFlowService = salFlowService;
+    }
+}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowProvider.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowProvider.xtend
deleted file mode 100644 (file)
index d2ed541..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2014 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.frm.flow
-
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
-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.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.inventory.rev130819.Nodes
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node
-import org.opendaylight.yangtools.concepts.Registration
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.slf4j.LoggerFactory
-
-class FlowProvider implements AutoCloseable {
-    
-    @Property
-    DataProviderService dataService;
-    
-    @Property
-    SalFlowService salFlowService;
-    
-    FlowCommitHandler commitHandler
-
-    Registration<DataCommitHandler<InstanceIdentifier<? extends DataObject>,DataObject>> commitHandlerRegistration;
-    
-    static val LOG = LoggerFactory.getLogger(FlowProvider);
-    
-    def void start() {
-        commitHandler = new FlowCommitHandler(salFlowService)
-        val InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(Nodes)
-            .child(Node)
-            .augmentation(FlowCapableNode)
-            .child(Table)
-            .child(Flow)
-            .toInstance();
-        commitHandlerRegistration = dataService.registerCommitHandler(path,commitHandler);
-        LOG.info("Flow Config Provider started.");
-    }
-
-    protected def startChange() {
-        return dataService.beginTransaction;
-    }
-    
-    override close() throws Exception {
-        throw new UnsupportedOperationException("TODO: auto-generated method stub")
-    }
-    
-}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowTransaction.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowTransaction.xtend
deleted file mode 100644 (file)
index 26846ad..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2014 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.frm.flow
-
-import org.opendaylight.controller.frm.AbstractTransaction
-import org.opendaylight.controller.md.sal.common.api.data.DataModification
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowTableRef
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlowBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlowBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowRef
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri
-
-class FlowTransaction extends AbstractTransaction {
-    
-    @Property
-    val SalFlowService salFlowService;   
-    
-    
-    new(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification,SalFlowService salFlowService) {
-        super(modification)        
-        _salFlowService = salFlowService;
-    }
-    
-    override remove(InstanceIdentifier<?> instanceId, DataObject obj) {
-        if(obj instanceof Flow) {
-            val flow = (obj as Flow)
-            val tableInstanceId = instanceId.firstIdentifierOf(Table);
-            val nodeInstanceId = instanceId.firstIdentifierOf(Node);
-            val builder = new RemoveFlowInputBuilder(flow);
-            builder.setFlowRef(new FlowRef(instanceId));            
-            builder.setNode(new NodeRef(nodeInstanceId));
-            builder.setFlowTable(new FlowTableRef(tableInstanceId));
-            builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
-            _salFlowService.removeFlow(builder.build());            
-        }
-    }
-    
-    override update(InstanceIdentifier<?> instanceId, DataObject originalObj, DataObject updatedObj) {
-        if(originalObj instanceof Flow && updatedObj instanceof Flow) {
-            val originalFlow = (originalObj as Flow)
-            val updatedFlow = (updatedObj as Flow)
-            val nodeInstanceId = instanceId.firstIdentifierOf(Node);
-            val builder = new UpdateFlowInputBuilder();
-            builder.setNode(new NodeRef(nodeInstanceId));
-            builder.setFlowRef(new FlowRef(instanceId));
-            val ufb = new UpdatedFlowBuilder(updatedFlow);
-            builder.setUpdatedFlow((ufb.build()));
-            builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
-            val ofb = new OriginalFlowBuilder(originalFlow);
-            builder.setOriginalFlow(ofb.build());      
-            _salFlowService.updateFlow(builder.build());
-           
-        }
-    }
-    
-    override add(InstanceIdentifier<?> instanceId, DataObject obj) {
-        if(obj instanceof Flow) {
-            val flow = (obj as Flow)
-            val tableInstanceId = instanceId.firstIdentifierOf(Table);
-            val nodeInstanceId = instanceId.firstIdentifierOf(Node);
-            val builder = new AddFlowInputBuilder(flow);
-            builder.setNode(new NodeRef(nodeInstanceId));
-            builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
-            builder.setFlowRef(new FlowRef(instanceId));
-            builder.setFlowTable(new FlowTableRef(tableInstanceId));
-            _salFlowService.addFlow(builder.build());            
-        }
-    }
-    
-    override validate() throws IllegalStateException {
-        FlowTransactionValidator.validate(this)
-    }  
-}
index 7c6f1ff..4ef93a5 100644 (file)
@@ -1,6 +1,6 @@
-/*
+/**
  * Copyright (c) 2014 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
@@ -9,8 +9,7 @@ package org.opendaylight.controller.frm.flow;
 
 public class FlowTransactionValidator {
 
-    public static void validate(FlowTransaction transaction) throws IllegalStateException {
+    public static void validate(FlowChangeListener transaction) throws IllegalStateException {
         // NOOP
     }
-
 }
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupChangeListener.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupChangeListener.java
new file mode 100644 (file)
index 0000000..1260f0e
--- /dev/null
@@ -0,0 +1,113 @@
+/**
+ * Copyright (c) 2014 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.frm.group;
+
+import org.opendaylight.controller.frm.AbstractChangeListener;
+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.group.service.rev130918.AddGroupInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.OriginalGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.OriginalGroupBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.UpdatedGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.UpdatedGroupBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ */
+public class GroupChangeListener extends AbstractChangeListener {
+
+    private final static Logger LOG = LoggerFactory.getLogger(GroupChangeListener.class);
+
+    private final SalGroupService salGroupService;
+
+    public SalGroupService getSalGroupService() {
+        return this.salGroupService;
+    }
+    
+    public GroupChangeListener(final SalGroupService manager) {
+        this.salGroupService = manager;
+    }
+
+    @Override
+    protected void validate() throws IllegalStateException {
+        GroupTransactionValidator.validate(this);
+    }
+
+    @Override
+    protected void remove(InstanceIdentifier<? extends DataObject> identifier, DataObject removeDataObj) {
+        if ((removeDataObj instanceof Group)) {
+            
+            final Group group = ((Group) removeDataObj);
+            final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node> firstIdentifierOf(Node.class);
+            final RemoveGroupInputBuilder builder = new RemoveGroupInputBuilder(group);
+            
+            builder.setNode(new NodeRef(nodeInstanceId));
+            builder.setGroupRef(new GroupRef(identifier));
+            
+            Uri uri = new Uri(this.getTransactionId());
+            builder.setTransactionUri(uri);
+            this.salGroupService.removeGroup((RemoveGroupInput) builder.build());
+            LOG.debug("Transaction {} - Remove Group has removed group: {}", new Object[]{uri, removeDataObj});
+        }
+    }
+
+    @Override
+    protected void update(InstanceIdentifier<? extends DataObject> identifier, DataObject original, DataObject update) {
+        if (original instanceof Group && update instanceof Group) {
+            
+            final Group originalGroup = ((Group) original);
+            final Group updatedGroup = ((Group) update);
+            final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node> firstIdentifierOf(Node.class);
+            final UpdateGroupInputBuilder builder = new UpdateGroupInputBuilder();
+            
+            builder.setNode(new NodeRef(nodeInstanceId));
+            builder.setGroupRef(new GroupRef(identifier));
+            
+            Uri uri = new Uri(this.getTransactionId());
+            builder.setTransactionUri(uri);
+            
+            builder.setUpdatedGroup((UpdatedGroup) (new UpdatedGroupBuilder(updatedGroup)).build());
+            builder.setOriginalGroup((OriginalGroup) (new OriginalGroupBuilder(originalGroup)).build());
+            
+            this.salGroupService.updateGroup((UpdateGroupInput) builder.build());
+            LOG.debug("Transaction {} - Update Group has updated group {} with group {}", new Object[]{uri, original, update});
+        }
+    }
+
+    @Override
+    protected void add(InstanceIdentifier<? extends DataObject> identifier, DataObject addDataObj) {
+        if ((addDataObj instanceof Group)) {
+            final Group group = ((Group) addDataObj);
+            final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node> firstIdentifierOf(Node.class);
+            final AddGroupInputBuilder builder = new AddGroupInputBuilder(group);
+            
+            builder.setNode(new NodeRef(nodeInstanceId));
+            builder.setGroupRef(new GroupRef(identifier));
+            
+            Uri uri = new Uri(this.getTransactionId());
+            builder.setTransactionUri(uri);
+            this.salGroupService.addGroup((AddGroupInput) builder.build());
+            LOG.debug("Transaction {} - Add Group has added group: {}", new Object[]{uri, addDataObj});
+        }
+    }
+}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupCommitHandler.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupCommitHandler.xtend
deleted file mode 100644 (file)
index b6d3851..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2014 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.frm.group
-
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.controller.md.sal.common.api.data.DataModification
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-
-class GroupCommitHandler implements DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> {
-       
-    @Property
-    val SalGroupService groupService;
-    
-    new(SalGroupService groupService) {
-        _groupService = groupService;
-    }
-    
-    override requestCommit(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
-        return new GroupTransaction(modification,groupService);
-    }
-    
-}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupProvider.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupProvider.java
new file mode 100644 (file)
index 0000000..14b1b6f
--- /dev/null
@@ -0,0 +1,67 @@
+/**
+ * Copyright (c) 2014 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.frm.group;
+
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+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.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class GroupProvider implements AutoCloseable {
+
+    private final static Logger LOG = LoggerFactory.getLogger(GroupProvider.class);
+
+    private SalGroupService salGroupService;
+    private DataProviderService dataService;
+
+    /* DataChangeListener */
+    private GroupChangeListener groupDataChangeListener;
+    ListenerRegistration<DataChangeListener> groupDataChangeListenerRegistration;
+
+    public void start() {
+        /* Build Path */
+        InstanceIdentifierBuilder<Nodes> nodesBuilder = InstanceIdentifier.<Nodes> builder(Nodes.class);
+        InstanceIdentifierBuilder<Node> nodeChild = nodesBuilder.<Node> child(Node.class);
+        InstanceIdentifierBuilder<FlowCapableNode> augmentFlowCapNode = nodeChild.<FlowCapableNode> augmentation(FlowCapableNode.class);
+        InstanceIdentifierBuilder<Group> groupChild = augmentFlowCapNode.<Group> child(Group.class);
+        final InstanceIdentifier<? extends DataObject> groupDataObjectPath = groupChild.toInstance();
+
+        /* DataChangeListener registration */
+        this.groupDataChangeListener = new GroupChangeListener(this.salGroupService);
+        this.groupDataChangeListenerRegistration = this.dataService.registerDataChangeListener(groupDataObjectPath, groupDataChangeListener);
+        LOG.info("Group Config Provider started.");
+    }
+    
+    protected DataModificationTransaction startChange() {
+        return this.dataService.beginTransaction();
+    }
+    
+    public void close() throws Exception {
+        if(groupDataChangeListenerRegistration != null){
+            groupDataChangeListenerRegistration.close();
+        }
+    }
+
+    public void setDataService(final DataProviderService dataService) {
+        this.dataService = dataService;
+    }
+
+    public void setSalGroupService(final SalGroupService salGroupService) {
+        this.salGroupService = salGroupService;
+    }
+}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupProvider.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupProvider.xtend
deleted file mode 100644 (file)
index 4ded8b6..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2014 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.frm.group
-
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode
-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.inventory.rev130819.Nodes
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node
-import org.opendaylight.yangtools.concepts.Registration
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.slf4j.LoggerFactory
-
-class GroupProvider implements AutoCloseable {
-    
-    @Property
-    DataProviderService dataService;
-    
-    @Property
-    SalGroupService salGroupService;
-    
-    GroupCommitHandler commitHandler
-
-    Registration<DataCommitHandler<InstanceIdentifier<? extends DataObject>,DataObject>> commitHandlerRegistration;
-    
-    static val LOG = LoggerFactory.getLogger(GroupProvider);
-    
-    def void start() {
-        commitHandler = new GroupCommitHandler(salGroupService)
-        val InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(Nodes)
-            .child(Node)
-            .augmentation(FlowCapableNode)
-            .child(Group)
-            .toInstance();
-        commitHandlerRegistration = dataService.registerCommitHandler(path,commitHandler);
-        LOG.info("Group Config Provider started.");
-    }
-
-    protected def startChange() {
-        return dataService.beginTransaction;
-    }
-    
-    override close() throws Exception {
-        throw new UnsupportedOperationException("TODO: auto-generated method stub")
-    }
-    
-}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupTransaction.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupTransaction.xtend
deleted file mode 100644 (file)
index e8d9982..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2014 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.frm.group
-
-import org.opendaylight.controller.frm.AbstractTransaction
-import org.opendaylight.controller.md.sal.common.api.data.DataModification
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.OriginalGroupBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.UpdatedGroupBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupRef
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri
-
-class GroupTransaction extends AbstractTransaction {
-    
-    @Property
-    val SalGroupService groupService;
-        
-    new(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification,SalGroupService groupService) {
-        super(modification)        
-        _groupService = groupService;
-    }
-    
-    override remove(InstanceIdentifier<?> instanceId, DataObject obj) {
-        if(obj instanceof Group) {
-            val group = (obj as Group)
-            val nodeInstanceId = instanceId.firstIdentifierOf(Node);
-            val builder = new RemoveGroupInputBuilder(group);
-            builder.setNode(new NodeRef(nodeInstanceId));
-            builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
-            builder.setGroupRef(new GroupRef(instanceId));
-            _groupService.removeGroup(builder.build());            
-        }
-    }
-    
-    override update(InstanceIdentifier<?> instanceId, DataObject originalObj, DataObject updatedObj) {
-        if(originalObj instanceof Group && updatedObj instanceof Group) {
-            val originalGroup = (originalObj as Group)
-            val updatedGroup = (updatedObj as Group)
-            val nodeInstanceId = instanceId.firstIdentifierOf(Node);
-            val builder = new UpdateGroupInputBuilder();
-            builder.setNode(new NodeRef(nodeInstanceId));
-            builder.setGroupRef(new GroupRef(instanceId));
-            val ufb = new UpdatedGroupBuilder(updatedGroup);
-            builder.setUpdatedGroup((ufb.build()));
-            builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
-            val ofb = new OriginalGroupBuilder(originalGroup);
-            builder.setOriginalGroup(ofb.build());      
-            _groupService.updateGroup(builder.build());
-           
-        }
-    }
-    
-    override add(InstanceIdentifier<?> instanceId, DataObject obj) {
-        if(obj instanceof Group) {
-            val group = (obj as Group)
-            val nodeInstanceId = instanceId.firstIdentifierOf(Node);
-            val builder = new AddGroupInputBuilder(group);
-            builder.setNode(new NodeRef(nodeInstanceId));
-            builder.setGroupRef(new GroupRef(instanceId));
-            builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
-            _groupService.addGroup(builder.build());            
-        }
-    }
-    
-    override validate() throws IllegalStateException {
-        GroupTransactionValidator.validate(this)
-    }  
-}
index 92baf7b..88eea0d 100644 (file)
@@ -1,4 +1,4 @@
-/*
+/**
  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
@@ -9,8 +9,7 @@ package org.opendaylight.controller.frm.group;
 
 public class GroupTransactionValidator {
 
-    public static void validate(GroupTransaction transaction) throws IllegalStateException {
+    public static void validate(GroupChangeListener transaction) throws IllegalStateException {
         // NOOP
     }
-
 }
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterChangeListener.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterChangeListener.java
new file mode 100644 (file)
index 0000000..839e556
--- /dev/null
@@ -0,0 +1,114 @@
+/**
+ * Copyright (c) 2014 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.frm.meter;
+
+import org.opendaylight.controller.frm.AbstractChangeListener;
+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.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.OriginalMeter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.OriginalMeterBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.UpdatedMeter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.UpdatedMeterBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.Meter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterRef;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ */
+public class MeterChangeListener extends AbstractChangeListener {
+
+    private final static Logger LOG = LoggerFactory.getLogger(MeterChangeListener.class);
+
+    private final SalMeterService salMeterService;
+
+    public SalMeterService getSalMeterService() {
+        return this.salMeterService;
+    }
+    
+    public MeterChangeListener(final SalMeterService manager) {
+        this.salMeterService = manager;
+    }
+
+    @Override
+    protected void validate() throws IllegalStateException {
+        MeterTransactionValidator.validate(this);
+    }
+
+    @Override
+    protected void remove(InstanceIdentifier<? extends DataObject> identifier, DataObject removeDataObj) {
+        if ((removeDataObj instanceof Meter)) {
+            
+            final Meter meter = ((Meter) removeDataObj);
+            final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node> firstIdentifierOf(Node.class);
+            final RemoveMeterInputBuilder builder = new RemoveMeterInputBuilder(meter);
+            
+            builder.setNode(new NodeRef(nodeInstanceId));
+            builder.setMeterRef(new MeterRef(identifier));
+            
+            Uri uri = new Uri(this.getTransactionId());
+            builder.setTransactionUri(uri);
+            this.salMeterService.removeMeter((RemoveMeterInput) builder.build());
+            LOG.debug("Transaction {} - Remove Meter has removed meter: {}", new Object[]{uri, removeDataObj});
+        }
+    }
+
+    @Override
+    protected void update(InstanceIdentifier<? extends DataObject> identifier, DataObject original, DataObject update) {
+        if (original instanceof Meter && update instanceof Meter) {
+            
+            final Meter originalMeter = ((Meter) original);
+            final Meter updatedMeter = ((Meter) update);
+            final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node> firstIdentifierOf(Node.class);
+            final UpdateMeterInputBuilder builder = new UpdateMeterInputBuilder();
+            
+            builder.setNode(new NodeRef(nodeInstanceId));
+            builder.setMeterRef(new MeterRef(identifier));
+            
+            Uri uri = new Uri(this.getTransactionId());
+            builder.setTransactionUri(uri);
+            
+            builder.setUpdatedMeter((UpdatedMeter) (new UpdatedMeterBuilder(updatedMeter)).build());
+            builder.setOriginalMeter((OriginalMeter) (new OriginalMeterBuilder(originalMeter)).build());
+            
+            this.salMeterService.updateMeter((UpdateMeterInput) builder.build());
+            LOG.debug("Transaction {} - Update Meter has updated meter {} with {}", new Object[]{uri, original, update});
+        }
+    }
+
+    @Override
+    protected void add(InstanceIdentifier<? extends DataObject> identifier, DataObject addDataObj) {
+        if ((addDataObj instanceof Meter)) {
+            
+            final Meter meter = ((Meter) addDataObj);
+            final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node> firstIdentifierOf(Node.class);
+            final AddMeterInputBuilder builder = new AddMeterInputBuilder(meter);
+            
+            builder.setNode(new NodeRef(nodeInstanceId));
+            builder.setMeterRef(new MeterRef(identifier));
+            
+            Uri uri = new Uri(this.getTransactionId());
+            builder.setTransactionUri(uri);
+            this.salMeterService.addMeter((AddMeterInput) builder.build());
+            LOG.debug("Transaction {} - Add Meter has added meter: {}", new Object[]{uri, addDataObj});
+        }
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterCommitHandler.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterCommitHandler.xtend
deleted file mode 100644 (file)
index d5292f0..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2014 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.frm.meter
-
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.controller.md.sal.common.api.data.DataModification
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-
-class FlowCommitHandler implements DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> {
-       
-    @Property
-    val SalMeterService salMeterService;
-    
-    new(SalMeterService manager) {
-        _salMeterService = manager;
-    }
-    
-    override requestCommit(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
-        return new MeterTransaction(modification,salMeterService);
-    }
-    
-}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterProvider.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterProvider.java
new file mode 100644 (file)
index 0000000..620801f
--- /dev/null
@@ -0,0 +1,67 @@
+/**
+ * Copyright (c) 2014 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.frm.meter;
+
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+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.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MeterProvider implements AutoCloseable {
+
+    private final static Logger LOG = LoggerFactory.getLogger(MeterProvider.class);
+
+    private DataProviderService dataService;
+    private SalMeterService salMeterService;
+
+    /* DataChangeListener */
+    private MeterChangeListener meterDataChangeListener;
+    ListenerRegistration<DataChangeListener> meterDataChangeListenerRegistration;
+
+    public void start() {
+        /* Build Path */
+        InstanceIdentifierBuilder<Nodes> nodesBuilder = InstanceIdentifier.<Nodes> builder(Nodes.class);
+        InstanceIdentifierBuilder<Node> nodeChild = nodesBuilder.<Node> child(Node.class);
+        InstanceIdentifierBuilder<FlowCapableNode> augmentFlowCapNode = nodeChild.<FlowCapableNode> augmentation(FlowCapableNode.class);
+        InstanceIdentifierBuilder<Meter> meterChild = augmentFlowCapNode.<Meter> child(Meter.class);
+        final InstanceIdentifier<? extends DataObject> meterDataObjectPath = meterChild.toInstance();
+
+        /* DataChangeListener registration */
+        this.meterDataChangeListener = new MeterChangeListener(this.salMeterService);
+        this.meterDataChangeListenerRegistration = this.dataService.registerDataChangeListener(meterDataObjectPath, meterDataChangeListener);
+        LOG.info("Meter Config Provider started.");
+    }
+    
+    protected DataModificationTransaction startChange() {
+        return this.dataService.beginTransaction();
+    }
+
+    public void close() throws Exception {
+        if(meterDataChangeListenerRegistration != null){
+            meterDataChangeListenerRegistration.close();
+        }
+    }
+
+    public void setDataService(final DataProviderService dataService) {
+        this.dataService = dataService;
+    }
+
+    public void setSalMeterService(final SalMeterService salMeterService) {
+        this.salMeterService = salMeterService;
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterProvider.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterProvider.xtend
deleted file mode 100644 (file)
index 323da57..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2014 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.frm.meter
-
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
-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.inventory.rev130819.Nodes
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService
-import org.opendaylight.yangtools.concepts.Registration
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.slf4j.LoggerFactory
-
-class MeterProvider implements AutoCloseable {
-    
-    @Property
-    DataProviderService dataService;
-    
-    @Property
-    SalMeterService salMeterService;
-    
-    FlowCommitHandler commitHandler
-
-    Registration<DataCommitHandler<InstanceIdentifier<? extends DataObject>,DataObject>> commitHandlerRegistration;
-    
-    static val LOG = LoggerFactory.getLogger(MeterProvider);
-    
-    def void start() {
-        commitHandler = new FlowCommitHandler(salMeterService)
-        val InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(Nodes)
-            .child(Node)
-            .augmentation(FlowCapableNode)
-            .child(Meter)
-            .toInstance();
-        commitHandlerRegistration = dataService.registerCommitHandler(path,commitHandler);
-        LOG.info("Meter Config Provider started.");
-    }
-
-    protected def startChange() {
-        return dataService.beginTransaction;
-    }
-    
-    override close() throws Exception {
-        throw new UnsupportedOperationException("TODO: auto-generated method stub")
-    }
-    
-}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterTransaction.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterTransaction.xtend
deleted file mode 100644 (file)
index 491fa08..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2014 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.frm.meter
-
-import org.opendaylight.controller.frm.AbstractTransaction
-import org.opendaylight.controller.md.sal.common.api.data.DataModification
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.OriginalMeterBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.UpdatedMeterBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.Meter
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterRef
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri
-
-class MeterTransaction extends AbstractTransaction {
-    
-    @Property
-    val SalMeterService salMeterService;
-        
-    new(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification,SalMeterService salMeterService) {
-        super(modification)    
-        _salMeterService = salMeterService;
-    }
-    
-    override remove(InstanceIdentifier<?> instanceId, DataObject obj) {
-        if(obj instanceof Meter) {
-            val meter = (obj as Meter)
-            val nodeInstanceId = instanceId.firstIdentifierOf(Node);
-            val builder = new RemoveMeterInputBuilder(meter);
-            builder.setNode(new NodeRef(nodeInstanceId));
-            builder.setMeterRef(new MeterRef(instanceId));
-            builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
-            _salMeterService.removeMeter(builder.build());            
-        }
-    }
-    
-    override update(InstanceIdentifier<?> instanceId, DataObject originalObj, DataObject updatedObj) {
-        if(originalObj instanceof Meter && updatedObj instanceof Meter) {
-            val originalMeter = (originalObj as Meter)
-            val updatedMeter = (updatedObj as Meter)
-            val nodeInstanceId = instanceId.firstIdentifierOf(Node);
-            val builder = new UpdateMeterInputBuilder();
-            builder.setNode(new NodeRef(nodeInstanceId));
-            builder.setMeterRef(new MeterRef(instanceId));
-            val ufb = new UpdatedMeterBuilder(updatedMeter);
-            builder.setUpdatedMeter((ufb.build()));
-            builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
-            val ofb = new OriginalMeterBuilder(originalMeter);
-            builder.setOriginalMeter(ofb.build());      
-            _salMeterService.updateMeter(builder.build());
-           
-        }
-    }
-    
-    override add(InstanceIdentifier<?> instanceId, DataObject obj) {
-        if(obj instanceof Meter) {
-            val meter = (obj as Meter)
-            val nodeInstanceId = instanceId.firstIdentifierOf(Node);
-            val builder = new AddMeterInputBuilder(meter);
-            builder.setNode(new NodeRef(nodeInstanceId));
-            builder.setMeterRef(new MeterRef(instanceId));
-            builder.setTransactionUri(new Uri(modification.getIdentifier() as String));
-            _salMeterService.addMeter(builder.build());            
-        }
-    }
-    
-    override validate() throws IllegalStateException {
-        MeterTransactionValidator.validate(this)
-    }  
-}
index b16739c..c8fba23 100644 (file)
@@ -1,4 +1,4 @@
-/*
+/**
  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
@@ -9,8 +9,7 @@ package org.opendaylight.controller.frm.meter;
 
 public class MeterTransactionValidator {
 
-    public static void validate(MeterTransaction transaction) throws IllegalStateException {
+    public static void validate(MeterChangeListener transaction) throws IllegalStateException {
         // NOOP
     }
-
 }
index 40a7903..1706996 100644 (file)
       <groupId>com.google.guava</groupId>
       <artifactId>guava</artifactId>
     </dependency>
-    <dependency>
-      <groupId>org.eclipse.xtend</groupId>
-      <artifactId>org.eclipse.xtend.lib</artifactId>
-    </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal-binding-api</artifactId>
           </instructions>
         </configuration>
       </plugin>
-      <plugin>
-        <groupId>org.eclipse.xtend</groupId>
-        <artifactId>xtend-maven-plugin</artifactId>
-      </plugin>
     </plugins>
   </build>
   <scm>
diff --git a/opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/FlowCapableInventoryProvider.java b/opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/FlowCapableInventoryProvider.java
new file mode 100644 (file)
index 0000000..7e4190f
--- /dev/null
@@ -0,0 +1,67 @@
+/**
+ * Copyright (c) 2014 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.md.inventory.manager;
+
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.yang.binding.NotificationListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class FlowCapableInventoryProvider implements AutoCloseable {
+
+    private final static Logger LOG = LoggerFactory.getLogger(FlowCapableInventoryProvider.class);
+
+    private DataProviderService dataService;
+    private NotificationProviderService notificationService;
+    private Registration<NotificationListener> listenerRegistration;
+    private final NodeChangeCommiter changeCommiter = new NodeChangeCommiter(FlowCapableInventoryProvider.this);
+
+    public void start() {
+        this.listenerRegistration = this.notificationService.registerNotificationListener(this.changeCommiter);
+        LOG.info("Flow Capable Inventory Provider started.");
+    }
+
+    protected DataModificationTransaction startChange() {
+        DataProviderService _dataService = this.dataService;
+        return _dataService.beginTransaction();
+    }
+
+    @Override
+    public void close() {
+        try {
+            LOG.info("Flow Capable Inventory Provider stopped.");
+            if (this.listenerRegistration != null) {
+                this.listenerRegistration.close();
+            }
+        } catch (Exception e) {
+            String errMsg = "Error by stop Flow Capable Inventory Provider.";
+            LOG.error(errMsg, e);
+            throw new RuntimeException(errMsg, e);
+        }
+    }
+
+    public DataProviderService getDataService() {
+        return this.dataService;
+    }
+
+    public void setDataService(final DataProviderService dataService) {
+        this.dataService = dataService;
+    }
+
+    public NotificationProviderService getNotificationService() {
+        return this.notificationService;
+    }
+
+    public void setNotificationService(
+            final NotificationProviderService notificationService) {
+        this.notificationService = notificationService;
+    }
+}
diff --git a/opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/FlowCapableInventoryProvider.xtend b/opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/FlowCapableInventoryProvider.xtend
deleted file mode 100644 (file)
index ec8da86..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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.md.inventory.manager
-
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryListener
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRemoved
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemoved
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdated
-import org.opendaylight.controller.sal.binding.api.NotificationProviderService
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
-import org.opendaylight.yangtools.concepts.Registration
-import org.opendaylight.yangtools.yang.binding.NotificationListener
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnectorUpdated
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeUpdated
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey
-import static extension org.opendaylight.controller.md.inventory.manager.InventoryMapping.*
-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.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
-import org.slf4j.LoggerFactory
-
-class FlowCapableInventoryProvider implements AutoCloseable {
-
-
-    static val LOG = LoggerFactory.getLogger(FlowCapableInventoryProvider);
-
-    @Property
-    DataProviderService dataService;
-
-    @Property
-    NotificationProviderService notificationService;
-    val NodeChangeCommiter changeCommiter = new NodeChangeCommiter(this);
-
-    Registration<NotificationListener> listenerRegistration
-
-    def void start() {
-        listenerRegistration = notificationService.registerNotificationListener(changeCommiter);
-        LOG.info("Flow Capable Inventory Provider started.");
-        
-    }
-
-    protected def startChange() {
-        return dataService.beginTransaction;
-    }
-
-    override close() {
-       LOG.info("Flow Capable Inventory Provider stopped.");
-        listenerRegistration?.close();
-    }
-    
-}
\ No newline at end of file
diff --git a/opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/InventoryActivator.java b/opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/InventoryActivator.java
new file mode 100644 (file)
index 0000000..6c06088
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * Copyright (c) 2014 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.md.inventory.manager;
+
+import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.osgi.framework.BundleContext;
+
+public class InventoryActivator extends AbstractBindingAwareProvider {
+
+    private static FlowCapableInventoryProvider provider = new FlowCapableInventoryProvider();
+
+    @Override
+    public void onSessionInitiated(final ProviderContext session) {
+        DataProviderService salDataService = session.<DataProviderService> getSALService(DataProviderService.class);
+        NotificationProviderService salNotifiService =
+                session.<NotificationProviderService> getSALService(NotificationProviderService.class);
+        InventoryActivator.provider.setDataService(salDataService);
+        InventoryActivator.provider.setNotificationService(salNotifiService);
+        InventoryActivator.provider.start();
+    }
+
+    @Override
+    protected void stopImpl(final BundleContext context) {
+        InventoryActivator.provider.close();
+    }
+}
diff --git a/opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/InventoryActivator.xtend b/opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/InventoryActivator.xtend
deleted file mode 100644 (file)
index 5d76924..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.md.inventory.manager
-
-import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext
-import org.osgi.framework.BundleContext
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
-import org.opendaylight.controller.sal.binding.api.NotificationProviderService
-
-class InventoryActivator extends AbstractBindingAwareProvider {
-
-    static var FlowCapableInventoryProvider provider = new FlowCapableInventoryProvider();
-
-    override onSessionInitiated(ProviderContext session) {
-        provider.dataService = session.getSALService(DataProviderService)
-        provider.notificationService = session.getSALService(NotificationProviderService)
-        provider.start();
-    }
-
-    override protected stopImpl(BundleContext context) {
-        provider.close();
-    }
-
-}
diff --git a/opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/InventoryMapping.java b/opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/InventoryMapping.java
new file mode 100644 (file)
index 0000000..928ae76
--- /dev/null
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2014 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.md.inventory.manager;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnectorBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowNodeConnector;
+
+public class InventoryMapping {
+
+    public static FlowCapableNodeConnector toInventoryAugment(final FlowNodeConnector updated) {
+        if ((updated instanceof FlowCapableNodeConnector)) {
+            return ((FlowCapableNodeConnector) updated);
+        }
+        final FlowCapableNodeConnectorBuilder builder = new FlowCapableNodeConnectorBuilder();
+        builder.setAdvertisedFeatures(updated.getAdvertisedFeatures());
+        builder.setConfiguration(updated.getConfiguration());
+        builder.setCurrentFeature(updated.getCurrentFeature());
+        builder.setCurrentSpeed(updated.getCurrentSpeed());
+        builder.setHardwareAddress(updated.getHardwareAddress());
+        builder.setMaximumSpeed(updated.getMaximumSpeed());
+        builder.setName(updated.getName());
+        builder.setPeerFeatures(updated.getPeerFeatures());
+        builder.setPortNumber(updated.getPortNumber());
+        builder.setState(updated.getState());
+        builder.setSupported(updated.getSupported());
+        return builder.build();
+    }
+
+    public static FlowCapableNode toInventoryAugment(final FlowNode source) {
+        if ((source instanceof FlowCapableNode)) {
+            return ((FlowCapableNode) source);
+        }
+        return (new FlowCapableNodeBuilder(source)).build();
+    }
+}
diff --git a/opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/InventoryMapping.xtend b/opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/InventoryMapping.xtend
deleted file mode 100644 (file)
index 6f1ef5e..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.md.inventory.manager
-
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowNodeConnector
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnectorBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowNode
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder
-
-class InventoryMapping {
-
-    static def FlowCapableNodeConnector toInventoryAugment(FlowNodeConnector updated) {
-        if (updated instanceof FlowCapableNodeConnector) {
-            return updated as FlowCapableNodeConnector;
-        }
-        val it = new FlowCapableNodeConnectorBuilder();
-        advertisedFeatures = updated.advertisedFeatures
-        configuration = updated.configuration
-        currentFeature = updated.currentFeature
-        currentSpeed = updated.currentSpeed
-        hardwareAddress = updated.hardwareAddress
-        maximumSpeed = updated.maximumSpeed
-        name = updated.name
-        peerFeatures = updated.peerFeatures
-        portNumber = updated.portNumber
-        state = updated.state
-        supported = updated.supported
-        return build();
-    }
-
-    static def FlowCapableNode toInventoryAugment(FlowNode source) {
-        if (source instanceof FlowCapableNode) {
-            return source as FlowCapableNode;
-        }
-        val it = new FlowCapableNodeBuilder(source);
-        return build();
-    }
-
-}
index ebb3de7..03cdf97 100644 (file)
@@ -20,7 +20,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeCon
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRemoved;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated;
-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.NodeRemoved;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdated;
@@ -39,8 +38,8 @@ import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Objects;
 
-@SuppressWarnings("all")
 public class NodeChangeCommiter implements OpendaylightInventoryListener {
+
     private final static Logger LOG = LoggerFactory.getLogger(NodeChangeCommiter.class);
 
     private final FlowCapableInventoryProvider manager;
@@ -75,7 +74,7 @@ public class NodeChangeCommiter implements OpendaylightInventoryListener {
         final NodeConnectorRef ref = connector.getNodeConnectorRef();
         final FlowCapableNodeConnectorUpdated flowConnector = connector
                 .getAugmentation(FlowCapableNodeConnectorUpdated.class);
-        final DataModificationTransaction it = this.getManager().startChange();
+        final DataModificationTransaction it = this.manager.startChange();
         final NodeConnectorBuilder data = new NodeConnectorBuilder(connector);
         NodeConnectorId id = connector.getId();
         NodeConnectorKey nodeConnectorKey = new NodeConnectorKey(id);
@@ -86,12 +85,9 @@ public class NodeChangeCommiter implements OpendaylightInventoryListener {
             data.addAugmentation(FlowCapableNodeConnector.class, augment);
         }
         InstanceIdentifier<? extends Object> value = ref.getValue();
-        String string = value.toString();
-        String plus = ("updating node connector : " + string);
-        NodeChangeCommiter.LOG.debug(plus);
-        InstanceIdentifier<? extends Object> value1 = ref.getValue();
+        NodeChangeCommiter.LOG.debug("updating node connector : {}.", value);
         NodeConnector build = data.build();
-        it.putOperationalData((value1), build);
+        it.putOperationalData((value), build);
         Future<RpcResult<TransactionStatus>> commitResult = it.commit();
         try {
             commitResult.get();
@@ -105,14 +101,9 @@ public class NodeChangeCommiter implements OpendaylightInventoryListener {
     public synchronized void onNodeRemoved(final NodeRemoved node) {
 
         final NodeRef ref = node.getNodeRef();
-        FlowCapableInventoryProvider manager = this.getManager();
-        final DataModificationTransaction it = manager.startChange();
-        InstanceIdentifier<? extends Object> value = ref.getValue();
-        String string = value.toString();
-        String plus = ("removing node : " + string);
-        NodeChangeCommiter.LOG.debug(plus);
-        InstanceIdentifier<? extends Object> value1 = ref.getValue();
-        it.removeOperationalData((value1));
+        final DataModificationTransaction it = this.manager.startChange();
+        NodeChangeCommiter.LOG.debug("removing node : {}", ref.getValue());
+        it.removeOperationalData((ref.getValue()));
         Future<RpcResult<TransactionStatus>> commitResult = it.commit();
         try {
             commitResult.get();
@@ -127,19 +118,15 @@ public class NodeChangeCommiter implements OpendaylightInventoryListener {
         final NodeRef ref = node.getNodeRef();
         final FlowCapableNodeUpdated flowNode = node
                 .<FlowCapableNodeUpdated> getAugmentation(FlowCapableNodeUpdated.class);
-        FlowCapableInventoryProvider manager = this.getManager();
-        final DataModificationTransaction it = manager.startChange();
-        NodeBuilder nodeBuilder = new NodeBuilder(node);
-        final NodeBuilder data = nodeBuilder;
-        NodeId id = node.getId();
-        NodeKey nodeKey = new NodeKey(id);
-        data.setKey(nodeKey);
+        final DataModificationTransaction it = this.manager.startChange();
+        final NodeBuilder nodeBuilder = new NodeBuilder(node);
+        nodeBuilder.setKey(new NodeKey(node.getId()));
         boolean equals = Objects.equal(flowNode, null);
         if (equals) {
             return;
         }
         final FlowCapableNode augment = InventoryMapping.toInventoryAugment(flowNode);
-        data.addAugmentation(FlowCapableNode.class, augment);
+        nodeBuilder.addAugmentation(FlowCapableNode.class, augment);
         InstanceIdentifier<? extends Object> value = ref.getValue();
         InstanceIdentifierBuilder<Node> builder = InstanceIdentifier.<Node> builder(((InstanceIdentifier<Node>) value));
         InstanceIdentifierBuilder<FlowCapableNode> augmentation = builder
index 6bd6e6a..cc9c6eb 100644 (file)
@@ -82,7 +82,7 @@ public class AbstractForwardedTransaction<T extends AsyncTransaction<org.openday
                 try {
                     final DataObject dataObject = normalizedNode.isPresent() ? codec.toBinding(path,
                             normalizedNode.get()) : null;
-                    if(dataObject != null) {
+                    if (dataObject != null) {
                         updateCache(store, path, dataObject);
                     }
                     return Optional.fromNullable(dataObject);
@@ -109,6 +109,27 @@ public class AbstractForwardedTransaction<T extends AsyncTransaction<org.openday
                 .toNormalizedNode(path, data);
 
         org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalizedPath = normalized.getKey();
+        ensureParentsByMerge(writeTransaction, store, normalized.getKey(), path);
+        LOG.debug("Tx: {} : Putting data {}",getDelegate().getIdentifier(),normalized.getKey());
+        writeTransaction.put(store, normalized.getKey(), normalized.getValue());
+    }
+
+    protected void doMergeWithEnsureParents(final DOMDataReadWriteTransaction writeTransaction,
+            final LogicalDatastoreType store, final InstanceIdentifier<?> path, final DataObject data) {
+        invalidateCache(store, path);
+        final Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>> normalized = codec
+                .toNormalizedNode(path, data);
+
+        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalizedPath = normalized.getKey();
+        ensureParentsByMerge(writeTransaction, store, normalized.getKey(), path);
+        LOG.debug("Tx: {} : Merge data {}",getDelegate().getIdentifier(),normalized.getKey());
+        writeTransaction.merge(store, normalized.getKey(), normalized.getValue());
+    }
+
+    private void ensureParentsByMerge(final DOMDataReadWriteTransaction writeTransaction,
+            final LogicalDatastoreType store,
+            final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalizedPath,
+            final InstanceIdentifier<?> path) {
         List<PathArgument> currentArguments = new ArrayList<>();
         DataNormalizationOperation<?> currentOp = codec.getDataNormalizer().getRootOperation();
         Iterator<PathArgument> iterator = normalizedPath.getPath().iterator();
@@ -135,8 +156,6 @@ public class AbstractForwardedTransaction<T extends AsyncTransaction<org.openday
                 writeTransaction.merge(store, currentPath, currentOp.createDefault(currentArg));
             }
         }
-        //LOG .info("Tx: {} : Putting data {}",getDelegate().getIdentifier(),normalized.getKey());
-        writeTransaction.put(store, normalized.getKey(), normalized.getValue());
     }
 
     protected void doMerge(final DOMDataWriteTransaction writeTransaction, final LogicalDatastoreType store,
index ab0dc6e..ddc79ae 100644 (file)
@@ -195,6 +195,7 @@ public class ForwardedBackwardsCompatibleDataBroker extends AbstractForwardedDat
     private class ForwardedBackwardsCompatibleTransacion extends
             AbstractForwardedTransaction<DOMDataReadWriteTransaction> implements DataModificationTransaction {
 
+        private final ListenerRegistry<DataTransactionListener> listeners = ListenerRegistry.create();
         private final Map<InstanceIdentifier<? extends DataObject>, DataObject> updated = new HashMap<>();
         private final Map<InstanceIdentifier<? extends DataObject>, DataObject> created = new HashMap<>();
         private final Set<InstanceIdentifier<? extends DataObject>> removed = new HashSet<>();
@@ -218,13 +219,17 @@ public class ForwardedBackwardsCompatibleDataBroker extends AbstractForwardedDat
 
         @Override
         public void putOperationalData(final InstanceIdentifier<? extends DataObject> path, final DataObject data) {
-            posponedRemovedOperational.remove(path);
-            doPutWithEnsureParents(getDelegate(), LogicalDatastoreType.OPERATIONAL, path, data);
+            boolean previouslyRemoved = posponedRemovedOperational.remove(path);
+            if(previouslyRemoved) {
+                doPutWithEnsureParents(getDelegate(), LogicalDatastoreType.OPERATIONAL, path, data);
+            } else {
+                doMergeWithEnsureParents(getDelegate(), LogicalDatastoreType.OPERATIONAL, path, data);
+            }
         }
 
         @Override
         public void putConfigurationData(final InstanceIdentifier<? extends DataObject> path, final DataObject data) {
-            posponedRemovedConfiguration.remove(path);
+            boolean previouslyRemoved = posponedRemovedConfiguration.remove(path);
             DataObject originalObj = readConfigurationData(path);
             if (originalObj != null) {
                 original.put(path, originalObj);
@@ -233,7 +238,11 @@ public class ForwardedBackwardsCompatibleDataBroker extends AbstractForwardedDat
                 created.put(path, data);
             }
             updated.put(path, data);
-            doPutWithEnsureParents(getDelegate(), LogicalDatastoreType.CONFIGURATION, path, data);
+            if(previouslyRemoved) {
+                doPutWithEnsureParents(getDelegate(), LogicalDatastoreType.CONFIGURATION, path, data);
+            } else {
+                doMergeWithEnsureParents(getDelegate(), LogicalDatastoreType.CONFIGURATION, path, data);
+            }
         }
 
         @Override
@@ -314,6 +323,14 @@ public class ForwardedBackwardsCompatibleDataBroker extends AbstractForwardedDat
         private void changeStatus(final TransactionStatus status) {
             LOG.trace("Transaction {} changed status to {}", getIdentifier(), status);
             this.status = status;
+
+            for(ListenerRegistration<DataTransactionListener> listener : listeners) {
+                try {
+                    listener.getInstance().onStatusUpdated(this, status);
+                } catch (Exception e) {
+                    LOG.error("Error during invoking transaction listener {}",listener.getInstance(),e);
+                }
+            }
         }
 
         @Override
@@ -327,10 +344,10 @@ public class ForwardedBackwardsCompatibleDataBroker extends AbstractForwardedDat
                 doDelete(getDelegate(), LogicalDatastoreType.OPERATIONAL, path);
             }
 
-            final ListenableFuture<RpcResult<TransactionStatus>> f = ForwardedBackwardsCompatibleDataBroker.this.commit(this);
-
             changeStatus(TransactionStatus.SUBMITED);
 
+            final ListenableFuture<RpcResult<TransactionStatus>> f = ForwardedBackwardsCompatibleDataBroker.this.commit(this);
+
             Futures.addCallback(f, new FutureCallback<RpcResult<TransactionStatus>>() {
                 @Override
                 public void onSuccess(final RpcResult<TransactionStatus> result) {
@@ -349,7 +366,7 @@ public class ForwardedBackwardsCompatibleDataBroker extends AbstractForwardedDat
 
         @Override
         public ListenerRegistration<DataTransactionListener> registerListener(final DataTransactionListener listener) {
-            throw new UnsupportedOperationException();
+            return listeners.register(listener);
         }
 
     }
index ac26445..4141bba 100644 (file)
@@ -33,6 +33,8 @@ public class SingletonHolder {
 
     public static final int CORE_NOTIFICATION_THREADS = 4;
     public static final int MAX_NOTIFICATION_THREADS = 32;
+    // block caller thread after MAX_NOTIFICATION_THREADS + MAX_NOTIFICATION_QUEUE_SIZE pending notifications
+    public static final int MAX_NOTIFICATION_QUEUE_SIZE = 10;
     public static final int NOTIFICATION_THREAD_LIFE = 15;
 
     private static ListeningExecutorService NOTIFICATION_EXECUTOR = null;
@@ -47,19 +49,15 @@ public class SingletonHolder {
     public static synchronized final ListeningExecutorService getDefaultNotificationExecutor() {
 
         if (NOTIFICATION_EXECUTOR == null) {
-            // Overriding the queue since we need an unbounded queue
-            // and threadpoolexecutor would not create new threads if the queue is not full
-            BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>() {
+            // Overriding the queue:
+            // ThreadPoolExecutor would not create new threads if the queue is not full, thus adding
+            // occurs in RejectedExecutionHandler.
+            // This impl saturates threadpool first, then queue. When both are full caller will get blocked.
+            BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>(MAX_NOTIFICATION_QUEUE_SIZE) {
                 @Override
                 public boolean offer(Runnable r) {
-                    if (size() <= 1) {
-                        // if the queue is empty (or has just 1), no need to rampup the threads
-                        return super.offer(r);
-                    } else {
-                        // if the queue is not empty, force the queue to return false.
-                        // threadpoolexecutor will spawn a new thread if the queue.offer returns false.
-                        return false;
-                    }
+                    // ThreadPoolExecutor will spawn a new thread after core size is reached only if the queue.offer returns false.
+                    return false;
                 }
             };
 
@@ -74,7 +72,8 @@ public class SingletonHolder {
                             try {
                                 executor.getQueue().put(r);
                             } catch (InterruptedException e) {
-                                e.printStackTrace();
+                                Thread.currentThread().interrupt();// set interrupt flag after clearing
+                                throw new IllegalStateException(e);
                             }
                         }
                     });
diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/codegen/impl/SingletonHolderTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/codegen/impl/SingletonHolderTest.java
new file mode 100644 (file)
index 0000000..0e4c5cc
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2014 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.sal.binding.codegen.impl;
+
+import com.google.common.util.concurrent.ListeningExecutorService;
+import java.lang.reflect.Field;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Ignore
+public class SingletonHolderTest {
+    private static final Logger logger = LoggerFactory.getLogger(SingletonHolderTest.class);
+
+    @Test
+    public void testNotificationExecutor() throws Exception {
+        ListeningExecutorService executor = SingletonHolder.getDefaultNotificationExecutor();
+        ThreadPoolExecutor tpExecutor = (ThreadPoolExecutor) setAccessible(executor.getClass().getDeclaredField("delegate")).get(executor);
+        BlockingQueue<Runnable> queue = tpExecutor.getQueue();
+
+        for (int idx = 0; idx < 100; idx++) {
+            final int idx2 = idx;
+            logger.info("Adding {}\t{}\t{}", idx, queue.size(), tpExecutor.getActiveCount());
+            executor.execute(new Runnable() {
+
+                @Override
+                public void run() {
+                    logger.info("in  {}", idx2);
+                    try {
+                        Thread.sleep(1000);
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+                    logger.info("out {}", idx2);
+                }
+            });
+        }
+        executor.shutdown();
+        executor.awaitTermination(10, TimeUnit.SECONDS);
+    }
+
+    private static Field setAccessible(Field field) {
+        field.setAccessible(true);
+        return field;
+    }
+}
index 21fa207..d1354f8 100644 (file)
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-binding</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal-binding-broker-impl</artifactId>
       <type>test-jar</type>
       <scope>test</scope>
     </dependency>
-    <dependency>
-    <groupId>org.opendaylight.yangtools</groupId>
-    <artifactId>yang-binding</artifactId>
-    </dependency>
     <dependency>
       <groupId>org.opendaylight.controller.model</groupId>
       <artifactId>model-flow-management</artifactId>
   </dependencies>
   <build>
     <plugins>
-    <plugin>
-        <groupId>org.opendaylight.yangtools</groupId>
-        <artifactId>yang-maven-plugin</artifactId>
-        <executions>
-          <execution>
-            <goals>
-              <goal>generate-sources</goal>
-            </goals>
-            <configuration>
-              <codeGenerators>
-                <generator>
-                  <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
-                  <outputBaseDir>${salGeneratorPath}</outputBaseDir>
-                </generator>
-              </codeGenerators>
-              <inspectDependencies>true</inspectDependencies>
-            </configuration>
-          </execution>
-        </executions>
-    </plugin>
       <plugin>
         <groupId>org.jacoco</groupId>
         <artifactId>jacoco-maven-plugin</artifactId>
           </execution>
         </executions>
       </plugin>
+      <plugin>
+        <groupId>org.opendaylight.yangtools</groupId>
+        <artifactId>yang-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>generate-sources</goal>
+            </goals>
+            <configuration>
+              <codeGenerators>
+                <generator>
+                  <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
+                  <outputBaseDir>${salGeneratorPath}</outputBaseDir>
+                </generator>
+              </codeGenerators>
+              <inspectDependencies>true</inspectDependencies>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
     </plugins>
   </build>
   <scm>
index a91799d..19235d2 100644 (file)
@@ -11,6 +11,7 @@ import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
 
 public final class ImmutableDataChangeEvent<P extends Path<P>, D> implements DataChangeEvent<P,D> {
 
@@ -127,6 +128,8 @@ public final class ImmutableDataChangeEvent<P extends Path<P>, D> implements Dat
             originalOperational.putAll(Maps.filterKeys(data.getOriginalOperationalData(), keyFilter));
             createdOperational.putAll(Maps.filterKeys(data.getCreatedOperationalData(), keyFilter));
             createdConfiguration.putAll(Maps.filterKeys(data.getCreatedConfigurationData(), keyFilter));
+            removedOperational.addAll(Sets.filter(data.getRemovedOperationalData(), keyFilter));
+            removedConfiguration.addAll(Sets.filter(data.getRemovedConfigurationData(), keyFilter));
             return this;
         }
 
index c62c27d..e74ba95 100644 (file)
@@ -394,7 +394,8 @@ public class ResolveDataChangeEventsTask implements Callable<Iterable<ChangeList
 
         Builder eventBuilder = builder(potentialScope) //
                 .setBefore(beforeCont) //
-                .setAfter(afterCont);
+                .setAfter(afterCont)
+                .addUpdated(path, beforeCont, afterCont);
         for (DOMImmutableDataChangeEvent childChange : childChanges) {
             eventBuilder.merge(childChange);
         }
@@ -447,27 +448,34 @@ public class ResolveDataChangeEventsTask implements Callable<Iterable<ChangeList
             final Collection<Node> listeners, final NormalizedNode<PathArgument, ?> node,
             final SimpleEventFactory eventFactory) {
 
-        DOMImmutableDataChangeEvent event = eventFactory.create(path, node);
-
-        if (!listeners.isEmpty()) {
+        final DOMImmutableDataChangeEvent event = eventFactory.create(path, node);
+        DOMImmutableDataChangeEvent propagateEvent = event;
             // We have listeners for this node or it's children, so we will try
             // to do additional processing
-            if (node instanceof NormalizedNodeContainer<?, ?, ?>) {
-                // Node has children, so we will try to resolve it's children
-                // changes.
-                @SuppressWarnings("unchecked")
-                NormalizedNodeContainer<?, PathArgument, NormalizedNode<PathArgument, ?>> container = (NormalizedNodeContainer<?, PathArgument, NormalizedNode<PathArgument, ?>>) node;
-                for (NormalizedNode<PathArgument, ?> child : container.getValue()) {
-                    PathArgument childId = child.getIdentifier();
-                    Collection<Node> childListeners = getListenerChildrenWildcarded(listeners, childId);
-                    if (!childListeners.isEmpty()) {
-                        resolveSameEventRecursivelly(append(path, childId), childListeners, child, eventFactory);
-                    }
-                }
+        if (node instanceof NormalizedNodeContainer<?, ?, ?>) {
+            Builder eventBuilder = builder(DataChangeScope.BASE);
+            eventBuilder.merge(event);
+            eventBuilder.setBefore(event.getOriginalSubtree());
+            eventBuilder.setAfter(event.getUpdatedSubtree());
+
+            // Node has children, so we will try to resolve it's children
+            // changes.
+            @SuppressWarnings("unchecked")
+            NormalizedNodeContainer<?, PathArgument, NormalizedNode<PathArgument, ?>> container = (NormalizedNodeContainer<?, PathArgument, NormalizedNode<PathArgument, ?>>) node;
+            for (NormalizedNode<PathArgument, ?> child : container.getValue()) {
+                PathArgument childId = child.getIdentifier();
+                Collection<Node> childListeners = getListenerChildrenWildcarded(listeners, childId);
+                eventBuilder.merge(resolveSameEventRecursivelly(append(path, childId), childListeners, child, eventFactory));
             }
+            propagateEvent = eventBuilder.build();
+        } else {
+            // We do not dispatch leaf events since Binding Aware components do not support them.
+            propagateEvent = builder(DataChangeScope.BASE).build();
+        }
+        if (!listeners.isEmpty()) {
             addPartialTask(listeners, event);
         }
-        return event;
+        return propagateEvent;
     }
 
     private DOMImmutableDataChangeEvent resolveSubtreeChangeEvent(final InstanceIdentifier path,
@@ -476,7 +484,7 @@ public class ResolveDataChangeEventsTask implements Callable<Iterable<ChangeList
 
         Builder one = builder(DataChangeScope.ONE).setBefore(before.getData()).setAfter(after.getData());
 
-        Builder subtree = builder(DataChangeScope.SUBTREE);
+        Builder subtree = builder(DataChangeScope.SUBTREE).setBefore(before.getData()).setAfter(after.getData());
 
         for (NodeModification childMod : modification.getModifications()) {
             PathArgument childId = childMod.getIdentifier();
index a5c9b79..7ea4d4e 100644 (file)
@@ -2,6 +2,7 @@ package org.opendaylight.controller.md.sal.dom.store.impl;
 
 import static com.google.common.base.Preconditions.checkArgument;
 
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -36,8 +37,10 @@ import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableCo
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableOrderedLeafSetNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableOrderedMapNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUnkeyedListEntryNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.AugmentationSchemaProxy;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
 import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
@@ -70,7 +73,7 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper
         } else if (schemaNode instanceof ChoiceNode) {
             return new ChoiceModificationStrategy((ChoiceNode) schemaNode);
         } else if (schemaNode instanceof LeafListSchemaNode) {
-            return new LeafSetEntryModificationStrategy((LeafListSchemaNode) schemaNode);
+            return fromLeafListSchemaNode((LeafListSchemaNode) schemaNode);
         } else if (schemaNode instanceof LeafSchemaNode) {
             return new LeafModificationStrategy((LeafSchemaNode) schemaNode);
         }
@@ -89,6 +92,15 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper
         return new UnorderedMapModificationStrategy(schemaNode);
     }
 
+    private static SchemaAwareApplyOperation fromLeafListSchemaNode(final LeafListSchemaNode schemaNode) {
+        if(schemaNode.isUserOrdered()) {
+            return new OrderedLeafSetModificationStrategy(schemaNode);
+        } else {
+            return new UnorderedLeafSetModificationStrategy(schemaNode);
+        }
+    }
+
+
     public static SchemaAwareApplyOperation from(final DataNodeContainer resolvedTree,
             final AugmentationTarget augSchemas, final AugmentationIdentifier identifier) {
         AugmentationSchema augSchema = null;
@@ -504,7 +516,7 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper
             DataNodeContainerModificationStrategy<AugmentationSchema> {
 
         protected AugmentationModificationStrategy(final AugmentationSchema schema, final DataNodeContainer resolved) {
-            super(schema, AugmentationNode.class);
+            super(createAugmentProxy(schema,resolved), AugmentationNode.class);
             // FIXME: Use resolved children instead of unresolved.
 
         }
@@ -563,12 +575,12 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper
 
     }
 
-    public static class LeafSetModificationStrategy extends NormalizedNodeContainerModificationStrategy {
+    public static class UnorderedLeafSetModificationStrategy extends NormalizedNodeContainerModificationStrategy {
 
         private final Optional<ModificationApplyOperation> entryStrategy;
 
         @SuppressWarnings({ "unchecked", "rawtypes" })
-        protected LeafSetModificationStrategy(final LeafListSchemaNode schema) {
+        protected UnorderedLeafSetModificationStrategy(final LeafListSchemaNode schema) {
             super((Class) LeafSetNode.class);
             entryStrategy = Optional.<ModificationApplyOperation> of(new LeafSetEntryModificationStrategy(schema));
         }
@@ -589,6 +601,32 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper
 
     }
 
+    public static class OrderedLeafSetModificationStrategy extends NormalizedNodeContainerModificationStrategy {
+
+        private final Optional<ModificationApplyOperation> entryStrategy;
+
+        @SuppressWarnings({ "unchecked", "rawtypes" })
+        protected OrderedLeafSetModificationStrategy(final LeafListSchemaNode schema) {
+            super((Class) LeafSetNode.class);
+            entryStrategy = Optional.<ModificationApplyOperation> of(new LeafSetEntryModificationStrategy(schema));
+        }
+
+        @SuppressWarnings("rawtypes")
+        @Override
+        protected NormalizedNodeContainerBuilder createBuilder(final PathArgument identifier) {
+            return ImmutableOrderedLeafSetNodeBuilder.create().withNodeIdentifier((NodeIdentifier) identifier);
+        }
+
+        @Override
+        public Optional<ModificationApplyOperation> getChild(final PathArgument identifier) {
+            if (identifier instanceof NodeWithValue) {
+                return entryStrategy;
+            }
+            return Optional.absent();
+        }
+
+    }
+
     public static class UnkeyedListModificationStrategy extends SchemaAwareApplyOperation {
 
         private final Optional<ModificationApplyOperation> entryStrategy;
@@ -698,4 +736,12 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper
 
     }
 
+    public static AugmentationSchema createAugmentProxy(final AugmentationSchema schema, final DataNodeContainer resolved) {
+        Set<DataSchemaNode> realChildSchemas = new HashSet<>();
+        for(DataSchemaNode augChild : schema.getChildNodes()) {
+            realChildSchemas.add(resolved.getDataChildByName(augChild.getQName()));
+        }
+        return new AugmentationSchemaProxy(schema, realChildSchemas);
+    }
+
 }
index 857cc3e..b77d92e 100644 (file)
@@ -13,6 +13,20 @@ import ch.ethz.ssh2.Session;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 import io.netty.channel.ChannelFuture;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.management.ManagementFactory;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+import javax.management.ObjectName;
+import javax.xml.parsers.ParserConfigurationException;
 import junit.framework.Assert;
 import org.apache.commons.io.IOUtils;
 import org.junit.After;
@@ -52,22 +66,6 @@ import org.w3c.dom.Element;
 import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
 import org.xml.sax.SAXException;
-
-import javax.management.ObjectName;
-import javax.xml.parsers.ParserConfigurationException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.management.ManagementFactory;
-import java.net.InetSocketAddress;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
-
 import static java.util.Collections.emptyList;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
@@ -411,7 +409,7 @@ public class NetconfITTest extends AbstractNetconfConfigTest {
                     try {
                         c = sess.getStdout().read(bytes);
                     } catch (IOException e) {
-                        e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
+                        throw new IllegalStateException("IO exception while reading data on ssh bridge.");
                     }
                     logger.info("got data:" + bytes);
                     if (c == 0) {
index 6ddc8eb..2e9a0b9 100644 (file)
@@ -7,42 +7,26 @@
  */
 package org.opendaylight.controller.netconf.ssh.authentication;
 
+import java.io.IOException;
 import org.opendaylight.controller.sal.authorization.AuthResultEnum;
-import org.opendaylight.controller.sal.authorization.UserLevel;
 import org.opendaylight.controller.usermanager.IUserManager;
-import org.opendaylight.controller.usermanager.UserConfig;
-
-import java.util.ArrayList;
-import java.util.List;
-
 import static com.google.common.base.Preconditions.checkNotNull;
 
 public class AuthProvider implements AuthProviderInterface {
 
-    private static IUserManager um; //FIXME static mutable state, no locks
-    private static final String DEFAULT_USER = "netconf";
-    private static final String DEFAULT_PASSWORD = "netconf";
+    private IUserManager um;
     private final String pem;
 
-    public AuthProvider(IUserManager ium, String pemCertificate) throws Exception {
+    public AuthProvider(IUserManager ium, String pemCertificate) throws IllegalArgumentException, IOException {
         checkNotNull(pemCertificate, "Parameter 'pemCertificate' is null");
-        AuthProvider.um = ium;
-        if (AuthProvider.um == null) {
-            throw new Exception("No usermanager service available.");
-        }
-
-        List<String> roles = new ArrayList<String>(1);
-        roles.add(UserLevel.SYSTEMADMIN.toString());
-        AuthProvider.um.addLocalUser(new UserConfig(DEFAULT_USER, DEFAULT_PASSWORD, roles)); //FIXME hardcoded auth
+        checkNotNull(ium, "No user manager service available.");
+        this.um = ium;
         pem = pemCertificate;
     }
 
     @Override
     public boolean authenticated(String username, String password) {
-        if (AuthProvider.um == null) {
-            throw new IllegalStateException("No usermanager service available.");
-        }
-        AuthResultEnum authResult = AuthProvider.um.authenticate(username, password);
+        AuthResultEnum authResult = this.um.authenticate(username, password);
         return authResult.equals(AuthResultEnum.AUTH_ACCEPT) || authResult.equals(AuthResultEnum.AUTH_ACCEPT_LOC);
     }
 
@@ -53,11 +37,11 @@ public class AuthProvider implements AuthProviderInterface {
 
     @Override
     public void removeUserManagerService() {
-        AuthProvider.um = null;
+        this.um = null;
     }
 
     @Override
     public void addUserManagerService(IUserManager userManagerService) {
-        AuthProvider.um = userManagerService;
+        this.um = userManagerService;
     }
 }
index 5b88030..ca0c945 100644 (file)
@@ -8,12 +8,21 @@
 package org.opendaylight.controller.netconf.ssh.osgi;
 
 import com.google.common.base.Optional;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.io.IOUtils;
 import org.opendaylight.controller.netconf.ssh.NetconfSSHServer;
 import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider;
 import org.opendaylight.controller.netconf.ssh.authentication.PEMGenerator;
 import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil;
+import org.opendaylight.controller.sal.authorization.UserLevel;
 import org.opendaylight.controller.usermanager.IUserManager;
+import org.opendaylight.controller.usermanager.UserConfig;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
@@ -21,16 +30,12 @@ import org.osgi.util.tracker.ServiceTracker;
 import org.osgi.util.tracker.ServiceTrackerCustomizer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.net.InetSocketAddress;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
  * Activator for netconf SSH bundle which creates SSH bridge between netconf client and netconf server. Activator
  * starts SSH Server in its own thread. This thread is closed when activator calls stop() method. Server opens socket
- * and listen for client connections. Each client connection creation is handled in separate
+ * and listens for client connections. Each client connection creation is handled in separate
  * {@link org.opendaylight.controller.netconf.ssh.threads.SocketThread} thread.
  * This thread creates two additional threads {@link org.opendaylight.controller.netconf.ssh.threads.IOThread}
  * forwarding data from/to client.IOThread closes servers session and server connection when it gets -1 on input stream.
@@ -44,6 +49,8 @@ public class NetconfSSHActivator implements BundleActivator{
     private static final String EXCEPTION_MESSAGE = "Netconf ssh bridge is not available.";
     private IUserManager iUserManager;
     private BundleContext context = null;
+    private Optional<String> defaultPassword;
+    private Optional<String> defaultUser;
 
     private ServiceTrackerCustomizer<IUserManager, IUserManager> customizer = new ServiceTrackerCustomizer<IUserManager, IUserManager>(){
         @Override
@@ -79,20 +86,23 @@ public class NetconfSSHActivator implements BundleActivator{
 
     @Override
     public void stop(BundleContext context) throws IOException {
+        if (this.defaultUser.isPresent()){
+            this.iUserManager.removeLocalUser(this.defaultUser.get());
+        }
         if (server != null){
             server.stop();
             logger.trace("Netconf SSH bridge is down ...");
         }
     }
     private void startSSHServer() throws IllegalStateException, IOException {
+        checkNotNull(this.iUserManager, "No user manager service available.");
         logger.trace("Starting netconf SSH  bridge.");
         Optional<InetSocketAddress> sshSocketAddressOptional = NetconfConfigUtil.extractSSHNetconfAddress(context, EXCEPTION_MESSAGE);
         InetSocketAddress tcpSocketAddress = NetconfConfigUtil.extractTCPNetconfAddress(context,
                 EXCEPTION_MESSAGE, true);
 
         if (sshSocketAddressOptional.isPresent()){
-            String path = NetconfConfigUtil.getPrivateKeyPath(context);
-            path = path.replace("\\", "/");  // FIXME: shouldn't this convert lines to system dependent path separator?
+            String path =  FilenameUtils.separatorsToSystem(NetconfConfigUtil.getPrivateKeyPath(context));
             if (path.equals("")){
                 throw new IllegalStateException("Missing netconf.ssh.pk.path key in configuration file.");
             }
@@ -100,11 +110,10 @@ public class NetconfSSHActivator implements BundleActivator{
             File privateKeyFile = new File(path);
             String privateKeyPEMString = null;
             if (privateKeyFile.exists() == false) {
-                // generate & save to file
                 try {
                     privateKeyPEMString = PEMGenerator.generateTo(privateKeyFile);
                 } catch (Exception e) {
-                    logger.error("Exception occured while generating PEM string {}",e);
+                    logger.error("Exception occurred while generating PEM string {}",e);
                 }
             } else {
                 // read from file
@@ -117,6 +126,17 @@ public class NetconfSSHActivator implements BundleActivator{
             }
             AuthProvider authProvider = null;
             try {
+                this.defaultPassword = NetconfConfigUtil.getSSHDefaultPassword(context);
+                this.defaultUser = NetconfConfigUtil.getSSHDefaultUser(context);
+                // Since there is no user data store yet (ldap, ...) this adds default user/password to UserManager
+                // if these parameters are set in netconf configuration file.
+                if (defaultUser.isPresent() &&
+                        defaultPassword.isPresent()){
+                    logger.trace(String.format("Default username and password for netconf ssh bridge found. Adding user %s to user manager.",defaultUser.get()));
+                    List<String> roles = new ArrayList<String>(1);
+                    roles.add(UserLevel.SYSTEMADMIN.toString());
+                    iUserManager.addLocalUser(new UserConfig(defaultUser.get(), defaultPassword.get(), roles));
+                }
                 authProvider = new AuthProvider(iUserManager, privateKeyPEMString);
             } catch (Exception e) {
                 logger.error("Error instantiating AuthProvider {}",e);
index b23a2d6..f89df2a 100644 (file)
@@ -9,12 +9,11 @@
 package org.opendaylight.controller.netconf.util.osgi;
 
 import com.google.common.base.Optional;
+import com.google.common.base.Strings;
+import java.net.InetSocketAddress;
 import org.osgi.framework.BundleContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
-import java.net.InetSocketAddress;
-
 import static com.google.common.base.Preconditions.checkNotNull;
 
 public final class NetconfConfigUtil {
@@ -32,6 +31,8 @@ public final class NetconfConfigUtil {
     private static final String ADDRESS_SUFFIX_PROP = ".address";
     private static final String CLIENT_PROP = ".client";
     private static final String PRIVATE_KEY_PATH_PROP = ".pk.path";
+    private static final String SSH_DEFAULT_USER = ".default.user";
+    private static final String SSH_DEFAULT_PASSWORD = ".default.password";
 
     private static final String CONNECTION_TIMEOUT_MILLIS_PROP = "connectionTimeoutMillis";
     private static final long DEFAULT_TIMEOUT_MILLIS = 5000;
@@ -72,6 +73,13 @@ public final class NetconfConfigUtil {
     public static String getPrivateKeyPath(BundleContext context){
         return getPropertyValue(context,PREFIX_PROP + InfixProp.ssh +PRIVATE_KEY_PATH_PROP);
     }
+    public static Optional<String> getSSHDefaultUser(BundleContext context){
+        return getOptionalPropertyValue(context,PREFIX_PROP + InfixProp.ssh +SSH_DEFAULT_USER);
+    }
+    public static Optional<String> getSSHDefaultPassword(BundleContext context){
+        return getOptionalPropertyValue(context,PREFIX_PROP + InfixProp.ssh +SSH_DEFAULT_PASSWORD);
+    }
+
     private static String getPropertyValue(BundleContext context, String propertyName){
         String propertyValue = context.getProperty(propertyName);
         if (propertyValue == null){
@@ -79,6 +87,13 @@ public final class NetconfConfigUtil {
         }
         return propertyValue;
     }
+    private static Optional<String> getOptionalPropertyValue(BundleContext context, String propertyName){
+        String propertyValue = context.getProperty(propertyName);
+        if (Strings.isNullOrEmpty(propertyValue)){
+            return Optional.absent();
+        }
+        return Optional.fromNullable(propertyValue);
+    }
     /**
      * @param context
      *            from which properties are being read.