Merge "Switch to using yangtools version of mockito-configuration"
authorEd Warnicke <eaw@cisco.com>
Sat, 18 Jan 2014 18:32:37 +0000 (18:32 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Sat, 18 Jan 2014 18:32:37 +0000 (18:32 +0000)
97 files changed:
opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/ValidationException.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BlankTransactionServiceTracker.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ConfigManagerActivator.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ExtenderBundleTracker.java
opendaylight/config/config-persister-directory-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/DirectoryStorageAdapterTest.java
opendaylight/config/config-persister-directory-autodetect-adapter/pom.xml
opendaylight/config/config-persister-directory-autodetect-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryPersister.java
opendaylight/config/config-persister-directory-autodetect-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryPersisterTest.java
opendaylight/config/config-persister-directory-xml-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/xml/DirectoryStorageAdapterTest.java
opendaylight/config/config-persister-file-xml-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/file/xml/model/ConfigSnapshot.java
opendaylight/config/config-persister-file-xml-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/file/xml/model/StringTrimAdapter.java [new file with mode: 0644]
opendaylight/config/shutdown-api/src/main/java/org/opendaylight/controller/config/shutdown/ShutdownService.java
opendaylight/config/shutdown-impl/src/main/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownModule.java
opendaylight/config/shutdown-impl/src/main/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownModuleFactory.java
opendaylight/config/shutdown-impl/src/main/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownServiceImpl.java
opendaylight/config/shutdown-impl/src/main/yang/shutdown-impl.yang
opendaylight/config/shutdown-impl/src/test/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownTest.java
opendaylight/distribution/opendaylight/pom.xml
opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/00-netty.xml [moved from opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/00-netty.xml.conf with 100% similarity]
opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.xml [moved from opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.xml.conf with 100% similarity]
opendaylight/distribution/opendaylight/src/main/resources/run.sh
opendaylight/md-sal/clustered-data-store/integrationtest/src/test/resources/controller.config [deleted file]
opendaylight/md-sal/clustered-data-store/integrationtest/src/test/resources/controller.xml [new file with mode: 0644]
opendaylight/md-sal/compatibility/inventory-topology-compatibility/src/main/java/org/opendaylight/controller/md/compatibility/topology/TopologyMapping.xtend
opendaylight/md-sal/compatibility/inventory-topology-compatibility/src/main/java/org/opendaylight/controller/md/compatibility/topology/TopologyReader.xtend
opendaylight/md-sal/compatibility/inventory-topology-compatibility/src/main/java/org/opendaylight/controller/md/compatibility/topologymanager/AdSalTopologyMapping.xtend
opendaylight/md-sal/compatibility/inventory-topology-compatibility/src/main/java/org/opendaylight/controller/md/compatibility/topologymanager/CompatibleTopologyManager.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyAdapter.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyCommitHandler.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyMapping.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyProvider.xtend
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/FRMConsumerImpl.java [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/FRMUtil.java [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/FlowConsumerImpl.java [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/GroupConsumerImpl.java [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/IForwardingRulesManager.java [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/MeterConsumerImpl.java [deleted file]
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/TableFeaturesConsumerImpl.java [deleted file]
opendaylight/md-sal/model/model-inventory/src/main/yang/netconf-node-inventory.yang
opendaylight/md-sal/model/model-inventory/src/main/yang/node-inventory.yang
opendaylight/md-sal/model/model-topology/src/main/yang/opendaylight-topology-inventory.yang
opendaylight/md-sal/model/model-topology/src/main/yang/opendaylight-topology.yang
opendaylight/md-sal/model/model-topology/src/main/yang/topology-view.yang
opendaylight/md-sal/sal-binding-it/pom.xml
opendaylight/md-sal/sal-binding-it/src/main/java/org/opendaylight/controller/test/sal/binding/it/TestHelper.java
opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/AbstractTest.java
opendaylight/md-sal/sal-binding-it/src/test/resources/controller.config [deleted file]
opendaylight/md-sal/sal-binding-it/src/test/resources/controller.xml [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/InventoryUtils.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.xtend
opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-it/src/test/resources/controller.config [deleted file]
opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-it/src/test/resources/controller.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/BrokerFacade.xtend
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/InstanceIdWithSchemaNode.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithDataFromSeveralModulesTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithDataFromSeveralModulesTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ControllerContextTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/DummyMountInstanceImpl.java [deleted file]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/MediaTypesTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestConfigDataTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestDeleteOperationTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestGetOperationTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestOperationUtils.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestPostOperationTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestPutOperationTest.java
opendaylight/md-sal/sal-rest-connector/src/test/resources/full-versions/yangs/simple-nodes.yang
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-of-several-modules/yang/module1.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-of-several-modules/yang/module2.yang [new file with mode: 0644]
opendaylight/md-sal/src/test/resources/controller.xml [new file with mode: 0644]
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsProvider.java
opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableNodeMapping.xtend
opendaylight/md-sal/topology-manager/src/main/java/org/opendaylight/md/controller/topology/manager/FlowCapableTopologyExporter.xtend
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleAttributeReadingStrategy.java
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiator.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java
opendaylight/networkconfiguration/neutron/implementation/pom.xml
opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/Activator.java
opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronFloatingIPInterface.java
opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronNetworkInterface.java
opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronPortInterface.java
opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronRouterInterface.java
opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSubnetInterface.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronFloatingIP.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronNetwork.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronPort.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter_Interface.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter_NetworkReference.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet_HostRoute.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet_IPAllocationPool.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/Neutron_IPs.java
opendaylight/northbound/controllermanager/pom.xml
opendaylight/northbound/controllermanager/src/main/java/org/opendaylight/controller/controllermanager/northbound/ControllerManagerNorthbound.java
opendaylight/web/devices/src/main/resources/js/page.js

index da54a83..f27d123 100644 (file)
@@ -140,8 +140,7 @@ public class ValidationException extends RuntimeException {
 
         @Override
         public String toString() {
-            return "ExceptionMessageWithStackTrace [message=" + message
-                    + ", stackTrace=" + stackTrace + "]";
+            return message;
         }
 
     }
index ec1a290..b973b92 100644 (file)
@@ -38,7 +38,7 @@ public class BlankTransactionServiceTracker implements ServiceTrackerCustomizer<
         return null;
     }
 
-    private synchronized void blankTransaction() {
+    synchronized void blankTransaction() {
         // race condition check: config-persister might push new configuration while server is starting up.
         ConflictingVersionException lastException = null;
         for (int i = 0; i < 10; i++) {
index 1ee6cca..be602e5 100644 (file)
@@ -46,11 +46,11 @@ public class ConfigManagerActivator implements BundleActivator {
         configRegistryJMXRegistrator.registerToJMX(configRegistry);
 
         // track bundles containing factories
-        extenderBundleTracker = new ExtenderBundleTracker(context);
+        BlankTransactionServiceTracker blankTransactionServiceTracker = new BlankTransactionServiceTracker(configRegistry);
+        extenderBundleTracker = new ExtenderBundleTracker(context, blankTransactionServiceTracker);
         extenderBundleTracker.open();
 
-        BlankTransactionServiceTracker customizer = new BlankTransactionServiceTracker(configRegistry);
-        ServiceTracker<?, ?> serviceTracker = new ServiceTracker(context, ModuleFactory.class, customizer);
+        ServiceTracker<?, ?> serviceTracker = new ServiceTracker(context, ModuleFactory.class, blankTransactionServiceTracker);
         serviceTracker.open();
     }
 
index 6663cdd..b55f313 100644 (file)
@@ -34,11 +34,12 @@ import org.slf4j.LoggerFactory;
  * Code based on http://www.toedter.com/blog/?p=236
  */
 public class ExtenderBundleTracker extends BundleTracker<Object> {
-
+    private final BlankTransactionServiceTracker blankTransactionServiceTracker;
     private static final Logger logger = LoggerFactory.getLogger(ExtenderBundleTracker.class);
 
-    public ExtenderBundleTracker(BundleContext context) {
+    public ExtenderBundleTracker(BundleContext context, BlankTransactionServiceTracker blankTransactionServiceTracker) {
         super(context, Bundle.ACTIVE, null);
+        this.blankTransactionServiceTracker = blankTransactionServiceTracker;
         logger.trace("Registered as extender with context {}", context);
     }
 
@@ -64,6 +65,8 @@ public class ExtenderBundleTracker extends BundleTracker<Object> {
     @Override
     public void removedBundle(Bundle bundle, BundleEvent event, Object object) {
         super.removedBundle(bundle,event,object);
+        // workaround for service tracker not getting removed service event
+        blankTransactionServiceTracker.blankTransaction();
     }
 
     // TODO:test
index 72bd208..3ae2906 100644 (file)
@@ -25,15 +25,18 @@ import static org.junit.Assert.fail;
 public class DirectoryStorageAdapterTest {
     Persister tested;
 
+    private Persister instantiatePersisterFromAdapter(File file){
+        PropertiesProviderTest pp = new PropertiesProviderTest();
+        pp.addProperty("directoryStorage",file.getPath());
+        DirectoryStorageAdapter dsa = new DirectoryStorageAdapter();
+        return dsa.instantiate(pp);
+    }
     @Test
     public void testEmptyDirectory() throws Exception {
         File folder = new File("target/emptyFolder");
         folder.mkdir();
 
-        PropertiesProviderTest pp = new PropertiesProviderTest();
-        pp.addProperty("directoryStorage",folder.getPath());
-        DirectoryStorageAdapter dsa = new DirectoryStorageAdapter();
-        tested = dsa.instantiate(pp);
+        tested =  instantiatePersisterFromAdapter(folder);
         assertEquals(Collections.<ConfigSnapshotHolder>emptyList(), tested.loadLastConfigs());
 
         try {
@@ -64,10 +67,8 @@ public class DirectoryStorageAdapterTest {
     @Test
     public void testOneFile() throws Exception {
         File folder = getFolder("oneFile");
-        PropertiesProviderTest pp = new PropertiesProviderTest();
-        pp.addProperty("directoryStorage",folder.getPath());
-        DirectoryStorageAdapter dsa = new DirectoryStorageAdapter();
-        tested = dsa.instantiate(pp);
+
+        tested = instantiatePersisterFromAdapter(folder);
 
         List<ConfigSnapshotHolder> results = tested.loadLastConfigs();
         assertEquals(1, results.size());
@@ -79,10 +80,7 @@ public class DirectoryStorageAdapterTest {
     @Test
     public void testTwoFiles() throws Exception {
         File folder = getFolder("twoFiles");
-        PropertiesProviderTest pp = new PropertiesProviderTest();
-        pp.addProperty("directoryStorage",folder.getPath());
-        DirectoryStorageAdapter dsa = new DirectoryStorageAdapter();
-        tested = dsa.instantiate(pp);
+        tested = instantiatePersisterFromAdapter(folder);
 
         List<ConfigSnapshotHolder> results = tested.loadLastConfigs();
         assertEquals(2, results.size());
index aaf60dd..c94f633 100644 (file)
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>mockito-configuration</artifactId>
         </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>config-persister-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
 
     </dependencies>
 
index f262952..2028d62 100644 (file)
@@ -67,6 +67,8 @@ public class AutodetectDirectoryPersister implements Persister {
     private ConfigSnapshotHolder loadLastConfig(File file, FileType fileType) throws IOException {
         switch (fileType) {
         case plaintext:
+            logger.warn("Plaintext configuration files are deprecated, and will not be supported in future versions. " +
+                    "Use xml files instead");
             return DirectoryPersister.loadLastConfig(file);
         case xml:
             try {
index 7e42391..f833460 100644 (file)
@@ -7,21 +7,26 @@
  */
 package org.opendaylight.controller.config.persist.storage.directory.autodetect;
 
+import java.io.File;
+import java.util.List;
 import junit.framework.Assert;
 import org.junit.Test;
 import org.junit.matchers.JUnitMatchers;
 import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
-
-import java.io.File;
-import java.util.List;
+import org.opendaylight.controller.config.persist.test.PropertiesProviderTest;
 
 public class AutodetectDirectoryPersisterTest {
 
     @Test
     public void testCombined() throws Exception {
         File resourcePath = FileTypeTest.getResourceAsFile("/combined/1controller.txt.config");
+        File parentFile = resourcePath.getParentFile();
+
+        AutodetectDirectoryStorageAdapter adapter = new AutodetectDirectoryStorageAdapter();
 
-        AutodetectDirectoryPersister persister = new AutodetectDirectoryPersister(resourcePath.getParentFile());
+        PropertiesProviderTest pp = new PropertiesProviderTest();
+        pp.addProperty("directoryStorage",parentFile.getPath());
+        AutodetectDirectoryPersister persister = (AutodetectDirectoryPersister) adapter.instantiate(pp);
         List<ConfigSnapshotHolder> configs = persister.loadLastConfigs();
 
         Assert.assertEquals(2, configs.size());
@@ -32,6 +37,5 @@ public class AutodetectDirectoryPersisterTest {
         String snapFromXml = configs.get(1).getConfigSnapshot();
         org.junit.Assert.assertThat(snapFromXml, JUnitMatchers.containsString("<config>xml</config>"));
 
-        Assert.assertEquals(configs.get(0).getCapabilities(), configs.get(1).getCapabilities());
-    }
+        Assert.assertEquals(configs.get(0).getCapabilities(), configs.get(1).getCapabilities());    }
 }
index 825eb94..8e34bc7 100644 (file)
@@ -14,6 +14,8 @@ import java.util.List;
 import java.util.SortedSet;
 import org.junit.Test;
 import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
+import org.opendaylight.controller.config.persist.api.Persister;
+import org.opendaylight.controller.config.persist.test.PropertiesProviderTest;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import static org.junit.Assert.assertEquals;
@@ -21,14 +23,22 @@ import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 public class DirectoryStorageAdapterTest {
-    XmlDirectoryPersister tested;
+    Persister tested;
     Logger logger = LoggerFactory.getLogger(DirectoryStorageAdapterTest.class.toString());
 
+    private Persister instantiatePersisterFromAdapter(File file){
+        PropertiesProviderTest pp = new PropertiesProviderTest();
+        pp.addProperty("directoryStorage",file.getPath());
+        XmlDirectoryStorageAdapter dsa = new XmlDirectoryStorageAdapter();
+        return dsa.instantiate(pp);
+    }
+
     @Test
     public void testEmptyDirectory() throws Exception {
         File folder = new File("target/emptyFolder");
         folder.mkdir();
-        tested = new XmlDirectoryPersister((folder));
+
+        tested = instantiatePersisterFromAdapter(folder);
         assertEquals(Collections.<ConfigSnapshotHolder>emptyList(), tested.loadLastConfigs());
 
         try {
@@ -59,7 +69,8 @@ public class DirectoryStorageAdapterTest {
     @Test
     public void testOneFile() throws Exception {
         File folder = getFolder("oneFile");
-        tested = new XmlDirectoryPersister(folder);
+        tested = instantiatePersisterFromAdapter(folder);
+
         logger.info("Testing : "+tested.toString());
         List<ConfigSnapshotHolder> results = tested.loadLastConfigs();
         assertEquals(1, results.size());
@@ -78,7 +89,7 @@ public class DirectoryStorageAdapterTest {
     @Test
     public void testTwoFiles() throws Exception {
         File folder = getFolder("twoFiles");
-        tested = new XmlDirectoryPersister((folder));
+        tested = instantiatePersisterFromAdapter(folder);
         logger.info("Testing : "+tested.toString());
         List<ConfigSnapshotHolder> results = tested.loadLastConfigs();
         assertEquals(2, results.size());
index cfc7085..d13052a 100644 (file)
@@ -13,6 +13,7 @@ import javax.xml.bind.annotation.XmlAnyElement;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 import java.util.SortedSet;
 
 @XmlRootElement(name = ConfigSnapshot.SNAPSHOT_ROOT_ELEMENT_NAME)
@@ -46,6 +47,7 @@ public class ConfigSnapshot {
 
     @XmlElement(name = "capability")
     @XmlElementWrapper(name = "required-capabilities")
+    @XmlJavaTypeAdapter(value=StringTrimAdapter.class)
     public SortedSet<String> getCapabilities() {
         return capabilities;
     }
@@ -62,4 +64,6 @@ public class ConfigSnapshot {
         sb.append('}');
         return sb.toString();
     }
+
 }
+
diff --git a/opendaylight/config/config-persister-file-xml-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/file/xml/model/StringTrimAdapter.java b/opendaylight/config/config-persister-file-xml-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/file/xml/model/StringTrimAdapter.java
new file mode 100644 (file)
index 0000000..3c544d4
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * 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.persist.storage.file.xml.model;
+
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+
+final class StringTrimAdapter extends XmlAdapter<String, String> {
+    @Override
+    public String unmarshal(String v) throws Exception {
+        if (v == null)
+            return null;
+        return v.trim();
+    }
+
+    @Override
+    public String marshal(String v) throws Exception {
+        if (v == null)
+            return null;
+        return v.trim();
+    }
+}
index 1042417..5cbe493 100644 (file)
@@ -17,5 +17,5 @@ public interface ShutdownService {
      * @param inputSecret must match configured secret of the implementation
      * @param reason Optional string to be logged while shutting down
      */
-    void shutdown(String inputSecret, Optional<String> reason);
+    void shutdown(String inputSecret, Long maxWaitTime, Optional<String> reason);
 }
index f6937f9..d58ebf2 100644 (file)
@@ -16,13 +16,11 @@ import org.osgi.framework.Bundle;
 
 public final class ShutdownModule extends AbstractShutdownModule {
     private final Bundle systemBundle;
-    private final ShutdownModule nullableOldModule;
 
     public ShutdownModule(ModuleIdentifier identifier, Bundle systemBundle) {
         super(identifier, null);
         singletonCheck(identifier);
         this.systemBundle = systemBundle;
-        this.nullableOldModule = null;
     }
 
     public ShutdownModule(ModuleIdentifier identifier, ShutdownModule oldModule, java.lang.AutoCloseable oldInstance,
@@ -30,7 +28,6 @@ public final class ShutdownModule extends AbstractShutdownModule {
         super(identifier, null, oldModule, oldInstance);
         singletonCheck(identifier);
         this.systemBundle = systemBundle;
-        this.nullableOldModule = oldModule;
     }
 
     private static void singletonCheck(ModuleIdentifier identifier) {
@@ -52,40 +49,13 @@ public final class ShutdownModule extends AbstractShutdownModule {
         throw new UnsupportedOperationException();
     }
 
-    @Override
-    public String getSecret() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getOldSecret() {
-        throw new UnsupportedOperationException();
-    }
-
-    String getActualSecret() {
-        return super.getSecret();
-    }
-
-    String getActualOldSecret() {
-        return super.getOldSecret();
-    }
-
     @Override
     protected void customValidation() {
-        JmxAttributeValidationException.checkNotNull(super.getOldSecret(), oldSecretJmxAttribute);
         JmxAttributeValidationException.checkNotNull(super.getSecret(), secretJmxAttribute);
-        if (nullableOldModule != null) {
-            // if nothing changed, remain valid
-            boolean sameAsOldModule = isSame(nullableOldModule);
-            if (sameAsOldModule == false) {
-                boolean valid = getActualOldSecret().equals(nullableOldModule.getActualSecret());
-                JmxAttributeValidationException.checkCondition(valid, "Invalid old secret", oldSecretJmxAttribute);
-            }
-        }
     }
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-        return new ShutdownServiceImpl(getActualSecret(), systemBundle, getRootRuntimeBeanRegistratorWrapper());
+        return new ShutdownServiceImpl(getSecret(), systemBundle, getRootRuntimeBeanRegistratorWrapper());
     }
 }
index 637395b..0517faf 100644 (file)
 package org.opendaylight.controller.config.yang.shutdown.impl;
 
 import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.DependencyResolverFactory;
 import org.opendaylight.controller.config.api.ModuleIdentifier;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 
-public class ShutdownModuleFactory extends AbstractShutdownModuleFactory {
-
-    @Override
-    public org.opendaylight.controller.config.spi.Module createModule(String instanceName, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.api.DynamicMBeanWithInstance old, org.osgi.framework.BundleContext bundleContext) throws Exception {
-        org.opendaylight.controller.config.yang.shutdown.impl.ShutdownModule oldModule = null;
-        try {
-            oldModule = (org.opendaylight.controller.config.yang.shutdown.impl.ShutdownModule) old.getModule();
-        } catch(Exception e) {
-            return handleChangedClass(old);
-        }
-        org.opendaylight.controller.config.yang.shutdown.impl.ShutdownModule module = instantiateModule(instanceName, dependencyResolver, oldModule, old.getInstance(), bundleContext);
-
-        module.setOldSecret(oldModule.getActualOldSecret());
-        module.setSecret(oldModule.getActualSecret());
-
-        return module;
-    }
+import java.util.Arrays;
+import java.util.Set;
 
+public class ShutdownModuleFactory extends AbstractShutdownModuleFactory {
 
     public ShutdownModule instantiateModule(String instanceName, DependencyResolver dependencyResolver,
                                             ShutdownModule oldModule, AutoCloseable oldInstance,
@@ -46,4 +33,12 @@ public class ShutdownModuleFactory extends AbstractShutdownModuleFactory {
         Bundle systemBundle = bundleContext.getBundle(0);
         return new ShutdownModule(new ModuleIdentifier(NAME, instanceName), systemBundle);
     }
+
+    @Override
+    public Set<ShutdownModule> getDefaultModules(DependencyResolverFactory dependencyResolverFactory, BundleContext bundleContext) {
+        ModuleIdentifier id = new ModuleIdentifier(NAME, NAME);
+        DependencyResolver dependencyResolver = dependencyResolverFactory.createDependencyResolver(id);
+        ShutdownModule shutdownModule = instantiateModule(NAME, dependencyResolver, bundleContext);
+        return new java.util.HashSet<>(Arrays.asList(shutdownModule));
+    }
 }
index e5b95c8..6cdcf60 100644 (file)
@@ -14,6 +14,9 @@ import org.osgi.framework.BundleException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadInfo;
+
 public class ShutdownServiceImpl implements ShutdownService, AutoCloseable {
     private final ShutdownService impl;
     private final ShutdownRuntimeRegistration registration;
@@ -28,8 +31,8 @@ public class ShutdownServiceImpl implements ShutdownService, AutoCloseable {
     }
 
     @Override
-    public void shutdown(String inputSecret, Optional<String> reason) {
-        impl.shutdown(inputSecret, reason);
+    public void shutdown(String inputSecret, Long maxWaitTime, Optional<String> reason) {
+        impl.shutdown(inputSecret, maxWaitTime, reason);
     }
 
     @Override
@@ -49,7 +52,7 @@ class Impl implements ShutdownService {
     }
 
     @Override
-    public void shutdown(String inputSecret, Optional<String> reason) {
+    public void shutdown(String inputSecret, Long maxWaitTime, Optional<String> reason) {
         logger.warn("Shutdown issued with secret {} and reason {}", inputSecret, reason);
         try {
             Thread.sleep(1000); // prevent brute force attack
@@ -60,22 +63,15 @@ class Impl implements ShutdownService {
         if (this.secret.equals(inputSecret)) {
             logger.info("Server is shutting down");
 
-            Thread stopSystemBundle = new Thread() {
-                @Override
-                public void run() {
-                    try {
-                        // wait so that JMX response is received
-                        Thread.sleep(1000);
-                        systemBundle.stop();
-                    } catch (BundleException e) {
-                        logger.warn("Can not stop OSGi server", e);
-                    } catch (InterruptedException e) {
-                        logger.warn("Shutdown process interrupted", e);
-                    }
-                }
-            };
-            stopSystemBundle.start();
-
+            // actual work:
+            Thread stopSystemBundleThread = new StopSystemBundleThread(systemBundle);
+            stopSystemBundleThread.start();
+            if (maxWaitTime != null && maxWaitTime > 0) {
+                Thread systemExitThread = new CallSystemExitThread(maxWaitTime);
+                logger.debug("Scheduling {}", systemExitThread);
+                systemExitThread.start();
+            }
+            // end
         } else {
             logger.warn("Unauthorized attempt to shut down server");
             throw new IllegalArgumentException("Invalid secret");
@@ -84,6 +80,70 @@ class Impl implements ShutdownService {
 
 }
 
+class StopSystemBundleThread extends Thread {
+    private static final Logger logger = LoggerFactory.getLogger(StopSystemBundleThread.class);
+    private final Bundle systemBundle;
+
+    StopSystemBundleThread(Bundle systemBundle) {
+        super("stop-system-bundle");
+        this.systemBundle = systemBundle;
+    }
+
+    @Override
+    public void run() {
+        try {
+            // wait so that JMX response is received
+            Thread.sleep(1000);
+            systemBundle.stop();
+        } catch (BundleException e) {
+            logger.warn("Can not stop OSGi server", e);
+        } catch (InterruptedException e) {
+            logger.warn("Shutdown process interrupted", e);
+        }
+    }
+}
+
+class CallSystemExitThread extends Thread {
+    private static final Logger logger = LoggerFactory.getLogger(CallSystemExitThread.class);
+    private final long maxWaitTime;
+    CallSystemExitThread(long maxWaitTime) {
+        super("call-system-exit-daemon");
+        setDaemon(true);
+        if (maxWaitTime <= 0){
+            throw new IllegalArgumentException("Cannot schedule to zero or negative time:" + maxWaitTime);
+        }
+        this.maxWaitTime = maxWaitTime;
+    }
+
+    @Override
+    public String toString() {
+        return "CallSystemExitThread{" +
+                "maxWaitTime=" + maxWaitTime +
+                '}';
+    }
+
+    @Override
+    public void run() {
+        try {
+            // wait specified time
+            Thread.sleep(maxWaitTime);
+            logger.error("Since some threads are still running, server is going to shut down via System.exit(1) !");
+            // do a thread dump
+            ThreadInfo[] threads = ManagementFactory.getThreadMXBean().dumpAllThreads(true, true);
+            StringBuffer sb = new StringBuffer();
+            for(ThreadInfo info : threads) {
+                sb.append(info);
+                sb.append("\n");
+            }
+            logger.warn("Thread dump:{}", sb);
+            System.exit(1);
+        } catch (InterruptedException e) {
+            logger.info("Interrupted, not going to call System.exit(1)");
+        }
+    }
+}
+
+
 class MXBeanImpl implements ShutdownRuntimeMXBean {
     private final ShutdownService impl;
 
@@ -92,13 +152,13 @@ class MXBeanImpl implements ShutdownRuntimeMXBean {
     }
 
     @Override
-    public void shutdown(String inputSecret, String nullableReason) {
+    public void shutdown(String inputSecret, Long maxWaitTime, String nullableReason) {
         Optional<String> optionalReason;
         if (nullableReason == null) {
             optionalReason = Optional.absent();
         } else {
             optionalReason = Optional.of(nullableReason);
         }
-        impl.shutdown(inputSecret, optionalReason);
+        impl.shutdown(inputSecret, maxWaitTime, optionalReason);
     }
 }
index 78b44ab..883735c 100644 (file)
@@ -37,10 +37,6 @@ module shutdown-impl {
                 type string;
                 default "";
             }
-            leaf old-secret {
-                type string;
-                default "";
-            }
         }
     }
 
@@ -63,6 +59,10 @@ module shutdown-impl {
             leaf input-secret {
                 type string;
             }
+            leaf max-wait-time {
+                type uint32;
+                description "Maximum time in milliseconds before process is forcibly exited. Zero or null cancels this functionality.";
+            }
             leaf reason {
                 type string;
             }
index 86cd6fa..5887e98 100644 (file)
@@ -11,8 +11,6 @@ import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.config.api.ValidationException;
-import org.opendaylight.controller.config.api.ValidationException.ExceptionMessageWithStackTrace;
 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
 import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
@@ -23,11 +21,8 @@ import org.osgi.framework.Bundle;
 import javax.management.JMX;
 import javax.management.ObjectName;
 import java.util.Collections;
-import java.util.Map;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
@@ -49,6 +44,9 @@ public class ShutdownTest extends AbstractConfigTest {
         doReturn(mockedSysBundle).when(mockedContext).getBundle(0);
         mockedContext.getBundle(0);
         doNothing().when(mockedSysBundle).stop();
+        ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
+        // initialize default instance
+        transaction.commit();
     }
 
     @Test
@@ -62,21 +60,20 @@ public class ShutdownTest extends AbstractConfigTest {
         }
     }
 
+    private static final ObjectName runtimeON = ObjectNameUtil.createRuntimeBeanName(NAME, NAME, Collections.<String, String>emptyMap());
+
     @Test
     public void testWithoutSecret() throws Exception {
-        ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
-        transaction.createModule(NAME, NAME);
-        transaction.commit();
         // test JMX rpc
-        ObjectName runtimeON = ObjectNameUtil.createRuntimeBeanName(NAME, NAME, Collections.<String, String>emptyMap());
+
         ShutdownRuntimeMXBean runtime = configRegistryClient.newMXBeanProxy(runtimeON, ShutdownRuntimeMXBean.class);
         try {
-            runtime.shutdown("foo", null);
+            runtime.shutdown("foo", 60000L, null);
             fail();
         } catch (IllegalArgumentException e) {
             assertEquals("Invalid secret", e.getMessage());
         }
-        runtime.shutdown("", null);
+        runtime.shutdown("", 60000L, null);
         assertStopped();
     }
 
@@ -84,57 +81,31 @@ public class ShutdownTest extends AbstractConfigTest {
     @Test
     public void testWithSecret() throws Exception {
         ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
-        ObjectName on = transaction.createModule(NAME, NAME);
+        ObjectName on = transaction.lookupConfigBean(NAME, NAME);
         ShutdownModuleMXBean proxy = transaction.newMXBeanProxy(on, ShutdownModuleMXBean.class);
         String secret = "secret";
         proxy.setSecret(secret);
         transaction.commit();
         shutdownViaRuntimeJMX(secret);
-
-        // test old secret
-        transaction = configRegistryClient.createTransaction();
-        on = transaction.lookupConfigBean(NAME, NAME);
-        proxy = transaction.newMXBeanProxy(on, ShutdownModuleMXBean.class);
-        try {
-            rethrowCause(proxy).getOldSecret();
-            fail();
-        } catch (UnsupportedOperationException e) {
-        }
         try {
-            rethrowCause(proxy).getSecret();
+            ShutdownRuntimeMXBean runtime = JMX.newMXBeanProxy(platformMBeanServer, runtimeON, ShutdownRuntimeMXBean.class);
+            runtime.shutdown("foo", 60000L, null);
             fail();
-        } catch (UnsupportedOperationException e) {
-        }
-        // set secret to nothing
-        String newSecret = "newSecret";
-        proxy.setSecret(newSecret);
-        try {
-            transaction.commit();
-            fail("Old secret not provided - should fail validation");
-        } catch (ValidationException e) {
-            Map<String, Map<String, ExceptionMessageWithStackTrace>> failedValidations = e.getFailedValidations();
-            assertTrue(failedValidations.containsKey(NAME));
-            ExceptionMessageWithStackTrace exceptionMessageWithStackTrace = failedValidations.get(NAME).get(NAME);
-            assertNotNull(exceptionMessageWithStackTrace);
-            assertEquals("OldSecret Invalid old secret", exceptionMessageWithStackTrace.getMessage());
-
+        } catch (IllegalArgumentException e) {
+            assertEquals("Invalid secret", e.getMessage());
         }
-        proxy.setOldSecret(secret);
-        transaction.commit();
-        shutdownViaRuntimeJMX(newSecret);
     }
 
     private void shutdownViaRuntimeJMX(String secret) throws Exception {
         // test JMX rpc
-        ObjectName runtimeON = ObjectNameUtil.createRuntimeBeanName(NAME, NAME, Collections.<String, String>emptyMap());
         ShutdownRuntimeMXBean runtime = JMX.newMXBeanProxy(platformMBeanServer, runtimeON, ShutdownRuntimeMXBean.class);
         try {
-            runtime.shutdown("", null);
+            runtime.shutdown("", 60000L, null);
             fail();
         } catch (IllegalArgumentException e) {
             assertEquals("Invalid secret", e.getMessage());
         }
-        runtime.shutdown(secret, null);
+        runtime.shutdown(secret, 60000L, null);
         assertStopped();
     }
 
index 5acdec8..a8dd607 100644 (file)
           </execution>
         </executions>
       </plugin>
+
+        <!--Make checkstyle ignore initial xml configuration files by overriding its configuration from parent-->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+        <version>${checkstyle.version}</version>
+        <configuration>
+            <excludes>**\/target\/,**\/bin\/,**\/target-ide\/,**\/configuration\/initial\/</excludes>
+        </configuration>
+      </plugin>
     </plugins>
   </build>
 </project>
index ffe53af..1f3e8e2 100755 (executable)
@@ -21,15 +21,15 @@ if [[ $platform == 'linux' ]]; then
     fi
 elif [[ $platform == 'osx' ]]; then
    TARGET_FILE=$0
-   cd `dirname $TARGET_FILE`
+   cd `dirname "$TARGET_FILE"`
    TARGET_FILE=`basename $TARGET_FILE`
 
    # Iterate down a (possible) chain of symlinks
    while [ -L "$TARGET_FILE" ]
    do
-       TARGET_FILE=`readlink $TARGET_FILE`
-       cd `dirname $TARGET_FILE`
-       TARGET_FILE=`basename $TARGET_FILE`
+       TARGET_FILE=`readlink "$TARGET_FILE"`
+       cd `dirname "$TARGET_FILE"`
+       TARGET_FILE=`basename "$TARGET_FILE"`
    done
 
    # Compute the canonicalized name by finding the physical path
@@ -47,13 +47,13 @@ fi
 JVM at path ${JAVA_HOME}/bin/java check your JAVA_HOME" && exit -1;
 
 if [ -z ${ODL_BASEDIR} ]; then
-    basedir=`dirname ${fullpath}`
+    basedir=`dirname "${fullpath}"`
 else
     basedir=${ODL_BASEDIR}
 fi
 
 if [ -z ${ODL_DATADIR} ]; then
-    datadir=`dirname ${fullpath}`
+    datadir=`dirname "${fullpath}"`
 else
     datadir=${ODL_DATADIR}
 fi
@@ -145,8 +145,8 @@ fi
 ########################################
 # Now add to classpath the OSGi JAR
 ########################################
-CLASSPATH=${basedir}/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar
-FWCLASSPATH=file:${basedir}/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar
+CLASSPATH="${basedir}"/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar
+FWCLASSPATH=file:"${basedir}"/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar
 
 ########################################
 # Now add the extensions
@@ -198,19 +198,24 @@ if [ "${statusdaemon}" -eq 1 ]; then
     fi
 fi
 
+iotmpdir=`echo "${datadir}" | sed 's/ /\\ /g'`
+bdir=`echo "${basedir}" | sed 's/ /\\ /g'`
+confarea=`echo "${datadir}" | sed 's/ /\\ /g'`
+fwclasspath=`echo "${FWCLASSPATH}" | sed 's/ /\\ /g'`
+
 if [ "${startdaemon}" -eq 1 ]; then
     if [ -e "${pidfile}" ]; then
         echo "Another instance of controller running, check with $0 -status"
         exit -1
     fi
     $JAVA_HOME/bin/java ${extraJVMOpts} \
-        -Djava.io.tmpdir=${datadir}/work/tmp \
-        -Dosgi.install.area=${basedir} \
-        -Dosgi.configuration.area=${datadir}/configuration \
-        -Dosgi.frameworkClassPath=${FWCLASSPATH} \
-        -Dosgi.framework=file:${basedir}/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar \
+        -Djava.io.tmpdir="${iotmpdir}/work/tmp" \
+        -Dosgi.install.area="${bdir}" \
+        -Dosgi.configuration.area="${confarea}/configuration" \
+        -Dosgi.frameworkClassPath="${fwclasspath}" \
+        -Dosgi.framework=file:"${bdir}/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar" \
         -Djava.awt.headless=true \
-        -classpath ${CLASSPATH} \
+        -classpath "${CLASSPATH}" \
         org.eclipse.equinox.launcher.Main \
         -console ${daemonport} \
         -consoleLog &
@@ -222,13 +227,13 @@ elif [ "${consolestart}" -eq 1 ]; then
         exit -1
     fi
     $JAVA_HOME/bin/java ${extraJVMOpts} \
-        -Djava.io.tmpdir=${datadir}/work/tmp \
-        -Dosgi.install.area=${basedir} \
-        -Dosgi.configuration.area=${datadir}/configuration \
-        -Dosgi.frameworkClassPath=${FWCLASSPATH} \
-        -Dosgi.framework=file:${basedir}/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar \
+        -Djava.io.tmpdir="${iotmpdir}/work/tmp" \
+        -Dosgi.install.area="${bdir}" \
+        -Dosgi.configuration.area="${confarea}/configuration" \
+        -Dosgi.frameworkClassPath="${fwclasspath}" \
+        -Dosgi.framework=file:"${bdir}/lib/org.eclipse.osgi-3.8.1.v20120830-144521.jar" \
         -Djava.awt.headless=true \
-        -classpath ${CLASSPATH} \
+        -classpath "${CLASSPATH}" \
         org.eclipse.equinox.launcher.Main \
         -console \
         -consoleLog
diff --git a/opendaylight/md-sal/clustered-data-store/integrationtest/src/test/resources/controller.config b/opendaylight/md-sal/clustered-data-store/integrationtest/src/test/resources/controller.config
deleted file mode 100644 (file)
index e49ba67..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-//START OF CONFIG-LAST
-<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
-<modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-    <module>
-        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:cluster:store">prefix:dom-clustered-store-impl</type>
-        <name>cluster-data-store</name>
-    </module>
-</modules>
-</data>
-
-
-//END OF SNAPSHOT
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:cluster:store?module=odl-sal-dom-clustered-store-cfg&revision=2013-10-28
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom?module=opendaylight-md-sal-dom&revision=2013-10-28
-urn:opendaylight:params:xml:ns:yang:controller:config?module=config&revision=2013-04-05
-urn:ietf:params:netconf:capability:candidate:1.0
-urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&revision=2010-10-04
-urn:ietf:params:xml:ns:yang:rpc-context?module=rpc-context&revision=2013-06-17
-urn:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&revision=2010-09-24
-urn:ietf:params:netconf:capability:rollback-on-error:1.0
-urn:ietf:params:xml:ns:yang:ietf-yang-types?module=ietf-yang-types&revision=2010-09-24
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:common?module=opendaylight-md-sal-common&revision=2013-10-28
-//END OF CONFIG
diff --git a/opendaylight/md-sal/clustered-data-store/integrationtest/src/test/resources/controller.xml b/opendaylight/md-sal/clustered-data-store/integrationtest/src/test/resources/controller.xml
new file mode 100644 (file)
index 0000000..96cf639
--- /dev/null
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<persisted-snapshots>
+    <snapshots>
+        <snapshot>
+            <required-capabilities>
+                <capability>
+                    urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:cluster:store?module=odl-sal-dom-clustered-store-cfg&amp;revision=2013-10-28
+                </capability>
+                <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom?module=opendaylight-md-sal-dom&amp;revision=2013-10-28</capability>
+                <capability>
+                    urn:opendaylight:params:xml:ns:yang:controller:config?module=config&amp;revision=2013-04-05
+                </capability>
+                <capability>urn:ietf:params:netconf:capability:candidate:1.0</capability>
+                <capability>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&amp;revision=2010-10-04</capability>
+                <capability>urn:ietf:params:xml:ns:yang:rpc-context?module=rpc-context&amp;revision=2013-06-17
+                </capability>
+                <capability>urn:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&amp;revision=2010-09-24
+                </capability>
+                <capability>urn:ietf:params:netconf:capability:rollback-on-error:1.0</capability>
+                <capability>urn:ietf:params:xml:ns:yang:ietf-yang-types?module=ietf-yang-types&amp;revision=2010-09-24
+                </capability>
+                <capability>
+                    urn:opendaylight:params:xml:ns:yang:controller:md:sal:common?module=opendaylight-md-sal-common&amp;revision=2013-10-28
+                </capability>
+            </required-capabilities>
+            <configuration>
+
+                <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+                    <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+                        <module>
+                            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:cluster:store">
+                                prefix:dom-clustered-store-impl
+                            </type>
+                            <name>cluster-data-store</name>
+                        </module>
+                    </modules>
+
+                    <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+
+                    </services>
+                </data>
+
+            </configuration>
+        </snapshot>
+    </snapshots>
+</persisted-snapshots>
index 5a4aae3..44c0c04 100644 (file)
@@ -2,23 +2,23 @@ package org.opendaylight.controller.md.compatibility.topology
 
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
 import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.TopologyKey
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.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
 import org.opendaylight.controller.sal.core.Edge
 import java.util.Set
 import org.opendaylight.controller.sal.core.Property
 import org.opendaylight.controller.sal.core.NodeConnector
 
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPoint
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Link
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPointKey
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TpId
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.NodeKey
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NodeId
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.LinkKey
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.LinkId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.LinkKey
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.LinkId
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Node
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node
 import org.opendaylight.controller.sal.compatibility.InventoryMapping
 class TopologyMapping {
 
index fb9d2b8..6c0e50e 100644 (file)
@@ -6,26 +6,26 @@ import org.opendaylight.controller.md.sal.common.api.data.DataReader
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
 import org.opendaylight.yangtools.yang.binding.DataObject
 import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.Topology
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Node
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPoint
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Link
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.TopologyKey
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NetworkTopology
+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.topology.Node
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link
+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.NetworkTopology
 import org.opendaylight.controller.md.compatibility.topology.TopologyMapping
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.LinkBuilder
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.LinkBuilder
 
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.TopologyBuilder
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder
 import java.util.ArrayList
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.NodeBuilder
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.NodeKey
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey
 import org.opendaylight.controller.sal.core.NodeConnector
 import org.opendaylight.controller.sal.topology.TopoEdgeUpdate
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TopologyId
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPointBuilder
+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.node.TerminationPointBuilder
 import org.opendaylight.controller.sal.core.Edge
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.link.attributes.SourceBuilder
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.link.attributes.DestinationBuilder
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.link.attributes.SourceBuilder
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.link.attributes.DestinationBuilder
 
 class TopologyReader implements RuntimeDataProvider {
 
index ad7537b..c8050b1 100644 (file)
@@ -1,16 +1,16 @@
 package org.opendaylight.controller.md.compatibility.topologymanager
 
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.TopologyKey
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPoint
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint
 import org.opendaylight.controller.sal.core.NodeConnector
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.Topology
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NetworkTopology
+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.NetworkTopology
 import java.util.Map
 import org.opendaylight.controller.sal.core.Edge
 import java.util.Set
 import java.util.List
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Node
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node
 import java.util.Collections
 import com.google.common.collect.FluentIterable
 import java.util.HashSet
@@ -18,13 +18,13 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeCon
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId
 import org.opendaylight.controller.sal.compatibility.NodeMapping
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Link
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.link.attributes.Source
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.link.attributes.Destination
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.link.attributes.Source
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.link.attributes.Destination
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TpId
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPointKey
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey
 import java.util.HashMap
 
 class AdSalTopologyMapping {
@@ -69,7 +69,7 @@ class AdSalTopologyMapping {
     }
 
     def org.opendaylight.controller.sal.core.Node toAdNode(
-        org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NodeId node) {
+        org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId node) {
         val key = new NodeKey(new NodeId(node))
         return new org.opendaylight.controller.sal.core.Node(NodeMapping.MD_SAL_TYPE, key);
     }
index c6a4912..23924c8 100644 (file)
@@ -8,7 +8,7 @@ import java.util.Set
 import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
 import java.util.HashMap
 import org.opendaylight.controller.sal.core.Edge
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.node.TerminationPoint
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint
 import com.google.common.collect.FluentIterable
 
 class CompatibleTopologyManager extends ConfigurableLinkManager implements ITopologyManager {
index bd2590f..c4a1108 100644 (file)
@@ -4,10 +4,10 @@ import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService
 import org.opendaylight.controller.sal.topology.IPluginInTopologyService
 import org.opendaylight.controller.sal.topology.IPluginOutTopologyService
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NetworkTopology
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TopologyId
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.Topology
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.TopologyKey
+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.yangtools.yang.binding.InstanceIdentifier
 
 import static extension org.opendaylight.controller.sal.compatibility.topology.TopologyMapping.*
index 7d05ce6..c02067a 100644 (file)
@@ -9,11 +9,11 @@ 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.rev130712.NetworkTopology
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TopologyId
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.Topology
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.TopologyKey
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Link
+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.*
index 62983cc..cd4b818 100644 (file)
@@ -10,10 +10,10 @@ import org.opendaylight.controller.sal.core.Node
 import org.opendaylight.controller.sal.core.NodeConnector
 import org.opendaylight.controller.sal.core.UpdateType
 import org.opendaylight.controller.sal.topology.TopoEdgeUpdate
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NodeId
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TpId
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.Topology
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.topology.Link
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId
+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.topology.Link
 
 import static com.google.common.base.Preconditions.*
 import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.*
index 1fde282..bf1a23d 100644 (file)
@@ -2,15 +2,15 @@ package org.opendaylight.controller.sal.compatibility.topology
 
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService
 import org.opendaylight.controller.sal.topology.IPluginOutTopologyService
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.NetworkTopology
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.TopologyId
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.Topology
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712.network.topology.TopologyKey
+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.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.rev130712.network.topology.topology.Link
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link
 import org.slf4j.LoggerFactory
 
 class TopologyProvider implements AutoCloseable{
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/FRMConsumerImpl.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/FRMConsumerImpl.java
deleted file mode 100644 (file)
index bbe771f..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (c) 2013 Ericsson , 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.forwardingrulesmanager.consumer.impl;
-
-import org.eclipse.osgi.framework.console.CommandProvider;
-import org.opendaylight.controller.clustering.services.IClusterContainerServices;
-import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
-import org.opendaylight.controller.sal.binding.api.NotificationService;
-import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
-import org.opendaylight.controller.sal.core.IContainer;
-import org.opendaylight.controller.sal.utils.ServiceHelper;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class FRMConsumerImpl extends AbstractBindingAwareProvider implements CommandProvider {
-    protected static final Logger logger = LoggerFactory.getLogger(FRMConsumerImpl.class);
-    private static ProviderContext p_session;
-    private static DataBrokerService dataBrokerService;
-    private static NotificationService notificationService;
-    private FlowConsumerImpl flowImplRef;
-    private GroupConsumerImpl groupImplRef;
-    private MeterConsumerImpl meterImplRef;
-    private static DataProviderService dataProviderService;
-    private static IClusterContainerServices clusterContainerService = null;
-    private static IContainer container;
-    
-    @Override
-    public void onSessionInitiated(ProviderContext session) {
-        FRMConsumerImpl.p_session = session;
-
-        if (!getDependentModule()) {
-            logger.error("Unable to fetch handlers for dependent modules");
-            System.out.println("Unable to fetch handlers for dependent modules");
-            return;
-        }
-
-        if (null != session) {
-            notificationService = session.getSALService(NotificationService.class);
-
-            if (null != notificationService) {
-                dataBrokerService = session.getSALService(DataBrokerService.class);
-
-                if (null != dataBrokerService) {
-                    dataProviderService = session.getSALService(DataProviderService.class);
-
-                    if (null != dataProviderService) {
-                        flowImplRef = new FlowConsumerImpl();
-                        groupImplRef = new GroupConsumerImpl();
-                        meterImplRef = new MeterConsumerImpl();
-                        registerWithOSGIConsole();
-                    } else {
-                        logger.error("Data Provider Service is down or NULL. "
-                                + "Accessing data from configuration data store will not be possible");
-                        System.out.println("Data Broker Service is down or NULL.");
-                    }
-
-                } else {
-                    logger.error("Data Broker Service is down or NULL.");
-                    System.out.println("Data Broker Service is down or NULL.");
-                }
-            } else {
-                logger.error("Notification Service is down or NULL.");
-                System.out.println("Notification Service is down or NULL.");
-            }
-        } else {
-            logger.error("Consumer session is NULL. Please check if provider is registered");
-            System.out.println("Consumer session is NULL. Please check if provider is registered");
-        }
-
-    }
-
-    public static IClusterContainerServices getClusterContainerService() {
-        return clusterContainerService;
-    }
-
-    public static void setClusterContainerService(IClusterContainerServices clusterContainerService) {
-        FRMConsumerImpl.clusterContainerService = clusterContainerService;
-    }
-
-    public static IContainer getContainer() {
-        return container;
-    }
-
-    public static void setContainer(IContainer container) {
-        FRMConsumerImpl.container = container;
-    }
-
-    private void registerWithOSGIConsole() {
-        BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
-        bundleContext.registerService(CommandProvider.class.getName(), this, null);
-    }
-
-    private boolean getDependentModule() {
-        do {
-            clusterContainerService = (IClusterContainerServices) ServiceHelper.getGlobalInstance(
-                    IClusterContainerServices.class, this);
-            try {
-                Thread.sleep(4);
-            } catch (InterruptedException e) {
-                // TODO Auto-generated catch block
-                e.printStackTrace();
-            }
-        } while (clusterContainerService == null);
-
-        do {
-
-            container = (IContainer) ServiceHelper.getGlobalInstance(IContainer.class, this);
-            try {
-                Thread.sleep(5);
-            } catch (InterruptedException e) {
-                // TODO Auto-generated catch block
-                e.printStackTrace();
-            }
-        } while (container == null);
-
-        return true;
-    }
-
-    public static DataProviderService getDataProviderService() {
-        return dataProviderService;
-    }
-
-    public FlowConsumerImpl getFlowImplRef() {
-        return flowImplRef;
-    }
-
-    public GroupConsumerImpl getGroupImplRef() {
-        return groupImplRef;
-    }
-
-    public static ProviderContext getProviderSession() {
-        return p_session;
-    }
-
-    public static NotificationService getNotificationService() {
-        return notificationService;
-    }
-
-    public static DataBrokerService getDataBrokerService() {
-        return dataBrokerService;
-    }
-
-    /*
-     * OSGI COMMANDS
-     */
-    @Override
-    public String getHelp() {
-        StringBuffer help = new StringBuffer();
-        return help.toString();
-    }
-
-}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/FRMUtil.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/FRMUtil.java
deleted file mode 100644 (file)
index ab2e19e..0000000
+++ /dev/null
@@ -1,402 +0,0 @@
-package org.opendaylight.controller.forwardingrulesmanager.consumer.impl;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.opendaylight.controller.sal.core.NodeConnector.NodeConnectorIDType;
-import org.opendaylight.controller.sal.utils.IPProtocols;
-import org.opendaylight.controller.sal.utils.NetUtils;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.ControllerActionCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushMplsActionCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushPbbActionCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlDstActionCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlSrcActionCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetQueueActionCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetTpDstActionCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetTpSrcActionCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdActionCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanPcpActionCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanPcp;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatch;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatch;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatch;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6Match;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ClearActionsCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.MeterCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteActionsCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
-
-public class FRMUtil {
-    protected static final Logger logger = LoggerFactory.getLogger(FRMUtil.class);
-    private static final String NAMEREGEX = "^[a-zA-Z0-9]+$";
-
-    public static enum operation {
-        ADD, DELETE, UPDATE, GET
-    };
-
-    private enum EtherIPType {
-        ANY, V4, V6;
-    };
-
-    public static boolean isNameValid(String name) {
-
-        // Name validation
-        if (name == null || name.trim().isEmpty() || !name.matches(NAMEREGEX)) {
-            return false;
-        }
-        return true;
-
-    }
-
-    public static boolean validateMatch(Flow flow) {
-        EtherIPType etype = EtherIPType.ANY;
-        EtherIPType ipsrctype = EtherIPType.ANY;
-        EtherIPType ipdsttype = EtherIPType.ANY;
-
-        Match match = flow.getMatch();
-        if (match != null) {
-            EthernetMatch ethernetmatch = match.getEthernetMatch();
-            IpMatch ipmatch = match.getIpMatch();
-            Layer3Match layer3match = match.getLayer3Match();
-            VlanMatch vlanmatch = match.getVlanMatch();
-            match.getIcmpv4Match();
-
-            if (ethernetmatch != null) {
-                if ((ethernetmatch.getEthernetSource() != null)
-                        && !isL2AddressValid(ethernetmatch.getEthernetSource().getAddress().getValue())) {
-
-                    logger.error("Ethernet source address is not valid. Example: 00:05:b9:7c:81:5f",
-                            ethernetmatch.getEthernetSource());
-                    return false;
-                }
-
-                if ((ethernetmatch.getEthernetDestination() != null)
-                        && !isL2AddressValid(ethernetmatch.getEthernetDestination().getAddress().getValue())) {
-                    logger.error("Ethernet destination address is not valid. Example: 00:05:b9:7c:81:5f",
-                            ethernetmatch.getEthernetDestination());
-                    return false;
-                }
-
-                if (ethernetmatch.getEthernetType() != null) {
-                    long type = ethernetmatch.getEthernetType().getType().getValue().longValue();
-                    if ((type < 0) || (type > 0xffff)) {
-                        logger.error("Ethernet type is not valid");
-                        return false;
-                    } else {
-                        if (type == 0x0800) {
-                            etype = EtherIPType.V4;
-                        } else if (type == 0x86dd) {
-                            etype = EtherIPType.V6;
-                        }
-                    }
-
-                }
-            }
-
-            if (layer3match != null) {
-                if (layer3match instanceof Ipv4Match) {
-                    if (((Ipv4Match) layer3match).getIpv4Source() != null) {
-                        if (NetUtils.isIPv4AddressValid(((Ipv4Match) layer3match).getIpv4Source().getValue())) {
-                            ipsrctype = EtherIPType.V4;
-                        } else {
-                            logger.error("IP source address is not valid");
-                            return false;
-                        }
-
-                    } else if (((Ipv4Match) layer3match).getIpv4Destination() != null) {
-                        if (NetUtils.isIPv4AddressValid(((Ipv4Match) layer3match).getIpv4Destination().getValue())) {
-                            ipdsttype = EtherIPType.V4;
-                        } else {
-                            logger.error("IP Destination address is not valid");
-                            return false;
-                        }
-
-                    }
-                } else if (layer3match instanceof Ipv6Match) {
-                    if (((Ipv6Match) layer3match).getIpv6Source() != null) {
-                        if (NetUtils.isIPv6AddressValid(((Ipv6Match) layer3match).getIpv6Source().getValue())) {
-                            ipsrctype = EtherIPType.V6;
-                        } else {
-                            logger.error("IPv6 source address is not valid");
-                            return false;
-                        }
-
-                    } else if (((Ipv6Match) layer3match).getIpv6Destination() != null) {
-                        if (NetUtils.isIPv6AddressValid(((Ipv6Match) layer3match).getIpv6Destination().getValue())) {
-                            ipdsttype = EtherIPType.V6;
-                        } else {
-                            logger.error("IPv6 Destination address is not valid");
-                            return false;
-                        }
-
-                    }
-
-                }
-
-                if (etype != EtherIPType.ANY) {
-                    if ((ipsrctype != EtherIPType.ANY) && (ipsrctype != etype)) {
-                        logger.error("Type mismatch between Ethernet & Src IP");
-                        return false;
-                    }
-                    if ((ipdsttype != EtherIPType.ANY) && (ipdsttype != etype)) {
-                        logger.error("Type mismatch between Ethernet & Dst IP");
-                        return false;
-                    }
-                }
-                if (ipsrctype != ipdsttype) {
-                    if (!((ipsrctype == EtherIPType.ANY) || (ipdsttype == EtherIPType.ANY))) {
-                        logger.error("IP Src Dest Type mismatch");
-                        return false;
-                    }
-                }
-            }
-
-            if (ipmatch != null) {
-                if (ipmatch.getIpProtocol() != null && !(isProtocolValid(ipmatch.getIpProtocol().toString()))) {
-                    logger.error("Protocol is not valid");
-                    return false;
-                }
-
-            }
-
-            if (vlanmatch != null) {
-                if (vlanmatch.getVlanId() != null
-                        && !(isVlanIdValid(vlanmatch.getVlanId().getVlanId().getValue().toString()))) {
-                    logger.error("Vlan ID is not in the range 0 - 4095");
-                    return false;
-                }
-
-                if (vlanmatch.getVlanPcp() != null
-                        && !(isVlanPriorityValid(vlanmatch.getVlanPcp().getValue().toString()))) {
-                    logger.error("Vlan priority is not in the range 0 - 7");
-                    return false;
-                }
-            }
-
-        }
-
-        return true;
-
-    }
-
-    public static boolean validateActions(List<Action> actions) {
-
-        if (actions == null || actions.isEmpty()) {
-            logger.error("Actions value is null or empty");
-            return false;
-        }
-
-        for (Action curaction : actions) {
-            org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action = curaction
-                    .getAction();
-            if (action instanceof ControllerActionCase) {
-                Integer length = ((ControllerActionCase) action).getControllerAction().getMaxLength();
-                if (length < 0 || length > 65294) {
-                    logger.error("Controller: MaxLength is not valid");
-                    return false;
-                }
-            } else if (action instanceof OutputActionCase) {
-                Integer length = ((OutputActionCase) action).getOutputAction().getMaxLength();
-                Uri outputnodeconnector = ((OutputActionCase) action).getOutputAction().getOutputNodeConnector();
-                if (length < 0 || length > 65294) {
-                    logger.error("OutputAction: MaxLength is not valid");
-                    return false;
-                }
-                if (outputnodeconnector != null) {
-                    if (!outputnodeconnector.getValue().equals(NodeConnectorIDType.ALL)
-                            || !outputnodeconnector.getValue().equals(NodeConnectorIDType.CONTROLLER)
-                            || !outputnodeconnector.getValue().equals(NodeConnectorIDType.HWPATH)
-                            || !outputnodeconnector.getValue().equals(NodeConnectorIDType.ONEPK)
-                            || !outputnodeconnector.getValue().equals(NodeConnectorIDType.ONEPK2OPENFLOW)
-                            || !outputnodeconnector.getValue().equals(NodeConnectorIDType.ONEPK2PCEP)
-                            || !outputnodeconnector.getValue().equals(NodeConnectorIDType.OPENFLOW)
-                            || !outputnodeconnector.getValue().equals(NodeConnectorIDType.OPENFLOW2ONEPK)
-                            || !outputnodeconnector.getValue().equals(NodeConnectorIDType.OPENFLOW2PCEP)
-                            || !outputnodeconnector.getValue().equals(NodeConnectorIDType.PCEP)
-                            || !outputnodeconnector.getValue().equals(NodeConnectorIDType.PCEP2ONEPK)
-                            || !outputnodeconnector.getValue().equals(NodeConnectorIDType.PCEP2OPENFLOW)
-                            || !outputnodeconnector.getValue().equals(NodeConnectorIDType.PRODUCTION)
-                            || !outputnodeconnector.getValue().equals(NodeConnectorIDType.SWSTACK)) {
-                        logger.error("Output Action: NodeConnector Type is not valid");
-                        return false;
-                    }
-
-                }
-            } else if (action instanceof PushMplsActionCase) {
-                Integer ethertype = ((PushMplsActionCase) action).getPushMplsAction().getEthernetType();
-                if (ethertype != null && ethertype != 0x8847 && ethertype != 0x8848) {
-                    logger.error("Ether Type is not valid for PushMplsAction");
-                    return false;
-                }
-            } else if (action instanceof PushPbbActionCase) {
-                Integer ethertype = ((PushPbbActionCase) action).getPushPbbAction().getEthernetType();
-                if (ethertype != null && ethertype != 0x88E7) {
-                    logger.error("Ether type is not valid for PushPbbAction");
-                    return false;
-                }
-            } else if (action instanceof PushVlanActionCase) {
-                Integer ethertype = ((PushVlanActionCase) action).getPushVlanAction().getEthernetType();
-                if (ethertype != null && ethertype != 0x8100 && ethertype != 0x88a8) {
-                    logger.error("Ether Type is not valid for PushVlanAction");
-                    return false;
-                }
-            } else if (action instanceof SetDlDstActionCase || action instanceof SetDlSrcActionCase) {
-                MacAddress address = ((SetDlDstActionCase) action).getSetDlDstAction().getAddress();
-                if (address != null && !isL2AddressValid(address.getValue())) {
-                    logger.error("SetDlDstAction: Address not valid");
-                    return false;
-                }
-            } else if (action instanceof SetDlSrcActionCase) {
-                MacAddress address = ((SetDlSrcActionCase) action).getSetDlSrcAction().getAddress();
-                if (address != null && !isL2AddressValid(address.getValue())) {
-                    logger.error("SetDlSrcAction: Address not valid");
-                    return false;
-                }
-            } else if (action instanceof SetQueueActionCase) {
-                String queue = ((SetQueueActionCase) action).getSetQueueAction().getQueue();
-                if (queue != null && !isQueueValid(queue)) {
-                    logger.error("Queue Id not valid");
-                    return false;
-                }
-            } else if (action instanceof SetTpDstActionCase) {
-                PortNumber port = ((SetTpDstActionCase) action).getSetTpDstAction().getPort();
-                if (port != null && !isPortValid(port)) {
-                    logger.error("Port not valid");
-                }
-            } else if (action instanceof SetTpSrcActionCase) {
-                PortNumber port = ((SetTpSrcActionCase) action).getSetTpSrcAction().getPort();
-                if (port != null && !isPortValid(port)) {
-                    logger.error("Port not valid");
-                }
-            } else if (action instanceof SetVlanIdActionCase) {
-                VlanId vlanid = ((SetVlanIdActionCase) action).getSetVlanIdAction().getVlanId();
-                if (vlanid != null && !isVlanIdValid(vlanid.toString())) {
-                    logger.error("Vlan ID %s is not in the range 0 - 4095");
-                    return false;
-                }
-            } else if (action instanceof SetVlanPcpActionCase) {
-                VlanPcp vlanpcp = ((SetVlanPcpActionCase) action).getSetVlanPcpAction().getVlanPcp();
-                if (vlanpcp != null && !isVlanPriorityValid(vlanpcp.toString())) {
-                    logger.error("Vlan priority %s is not in the range 0 - 7");
-                    return false;
-                }
-            }
-        }
-        return true;
-
-    }
-
-    public static boolean validateInstructions(Flow flow) {
-        List<Instruction> instructionsList = new ArrayList<>();
-        Instructions instructions = flow.getInstructions();
-        if (instructions == null) {
-            return false;
-        }
-        instructionsList = instructions.getInstruction();
-
-        for (Instruction instruction : instructionsList) {
-            org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction curInstruction = instruction
-                    .getInstruction();
-            if (curInstruction instanceof GoToTableCase) {
-
-                Short tableid = ((GoToTableCase) curInstruction).getGoToTable().getTableId();
-                if (tableid < 0) {
-                    logger.error("table id is not valid");
-                    return false;
-                }
-            }
-
-            else if (curInstruction instanceof WriteActionsCase) {
-
-                List<Action> action = ((WriteActionsCase) curInstruction).getWriteActions().getAction();
-                validateActions(action);
-
-            }
-
-            else if (curInstruction instanceof ApplyActionsCase) {
-                List<Action> action = ((ApplyActionsCase) curInstruction).getApplyActions().getAction();
-                validateActions(action);
-            }
-
-            else if (curInstruction instanceof ClearActionsCase) {
-                List<Action> action = ((ClearActionsCase) curInstruction).getClearActions().getAction();
-                validateActions(action);
-            }
-
-            else if (curInstruction instanceof MeterCase) {
-
-                MeterId meter = ((MeterCase) curInstruction).getMeter().getMeterId();
-                if (meter != null && !isValidMeter(meter)) {
-                    logger.error("Meter Id is not valid");
-                    return false;
-                }
-            }
-
-        }
-
-        return true;
-    }
-
-    public static boolean isValidMeter(MeterId meter) {
-        // TODO
-        return true;
-    }
-
-    public static boolean isQueueValid(String queue) {
-        // TODO
-        return true;
-    }
-
-    public static boolean isPortValid(PortNumber port) {
-        // TODO
-        return true;
-    }
-
-    public static boolean isL2AddressValid(String mac) {
-        if (mac == null) {
-            return false;
-        }
-
-        Pattern macPattern = Pattern.compile("([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}");
-        Matcher mm = macPattern.matcher(mac);
-        if (!mm.matches()) {
-            logger.debug("Ethernet address {} is not valid. Example: 00:05:b9:7c:81:5f", mac);
-            return false;
-        }
-        return true;
-    }
-
-    public static boolean isProtocolValid(String protocol) {
-        IPProtocols proto = IPProtocols.fromString(protocol);
-        return (proto != null);
-    }
-
-    public static boolean isVlanIdValid(String vlanId) {
-        int vlan = Integer.decode(vlanId);
-        return ((vlan >= 0) && (vlan < 4096));
-    }
-
-    public static boolean isVlanPriorityValid(String vlanPriority) {
-        int pri = Integer.decode(vlanPriority);
-        return ((pri >= 0) && (pri < 8));
-    }
-}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/FlowConsumerImpl.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/FlowConsumerImpl.java
deleted file mode 100644 (file)
index d2f2420..0000000
+++ /dev/null
@@ -1,365 +0,0 @@
-package org.opendaylight.controller.forwardingrulesmanager.consumer.impl;
-
-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.md.sal.common.api.data.DataCommitHandler;
-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.yang.gen.v1.urn.opendaylight.flow.config.rev130819.Flows;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAdded;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemoved;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowTableRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowUpdated;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeErrorNotification;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeExperimenterErrorNotification;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowListener;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SwitchFlowRemoved;
-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.inventory.rev130819.NodeRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.config.rev131024.Tables;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.config.rev131024.tables.Table;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.config.rev131024.tables.TableBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.config.rev131024.tables.TableKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableRef;
-import org.opendaylight.yangtools.concepts.Registration;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.NotificationListener;
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class FlowConsumerImpl {
-    protected static final Logger logger = LoggerFactory.getLogger(FlowConsumerImpl.class);
-    private final FlowEventListener flowEventListener = new FlowEventListener();
-    private Registration<NotificationListener> listener1Reg;
-    private SalFlowService flowService;
-    // private FlowDataListener listener;
-    private FlowDataCommitHandler commitHandler;    
-
-    public FlowConsumerImpl() {
-        InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(Flows.class).toInstance();
-        flowService = FRMConsumerImpl.getProviderSession().getRpcService(SalFlowService.class);
-
-        if (null == flowService) {
-            logger.error("Consumer SAL Service is down or NULL. FRM may not function as intended");
-            return;
-        }
-        
-        // For switch events
-        listener1Reg = FRMConsumerImpl.getNotificationService().registerNotificationListener(flowEventListener);
-
-        if (null == listener1Reg) {
-            logger.error("Listener to listen on flow data modifcation events");
-            return;
-        }
-        // addFlowTest();
-        commitHandler = new FlowDataCommitHandler();
-        FRMConsumerImpl.getDataProviderService().registerCommitHandler(path, commitHandler);        
-    }
-    
-    /**
-     * Adds flow to the southbound plugin and our internal database
-     *
-     * @param path
-     * @param dataObject
-     */
-    private void addFlow(InstanceIdentifier<?> path, Flow dataObject) {
-
-        AddFlowInputBuilder input = new AddFlowInputBuilder();
-        input.fieldsFrom(dataObject);
-        input.setNode((dataObject).getNode());
-        input.setFlowTable(new FlowTableRef(createTableInstance(dataObject.getId(), dataObject.getNode())));
-        // We send flow to the sounthbound plugin
-        flowService.addFlow(input.build());
-    }
-
-    /**
-     * Removes flow to the southbound plugin and our internal database
-     *
-     * @param path
-     * @param dataObject
-     */
-    private void removeFlow(InstanceIdentifier<?> path, Flow dataObject) {
-        
-        RemoveFlowInputBuilder input = new RemoveFlowInputBuilder();
-        input.fieldsFrom(dataObject);
-        input.setNode((dataObject).getNode());
-        input.setTableId(dataObject.getTableId());
-        input.setFlowTable(new FlowTableRef(createTableInstance((long)dataObject.getTableId(), (dataObject).getNode())));
-        // We send flow to the sounthbound plugin
-        flowService.removeFlow(input.build());
-    }
-
-    /**
-     * Update flow to the southbound plugin and our internal database
-     *
-     * @param path
-     * @param dataObject
-     */
-    private void updateFlow(InstanceIdentifier<?> path, Flow updatedFlow, Flow originalFlow) {
-
-        UpdateFlowInputBuilder input = new UpdateFlowInputBuilder();
-        UpdatedFlowBuilder updatedflowbuilder = new UpdatedFlowBuilder();
-        updatedflowbuilder.fieldsFrom(updatedFlow);
-        input.setNode(updatedFlow.getNode());
-        input.setUpdatedFlow(updatedflowbuilder.build());  
-        OriginalFlowBuilder ofb = new OriginalFlowBuilder(originalFlow);
-        input.setOriginalFlow(ofb.build());
-        // We send flow to the sounthbound plugin
-        flowService.updateFlow(input.build());
-    }
-    private void commitToPlugin(internalTransaction transaction) {
-        Set<Entry<InstanceIdentifier<?>, DataObject>> createdEntries = transaction.getModification()
-                .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.
-         */
-        Set<Entry<InstanceIdentifier<?>, DataObject>> updatedEntries = new HashSet<Entry<InstanceIdentifier<?>, DataObject>>();
-        updatedEntries.addAll(transaction.getModification().getUpdatedConfigurationData().entrySet());
-        updatedEntries.removeAll(createdEntries);
-
-        Set<InstanceIdentifier<?>> removeEntriesInstanceIdentifiers = transaction.getModification()
-                .getRemovedConfigurationData();
-        transaction.getModification().getOriginalConfigurationData();
-        for (Entry<InstanceIdentifier<?>, DataObject> entry : createdEntries) {
-            if (entry.getValue() instanceof Flow) {
-                logger.debug("Coming add cc in FlowDatacommitHandler");
-                Flow flow = (Flow) entry.getValue();
-                boolean status = validate(flow);
-                if (!status) {
-                    return;
-                }
-                addFlow(entry.getKey(), (Flow) entry.getValue());
-            }
-        }
-       
-        for (Entry<InstanceIdentifier<?>, DataObject> entry : updatedEntries) {
-            if (entry.getValue() instanceof Flow) {
-                logger.debug("Coming update cc in FlowDatacommitHandler");
-                Flow updatedFlow = (Flow) entry.getValue();
-                Flow originalFlow = (Flow) transaction.modification.getOriginalConfigurationData().get(entry.getKey());
-                boolean status = validate(updatedFlow);
-                if (!status) {
-                    return;
-                }
-                updateFlow(entry.getKey(), updatedFlow, originalFlow);
-            }
-        }
-
-        for (InstanceIdentifier<?> instanceId : removeEntriesInstanceIdentifiers) {
-            DataObject removeValue = transaction.getModification().getOriginalConfigurationData().get(instanceId);
-            if (removeValue instanceof Flow) {
-                logger.debug("Coming remove cc in FlowDatacommitHandler");
-                Flow flow = (Flow) removeValue;
-                boolean status = validate(flow);
-                
-                if (!status) {
-                    return;
-                }
-                
-                removeFlow(instanceId, (Flow) removeValue);
-            }
-        }
-    }
-
-    private final class FlowDataCommitHandler implements DataCommitHandler<InstanceIdentifier<?>, DataObject> {   
-     
-        @SuppressWarnings("unchecked")
-        public DataCommitTransaction<InstanceIdentifier<?>, DataObject> requestCommit(DataModification<InstanceIdentifier<?>, DataObject> modification) {
-            // We should verify transaction
-            logger.debug("Coming in FlowDatacommitHandler");
-            internalTransaction transaction = new internalTransaction(modification);
-            transaction.prepareUpdate();
-            return transaction;
-        }
-    }
-
-    private final class internalTransaction implements DataCommitTransaction<InstanceIdentifier<?>, DataObject> {
-
-        private final DataModification<InstanceIdentifier<?>, DataObject> modification;
-
-        @Override
-        public DataModification<InstanceIdentifier<?>, DataObject> getModification() {
-            return modification;
-        }
-
-        public internalTransaction(DataModification<InstanceIdentifier<?>, DataObject> modification) {
-            this.modification = modification;
-        }
-        
-        /**
-         * We create a plan which flows will be added, which will be updated and
-         * which will be removed based on our internal state.
-         *
-         */
-        void prepareUpdate() {          
-
-        }
-       
-        /**
-         * We are OK to go with execution of plan
-         *
-         */
-        @Override
-        public RpcResult<Void> finish() throws IllegalStateException {
-            commitToPlugin(this);            
-            return Rpcs.getRpcResult(true, null, Collections.<RpcError> emptySet());
-        }
-
-        /**
-         *
-         * We should rollback our preparation
-         *
-         */
-        @Override
-        public RpcResult<Void> rollback() throws IllegalStateException {       
-            rollBackFlows(modification);
-            return Rpcs.getRpcResult(true, null, Collections.<RpcError> emptySet());
-
-        }       
-    }
-
-    private void rollBackFlows(DataModification<InstanceIdentifier<?>, DataObject> modification) {
-     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.
-     */
-    Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> updatedEntries = new HashSet<Entry<InstanceIdentifier<? extends DataObject>, DataObject>>();
-    updatedEntries.addAll(modification.getUpdatedConfigurationData().entrySet());
-    updatedEntries.removeAll(createdEntries);
-
-    Set<InstanceIdentifier<? >> removeEntriesInstanceIdentifiers = modification.getRemovedConfigurationData();
-    for (Entry<InstanceIdentifier<?>, DataObject> entry : createdEntries) {
-        if(entry.getValue() instanceof Flow) {
-            removeFlow(entry.getKey(),(Flow) entry.getValue()); // because we are rolling back, remove what we would have added.
-        }
-    }
-    
-    for (Entry<InstanceIdentifier<?>, DataObject> entry : updatedEntries) {
-        if(entry.getValue() instanceof Flow) {            
-            Flow updatedFlow = (Flow) entry.getValue();
-            Flow originalFlow = (Flow) modification.getOriginalConfigurationData().get(entry.getKey());
-            updateFlow(entry.getKey(), updatedFlow ,originalFlow);// because we are rolling back, replace the updated with the original
-        }
-    }
-
-    for (InstanceIdentifier<?> instanceId : removeEntriesInstanceIdentifiers ) {
-        DataObject removeValue = (Flow) modification.getOriginalConfigurationData().get(instanceId);
-        if(removeValue instanceof Flow) {
-            addFlow(instanceId,(Flow) removeValue);// because we are rolling back, add what we would have removed.
-
-        }
-    }
-}
-    final class FlowEventListener implements SalFlowListener {
-
-        List<FlowAdded> addedFlows = new ArrayList<>();
-        List<FlowRemoved> removedFlows = new ArrayList<>();
-        List<FlowUpdated> updatedFlows = new ArrayList<>();
-
-        @Override
-        public void onFlowAdded(FlowAdded notification) {
-            addedFlows.add(notification);
-        }
-
-        @Override
-        public void onFlowRemoved(FlowRemoved notification) {
-            removedFlows.add(notification);
-        }
-
-        @Override
-        public void onFlowUpdated(FlowUpdated notification) {
-            updatedFlows.add(notification);
-        }
-
-        @Override
-        public void onNodeErrorNotification(NodeErrorNotification notification) {
-            // TODO Auto-generated method stub
-
-        }
-
-        @Override
-        public void onNodeExperimenterErrorNotification(NodeExperimenterErrorNotification notification) {
-            // TODO Auto-generated method stub
-
-        }
-
-        @Override
-        public void onSwitchFlowRemoved(SwitchFlowRemoved notification) {
-            // TODO Auto-generated method stub
-
-        }
-    }
-
-    public boolean validate(Flow flow) {
-        String msg = ""; // Specific part of warn/error log
-
-        boolean result = true;
-        // flow Name validation
-        if (!FRMUtil.isNameValid(flow.getFlowName())) {
-            msg = "Invalid Flow name";
-            result = false;
-        }
-        
-        // Node Validation
-        if (result == true && flow.getNode() == null) {
-            msg = "Node is null";
-            result = false;
-        }
-
-        // TODO: Validate we are seeking to program a flow against a valid
-        // Node
-
-        if (result == true && flow.getPriority() != null) {
-            if (flow.getPriority() < 0 || flow.getPriority() > 65535) {
-                msg = String.format("priority %s is not in the range 0 - 65535", flow.getPriority());
-                result = false;
-            }
-        }
-       
-        if (!FRMUtil.validateMatch(flow)) {
-            logger.error("Not a valid Match");
-            result = false;
-        }
-        if (!FRMUtil.validateInstructions(flow)) {
-            logger.error("Not a valid Instruction");
-            result = false;
-        }
-        if (result == false) {
-            logger.warn("Invalid Configuration for flow {}. The failure is {}", flow, msg);
-            logger.error("Invalid Configuration ({})", msg);
-        }
-        return result;
-    }
-    
-    private InstanceIdentifier<?> createTableInstance(Long tableId, NodeRef nodeRef) {        
-        Table table;
-        InstanceIdentifier<Table> tableInstance;
-        TableBuilder builder = new TableBuilder();
-        builder.setId(tableId);
-        builder.setKey(new TableKey(tableId, nodeRef));
-        table = builder.build();
-        tableInstance = InstanceIdentifier.builder(Tables.class).child(Table.class, table.getKey()).toInstance();
-        return tableInstance;
-    }
-}
\ No newline at end of file
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/GroupConsumerImpl.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/GroupConsumerImpl.java
deleted file mode 100644 (file)
index f4064f2..0000000
+++ /dev/null
@@ -1,323 +0,0 @@
-package org.opendaylight.controller.forwardingrulesmanager.consumer.impl;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import org.opendaylight.controller.clustering.services.CacheConfigException;
-import org.opendaylight.controller.clustering.services.CacheExistException;
-import org.opendaylight.controller.clustering.services.IClusterContainerServices;
-import org.opendaylight.controller.clustering.services.IClusterServices;
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
-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.controller.sal.core.IContainer;
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.utils.GlobalConstants;
-import org.opendaylight.controller.sal.utils.Status;
-import org.opendaylight.controller.sal.utils.StatusCode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.config.rev131024.Groups;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.config.rev131024.groups.Group;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.config.rev131024.groups.GroupKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.GroupAdded;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.GroupRemoved;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.GroupUpdated;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupListener;
-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.GroupId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.Buckets;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
-import org.opendaylight.yangtools.concepts.Registration;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.NotificationListener;
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@SuppressWarnings("unused")
-public class GroupConsumerImpl {
-
-    protected static final Logger logger = LoggerFactory.getLogger(GroupConsumerImpl.class);
-    private final GroupEventListener groupEventListener = new GroupEventListener();
-    private Registration<NotificationListener> groupListener;
-    private SalGroupService groupService;
-    private GroupDataCommitHandler groupCommitHandler;
-
-    private IContainer container;
-
-    public GroupConsumerImpl() {
-
-        InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(Groups.class).toInstance();
-        groupService = FRMConsumerImpl.getProviderSession().getRpcService(SalGroupService.class);      
-
-        if (null == groupService) {
-            logger.error("Consumer SAL Group Service is down or NULL. FRM may not function as intended");
-            System.out.println("Consumer SAL Group Service is down or NULL.");
-            return;
-        }
-
-        // For switch events
-        groupListener = FRMConsumerImpl.getNotificationService().registerNotificationListener(groupEventListener);
-
-        if (null == groupListener) {
-            logger.error("Listener to listen on group data modifcation events");
-            System.out.println("Listener to listen on group data modifcation events.");
-            return;
-        }
-
-        groupCommitHandler = new GroupDataCommitHandler();
-        FRMConsumerImpl.getDataProviderService().registerCommitHandler(path, groupCommitHandler);
-    }  
-
-    public Status validateGroup(Group group) {        
-        String groupName;
-        Iterator<Bucket> bucketIterator;
-        boolean returnResult;
-        Buckets groupBuckets;
-
-        if (null != group) {   
-            groupName = group.getGroupName();
-            if (!FRMUtil.isNameValid(groupName)) {
-                logger.error("Group Name is invalid %s" + groupName);
-                return new Status(StatusCode.BADREQUEST, "Group Name is invalid");
-            }
-            
-            if (!(group.getGroupType().getIntValue() >= GroupTypes.GroupAll.getIntValue() && group.getGroupType()
-                    .getIntValue() <= GroupTypes.GroupFf.getIntValue())) {
-                logger.error("Invalid Group type %d" + group.getGroupType().getIntValue());
-                return new Status(StatusCode.BADREQUEST, "Invalid Group type");
-            }
-
-            groupBuckets = group.getBuckets();
-
-            if (null != groupBuckets && null != groupBuckets.getBucket()) {
-                bucketIterator = groupBuckets.getBucket().iterator();
-
-                while (bucketIterator.hasNext()) {
-                    if (!(FRMUtil.validateActions(bucketIterator.next().getAction()))) {
-                        logger.error("Error in action bucket");
-                        return new Status(StatusCode.BADREQUEST, "Invalid Group bucket contents");
-                    }
-                }
-            }
-        }
-
-        return new Status(StatusCode.SUCCESS);
-    }
-
-    /**
-     * Update Group entries to the southbound plugin/inventory and our internal
-     * database
-     *
-     * @param path
-     * @param dataObject
-     */
-    private void updateGroup(InstanceIdentifier<?> path, 
-        Group updatedGroupDataObject, Group originalGroupDataObject) {
-        UpdatedGroupBuilder updateGroupBuilder = null;
-        Status groupOperationStatus = validateGroup(updatedGroupDataObject);
-        
-        if (!groupOperationStatus.isSuccess()) {
-            logger.error("Group data object validation failed %s" + updatedGroupDataObject.getGroupName());
-            return;
-        }
-        
-        UpdateGroupInputBuilder groupInputBuilder = new UpdateGroupInputBuilder();        
-        updateGroupBuilder = new UpdatedGroupBuilder(updatedGroupDataObject);        
-        updateGroupBuilder.setGroupId(new GroupId(updatedGroupDataObject.getId())); 
-        groupInputBuilder.setNode(updatedGroupDataObject.getNode());
-        groupInputBuilder.setUpdatedGroup(updateGroupBuilder.build());       
-        OriginalGroupBuilder originalGroupBuilder = new OriginalGroupBuilder(originalGroupDataObject);
-        groupInputBuilder.setOriginalGroup(originalGroupBuilder.build());     
-        groupService.updateGroup(groupInputBuilder.build());
-        return;
-    }
-
-    /**
-     * Adds Group to the southbound plugin and our internal database
-     *
-     * @param path
-     * @param dataObject
-     */
-    private void addGroup(InstanceIdentifier<?> path, Group groupAddDataObject) {
-        GroupKey groupKey = groupAddDataObject.getKey();
-        Status groupOperationStatus = validateGroup(groupAddDataObject);
-
-        if (!groupOperationStatus.isSuccess()) {
-            logger.error("Group data object validation failed %s" + groupAddDataObject.getGroupName());
-            return;
-        }
-        
-        AddGroupInputBuilder groupData = new AddGroupInputBuilder();
-        groupData.fieldsFrom(groupAddDataObject);       
-        groupData.setGroupId(new GroupId(groupAddDataObject.getId()));     
-        groupData.setNode(groupAddDataObject.getNode());    
-        groupService.addGroup(groupData.build());
-        return;
-    }
-
-    /**
-     * Remove Group to the southbound plugin and our internal database
-     *
-     * @param path
-     * @param dataObject
-     */
-    private void removeGroup(InstanceIdentifier<?> path, Group groupRemoveDataObject) {
-        GroupKey groupKey = groupRemoveDataObject.getKey();
-        Status groupOperationStatus = validateGroup(groupRemoveDataObject);
-
-        if (!groupOperationStatus.isSuccess()) {
-            logger.error("Group data object validation failed %s" + groupRemoveDataObject.getGroupName());
-            return;
-        }
-       
-        RemoveGroupInputBuilder groupData = new RemoveGroupInputBuilder();
-        groupData.fieldsFrom(groupRemoveDataObject);
-        groupData.setGroupId(new GroupId(groupRemoveDataObject.getId()));    
-        groupData.setNode(groupRemoveDataObject.getNode());
-        groupService.removeGroup(groupData.build());  
-        return;
-    }
-    
-    private RpcResult<Void> commitToPlugin(InternalTransaction transaction) {
-        DataModification<InstanceIdentifier<?>, DataObject> modification = transaction.modification;         
-        //get created entries      
-        Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> createdEntries = 
-                                        modification.getCreatedConfigurationData().entrySet();
-        
-        //get updated entries
-        Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> updatedEntries = 
-                    new HashSet<Entry<InstanceIdentifier<? extends DataObject>, DataObject>>(); 
-        
-        updatedEntries.addAll(modification.getUpdatedConfigurationData().entrySet());
-        updatedEntries.removeAll(createdEntries);
-
-        //get removed entries
-        Set<InstanceIdentifier<? extends DataObject>> removeEntriesInstanceIdentifiers = 
-                                                    modification.getRemovedConfigurationData();
-        
-        for (Entry<InstanceIdentifier<? extends DataObject >, DataObject> entry : createdEntries) { 
-            if(entry.getValue() instanceof Group) {   
-                addGroup(entry.getKey(), (Group)entry.getValue());   
-            }   
-        } 
-        
-        for (Entry<InstanceIdentifier<?>, DataObject> entry : updatedEntries) { 
-            if(entry.getValue() instanceof Group) {   
-                Group originalGroup = (Group) modification.getOriginalConfigurationData().get(entry.getKey());    
-                Group updatedGroup = (Group) entry.getValue(); 
-                updateGroup(entry.getKey(), originalGroup, updatedGroup);   
-            }   
-        }   
-
-        for (InstanceIdentifier<?> instanceId : removeEntriesInstanceIdentifiers ) {    
-            DataObject removeValue = modification.getOriginalConfigurationData().get(instanceId);   
-            if(removeValue instanceof Group) {   
-                removeGroup(instanceId, (Group)removeValue); 
-            }   
-        }
-
-        return Rpcs.getRpcResult(true, null, Collections.<RpcError>emptySet());
-    }
-
-    private final class GroupDataCommitHandler implements DataCommitHandler<InstanceIdentifier<?>, DataObject> {
-
-        @Override
-        public DataCommitTransaction<InstanceIdentifier<?>, DataObject> requestCommit(
-                DataModification<InstanceIdentifier<?>, DataObject> modification) {            
-            InternalTransaction transaction = new InternalTransaction(modification);
-            transaction.prepareUpdate();
-            return transaction;
-        }
-    }
-
-    private final class InternalTransaction implements DataCommitTransaction<InstanceIdentifier<?>, DataObject> {      
-
-        private final DataModification<InstanceIdentifier<?>, DataObject> modification;
-        
-        public InternalTransaction(DataModification<InstanceIdentifier<?>, DataObject> modification) {   
-            this.modification = modification;
-        }
-        
-        /**
-         * We create a plan which flows will be added, which will be updated and
-         * which will be removed based on our internal state.
-         *
-         */
-        void prepareUpdate() {
-               
-        }
-        
-        /**
-         * We are OK to go with execution of plan
-         *
-         */
-        @Override
-        public RpcResult<Void> finish() throws IllegalStateException {
-
-            RpcResult<Void> rpcStatus = commitToPlugin(this);            
-            return rpcStatus;
-        }
-
-        /**
-         *
-         * We should rollback our preparation
-         *
-         */
-        @Override
-        public RpcResult<Void> rollback() throws IllegalStateException { 
-            
-            ///needs to be implemented as per gerrit 3314
-            return Rpcs.getRpcResult(true, null, Collections.<RpcError>emptySet());
-        }
-
-        @Override
-        public DataModification<InstanceIdentifier<?>, DataObject> getModification() {            
-            return modification;
-        }
-
-    }
-
-    final class GroupEventListener implements SalGroupListener {
-
-        List<GroupAdded> addedGroups = new ArrayList<>();
-        List<GroupRemoved> removedGroups = new ArrayList<>();
-        List<GroupUpdated> updatedGroups = new ArrayList<>();
-
-        @Override
-        public void onGroupAdded(GroupAdded notification) {
-            addedGroups.add(notification);
-        }
-
-        @Override
-        public void onGroupRemoved(GroupRemoved notification) {
-            // TODO Auto-generated method stub
-
-        }
-
-        @Override
-        public void onGroupUpdated(GroupUpdated notification) {
-            // TODO Auto-generated method stub
-
-        }
-    }
- }
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/IForwardingRulesManager.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/IForwardingRulesManager.java
deleted file mode 100644 (file)
index 85ed8d4..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-package org.opendaylight.controller.forwardingrulesmanager.consumer.impl;
-
-import java.util.List;
-
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-
-/**
- * Interface that describes methods for accessing the flows database.
- */
-public interface IForwardingRulesManager {
-
-    /**
-     * Returns the specifications of all the flows configured for all the
-     * switches on the current container
-     *
-     * @return the list of flow configurations present in the database
-     */
-    public List<DataObject> get();
-
-    /**
-     * Returns the specification of the flow configured for the given network
-     * node on the current container
-     *
-     * @param name
-     *            the flow name
-     * @param n
-     *            the network node identifier
-     * @return the {@code FlowConfig} object
-     */
-    public DataObject getWithName(String name, Node n);
-
-}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/MeterConsumerImpl.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/MeterConsumerImpl.java
deleted file mode 100644 (file)
index bf8c8b7..0000000
+++ /dev/null
@@ -1,337 +0,0 @@
-package org.opendaylight.controller.forwardingrulesmanager.consumer.impl;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import org.opendaylight.controller.clustering.services.CacheConfigException;
-import org.opendaylight.controller.clustering.services.CacheExistException;
-import org.opendaylight.controller.clustering.services.IClusterContainerServices;
-import org.opendaylight.controller.clustering.services.IClusterServices;
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
-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.controller.sal.core.IContainer;
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.utils.GlobalConstants;
-import org.opendaylight.controller.sal.utils.Status;
-import org.opendaylight.controller.sal.utils.StatusCode;
-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.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.GroupId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.config.rev131024.Meters;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.config.rev131024.meters.Meter;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.config.rev131024.meters.MeterKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.MeterAdded;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.MeterRemoved;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.MeterUpdated;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterListener;
-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.MeterId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.BandType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.Drop;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.DscpRemark;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.Experimenter;
-import org.opendaylight.yangtools.concepts.Registration;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.NotificationListener;
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class MeterConsumerImpl {
-    protected static final Logger logger = LoggerFactory.getLogger(MeterConsumerImpl.class);
-    private final MeterEventListener meterEventListener = new MeterEventListener();
-    private Registration<NotificationListener> meterListener;
-    private SalMeterService meterService;
-    private MeterDataCommitHandler commitHandler;
-
-    public MeterConsumerImpl() {
-        InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(Meters.class).toInstance();
-        meterService = FRMConsumerImpl.getProviderSession().getRpcService(SalMeterService.class);
-        
-        if (null == meterService) {
-            logger.error("Consumer SAL Meter Service is down or NULL. FRM may not function as intended");
-            System.out.println("Consumer SAL Meter Service is down or NULL.");
-            return;
-        }
-
-        // For switch/plugin events
-        meterListener = FRMConsumerImpl.getNotificationService().registerNotificationListener(meterEventListener);
-
-        if (null == meterListener) {
-            logger.error("Listener to listen on meter data modifcation events");
-            System.out.println("Listener to listen on meter data modifcation events.");
-            return;
-        }
-
-        commitHandler = new MeterDataCommitHandler();
-        FRMConsumerImpl.getDataProviderService().registerCommitHandler(path, commitHandler);
-    }
-    
-    /**
-     * Adds Meter to the southbound plugin and our internal database
-     *
-     * @param path
-     * @param dataObject
-     */
-    private Status addMeter(InstanceIdentifier<?> path, Meter meterAddDataObject) {
-        MeterKey meterKey = meterAddDataObject.getKey();
-        
-        if (null != meterKey && validateMeter(meterAddDataObject).isSuccess()) {                
-            AddMeterInputBuilder meterBuilder = new AddMeterInputBuilder();
-            meterBuilder.fieldsFrom(meterAddDataObject);            
-            meterBuilder.setMeterId(new MeterId(meterAddDataObject.getId()));
-            meterBuilder.setNode(meterAddDataObject.getNode());           
-            meterService.addMeter(meterBuilder.build());
-        } else {       
-            return new Status(StatusCode.BADREQUEST, "Meter Key or attribute validation failed");
-        }
-
-        return new Status(StatusCode.SUCCESS);
-    }
-
-    /*
-     * Update Meter to the southbound plugin and our internal database
-     *
-     * @param path
-     *
-     * @param dataObject
-     */
-    private Status updateMeter(InstanceIdentifier<?> path, 
-                Meter updatedMeter, Meter originalMeter) {        
-        UpdatedMeterBuilder updateMeterBuilder = null;
-        
-        if (validateMeter(updatedMeter).isSuccess()) {                
-            UpdateMeterInputBuilder updateMeterInputBuilder = new UpdateMeterInputBuilder();
-            updateMeterInputBuilder.setNode(updatedMeter.getNode());
-            updateMeterBuilder = new UpdatedMeterBuilder();
-            updateMeterBuilder.fieldsFrom(updatedMeter);            
-            updateMeterBuilder.setMeterId(new MeterId(updatedMeter.getId()));            
-            updateMeterInputBuilder.setUpdatedMeter(updateMeterBuilder.build());
-            OriginalMeterBuilder originalMeterBuilder = new OriginalMeterBuilder(originalMeter);
-            updateMeterInputBuilder.setOriginalMeter(originalMeterBuilder.build());
-            meterService.updateMeter(updateMeterInputBuilder.build());
-        } else {
-            return new Status(StatusCode.BADREQUEST, "Meter Key or attribute validation failed");
-        }
-
-        return new Status(StatusCode.SUCCESS);
-    }
-
-    /*
-     * Remove Meter to the southbound plugin and our internal database
-     *
-     * @param path
-     *
-     * @param dataObject
-     */
-    private Status removeMeter(InstanceIdentifier<?> path, Meter meterRemoveDataObject) {
-        MeterKey meterKey = meterRemoveDataObject.getKey();
-
-        if (null != meterKey && validateMeter(meterRemoveDataObject).isSuccess()) {            
-            RemoveMeterInputBuilder meterBuilder = new RemoveMeterInputBuilder();
-            meterBuilder.fieldsFrom(meterRemoveDataObject);
-            meterBuilder.setNode(meterRemoveDataObject.getNode());            
-            meterBuilder.setMeterId(new MeterId(meterRemoveDataObject.getId()));           
-            meterService.removeMeter(meterBuilder.build());
-        } else {
-            return new Status(StatusCode.BADREQUEST, "Meter Key or attribute validation failed");
-        }
-
-        return new Status(StatusCode.SUCCESS);
-    }
-
-    public Status validateMeter(Meter meter) {        
-        String meterName;
-        Status returnStatus = null;
-
-        if (null != meter) {
-            meterName = meter.getMeterName();
-            if (!FRMUtil.isNameValid(meterName)) {
-                logger.error("Meter Name is invalid %s" + meterName);
-                returnStatus = new Status(StatusCode.BADREQUEST, "Meter Name is invalid");
-                return returnStatus;
-            }
-
-            for (int i = 0; i < meter.getMeterBandHeaders().getMeterBandHeader().size(); i++) {
-                if (null != meter.getFlags() && !meter.getFlags().isMeterBurst()) {
-                    if (0 < meter.getMeterBandHeaders().getMeterBandHeader().get(i).getBurstSize()) {
-                        logger.error("Burst size should only be associated when Burst FLAG is set");
-                        returnStatus = new Status(StatusCode.BADREQUEST,
-                                "Burst size should only be associated when Burst FLAG is set");
-                        break;
-                    }
-                }
-            }
-
-            if (null != returnStatus && !returnStatus.isSuccess()) {
-                return returnStatus;
-            } else if (null != meter.getMeterBandHeaders()) {
-                BandType setBandType = null;
-                DscpRemark dscpRemark = null;
-                for (int i = 0; i < meter.getMeterBandHeaders().getMeterBandHeader().size(); i++) {
-                    setBandType = meter.getMeterBandHeaders().getMeterBandHeader().get(i).getBandType();
-                    if (setBandType instanceof DscpRemark) {
-                        dscpRemark = (DscpRemark) setBandType;
-                        if (0 > dscpRemark.getRate()) {
-
-                        }
-                    } else if (setBandType instanceof Drop) {
-                        if (0 < dscpRemark.getPercLevel()) {
-                            logger.error("Number of drop Precedence level");
-                        }
-                    } else if (setBandType instanceof Experimenter) {
-
-                    }
-                }
-            }
-        }
-        return new Status(StatusCode.SUCCESS);
-    }
-
-    private RpcResult<Void> commitToPlugin(InternalTransaction transaction) {
-        DataModification<InstanceIdentifier<?>, DataObject> modification = transaction.modification;         
-        //get created entries      
-        Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> createdEntries = 
-                                        modification.getCreatedConfigurationData().entrySet();
-        
-        //get updated entries
-        Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> updatedEntries = 
-                    new HashSet<Entry<InstanceIdentifier<? extends DataObject>, DataObject>>(); 
-        
-        updatedEntries.addAll(modification.getUpdatedConfigurationData().entrySet());
-        updatedEntries.removeAll(createdEntries);
-
-        //get removed entries
-        Set<InstanceIdentifier<? extends DataObject>> removeEntriesInstanceIdentifiers = 
-                                                    modification.getRemovedConfigurationData();
-        
-        for (Entry<InstanceIdentifier<? extends DataObject >, DataObject> entry : createdEntries) { 
-            if(entry.getValue() instanceof Meter) {   
-                addMeter(entry.getKey(), (Meter)entry.getValue());   
-            }   
-        } 
-        
-        for (Entry<InstanceIdentifier<?>, DataObject> entry : updatedEntries) { 
-            if(entry.getValue() instanceof Meter) {   
-                Meter originalMeter = (Meter) modification.getOriginalConfigurationData().get(entry.getKey());    
-                Meter updatedMeter = (Meter) entry.getValue(); 
-                updateMeter(entry.getKey(), originalMeter, updatedMeter);   
-            }   
-        }   
-
-        for (InstanceIdentifier<?> instanceId : removeEntriesInstanceIdentifiers ) {    
-            DataObject removeValue = modification.getOriginalConfigurationData().get(instanceId);   
-            if(removeValue instanceof Meter) {   
-                removeMeter(instanceId, (Meter)removeValue); 
-            }   
-        }
-
-        return Rpcs.getRpcResult(true, null, Collections.<RpcError>emptySet());
-    }
-    
-    final class InternalTransaction implements DataCommitTransaction<InstanceIdentifier<?>, DataObject> {
-
-        private final DataModification<InstanceIdentifier<?>, DataObject> modification;
-
-        @Override
-        public DataModification<InstanceIdentifier<?>, DataObject> getModification() {
-            return modification;
-        }
-
-        public InternalTransaction(DataModification<InstanceIdentifier<?>, DataObject> modification) {
-            this.modification = modification;
-        }
-
-        /**
-         * We create a plan which flows will be added, which will be updated and
-         * which will be removed based on our internal state.
-         *
-         */
-        void prepareUpdate() {           
-            
-        }
-
-        /**
-         * We are OK to go with execution of plan
-         *
-         */
-        @Override
-        public RpcResult<Void> finish() throws IllegalStateException {
-
-            RpcResult<Void> rpcStatus = commitToPlugin(this);           
-            return rpcStatus;
-        }
-
-        /**
-         *
-         * We should rollback our preparation
-         *
-         */
-        @Override
-        public RpcResult<Void> rollback() throws IllegalStateException {            
-            return Rpcs.getRpcResult(true, null, Collections.<RpcError>emptySet());
-
-        }
-
-    }
-    
-    private final class MeterDataCommitHandler implements DataCommitHandler<InstanceIdentifier<?>, DataObject> {
-        @Override
-        public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<InstanceIdentifier<?>, DataObject> requestCommit(
-                DataModification<InstanceIdentifier<?>, DataObject> modification) {
-            // We should verify transaction
-            InternalTransaction transaction = new InternalTransaction(modification);
-            transaction.prepareUpdate();
-            return transaction;
-        }
-    }
-
-    final class MeterEventListener implements SalMeterListener {
-
-        List<MeterAdded> addedMeter = new ArrayList<>();
-        List<MeterRemoved> removeMeter = new ArrayList<>();
-        List<MeterUpdated> updatedMeter = new ArrayList<>();
-
-        @Override
-        public void onMeterAdded(MeterAdded notification) {
-            // TODO Auto-generated method stub
-
-        }
-
-        @Override
-        public void onMeterRemoved(MeterRemoved notification) {
-            // TODO Auto-generated method stub
-
-        }
-
-        @Override
-        public void onMeterUpdated(MeterUpdated notification) {
-            // TODO Auto-generated method stub
-
-        }
-    }   
-}
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/TableFeaturesConsumerImpl.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/TableFeaturesConsumerImpl.java
deleted file mode 100644 (file)
index 11d1189..0000000
+++ /dev/null
@@ -1,193 +0,0 @@
-package org.opendaylight.controller.forwardingrulesmanager.consumer.impl;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.opendaylight.controller.clustering.services.IClusterContainerServices;
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
-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.controller.sal.core.IContainer;
-import org.opendaylight.controller.sal.utils.ServiceHelper;
-import org.opendaylight.controller.sal.utils.Status;
-import org.opendaylight.controller.sal.utils.StatusCode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.config.rev131024.Tables;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.config.rev131024.tables.Table;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.SalTableService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.table.update.UpdatedTableBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeatures;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class TableFeaturesConsumerImpl {
-    protected static final Logger logger = LoggerFactory.getLogger(TableFeaturesConsumerImpl.class);
-    private SalTableService tableService;
-    private TableDataCommitHandler commitHandler;
-    private final IClusterContainerServices clusterContainerService = null;
-    private IContainer container;
-    private static final String NAMEREGEX = "^[a-zA-Z0-9]+$";
-    private boolean inContainerMode; // being used by global instance only
-
-    public TableFeaturesConsumerImpl() {
-        InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(Tables.class).toInstance();
-        tableService = FRMConsumerImpl.getProviderSession().getRpcService(SalTableService.class);
-
-        if (null == tableService) {
-            logger.error("Consumer SAL Service is down or NULL. FRM may not function as intended");
-            System.out.println("Consumer SAL Service is down or NULL.");
-            return;
-        }
-
-        System.out.println("-------------------------------------------------------------------");
-        commitHandler = new TableDataCommitHandler();
-        FRMConsumerImpl.getDataProviderService().registerCommitHandler(path, commitHandler);
-        container = (IContainer) ServiceHelper.getGlobalInstance(IContainer.class, this);
-    }
-
-    /**
-     * Updates TableFeatures to the southbound plugin and our internal database
-     *
-     * @param path
-     * @param dataObject
-     */
-    private void updateTableFeatures(InstanceIdentifier<?> path, TableFeatures dataObject) {
-
-        UpdateTableInputBuilder input = new UpdateTableInputBuilder();
-        UpdatedTableBuilder updatedtablebuilder = new UpdatedTableBuilder();
-        updatedtablebuilder.fieldsFrom(dataObject);
-        List<TableFeatures> features = updatedtablebuilder.build().getTableFeatures();
-        for (TableFeatures feature : features) {
-            if (feature != null && feature.getMaxEntries() != null) {
-                logger.error("Max Entries field is read-only, cannot be changed");
-                return;
-            }
-        }
-        input.setUpdatedTable(updatedtablebuilder.build());
-
-        // We send table feature update request to the sounthbound plugin
-        tableService.updateTable(input.build());
-    }
-
-    @SuppressWarnings("unchecked")
-    private void commitToPlugin(internalTransaction transaction) {
-
-        for (@SuppressWarnings("unused")
-        Entry<InstanceIdentifier<?>, TableFeatures> entry : transaction.updates.entrySet()) {
-            System.out.println("Coming update cc in TableDatacommitHandler");
-            updateTableFeatures(entry.getKey(), entry.getValue());
-        }
-
-    }
-
-    private final class TableDataCommitHandler implements DataCommitHandler<InstanceIdentifier<?>, DataObject> {
-
-        @SuppressWarnings("unchecked")
-        @Override
-        public DataCommitTransaction requestCommit(DataModification<InstanceIdentifier<?>, DataObject> modification) {
-            // We should verify transaction
-            System.out.println("Coming in TableFeaturesDatacommitHandler");
-            internalTransaction transaction = new internalTransaction(modification);
-            transaction.prepareUpdate();
-            return transaction;
-        }
-    }
-
-    private final class internalTransaction implements DataCommitTransaction<InstanceIdentifier<?>, DataObject> {
-
-        private final DataModification<InstanceIdentifier<?>, DataObject> modification;
-
-        @Override
-        public DataModification<InstanceIdentifier<?>, DataObject> getModification() {
-            return modification;
-        }
-
-        public internalTransaction(DataModification<InstanceIdentifier<?>, DataObject> modification) {
-            this.modification = modification;
-        }
-
-        Map<InstanceIdentifier<?>, TableFeatures> updates = new HashMap<>();
-        Map<InstanceIdentifier<?>, TableFeatures> createdEntries = new HashMap<>();
-
-        /**
-         * We create a plan which table features will be updated.
-         *
-         */
-        void prepareUpdate() {
-               Set<Entry<InstanceIdentifier<?>, DataObject>> createdEntries = modification.getCreatedConfigurationData().entrySet();
-
-            Set<Entry<InstanceIdentifier<?>, DataObject>> puts = modification.getUpdatedConfigurationData().entrySet();
-            for (Entry<InstanceIdentifier<?>, DataObject> entry : puts) {
-
-                // validating the DataObject
-
-                Status status = validate(container, (TableFeatures) entry);
-                if (!status.isSuccess()) {
-                    logger.warn("Invalid Configuration for table features The failure is {}", entry,
-                            status.getDescription());
-                    String error = "Invalid Configuration (" + status.getDescription() + ")";
-                    logger.error(error);
-                    return;
-                }
-                if (entry.getValue() instanceof TableFeatures) {
-                    TableFeatures tablefeatures = (TableFeatures) entry.getValue();
-                    preparePutEntry(entry.getKey(), tablefeatures);
-                }
-
-            }
-        }
-
-        private void preparePutEntry(InstanceIdentifier<?> key, TableFeatures tablefeatures) {
-            if (tablefeatures != null) {
-                // Updating the Map
-                System.out.println("Coming update  in TableFeaturesDatacommitHandler");
-                updates.put(key, tablefeatures);
-            }
-        }
-
-        /**
-         * We are OK to go with execution of plan
-         *
-         */
-        @Override
-        public RpcResult<Void> finish() throws IllegalStateException {
-
-            commitToPlugin(this);
-            // We return true if internal transaction is successful.
-            // return Rpcs.getRpcResult(true, null, Collections.emptySet());
-            return Rpcs.getRpcResult(true, null, null);
-        }
-
-        /**
-         *
-         * We should rollback our preparation
-         *
-         */
-        @Override
-        public RpcResult<Void> rollback() throws IllegalStateException {
-            // NOOP - we did not modified any internal state during
-            // requestCommit phase
-            // return Rpcs.getRpcResult(true, null, Collections.emptySet());
-            return Rpcs.getRpcResult(true, null, null);
-
-        }
-
-        public Status validate(IContainer container, TableFeatures dataObject) {
-
-            String tablename = dataObject.getName();
-            if (tablename == null || tablename.trim().isEmpty() || !tablename.matches(NAMEREGEX)
-                    || tablename.length() != 32) {
-                return new Status(StatusCode.BADREQUEST, "Invalid table name");
-            }
-
-            return new Status(StatusCode.SUCCESS);
-        }
-    }
-}
index b5cde6e..7914de0 100644 (file)
@@ -10,6 +10,10 @@ module netconf-node-inventory {
     }
     
     grouping netconf-node-fields {
+        leaf connected {
+            type boolean; 
+        }
+    
         leaf-list initial-capability {
             type string;
         }
index 1ffc887..77c92f9 100644 (file)
@@ -63,7 +63,6 @@ module opendaylight-inventory {
 
             uses node-connector;
         }
-
     }
 
     grouping node-connector {
index 87de0f5..9fccb99 100644 (file)
@@ -8,7 +8,7 @@ module opendaylight-topology-inventory {
     import ietf-inet-types { prefix "inet"; }
     import opendaylight-inventory {prefix "inv";}
     import opendaylight-topology {prefix "odt";}
-    import network-topology {prefix "topo"; revision-date "2013-07-12"; }
+    import network-topology {prefix "topo"; revision-date "2013-10-21"; }
 
     organization "TBD";
 
index 6bbfd4b..c39759a 100644 (file)
@@ -7,7 +7,7 @@ module opendaylight-topology {
     import yang-ext { prefix "ext"; }
     import ietf-inet-types { prefix "inet"; }
     import opendaylight-inventory {prefix "inv";}
-    import network-topology {prefix "topo"; revision-date "2013-07-12"; }
+    import network-topology {prefix "topo"; revision-date "2013-10-21"; }
 
     organization "TBD";
 
index 1a10bf6..21cf8fc 100644 (file)
@@ -6,7 +6,7 @@ module opendaylight-topology-view  {
 
     import yang-ext { prefix "ext"; }
     import ietf-inet-types { prefix "inet"; }
-    import network-topology {prefix "topo"; revision-date "2013-07-12"; }
+    import network-topology {prefix "topo"; revision-date "2013-10-21"; }
     import opendaylight-topology {prefix "odl";}
 
     organization "TBD";
index 235e6ac..8b2c89a 100644 (file)
@@ -21,6 +21,7 @@
         <sonar.jacoco.itReportPath>../sal-binding-broker/target/jacoco-it.exec</sonar.jacoco.itReportPath>
         <netconf.version>0.2.3-SNAPSHOT</netconf.version>
         <config.version>0.2.3-SNAPSHOT</config.version>
+        <moxy.controller.version>2.5.0</moxy.controller.version>
     </properties>
 
     <build>
@@ -63,7 +64,7 @@
         </plugins>
         <pluginManagement>
             <plugins>
-                <!--This plugin's configuration is used to store Eclipse 
+                <!--This plugin's configuration is used to store Eclipse
                     m2e settings only. It has no influence on the Maven build itself. -->
                 <plugin>
                     <groupId>org.eclipse.m2e</groupId>
 
 
     <dependencies>
+
         <dependency>
             <groupId>org.opendaylight.yangtools.thirdparty</groupId>
             <artifactId>xtend-lib-osgi</artifactId>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
-            <artifactId>config-persister-file-adapter</artifactId>
+            <artifactId>config-persister-file-xml-adapter</artifactId>
             <version>${config.version}</version>
         </dependency>
-                <dependency>
+        <dependency>
+            <groupId>org.eclipse.persistence</groupId>
+            <artifactId>org.eclipse.persistence.moxy</artifactId>
+            <version>${moxy.controller.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.persistence</groupId>
+            <artifactId>org.eclipse.persistence.core</artifactId>
+            <version>${moxy.controller.version}</version>
+        </dependency>
+        <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>netconf-impl</artifactId>
             <version>${netconf.version}</version>
             <groupId>org.ops4j.pax.exam</groupId>
             <artifactId>pax-exam</artifactId>
             <version>${exam.version}</version>
-            <!-- Compile scope here is intentional, it is used in TestHelper 
-                class which could be downloaded via nexus and reused in other integration 
+            <!-- Compile scope here is intentional, it is used in TestHelper
+                class which could be downloaded via nexus and reused in other integration
                 tests. -->
             <scope>compile</scope>
         </dependency>
index c943226..2e2d770 100644 (file)
@@ -78,7 +78,9 @@ public class TestHelper {
                 mavenBundle(CONTROLLER, "config-netconf-connector").versionAsInProject(), //
                 mavenBundle(CONTROLLER, "netconf-impl").versionAsInProject(), //
 
-                mavenBundle(CONTROLLER, "config-persister-file-adapter").versionAsInProject().noStart());
+                mavenBundle(CONTROLLER, "config-persister-file-xml-adapter").versionAsInProject().noStart(),
+                mavenBundle("org.eclipse.persistence", "org.eclipse.persistence.moxy").versionAsInProject(),
+                mavenBundle("org.eclipse.persistence", "org.eclipse.persistence.core").versionAsInProject());
 
     }
 
@@ -119,9 +121,9 @@ public class TestHelper {
                 systemProperty("netconf.tcp.client.port").value("18383"), //
                 systemProperty("netconf.config.persister.active").value("1"), //
                 systemProperty("netconf.config.persister.1.storageAdapterClass").value(
-                        "org.opendaylight.controller.config.persist.storage.file.FileStorageAdapter"), //
+                        "org.opendaylight.controller.config.persist.storage.file.xml.XmlFileStorageAdapter"), //
                 systemProperty("netconf.config.persister.1.properties.fileStorage")
-                        .value(PathUtils.getBaseDir() + "/src/test/resources/controller.config"), //
+                        .value(PathUtils.getBaseDir() + "/src/test/resources/controller.xml"), //
                 systemProperty("netconf.config.persister.1.properties.numberOfBackups").value("1") //
                 //systemProperty("yangstore.blacklist").value(".*controller.model.*") //
 
index 9b81429..302d94b 100644 (file)
@@ -27,7 +27,7 @@ public abstract class AbstractTest {
     @Inject
     @Filter(timeout=60*1000)
     BindingAwareBroker broker;
-    
+
     @Inject
     BundleContext bundleContext;
 
@@ -64,9 +64,12 @@ public abstract class AbstractTest {
                 bindingAwareSalBundles(),
                 configMinumumBundles(),
                 // BASE Models
-                baseModelBundles(), 
-                flowCapableModelBundles(), 
+                baseModelBundles(),
+                flowCapableModelBundles(),
+
+                // Set fail if unresolved bundle present
+                systemProperty("pax.exam.osgi.unresolved.fail").value("true"),
                 junitAndMockitoBundles());
     }
-    
+
 }
diff --git a/opendaylight/md-sal/sal-binding-it/src/test/resources/controller.config b/opendaylight/md-sal/sal-binding-it/src/test/resources/controller.config
deleted file mode 100644 (file)
index 28c3bec..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-//START OF CONFIG-LAST
-<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
-<modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-       <module>
-               <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>
-       <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>
-       <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-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>
-                       <name>ref_hash-map-data-store</name>
-               </data-store>
-       </module>
-       <module>
-               <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-broker-impl</type>
-               <name>binding-broker-impl</name>
-               <notification-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">binding:binding-notification-service</type>
-                       <name>ref_binding-notification-broker</name>
-               </notification-service>
-               <data-broker 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">binding:binding-data-broker</type>
-                       <name>ref_binding-data-broker</name>
-               </data-broker>
-       </module>
-       <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>
-       </module>
-       <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>ref_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>ref_runtime-mapping-singleton</name>
-               </mapping-service>
-       </module>
-</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>ref_yang-schema-service</name>
-               <provider>/config/modules/module[name='schema-service-singleton']/instance[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>ref_binding-notification-broker</name>
-                       <provider>/config/modules/module[name='binding-notification-broker']/instance[name='binding-notification-broker']</provider>
-               </instance>
-       </service>
-       <service>
-               <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-data-store</type>
-               <instance>
-                       <name>ref_hash-map-data-store</name>
-                       <provider>/config/modules/module[name='hash-map-data-store']/instance[name='hash-map-data-store']</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>ref_binding-broker-impl</name>
-                       <provider>/config/modules/module[name='binding-broker-impl']/instance[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>ref_runtime-mapping-singleton</name>
-                       <provider>/config/modules/module[name='runtime-generated-mapping']/instance[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>ref_dom-broker</name>
-                       <provider>/config/modules/module[name='dom-broker-impl']/instance[name='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>ref_binding-data-broker</name>
-               <provider>/config/modules/module[name='binding-data-broker']/instance[name='binding-data-broker']</provider>
-       </instance>
-       </service>
-</services>
-</data>
-
-
-//END OF SNAPSHOT
-urn:opendaylight:l2:types?module=opendaylight-l2-types&revision=2013-08-27
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&revision=2013-10-28
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom?module=opendaylight-md-sal-dom&revision=2013-10-28
-urn:opendaylight:params:xml:ns:yang:controller:config?module=config&revision=2013-04-05
-urn:ietf:params:netconf:capability:candidate:1.0
-urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&revision=2010-10-04
-urn:ietf:params:xml:ns:yang:rpc-context?module=rpc-context&revision=2013-06-17
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl?module=opendaylight-sal-binding-broker-impl&revision=2013-10-28
-urn:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&revision=2010-09-24
-urn:ietf:params:netconf:capability:rollback-on-error:1.0
-urn:ietf:params:xml:ns:yang:ietf-yang-types?module=ietf-yang-types&revision=2010-09-24
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&revision=2013-10-28
-urn:opendaylight:params:xml:ns:yang:controller:logback:config?module=config-logging&revision=2013-07-16
-urn:opendaylight:yang:extension:yang-ext?module=yang-ext&revision=2013-07-09
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:common?module=opendaylight-md-sal-common&revision=2013-10-28
-//END OF CONFIG
diff --git a/opendaylight/md-sal/sal-binding-it/src/test/resources/controller.xml b/opendaylight/md-sal/sal-binding-it/src/test/resources/controller.xml
new file mode 100644 (file)
index 0000000..08d22b9
--- /dev/null
@@ -0,0 +1,200 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<persisted-snapshots>
+    <snapshots>
+        <snapshot>
+            <required-capabilities>
+                <capability>urn:opendaylight:l2:types?module=opendaylight-l2-types&amp;revision=2013-08-27</capability>
+                <capability>
+                    urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&amp;revision=2013-10-28
+                </capability>
+                <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom?module=opendaylight-md-sal-dom&amp;revision=2013-10-28</capability>
+                <capability>
+                    urn:opendaylight:params:xml:ns:yang:controller:config?module=config&amp;revision=2013-04-05
+                </capability>
+                <capability>urn:ietf:params:netconf:capability:candidate:1.0</capability>
+                <capability>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&amp;revision=2010-10-04</capability>
+                <capability>urn:ietf:params:xml:ns:yang:rpc-context?module=rpc-context&amp;revision=2013-06-17
+                </capability>
+                <capability>
+                    urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl?module=opendaylight-sal-binding-broker-impl&amp;revision=2013-10-28
+                </capability>
+                <capability>urn:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&amp;revision=2010-09-24
+                </capability>
+                <capability>urn:ietf:params:netconf:capability:rollback-on-error:1.0</capability>
+                <capability>urn:ietf:params:xml:ns:yang:ietf-yang-types?module=ietf-yang-types&amp;revision=2010-09-24
+                </capability>
+                <capability>
+                    urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&amp;revision=2013-10-28
+                </capability>
+                <capability>urn:opendaylight:params:xml:ns:yang:controller:logback:config?module=config-logging&amp;revision=2013-07-16</capability>
+                <capability>urn:opendaylight:yang:extension:yang-ext?module=yang-ext&amp;revision=2013-07-09
+                </capability>
+                <capability>
+                    urn:opendaylight:params:xml:ns:yang:controller:md:sal:common?module=opendaylight-md-sal-common&amp;revision=2013-10-28
+                </capability>
+
+            </required-capabilities>
+            <configuration>
+
+                <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+                    <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+                        <module>
+                            <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>
+                        <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>
+                        <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-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>
+                                <name>ref_hash-map-data-store</name>
+                            </data-store>
+                        </module>
+                        <module>
+                            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+                                prefix:binding-broker-impl
+                            </type>
+                            <name>binding-broker-impl</name>
+                            <notification-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">
+                                    binding:binding-notification-service
+                                </type>
+                                <name>ref_binding-notification-broker</name>
+                            </notification-service>
+                            <data-broker 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">
+                                    binding:binding-data-broker
+                                </type>
+                                <name>ref_binding-data-broker</name>
+                            </data-broker>
+                        </module>
+                        <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>
+                        </module>
+                        <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>ref_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>ref_runtime-mapping-singleton</name>
+                            </mapping-service>
+                        </module>
+                    </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>ref_yang-schema-service</name>
+                                <provider>
+                                    /config/modules/module[name='schema-service-singleton']/instance[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>ref_binding-notification-broker</name>
+                                <provider>
+                                    /config/modules/module[name='binding-notification-broker']/instance[name='binding-notification-broker']
+                                </provider>
+                            </instance>
+                        </service>
+                        <service>
+                            <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">
+                                dom:dom-data-store
+                            </type>
+                            <instance>
+                                <name>ref_hash-map-data-store</name>
+                                <provider>
+                                    /config/modules/module[name='hash-map-data-store']/instance[name='hash-map-data-store']
+                                </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>ref_binding-broker-impl</name>
+                                <provider>
+                                    /config/modules/module[name='binding-broker-impl']/instance[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>ref_runtime-mapping-singleton</name>
+                                <provider>
+                                    /config/modules/module[name='runtime-generated-mapping']/instance[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>ref_dom-broker</name>
+                                <provider>/config/modules/module[name='dom-broker-impl']/instance[name='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>ref_binding-data-broker</name>
+                                <provider>
+                                    /config/modules/module[name='binding-data-broker']/instance[name='binding-data-broker']
+                                </provider>
+                            </instance>
+                        </service>
+                    </services>
+                </data>
+
+            </configuration>
+        </snapshot>
+
+    </snapshots>
+</persisted-snapshots>
index 8350e39..f2a09d9 100644 (file)
@@ -3,7 +3,6 @@ package org.opendaylight.controller.sal.connect.netconf;
 import java.net.URI;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
-import java.util.Calendar;
 import java.util.Date;
 
 import org.opendaylight.yangtools.yang.common.QName;
@@ -12,28 +11,33 @@ import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 public class InventoryUtils {
 
     private static final URI INVENTORY_NAMESPACE = URI.create("urn:opendaylight:inventory");
-    private static final Date INVENTORY_REVISION = date();
+    private static final URI NETCONF_INVENTORY_NAMESPACE = URI.create("urn:opendaylight:netconf-node-inventory");
+    private static final Date INVENTORY_REVISION = dateFromString("2013-08-19");
+    private static final Date NETCONF_INVENTORY_REVISION = dateFromString("2014-01-08");
     public static final QName INVENTORY_NODES = new QName(INVENTORY_NAMESPACE, INVENTORY_REVISION, "nodes");
     public static final QName INVENTORY_NODE = new QName(INVENTORY_NAMESPACE, INVENTORY_REVISION, "node");
     public static final QName INVENTORY_ID = new QName(INVENTORY_NAMESPACE, INVENTORY_REVISION, "id");
+    public static final QName INVENTORY_CONNECTED = new QName(NETCONF_INVENTORY_NAMESPACE, NETCONF_INVENTORY_REVISION,
+            "connected");
+    public static final QName NETCONF_INVENTORY_INITIAL_CAPABILITY = new QName(NETCONF_INVENTORY_NAMESPACE,
+            NETCONF_INVENTORY_REVISION, "initial-capability");
 
     public static final InstanceIdentifier INVENTORY_PATH = InstanceIdentifier.builder().node(INVENTORY_NODES)
             .toInstance();
     public static final QName NETCONF_INVENTORY_MOUNT = null;
-    
-    
-    
-    private static Date date() {
+
+    /**
+     * Converts date in string format yyyy-MM-dd to java.util.Date.
+     * 
+     * @return java.util.Date conformant to string formatted date yyyy-MM-dd.
+     */
+    private static Date dateFromString(final String date) {
         SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
         try {
-            return formatter.parse("2013-08-19");
+            return formatter.parse(date);
         } catch (ParseException e) {
-            // TODO Auto-generated catch block
             e.printStackTrace();
         }
         return null;
     }
-
-    
-    
 }
index 21500e1..3799dd2 100644 (file)
@@ -17,6 +17,7 @@ import org.opendaylight.controller.md.sal.common.api.data.DataReader
 import org.opendaylight.controller.netconf.api.NetconfMessage
 import org.opendaylight.controller.netconf.client.NetconfClient
 import org.opendaylight.controller.netconf.client.NetconfClientDispatcher
+import org.opendaylight.controller.netconf.util.xml.XmlUtil
 import org.opendaylight.controller.sal.core.api.Broker.ProviderSession
 import org.opendaylight.controller.sal.core.api.Provider
 import org.opendaylight.controller.sal.core.api.RpcImplementation
@@ -25,7 +26,6 @@ import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction
 import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance
 import org.opendaylight.controller.sal.core.api.mount.MountProvisionService
 import org.opendaylight.protocol.framework.ReconnectStrategy
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState
 import org.opendaylight.yangtools.concepts.Registration
 import org.opendaylight.yangtools.yang.common.QName
 import org.opendaylight.yangtools.yang.data.api.CompositeNode
@@ -39,7 +39,6 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext
 import org.opendaylight.yangtools.yang.model.util.repo.AbstractCachingSchemaSourceProvider
 import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider
 import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProviders
-import org.opendaylight.yangtools.yang.model.util.repo.SourceIdentifier
 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl
 import org.opendaylight.yangtools.yang.parser.impl.util.YangSourceContext
 import org.slf4j.Logger
@@ -49,7 +48,6 @@ import static com.google.common.base.Preconditions.*
 import static org.opendaylight.controller.sal.connect.netconf.InventoryUtils.*
 
 import static extension org.opendaylight.controller.sal.connect.netconf.NetconfMapping.*
-import org.opendaylight.controller.netconf.util.xml.XmlUtil
 
 class NetconfDevice implements Provider, // 
 DataReader<InstanceIdentifier, CompositeNode>, //
@@ -105,6 +103,8 @@ AutoCloseable {
 
     @Property
     var SchemaSourceProvider<InputStream> remoteSourceProvider
+    
+    DataBrokerService dataBroker
 
     public new(String name) {
         this.name = name;
@@ -121,8 +121,6 @@ AutoCloseable {
         val listener = new NetconfDeviceListener(this, eventExecutor);
         val task = startClientTask(dispatcher, listener)
         if (mountInstance != null) {
-            confReaderReg = mountInstance.registerConfigurationReader(ROOT_PATH, this);
-            operReaderReg = mountInstance.registerOperationalReader(ROOT_PATH, this);
             commitHandlerReg = mountInstance.registerCommitHandler(ROOT_PATH, this)
         }
         return processingExecutor.submit(task) as Future<Void>;
@@ -138,29 +136,63 @@ AutoCloseable {
     }
 
     private def Runnable startClientTask(NetconfClientDispatcher dispatcher, NetconfDeviceListener listener) {
-
         return [ |
-            logger.info("Starting Netconf Client on: {}", socketAddress);
-            client = NetconfClient.clientFor(name, socketAddress, reconnectStrategy, dispatcher, listener);
-            logger.debug("Initial capabilities {}", initialCapabilities);
-            var SchemaSourceProvider<String> delegate;
-            if (NetconfRemoteSchemaSourceProvider.isSupportedFor(initialCapabilities)) {
-                delegate = new NetconfRemoteSchemaSourceProvider(this);
-            }  else if(client.capabilities.contains(NetconfRemoteSchemaSourceProvider.IETF_NETCONF_MONITORING.namespace.toString)) {
-                delegate = new NetconfRemoteSchemaSourceProvider(this);
-            } else {
-                logger.info("Netconf server {} does not support IETF Netconf Monitoring", socketAddress);
-                delegate = SchemaSourceProviders.<String>noopProvider();
-            }
-            remoteSourceProvider = schemaSourceProvider.createInstanceFor(delegate);
-            deviceContextProvider = new NetconfDeviceSchemaContextProvider(this, remoteSourceProvider);
-            deviceContextProvider.createContextFromCapabilities(initialCapabilities);
-            if (mountInstance != null && schemaContext.isPresent) {
-                mountInstance.schemaContext = schemaContext.get();
+            try {
+                logger.info("Starting Netconf Client on: {}", socketAddress);
+                client = NetconfClient.clientFor(name, socketAddress, reconnectStrategy, dispatcher, listener);
+                logger.debug("Initial capabilities {}", initialCapabilities);
+                var SchemaSourceProvider<String> delegate;
+                if (NetconfRemoteSchemaSourceProvider.isSupportedFor(initialCapabilities)) {
+                    delegate = new NetconfRemoteSchemaSourceProvider(this);
+                }  else if(client.capabilities.contains(NetconfRemoteSchemaSourceProvider.IETF_NETCONF_MONITORING.namespace.toString)) {
+                    delegate = new NetconfRemoteSchemaSourceProvider(this);
+                } else {
+                    logger.info("Netconf server {} does not support IETF Netconf Monitoring", socketAddress);
+                    delegate = SchemaSourceProviders.<String>noopProvider();
+                }
+                remoteSourceProvider = schemaSourceProvider.createInstanceFor(delegate);
+                deviceContextProvider = new NetconfDeviceSchemaContextProvider(this, remoteSourceProvider);
+                deviceContextProvider.createContextFromCapabilities(initialCapabilities);
+                if (mountInstance != null && schemaContext.isPresent) {
+                    mountInstance.schemaContext = schemaContext.get();
+                }
+                updateDeviceState()
+                if (mountInstance != null && confReaderReg == null && operReaderReg == null) {
+                    confReaderReg = mountInstance.registerConfigurationReader(ROOT_PATH, this);
+                    operReaderReg = mountInstance.registerOperationalReader(ROOT_PATH, this);
+                }
+            } catch (Exception e) {
+                logger.error("Netconf client NOT started. ", e)
             }
         ]
     }
 
+    private def updateDeviceState() {
+        val transaction = dataBroker.beginTransaction
+
+        val it = ImmutableCompositeNode.builder
+        setQName(INVENTORY_NODE)
+        addLeaf(INVENTORY_ID, name)
+        addLeaf(INVENTORY_CONNECTED, client.clientSession.up)
+
+        logger.debug("Client capabilities {}", client.capabilities)
+        for (capability : client.capabilities) {
+            addLeaf(NETCONF_INVENTORY_INITIAL_CAPABILITY, capability)
+        }
+
+        logger.debug("Update device state transaction " + transaction.identifier + " putting operational data started.")
+        transaction.putOperationalData(path, it.toInstance)
+        logger.debug("Update device state transaction " + transaction.identifier + " putting operational data ended.")
+        val transactionStatus = transaction.commit.get;
+
+        if (transactionStatus.successful) {
+            logger.debug("Update device state transaction " + transaction.identifier + " SUCCESSFUL.")
+        } else {
+            logger.debug("Update device state transaction " + transaction.identifier + " FAILED!")
+            logger.debug("Update device state transaction status " + transaction.status)
+        }
+    }
+
     override readConfigurationData(InstanceIdentifier path) {
         val result = invokeRpc(NETCONF_GET_CONFIG_QNAME,
             wrap(NETCONF_GET_CONFIG_QNAME, CONFIG_SOURCE_RUNNING, path.toFilterStructure()));
@@ -209,7 +241,7 @@ AutoCloseable {
     }
 
     override onSessionInitiated(ProviderSession session) {
-        val dataBroker = session.getService(DataBrokerService);
+        dataBroker = session.getService(DataBrokerService);
 
         val transaction = dataBroker.beginTransaction
         if (transaction.operationalNodeNotExisting) {
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-it/src/test/resources/controller.config b/opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-it/src/test/resources/controller.config
deleted file mode 100644 (file)
index 0d9cd6a..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-//START OF CONFIG-LAST
-<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
-<modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-       <module>
-               <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>
-       <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>
-       <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-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>
-                       <name>ref_hash-map-data-store</name>
-               </data-store>
-       </module>
-       <module>
-               <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-broker-impl</type>
-               <name>binding-broker-impl</name>
-               <notification-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">binding:binding-notification-service</type>
-                       <name>ref_binding-notification-broker</name>
-               </notification-service>
-               <data-broker 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">binding:binding-data-broker</type>
-                       <name>ref_binding-data-broker</name>
-               </data-broker>
-       </module>
-       <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>
-       </module>
-       <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>ref_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>ref_runtime-mapping-singleton</name>
-               </mapping-service>
-       </module>
-       <module>
-               <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote:rpc">prefix:remote-zeromq-rpc-server</type>
-               <name>remoter</name>
-               <port xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote:rpc">5666</port>
-               <dom-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote:rpc">
-                       <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-broker-osgi-registry</type>
-                       <name>ref_dom-broker</name>
-               </dom-broker>
-       </module>
-</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>ref_yang-schema-service</name>
-               <provider>/config/modules/module[name='schema-service-singleton']/instance[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>ref_binding-notification-broker</name>
-                       <provider>/config/modules/module[name='binding-notification-broker']/instance[name='binding-notification-broker']</provider>
-               </instance>
-       </service>
-       <service>
-               <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-data-store</type>
-               <instance>
-                       <name>ref_hash-map-data-store</name>
-                       <provider>/config/modules/module[name='hash-map-data-store']/instance[name='hash-map-data-store']</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>ref_binding-broker-impl</name>
-                       <provider>/config/modules/module[name='binding-broker-impl']/instance[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>ref_runtime-mapping-singleton</name>
-                       <provider>/config/modules/module[name='runtime-generated-mapping']/instance[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>ref_dom-broker</name>
-                       <provider>/config/modules/module[name='dom-broker-impl']/instance[name='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>ref_binding-data-broker</name>
-               <provider>/config/modules/module[name='binding-data-broker']/instance[name='binding-data-broker']</provider>
-       </instance>
-       </service>
-</services>
-</data>
-
-
-//END OF SNAPSHOT
-urn:opendaylight:params:xml:ns:yang:controller:config?module=config&revision=2013-04-05
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl?module=opendaylight-sal-binding-broker-impl&revision=2013-10-28
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&revision=2013-10-28
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&revision=2013-10-28
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom?module=opendaylight-md-sal-dom&revision=2013-10-28
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote:rpc?module=odl-sal-dom-rpc-remote-cfg&revision=2013-10-28
-//END OF CONFIG
diff --git a/opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-it/src/test/resources/controller.xml b/opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-it/src/test/resources/controller.xml
new file mode 100644 (file)
index 0000000..c8e3b83
--- /dev/null
@@ -0,0 +1,197 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<persisted-snapshots>
+    <snapshots>
+        <snapshot>
+            <required-capabilities>
+                <capability>urn:opendaylight:params:xml:ns:yang:controller:config?module=config&amp;revision=2013-04-05
+                </capability>
+                <capability>
+                    urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl?module=opendaylight-sal-binding-broker-impl&amp;revision=2013-10-28
+                </capability>
+                <capability>
+                    urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&amp;revision=2013-10-28
+                </capability>
+                <capability>
+                    urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&amp;revision=2013-10-28
+                </capability>
+                <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom?module=opendaylight-md-sal-dom&amp;revision=2013-10-28</capability>
+                <capability>
+                    urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote:rpc?module=odl-sal-dom-rpc-remote-cfg&amp;revision=2013-10-28
+                </capability>
+            </required-capabilities>
+            <configuration>
+
+                <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+                    <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+                        <module>
+                            <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>
+                        <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>
+                        <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-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>
+                                <name>ref_hash-map-data-store</name>
+                            </data-store>
+                        </module>
+                        <module>
+                            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+                                prefix:binding-broker-impl
+                            </type>
+                            <name>binding-broker-impl</name>
+                            <notification-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">
+                                    binding:binding-notification-service
+                                </type>
+                                <name>ref_binding-notification-broker</name>
+                            </notification-service>
+                            <data-broker 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">
+                                    binding:binding-data-broker
+                                </type>
+                                <name>ref_binding-data-broker</name>
+                            </data-broker>
+                        </module>
+                        <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>
+                        </module>
+                        <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>ref_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>ref_runtime-mapping-singleton</name>
+                            </mapping-service>
+                        </module>
+                        <module>
+                            <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote:rpc">
+                                prefix:remote-zeromq-rpc-server
+                            </type>
+                            <name>remoter</name>
+                            <port xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote:rpc">5666</port>
+                            <dom-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote:rpc">
+                                <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">
+                                    prefix:dom-broker-osgi-registry
+                                </type>
+                                <name>ref_dom-broker</name>
+                            </dom-broker>
+                        </module>
+                    </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>ref_yang-schema-service</name>
+                                <provider>
+                                    /config/modules/module[name='schema-service-singleton']/instance[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>ref_binding-notification-broker</name>
+                                <provider>
+                                    /config/modules/module[name='binding-notification-broker']/instance[name='binding-notification-broker']
+                                </provider>
+                            </instance>
+                        </service>
+                        <service>
+                            <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">
+                                dom:dom-data-store
+                            </type>
+                            <instance>
+                                <name>ref_hash-map-data-store</name>
+                                <provider>
+                                    /config/modules/module[name='hash-map-data-store']/instance[name='hash-map-data-store']
+                                </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>ref_binding-broker-impl</name>
+                                <provider>
+                                    /config/modules/module[name='binding-broker-impl']/instance[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>ref_runtime-mapping-singleton</name>
+                                <provider>
+                                    /config/modules/module[name='runtime-generated-mapping']/instance[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>ref_dom-broker</name>
+                                <provider>/config/modules/module[name='dom-broker-impl']/instance[name='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>ref_binding-data-broker</name>
+                                <provider>
+                                    /config/modules/module[name='binding-data-broker']/instance[name='binding-data-broker']
+                                </provider>
+                            </instance>
+                        </service>
+                    </services>
+                </data>
+
+            </configuration>
+        </snapshot>
+    </snapshots>
+</persisted-snapshots>
index 3436018..c575058 100644 (file)
@@ -10,6 +10,7 @@ import org.opendaylight.yangtools.yang.common.RpcResult
 import org.opendaylight.yangtools.yang.data.api.CompositeNode
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
 import org.slf4j.LoggerFactory
+import org.opendaylight.controller.sal.core.api.mount.MountInstance
 
 class BrokerFacade implements DataReader<InstanceIdentifier, CompositeNode> {
 
@@ -44,12 +45,24 @@ class BrokerFacade implements DataReader<InstanceIdentifier, CompositeNode> {
         LOG.info("Read Configuration via Restconf: {}", path)
         return dataService.readConfigurationData(path);
     }
+    
+    def readConfigurationDataBehindMountPoint(MountInstance mountPoint, InstanceIdentifier path) {
+        checkPreconditions
+        LOG.info("Read Configuration via Restconf: {}", path)
+        return mountPoint.readConfigurationData(path);
+    }
 
     override readOperationalData(InstanceIdentifier path) {
         checkPreconditions
         LOG.info("Read Operational via Restconf: {}", path)
         return dataService.readOperationalData(path);
     }
+    
+    def readOperationalDataBehindMountPoint(MountInstance mountPoint, InstanceIdentifier path) {
+        checkPreconditions
+        LOG.info("Read Operational via Restconf: {}", path)
+        return mountPoint.readOperationalData(path);
+    }
 
     def RpcResult<CompositeNode> invokeRpc(QName type, CompositeNode payload) {
         checkPreconditions
@@ -64,6 +77,14 @@ class BrokerFacade implements DataReader<InstanceIdentifier, CompositeNode> {
         transaction.putConfigurationData(path, payload);
         return transaction.commit
     }
+    
+    def commitConfigurationDataPutBehindMountPoint(MountInstance mountPoint, InstanceIdentifier path, CompositeNode payload) {
+        checkPreconditions
+        val transaction = mountPoint.beginTransaction;
+        LOG.info("Put Configuration via Restconf: {}", path)
+        transaction.putConfigurationData(path, payload);
+        return transaction.commit
+    }
 
     def commitConfigurationDataPost(InstanceIdentifier path, CompositeNode payload) {
         checkPreconditions
@@ -76,6 +97,18 @@ class BrokerFacade implements DataReader<InstanceIdentifier, CompositeNode> {
         LOG.info("Post Configuration via Restconf was not executed because data already exists: {}", path)
         return null;
     }
+    
+    def commitConfigurationDataPostBehindMountPoint(MountInstance mountPoint, InstanceIdentifier path, CompositeNode payload) {
+        checkPreconditions
+        val transaction = mountPoint.beginTransaction;
+        transaction.putConfigurationData(path, payload);
+        if (payload == transaction.createdConfigurationData.get(path)) {
+            LOG.info("Post Configuration via Restconf: {}", path)
+            return transaction.commit
+        }
+        LOG.info("Post Configuration via Restconf was not executed because data already exists: {}", path)
+        return null;
+    }
 
     def commitConfigurationDataDelete(InstanceIdentifier path) {
         checkPreconditions
@@ -83,5 +116,12 @@ class BrokerFacade implements DataReader<InstanceIdentifier, CompositeNode> {
         transaction.removeConfigurationData(path)
         return transaction.commit
     }
+    
+    def commitConfigurationDataDeleteBehindMountPoint(MountInstance mountPoint, InstanceIdentifier path) {
+        checkPreconditions
+        val transaction = mountPoint.beginTransaction;
+        transaction.removeConfigurationData(path)
+        return transaction.commit
+    }
 
 }
index 308975c..61237f0 100644 (file)
@@ -10,7 +10,6 @@ import java.util.HashMap
 import java.util.List
 import java.util.Map
 import java.util.concurrent.ConcurrentHashMap
-import javax.ws.rs.core.Response
 import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener
 import org.opendaylight.controller.sal.core.api.mount.MountService
 import org.opendaylight.controller.sal.rest.impl.RestUtil
@@ -37,12 +36,16 @@ import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition
 import org.slf4j.LoggerFactory
 
 import static com.google.common.base.Preconditions.*
-import java.util.ArrayList
+import static javax.ws.rs.core.Response.Status.*
+import org.opendaylight.controller.sal.core.api.mount.MountInstance
 
 class ControllerContext implements SchemaServiceListener {
     val static LOG = LoggerFactory.getLogger(ControllerContext)
     val static ControllerContext INSTANCE = new ControllerContext
     val static NULL_VALUE = "null"
+    val static MOUNT_MODULE = "yang-ext"
+    val static MOUNT_NODE = "mount"
+    val static MOUNT = "yang-ext:mount"
 
     @Property
     var SchemaContext globalSchema;
@@ -66,7 +69,7 @@ class ControllerContext implements SchemaServiceListener {
 
     private def void checkPreconditions() {
         if (globalSchema === null) {
-            throw new ResponseException(Response.Status.SERVICE_UNAVAILABLE, RestconfProvider::NOT_INITALIZED_MSG)
+            throw new ResponseException(SERVICE_UNAVAILABLE, RestconfProvider::NOT_INITALIZED_MSG)
         }
     }
 
@@ -76,7 +79,6 @@ class ControllerContext implements SchemaServiceListener {
 
     public def InstanceIdWithSchemaNode toInstanceIdentifier(String restconfInstance) {
         checkPreconditions
-        val ret = InstanceIdentifier.builder();
         val pathArgs = restconfInstance.split("/");
         if (pathArgs.empty) {
             return null;
@@ -84,21 +86,19 @@ class ControllerContext implements SchemaServiceListener {
         if (pathArgs.head.empty) {
             pathArgs.remove(0)
         }
-        val mountPoints = new ArrayList
-        val schemaNode = ret.collectPathArguments(pathArgs, globalSchema.findModule(pathArgs.head), mountPoints);
-        if (schemaNode === null) {
-            return null
+        val startModule = pathArgs.head.toModuleName();
+        if (startModule === null) {
+            throw new ResponseException(BAD_REQUEST, "First node in URI has to be in format \"moduleName:nodeName\"")
         }
-        return new InstanceIdWithSchemaNode(ret.toInstance, schemaNode, mountPoints.last)
+        val iiWithSchemaNode = collectPathArguments(InstanceIdentifier.builder(), pathArgs,
+            globalSchema.getLatestModule(startModule), null);
+        if (iiWithSchemaNode === null) {
+            throw new ResponseException(BAD_REQUEST, "URI has bad format")
+        }
+        return iiWithSchemaNode
     }
 
-    private def findModule(SchemaContext context,String argument) {
-        checkNotNull(argument);
-        val startModule = argument.toModuleName();
-        return context.getLatestModule(startModule)
-    }
-    
-    private def getLatestModule(SchemaContext schema,String moduleName) {
+    private def getLatestModule(SchemaContext schema, String moduleName) {
         checkArgument(schema !== null);
         checkArgument(moduleName !== null && !moduleName.empty)
         val modules = schema.modules.filter[m|m.name == moduleName]
@@ -121,9 +121,9 @@ class ControllerContext implements SchemaServiceListener {
         return globalSchema.getLatestModule(moduleName)
     }
     
-    def findModuleByName(String moduleName, InstanceIdentifier partialPath) {
-        checkArgument(moduleName !== null && !moduleName.empty && partialPath !== null && !partialPath.path.empty)
-        val mountPointSchema = mountService?.getMountPoint(partialPath)?.schemaContext;
+    def findModuleByName(MountInstance mountPoint, String moduleName) {
+        checkArgument(moduleName !== null && mountPoint !== null)
+        val mountPointSchema = mountPoint.schemaContext;
         return mountPointSchema?.getLatestModule(moduleName);
     }
     
@@ -133,9 +133,9 @@ class ControllerContext implements SchemaServiceListener {
         return moduleSchemas?.filterLatestModule
     }
     
-    def findModuleByNamespace(URI namespace, InstanceIdentifier partialPath) {
-        checkArgument(namespace !== null && !namespace.toString.empty && partialPath !== null && !partialPath.path.empty)
-        val mountPointSchema = mountService?.getMountPoint(partialPath)?.schemaContext;
+    def findModuleByNamespace(MountInstance mountPoint, URI namespace) {
+        checkArgument(namespace !== null && mountPoint !== null)
+        val mountPointSchema = mountPoint.schemaContext;
         val moduleSchemas = mountPointSchema?.findModuleByNamespace(namespace)
         return moduleSchemas?.filterLatestModule
     }
@@ -254,39 +254,92 @@ class ControllerContext implements SchemaServiceListener {
         if(object === null) return "";
         return URLEncoder.encode(object.toString)
     }
-
-    private def DataSchemaNode collectPathArguments(InstanceIdentifierBuilder builder, List<String> strings,
-        DataNodeContainer parentNode, List<InstanceIdentifier> mountPoints) {
+    
+    private def InstanceIdWithSchemaNode collectPathArguments(InstanceIdentifierBuilder builder, List<String> strings,
+        DataNodeContainer parentNode, MountInstance mountPoint) {
         checkNotNull(strings)
         if (parentNode === null) {
             return null;
         }
         if (strings.empty) {
-            return parentNode as DataSchemaNode;
-        }
-        val nodeRef = strings.head;
-
-        val nodeName = nodeRef.toNodeName;
-        var targetNode = parentNode.findInstanceDataChild(nodeName);
-        if (targetNode instanceof ChoiceNode) {
-            return null
+            return new InstanceIdWithSchemaNode(builder.toInstance, parentNode as DataSchemaNode, mountPoint)
         }
         
-        if (targetNode === null) {
-            // Node is possibly in other mount point
-            val partialPath = builder.toInstance;
-            val mountPointSchema = mountService?.getMountPoint(partialPath)?.schemaContext;
-            if(mountPointSchema !== null) {
-                val module = mountPointSchema.findModule(strings.head)
-                if (module !== null) {
-                    mountPoints.add(partialPath)
+        val nodeName = strings.head.toNodeName
+        val moduleName = strings.head.toModuleName
+        var DataSchemaNode targetNode = null
+        if (!moduleName.nullOrEmpty) {
+            // if it is mount point
+            if (moduleName == MOUNT_MODULE && nodeName == MOUNT_NODE) {
+                if (mountPoint !== null) {
+                    throw new ResponseException(BAD_REQUEST, "Restconf supports just one mount point in URI.")
+                }
+                
+                if (mountService === null) {
+                    throw new ResponseException(SERVICE_UNAVAILABLE, "MountService was not found. " 
+                        + "Finding behind mount points does not work."
+                    )
+                }
+                
+                val partialPath = builder.toInstance;
+                val mount = mountService.getMountPoint(partialPath)
+                if (mount === null) {
+                    LOG.debug("Instance identifier to missing mount point: {}", partialPath)
+                    throw new ResponseException(BAD_REQUEST, "Mount point does not exist.")
+                }
+                
+                val mountPointSchema = mount.schemaContext;
+                if (mountPointSchema === null) {
+                    throw new ResponseException(BAD_REQUEST, "Mount point does not contain any schema with modules.")
+                }
+                
+                if (strings.size == 1) { // any data node is not behind mount point
+                    return new InstanceIdWithSchemaNode(InstanceIdentifier.builder().toInstance, mountPointSchema, mount)
+                }
+                
+                val moduleNameBehindMountPoint = strings.get(1).toModuleName()
+                if (moduleNameBehindMountPoint === null) {
+                    throw new ResponseException(BAD_REQUEST,
+                        "First node after mount point in URI has to be in format \"moduleName:nodeName\"")
+                }
+                
+                val moduleBehindMountPoint = mountPointSchema.getLatestModule(moduleNameBehindMountPoint)
+                if (moduleBehindMountPoint === null) {
+                    throw new ResponseException(BAD_REQUEST,
+                        "URI has bad format. \"" + moduleName + "\" module does not exist in mount point.")
+                }
+                
+                return collectPathArguments(InstanceIdentifier.builder(), strings.subList(1, strings.size),
+                    moduleBehindMountPoint, mount);
+            }
+            
+            var Module module = null;
+            if (mountPoint === null) {
+                module = globalSchema.getLatestModule(moduleName)
+                if (module === null) {
+                    throw new ResponseException(BAD_REQUEST,
+                        "URI has bad format. \"" + moduleName + "\" module does not exist.")
                 }
-                return builder.collectPathArguments(strings, module, mountPoints);
+            } else {
+                module = mountPoint.schemaContext?.getLatestModule(moduleName)
+                if (module === null) {
+                    throw new ResponseException(BAD_REQUEST,
+                        "URI has bad format. \"" + moduleName + "\" module does not exist in mount point.")
+                }
+            }
+            targetNode = parentNode.findInstanceDataChild(nodeName, module.namespace)
+            if (targetNode === null) {
+                throw new ResponseException(BAD_REQUEST, "URI has bad format. Possible reasons:\n" + 
+                    "1. \"" + strings.head + "\" was not found in parent data node.\n" + 
+                    "2. \"" + strings.head + "\" is behind mount point. Then it should be in format \"/" + MOUNT + "/" + strings.head + "\".")
+            }
+        } else { // string without module name
+            targetNode = parentNode.findInstanceDataChild(nodeName, null)
+            if (targetNode === null) {
+                throw new ResponseException(BAD_REQUEST, "URI has bad format. \"" + nodeName + "\" was not found in parent data node.\n")
             }
-            return null
         }
         
-
         // Number of consumed elements
         var consumed = 1;
         if (targetNode instanceof ListSchemaNode) {
@@ -295,7 +348,7 @@ class ControllerContext implements SchemaServiceListener {
 
             // every key has to be filled
             if ((strings.length - consumed) < keysSize) {
-                return null;
+                throw new ResponseException(BAD_REQUEST,"Missing key for list \"" + listNode.QName.localName + "\".")
             }
             val uriKeyValues = strings.subList(consumed, consumed + keysSize);
             val keyValues = new HashMap<QName, Object>();
@@ -305,7 +358,9 @@ class ControllerContext implements SchemaServiceListener {
 
                 // key value cannot be NULL
                 if (uriKeyValue.equals(NULL_VALUE)) {
-                    return null
+                    throw new ResponseException(BAD_REQUEST, "URI has bad format. List \"" + listNode.QName.localName 
+                        + "\" cannot contain \"null\" value as a key."
+                    )
                 }
                 keyValues.addKeyValue(listNode.getDataChildByName(key), uriKeyValue);
                 i = i + 1;
@@ -319,23 +374,28 @@ class ControllerContext implements SchemaServiceListener {
         }
         if (targetNode instanceof DataNodeContainer) {
             val remaining = strings.subList(consumed, strings.length);
-            val result = builder.collectPathArguments(remaining, targetNode as DataNodeContainer, mountPoints);
+            val result = builder.collectPathArguments(remaining, targetNode as DataNodeContainer, mountPoint);
             return result
         }
 
-        return targetNode
+        return new InstanceIdWithSchemaNode(builder.toInstance, targetNode, mountPoint)
     }
-    
-    static def DataSchemaNode findInstanceDataChild(DataNodeContainer container, String name) {
-        // FIXME: Add namespace comparison
-        var potentialNode = container.getDataChildByName(name);
-        if(potentialNode.instantiatedDataSchema) {
+
+    def DataSchemaNode findInstanceDataChild(DataNodeContainer container, String name, URI moduleNamespace) {
+        var DataSchemaNode potentialNode = null
+        if (moduleNamespace === null) {
+            potentialNode = container.getDataChildByName(name);
+        } else {
+            potentialNode = container.childNodes.filter[n|n.QName.localName == name && n.QName.namespace == moduleNamespace].head
+        }
+        
+        if (potentialNode.instantiatedDataSchema) {
             return potentialNode;
         }
         val allCases = container.childNodes.filter(ChoiceNode).map[cases].flatten
         for (caze : allCases) {
-            potentialNode = caze.findInstanceDataChild(name);
-            if(potentialNode !== null) {
+            potentialNode = caze.findInstanceDataChild(name, moduleNamespace);
+            if (potentialNode !== null) {
                 return potentialNode;
             }
         }
@@ -372,21 +432,21 @@ class ControllerContext implements SchemaServiceListener {
         checkNotNull(str)
         if (str.contains(":")) {
             val args = str.split(":");
-            checkArgument(args.size === 2);
-            return args.get(0);
-        } else {
-            return null;
+            if (args.size === 2) {
+                return args.get(0);
+            }
         }
+        return null;
     }
 
     private def String toNodeName(String str) {
         if (str.contains(":")) {
             val args = str.split(":");
-            checkArgument(args.size === 2);
-            return args.get(1);
-        } else {
-            return str;
+            if (args.size === 2) {
+                return args.get(1);
+            }
         }
+        return str;
     }
 
     private def QName toQName(String name) {
index ba0e47f..1c958b9 100644 (file)
@@ -1,5 +1,6 @@
 package org.opendaylight.controller.sal.restconf.impl;
 
+import org.opendaylight.controller.sal.core.api.mount.MountInstance;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 
@@ -7,9 +8,9 @@ public class InstanceIdWithSchemaNode {
 
     private final InstanceIdentifier instanceIdentifier;
     private final DataSchemaNode schemaNode;
-    private final InstanceIdentifier mountPoint;
+    private final MountInstance mountPoint;
 
-    public InstanceIdWithSchemaNode(InstanceIdentifier instanceIdentifier, DataSchemaNode schemaNode, InstanceIdentifier mountPoint) {
+    public InstanceIdWithSchemaNode(InstanceIdentifier instanceIdentifier, DataSchemaNode schemaNode, MountInstance mountPoint) {
         this.instanceIdentifier = instanceIdentifier;
         this.schemaNode = schemaNode;
         this.mountPoint = mountPoint;
@@ -23,7 +24,7 @@ public class InstanceIdWithSchemaNode {
         return schemaNode;
     }
 
-    public InstanceIdentifier getMountPoint() {
+    public MountInstance getMountPoint() {
         return mountPoint;
     }
 
index a65c0ff..5ad6f1e 100644 (file)
@@ -1,13 +1,17 @@
 package org.opendaylight.controller.sal.restconf.impl
 
+import com.google.common.base.Preconditions
+import java.net.URI
 import java.util.ArrayList
 import java.util.HashMap
 import java.util.List
 import java.util.Set
 import javax.ws.rs.core.Response
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus
+import org.opendaylight.controller.sal.core.api.mount.MountInstance
 import org.opendaylight.controller.sal.rest.api.RestconfService
 import org.opendaylight.yangtools.yang.common.QName
+import org.opendaylight.yangtools.yang.common.RpcResult
 import org.opendaylight.yangtools.yang.data.api.CompositeNode
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.InstanceIdentifierBuilder
@@ -21,11 +25,11 @@ import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode
 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
 import org.opendaylight.yangtools.yang.model.api.Module
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition
 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition
 
 import static javax.ws.rs.core.Response.Status.*
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition
 
 class RestconfImpl implements RestconfService {
 
@@ -92,21 +96,36 @@ class RestconfImpl implements RestconfService {
     }
 
     override readData(String identifier) {
-        val instanceIdentifierWithSchemaNode = identifier.resolveInstanceIdentifier
-        val data = broker.readOperationalData(instanceIdentifierWithSchemaNode.getInstanceIdentifier);
-        return new StructuredData(data, instanceIdentifierWithSchemaNode.schemaNode)
+        val iiWithData = identifier.toInstanceIdentifier
+        var CompositeNode data = null;
+        if (iiWithData.mountPoint !== null) {
+            data = broker.readOperationalDataBehindMountPoint(iiWithData.mountPoint, iiWithData.instanceIdentifier)
+        } else {
+            data = broker.readOperationalData(iiWithData.getInstanceIdentifier);
+        }
+        return new StructuredData(data, iiWithData.schemaNode)
     }
 
     override readConfigurationData(String identifier) {
-        val instanceIdentifierWithSchemaNode = identifier.resolveInstanceIdentifier
-        val data = broker.readConfigurationData(instanceIdentifierWithSchemaNode.getInstanceIdentifier);
-        return new StructuredData(data, instanceIdentifierWithSchemaNode.schemaNode)
+        val iiWithData = identifier.toInstanceIdentifier
+        var CompositeNode data = null;
+        if (iiWithData.mountPoint !== null) {
+            data = broker.readConfigurationDataBehindMountPoint(iiWithData.mountPoint, iiWithData.getInstanceIdentifier)
+        } else {
+            data = broker.readConfigurationData(iiWithData.getInstanceIdentifier);
+        }
+        return new StructuredData(data, iiWithData.schemaNode)
     }
 
     override readOperationalData(String identifier) {
-        val instanceIdentifierWithSchemaNode = identifier.resolveInstanceIdentifier
-        val data = broker.readOperationalData(instanceIdentifierWithSchemaNode.getInstanceIdentifier);
-        return new StructuredData(data, instanceIdentifierWithSchemaNode.schemaNode)
+        val iiWithData = identifier.toInstanceIdentifier
+        var CompositeNode data = null;
+        if (iiWithData.mountPoint !== null) {
+            data = broker.readOperationalDataBehindMountPoint(iiWithData.mountPoint, iiWithData.getInstanceIdentifier)
+        } else {
+            data = broker.readOperationalData(iiWithData.getInstanceIdentifier);
+        }
+        return new StructuredData(data, iiWithData.schemaNode)
     }
 
     override updateConfigurationDataLegacy(String identifier, CompositeNode payload) {
@@ -114,9 +133,15 @@ class RestconfImpl implements RestconfService {
     }
 
     override updateConfigurationData(String identifier, CompositeNode payload) {
-        val identifierWithSchemaNode = identifier.resolveInstanceIdentifier
-        val value = normalizeNode(payload, identifierWithSchemaNode.schemaNode, identifierWithSchemaNode.mountPoint)
-        val status = broker.commitConfigurationDataPut(identifierWithSchemaNode.instanceIdentifier, value).get();
+        val iiWithData = identifier.toInstanceIdentifier
+        val value = normalizeNode(payload, iiWithData.schemaNode, iiWithData.mountPoint)
+        var RpcResult<TransactionStatus> status = null
+        if (iiWithData.mountPoint !== null) {
+            status = broker.commitConfigurationDataPutBehindMountPoint(iiWithData.mountPoint,
+                iiWithData.instanceIdentifier, value).get()
+        } else {
+            status = broker.commitConfigurationDataPut(iiWithData.instanceIdentifier, value).get();
+        }
         switch status.result {
             case TransactionStatus.COMMITED: Response.status(OK).build
             default: Response.status(INTERNAL_SERVER_ERROR).build
@@ -128,14 +153,21 @@ class RestconfImpl implements RestconfService {
     }
 
     override createConfigurationData(String identifier, CompositeNode payload) {
-        val uncompleteIdentifierWithSchemaNode = identifier.resolveInstanceIdentifier
-        var schemaNode = (uncompleteIdentifierWithSchemaNode.schemaNode as DataNodeContainer).getSchemaChildNode(payload)
-        if (schemaNode === null) {
-            schemaNode = payload.findModule(uncompleteIdentifierWithSchemaNode.instanceIdentifier)?.getSchemaChildNode(payload)
-        }
-        val value = normalizeNode(payload, schemaNode, uncompleteIdentifierWithSchemaNode.instanceIdentifier)
-        val completeIdentifierWithSchemaNode = uncompleteIdentifierWithSchemaNode.addLastIdentifierFromData(value, schemaNode)
-        val status = broker.commitConfigurationDataPost(completeIdentifierWithSchemaNode.instanceIdentifier, value)?.get();
+        if (payload.namespace === null) {
+            throw new ResponseException(BAD_REQUEST,
+                "Data has bad format. Root element node must have namespace (XML format) or module name(JSON format)");
+        }
+        val uncompleteInstIdWithData = identifier.toInstanceIdentifier
+        val schemaNode = uncompleteInstIdWithData.mountPoint.findModule(payload)?.getSchemaChildNode(payload)
+        val value = normalizeNode(payload, schemaNode, uncompleteInstIdWithData.mountPoint)
+        val completeInstIdWithData = uncompleteInstIdWithData.addLastIdentifierFromData(value, schemaNode)
+        var RpcResult<TransactionStatus> status = null
+        if (completeInstIdWithData.mountPoint !== null) {
+            status = broker.commitConfigurationDataPostBehindMountPoint(completeInstIdWithData.mountPoint,
+                completeInstIdWithData.instanceIdentifier, value)?.get();
+        } else {
+            status = broker.commitConfigurationDataPost(completeInstIdWithData.instanceIdentifier, value)?.get();
+        }
         if (status === null) {
             return Response.status(ACCEPTED).build
         }
@@ -146,10 +178,20 @@ class RestconfImpl implements RestconfService {
     }
     
     override createConfigurationData(CompositeNode payload) {
-        val schemaNode = payload.findModule(null)?.getSchemaChildNode(payload)
+        if (payload.namespace === null) {
+            throw new ResponseException(BAD_REQUEST,
+                "Data has bad format. Root element node must have namespace (XML format) or module name(JSON format)");
+        }
+        val schemaNode = findModule(null, payload)?.getSchemaChildNode(payload)
         val value = normalizeNode(payload, schemaNode, null)
-        val identifierWithSchemaNode = addLastIdentifierFromData(null, value, schemaNode)
-        val status = broker.commitConfigurationDataPost(identifierWithSchemaNode.instanceIdentifier, value)?.get();
+        val iiWithData = addLastIdentifierFromData(null, value, schemaNode)
+        var RpcResult<TransactionStatus> status = null
+        if (iiWithData.mountPoint !== null) {
+            status = broker.commitConfigurationDataPostBehindMountPoint(iiWithData.mountPoint,
+                iiWithData.instanceIdentifier, value)?.get();
+        } else {
+            status = broker.commitConfigurationDataPost(iiWithData.instanceIdentifier, value)?.get();
+        }
         if (status === null) {
             return Response.status(ACCEPTED).build
         }
@@ -160,36 +202,43 @@ class RestconfImpl implements RestconfService {
     }
     
     override deleteConfigurationData(String identifier) {
-        val instanceIdentifierWithSchemaNode = identifier.resolveInstanceIdentifier
-        val status = broker.commitConfigurationDataDelete(instanceIdentifierWithSchemaNode.getInstanceIdentifier).get;
+        val iiWithData = identifier.toInstanceIdentifier
+        var RpcResult<TransactionStatus> status = null
+        if (iiWithData.mountPoint !== null) {
+            status = broker.commitConfigurationDataDeleteBehindMountPoint(iiWithData.mountPoint,
+                iiWithData.getInstanceIdentifier).get;
+        } else {
+            status = broker.commitConfigurationDataDelete(iiWithData.getInstanceIdentifier).get;
+        }
         switch status.result {
             case TransactionStatus.COMMITED: Response.status(OK).build
             default: Response.status(INTERNAL_SERVER_ERROR).build
         }
     }
-
-    private def InstanceIdWithSchemaNode resolveInstanceIdentifier(String identifier) {
-        val identifierWithSchemaNode = identifier.toInstanceIdentifier
-        if (identifierWithSchemaNode === null) {
-            throw new ResponseException(BAD_REQUEST, "URI has bad format");
-        }
-        return identifierWithSchemaNode
+    
+    private def dispatch URI namespace(CompositeNode data) {
+        return data.nodeType.namespace
+    }
+    
+    private def dispatch URI namespace(CompositeNodeWrapper data) {
+        return data.namespace
     }
 
-    private def dispatch Module findModule(CompositeNode data, InstanceIdentifier partialPath) {
-        if (partialPath !== null && !partialPath.path.empty) {
-            return data.nodeType.namespace.findModuleByNamespace(partialPath)
+    private def dispatch Module findModule(MountInstance mountPoint, CompositeNode data) {
+        if (mountPoint !== null) {
+            return mountPoint.findModuleByNamespace(data.nodeType.namespace)
         } else {
-            return data.nodeType.namespace.findModuleByNamespace
+            return findModuleByNamespace(data.nodeType.namespace)
         }
     }
 
-    private def dispatch Module findModule(CompositeNodeWrapper data, InstanceIdentifier partialPath) {
+    private def dispatch Module findModule(MountInstance mountPoint, CompositeNodeWrapper data) {
+        Preconditions.checkNotNull(data.namespace)
         var Module module = null;
-        if (partialPath !== null && !partialPath.path.empty) {
-            module = data.namespace.findModuleByNamespace(partialPath) // namespace from XML
+        if (mountPoint !== null) {
+            module = mountPoint.findModuleByNamespace(data.namespace) // namespace from XML
             if (module === null) {
-                module = data.namespace.toString.findModuleByName(partialPath) // namespace (module name) from JSON
+                module = mountPoint.findModuleByName(data.namespace.toString) // namespace (module name) from JSON
             }
         } else {
             module = data.namespace.findModuleByNamespace // namespace from XML
@@ -208,10 +257,11 @@ class RestconfImpl implements RestconfService {
         return parentSchemaNode?.getDataChildByName(data.localName)
     }
 
-    private def InstanceIdWithSchemaNode addLastIdentifierFromData(InstanceIdWithSchemaNode identifierWithSchemaNode, CompositeNode data, DataSchemaNode schemaOfData) {
+    private def InstanceIdWithSchemaNode addLastIdentifierFromData(InstanceIdWithSchemaNode identifierWithSchemaNode,
+        CompositeNode data, DataSchemaNode schemaOfData) {
         val iiOriginal = identifierWithSchemaNode?.instanceIdentifier
-        var  InstanceIdentifierBuilder iiBuilder = null
-        if (iiOriginal === null) { 
+        var InstanceIdentifierBuilder iiBuilder = null
+        if (iiOriginal === null) {
             iiBuilder = InstanceIdentifier.builder
         } else {
             iiBuilder = InstanceIdentifier.builder(iiOriginal)
@@ -230,15 +280,20 @@ class RestconfImpl implements RestconfService {
         for (key : listNode.keyDefinition) {
             val dataNodeKeyValueObject = dataNode.getSimpleNodesByName(key.localName)?.head?.value
             if (dataNodeKeyValueObject === null) {
-                throw new ResponseException(BAD_REQUEST, "Data contains list \"" + dataNode.nodeType.localName + "\" which does not contain key: \"" + key.localName + "\"")
+                throw new ResponseException(BAD_REQUEST,
+                    "Data contains list \"" + dataNode.nodeType.localName + "\" which does not contain key: \"" +
+                        key.localName + "\"")
             }
             keyValues.put(key, dataNodeKeyValueObject);
         }
         return keyValues
     }
 
-    private def CompositeNode normalizeNode(CompositeNode node, DataSchemaNode schema, InstanceIdentifier mountPoint) {
-        if (schema !== null && !schema.containerOrList) {
+    private def CompositeNode normalizeNode(CompositeNode node, DataSchemaNode schema, MountInstance mountPoint) {
+        if (schema === null) {
+            throw new ResponseException(INTERNAL_SERVER_ERROR, "Data schema node was not found for " + node?.nodeType?.localName)
+        }
+        if (!(schema instanceof DataNodeContainer)) {
             throw new ResponseException(BAD_REQUEST, "Root element has to be container or list yang datatype.");
         }
         if (node instanceof CompositeNodeWrapper) {
@@ -250,12 +305,8 @@ class RestconfImpl implements RestconfService {
         return node
     }
 
-    private def isContainerOrList(DataSchemaNode schemaNode) {
-        return (schemaNode instanceof ContainerSchemaNode) || (schemaNode instanceof ListSchemaNode)
-    }
-
     private def void normalizeNode(NodeWrapper<?> nodeBuilder, DataSchemaNode schema, QName previousAugment,
-        InstanceIdentifier mountPoint) {
+        MountInstance mountPoint) {
         if (schema === null) {
             throw new ResponseException(BAD_REQUEST,
                 "Data has bad format.\n\"" + nodeBuilder.localName + "\" does not exist in yang schema.");
@@ -267,9 +318,11 @@ class RestconfImpl implements RestconfService {
         } else if (previousAugment !== null && schema.QName.namespace !== previousAugment.namespace) {
             validQName = QName.create(currentAugment, schema.QName.localName);
         }
-        var moduleName = controllerContext.findModuleNameByNamespace(validQName.namespace);
-        if (moduleName === null && mountPoint !== null && !mountPoint.path.empty) {
-            moduleName = controllerContext.findModuleByNamespace(validQName.namespace, mountPoint)?.name
+        var String moduleName = null;
+        if (mountPoint === null) {
+            moduleName = controllerContext.findModuleNameByNamespace(validQName.namespace);
+        } else {
+            moduleName = mountPoint.findModuleByNamespace(validQName.namespace)?.name
         }
         if (nodeBuilder.namespace === null || nodeBuilder.namespace == validQName.namespace ||
             nodeBuilder.namespace.toString == moduleName) {
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithDataFromSeveralModulesTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithDataFromSeveralModulesTest.java
new file mode 100644 (file)
index 0000000..fdc10b7
--- /dev/null
@@ -0,0 +1,108 @@
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.ws.rs.WebApplicationException;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
+import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class CnSnToJsonWithDataFromSeveralModulesTest extends YangAndXmlAndDataSchemaLoader {
+
+    @BeforeClass
+    public static void initialize() {
+        dataLoad("/xml-to-cnsn/data-of-several-modules/yang",2,"module1","cont_m1");
+    }
+
+    @Test
+    public void dataFromSeveralModulesToJsonTest() throws WebApplicationException, IOException, URISyntaxException {
+        SchemaContext schemaContext = TestUtils.loadSchemaContext(modules);
+        String output = TestUtils.writeCompNodeWithSchemaContextToOutput(prepareCnSn(), modules, schemaContext,
+                StructuredDataToJsonProvider.INSTANCE);
+
+//         String output =
+//         String.format("\"data\"   :   {\n" +
+//                             "\t\"cont_m1\"   :  {\n" +
+//                                 "\t\t\"lf1_m1\"   :  \"lf1 m1 value\"\n" +
+//                             "\t}\n" +
+//                             "\t\"cont_m2\"   :  {\n" +
+//                                 "\t\t\"lf1_m2\"   :  \"lf1 m2 value\"\n" +
+//                             "\t}\n" +
+//                     "}");
+
+        StringBuilder regex = new StringBuilder();
+        regex.append("^");
+
+        regex.append(".*\"data\"");
+        regex.append(".*:");
+        regex.append(".*\\{");
+        
+        regex.append(".*\"contB_m1\"");
+        regex.append(".*:");
+        regex.append(".*\\{");
+        regex.append(".*\\}");
+        
+        regex.append(".*\"cont_m1\"");
+        regex.append(".*:");
+        regex.append(".*\\{");
+        regex.append(".*\\}");
+
+        regex.append(".*\"contB_m2\"");
+        regex.append(".*:");
+        regex.append(".*\\{");
+        regex.append(".*\\}");
+        
+        regex.append(".*\"cont_m2\"");
+        regex.append(".*:");
+        regex.append(".*\\{");
+        regex.append(".*\\}");
+        
+        regex.append(".*\\}");
+
+        regex.append(".*");
+        regex.append("$");
+
+        Pattern ptrn = Pattern.compile(regex.toString(), Pattern.DOTALL);
+        Matcher matcher = ptrn.matcher(output);
+
+        assertTrue(matcher.find());
+
+    }
+
+    private CompositeNode prepareCnSn() throws URISyntaxException {
+        CompositeNodeWrapper data = new CompositeNodeWrapper(new URI("urn:ietf:params:xml:ns:netconf:base:1.0"), "data");
+
+        URI uriModule1 = new URI("module:one");
+        CompositeNodeWrapper cont_m1 = new CompositeNodeWrapper(uriModule1, "cont_m1");
+        SimpleNodeWrapper lf1_m1 = new SimpleNodeWrapper(uriModule1, "lf1_m1", "lf1 m1 value");
+        cont_m1.addValue(lf1_m1);
+        CompositeNodeWrapper contB_m1 = new CompositeNodeWrapper(uriModule1, "contB_m1");
+        
+        data.addValue(contB_m1);
+        data.addValue(cont_m1);
+
+        URI uriModule2 = new URI("module:two");
+        CompositeNodeWrapper cont_m2 = new CompositeNodeWrapper(uriModule2, "cont_m2");
+        SimpleNodeWrapper lf1_m2 = new SimpleNodeWrapper(uriModule2, "lf1_m2", "lf1 m2 value");
+        cont_m2.addValue(lf1_m2);
+        CompositeNodeWrapper contB_m2 = new CompositeNodeWrapper(uriModule2, "contB_m2");
+        data.addValue(contB_m2);
+        data.addValue(cont_m2);
+        return data;
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithDataFromSeveralModulesTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithDataFromSeveralModulesTest.java
new file mode 100644 (file)
index 0000000..57a1495
--- /dev/null
@@ -0,0 +1,107 @@
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.xml.test;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.ws.rs.WebApplicationException;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
+import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class CnSnToXmlWithDataFromSeveralModulesTest extends YangAndXmlAndDataSchemaLoader {
+
+    @BeforeClass
+    public static void initialize() {
+        dataLoad("/xml-to-cnsn/data-of-several-modules/yang",2,"module1","cont_m1");
+    }
+
+    @Test
+    public void dataFromSeveralModulesToXmlTest() throws WebApplicationException, IOException, URISyntaxException {
+        SchemaContext schemaContext = TestUtils.loadSchemaContext(modules);
+        String output = TestUtils.writeCompNodeWithSchemaContextToOutput(prepareCnSn(), modules, schemaContext,
+                StructuredDataToXmlProvider.INSTANCE);
+
+//         String output =
+//         String.format("<data>" +
+//                      "\n<cont_m1>" +
+//                             "\n\t<lf1_m1>" +
+//                                 "\n\t\tlf1 m1 value" +
+//                                     "\n\t</lf1_m1>" +
+//                         "\n</cont_m1>" +
+//                         "\n<cont_m2>" +
+//                             "\n\t<lf1_m2>" +
+//                                 "\n\t\tlf1 m2 value" +
+//                             "\n\t</lf1_m2>" +
+//                         "\n</cont_m2>" +
+//                     "\n</data>");
+
+        StringBuilder regex = new StringBuilder();
+        regex.append("^");
+
+        regex.append(".*<data.*");
+        regex.append(".*xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"");
+        regex.append(".*>");
+        
+        
+        regex.append(".*<contB_m1.*\\/>");
+        regex.append(".*xmlns=\"module:one\"");
+        regex.append(".*>");
+        regex.append(".*<lf1_m1.*>");
+        regex.append(".*<\\/lf1_m1>");
+        regex.append(".*<\\/cont_m1>");
+
+        regex.append(".*<contB_m2.*/>");
+        regex.append(".*<cont_m2.*");
+        regex.append(".*xmlns=\"module:two\"");
+        regex.append(".*>");
+        regex.append(".*<lf1_m2.*>");
+        regex.append(".*<\\/lf1_m2>");
+        regex.append(".*<\\/cont_m2>");
+
+        regex.append(".*<\\/data.*>");
+
+        regex.append(".*");
+        regex.append("$");
+
+        Pattern ptrn = Pattern.compile(regex.toString(), Pattern.DOTALL);
+        Matcher matcher = ptrn.matcher(output);
+
+        assertTrue(matcher.find());
+
+    }
+
+    private CompositeNode prepareCnSn() throws URISyntaxException {
+        CompositeNodeWrapper data = new CompositeNodeWrapper(new URI("urn:ietf:params:xml:ns:netconf:base:1.0"), "data");
+
+        URI uriModule1 = new URI("module:one");
+        CompositeNodeWrapper cont_m1 = new CompositeNodeWrapper(uriModule1, "cont_m1");
+        SimpleNodeWrapper lf1_m1 = new SimpleNodeWrapper(uriModule1, "lf1_m1", "lf1 m1 value");
+        cont_m1.addValue(lf1_m1);
+        CompositeNodeWrapper contB_m1 = new CompositeNodeWrapper(uriModule1, "contB_m1");
+        
+        data.addValue(contB_m1);
+        data.addValue(cont_m1);
+
+        URI uriModule2 = new URI("module:two");
+        CompositeNodeWrapper cont_m2 = new CompositeNodeWrapper(uriModule2, "cont_m2");
+        SimpleNodeWrapper lf1_m2 = new SimpleNodeWrapper(uriModule2, "lf1_m2", "lf1 m2 value");
+        cont_m2.addValue(lf1_m2);
+        CompositeNodeWrapper contB_m2 = new CompositeNodeWrapper(uriModule2, "contB_m2");
+        data.addValue(contB_m2);
+        data.addValue(cont_m2);
+        return data;
+    }
+
+}
index c68fcb9..4c5922d 100644 (file)
@@ -2,21 +2,19 @@ package org.opendaylight.controller.sal.restconf.impl.test;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
 
 import java.io.FileNotFoundException;
 import java.util.Set;
 
+import org.junit.After;
 import org.junit.BeforeClass;
+import org.junit.Rule;
 import org.junit.Test;
-import org.opendaylight.controller.sal.core.api.mount.MountInstance;
-import org.opendaylight.controller.sal.core.api.mount.MountService;
+import org.junit.rules.ExpectedException;
 import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
 import org.opendaylight.controller.sal.restconf.impl.InstanceIdWithSchemaNode;
+import org.opendaylight.controller.sal.restconf.impl.ResponseException;
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
@@ -25,6 +23,9 @@ public class ControllerContextTest {
 
     private static final ControllerContext controllerContext = ControllerContext.getInstance();
 
+    @Rule
+    public ExpectedException exception = ExpectedException.none();
+
     @BeforeClass
     public static void init() throws FileNotFoundException {
         Set<Module> allModules = TestUtils.loadModulesFrom("/full-versions/yangs");
@@ -33,6 +34,11 @@ public class ControllerContextTest {
         controllerContext.setSchemas(schemaContext);
     }
 
+    @After
+    public void releaseMountService() {
+        controllerContext.setMountService(null);
+    }
+
     @Test
     public void testToInstanceIdentifierList() throws FileNotFoundException {
         InstanceIdWithSchemaNode instanceIdentifier = controllerContext
@@ -50,48 +56,20 @@ public class ControllerContextTest {
 
         instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:users/user/foo");
         assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "user");
-
-        instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:user/null/boo");
-        assertNull(instanceIdentifier);
-
-        instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:user/foo");
-        assertNull(instanceIdentifier);
-
     }
 
     @Test
-    public void testToInstanceIdentifierMountPoint() throws FileNotFoundException {
-        try {
-            String mountPointPath = "simple-nodes:user/foo/boo";
-            String nestedPath = "simple-nodes:user/foo/boo/simple-nodes:users";
-            InstanceIdWithSchemaNode mountInstanceIdentifier = controllerContext.toInstanceIdentifier(mountPointPath);
-            assertEquals("user", mountInstanceIdentifier.getSchemaNode().getQName().getLocalName());
-
-            MountInstance mountInstance = mock(MountInstance.class);
-            MountService mountService = mock(MountService.class);
-
-            controllerContext.setMountService(mountService);
-            // when(mountService.getMountPoint(any(InstanceIdentifier.class))).thenReturn(null);
-
-            when(mountService.getMountPoint(eq(mountInstanceIdentifier.getInstanceIdentifier()))).thenReturn(
-                    mountInstance);
-
-            when(mountInstance.getSchemaContext()).thenReturn(controllerContext.getGlobalSchema());
-
-            InstanceIdWithSchemaNode mountedInstanceIdentifier = controllerContext.toInstanceIdentifier(nestedPath);
-            assertEquals("users", mountedInstanceIdentifier.getSchemaNode().getQName().getLocalName());
-
-            mountedInstanceIdentifier = controllerContext.toInstanceIdentifier(mountPointPath + "/" + mountPointPath);
-            assertEquals("user", mountedInstanceIdentifier.getSchemaNode().getQName().getLocalName());
-
-            mountedInstanceIdentifier = controllerContext
-                    .toInstanceIdentifier("simple-nodes:user/foo/var/simple-nodes:users");
-            assertNull(mountedInstanceIdentifier);
-
-        } finally {
-            controllerContext.setMountService(null);
-        }
+    public void testToInstanceIdentifierListWithNullKey() {
+        exception.expect(ResponseException.class);
+        exception.expectMessage("HTTP 400 Bad Request");
+        controllerContext.toInstanceIdentifier("simple-nodes:user/null/boo");
+    }
 
+    @Test
+    public void testToInstanceIdentifierListWithMissingKey() {
+        exception.expect(ResponseException.class);
+        exception.expectMessage("HTTP 400 Bad Request");
+        controllerContext.toInstanceIdentifier("simple-nodes:user/foo");
     }
 
     @Test
@@ -104,18 +82,30 @@ public class ControllerContextTest {
 
     @Test
     public void testToInstanceIdentifierChoice() throws FileNotFoundException {
-        InstanceIdWithSchemaNode instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:food/beer");
+        InstanceIdWithSchemaNode instanceIdentifier = controllerContext
+                .toInstanceIdentifier("simple-nodes:food/nonalcoholic/beer");
         assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "beer");
+    }
 
-        instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:food/snack");
-        assertNull(instanceIdentifier);
-
-        instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:food/sports-arena");
-        assertNull(instanceIdentifier);
+    @Test
+    public void testToInstanceIdentifierChoiceException() {
+        exception.expect(ResponseException.class);
+        exception.expectMessage("HTTP 400 Bad Request");
+        controllerContext.toInstanceIdentifier("simple-nodes:food/snack");
+    }
 
-        instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:food/snack/sports-arena");
-        assertNull(instanceIdentifier);
+    @Test
+    public void testToInstanceIdentifierCaseException() {
+        exception.expect(ResponseException.class);
+        exception.expectMessage("HTTP 400 Bad Request");
+        controllerContext.toInstanceIdentifier("simple-nodes:food/sports-arena");
+    }
 
+    @Test
+    public void testToInstanceIdentifierChoiceCaseException() {
+        exception.expect(ResponseException.class);
+        exception.expectMessage("HTTP 400 Bad Request");
+        controllerContext.toInstanceIdentifier("simple-nodes:food/snack/sports-arena");
     }
 
 }
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/DummyMountInstanceImpl.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/DummyMountInstanceImpl.java
deleted file mode 100644 (file)
index 181aa04..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-package org.opendaylight.controller.sal.restconf.impl.test;
-
-import java.util.concurrent.Future;
-
-import org.opendaylight.controller.sal.core.api.data.DataChangeListener;
-import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
-import org.opendaylight.controller.sal.core.api.mount.MountInstance;
-import org.opendaylight.controller.sal.core.api.notify.NotificationListener;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.concepts.Registration;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-class DummyMountInstanceImpl implements MountInstance {
-
-    SchemaContext schemaContext;
-
-    public static class Builder {
-        SchemaContext schemaContext;
-
-        public Builder setSchemaContext(SchemaContext schemaContext) {
-            this.schemaContext = schemaContext;
-            return this;
-        }
-
-        public MountInstance build() {
-            DummyMountInstanceImpl instance = new DummyMountInstanceImpl();
-            instance.schemaContext = schemaContext;
-            return instance;
-        }
-    }
-
-    @Override
-    public Registration<NotificationListener> addNotificationListener(QName notification, NotificationListener listener) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public CompositeNode readConfigurationData(InstanceIdentifier path) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public CompositeNode readOperationalData(InstanceIdentifier path) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public DataModificationTransaction beginTransaction() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public ListenerRegistration<DataChangeListener> registerDataChangeListener(InstanceIdentifier path,
-            DataChangeListener listener) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public SchemaContext getSchemaContext() {
-        return schemaContext;
-    }
-
-    @Override
-    public Future<RpcResult<CompositeNode>> rpc(QName type, CompositeNode input) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/MediaTypesTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/MediaTypesTest.java
new file mode 100644 (file)
index 0000000..bbedd2b
--- /dev/null
@@ -0,0 +1,225 @@
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.JSON;
+import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.XML;
+import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.createUri;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.MediaType;
+
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.api.Draft02;
+import org.opendaylight.controller.sal.rest.api.RestconfService;
+import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+public class MediaTypesTest extends JerseyTest {
+    
+    private static RestconfService restconfService;
+    private static String jsonData;
+    private static String xmlData;
+    
+    @BeforeClass
+    public static void init() throws IOException {
+        restconfService = mock(RestconfService.class);
+        String jsonPath = RestconfImplTest.class.getResource("/parts/ietf-interfaces_interfaces.json").getPath();
+        jsonData = TestUtils.loadTextFile(jsonPath);
+        InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
+        xmlData = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream));
+    }
+    
+    @Override
+    protected Application configure() {
+        /* enable/disable Jersey logs to console */
+//        enable(TestProperties.LOG_TRAFFIC);
+//        enable(TestProperties.DUMP_ENTITY);
+//        enable(TestProperties.RECORD_LOG_LEVEL);
+//        set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
+        ResourceConfig resourceConfig = new ResourceConfig();
+        resourceConfig = resourceConfig.registerInstances(restconfService, StructuredDataToXmlProvider.INSTANCE,
+                StructuredDataToJsonProvider.INSTANCE, XmlToCompositeNodeProvider.INSTANCE,
+                JsonToCompositeNodeProvider.INSTANCE);
+        return resourceConfig;
+    }
+    
+  @Test
+  public void testPostOperationsWithInputDataMediaTypes() throws UnsupportedEncodingException {
+      String uriPrefix = "/operations/";
+      String uriPath = "ietf-interfaces:interfaces";
+      String uri = createUri(uriPrefix, uriPath);
+      when(restconfService.invokeRpc(eq(uriPath), any(CompositeNode.class))).thenReturn(null);
+      post(uri, Draft02.MediaTypes.DATA+JSON, Draft02.MediaTypes.DATA+JSON, jsonData);
+      verify(restconfService, times(1)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+      post(uri, Draft02.MediaTypes.DATA+XML, Draft02.MediaTypes.DATA+XML, xmlData);
+      verify(restconfService, times(2)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+      post(uri, MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON, jsonData);
+      verify(restconfService, times(3)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+      post(uri, MediaType.APPLICATION_XML, MediaType.APPLICATION_XML, xmlData);
+      verify(restconfService, times(4)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+      post(uri, MediaType.TEXT_XML, MediaType.TEXT_XML, xmlData);
+      verify(restconfService, times(5)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+      post(uri, null, MediaType.TEXT_XML, xmlData);
+      verify(restconfService, times(6)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+      
+      // negative tests
+      post(uri, MediaType.TEXT_PLAIN, MediaType.TEXT_XML, xmlData);
+      verify(restconfService, times(6)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+      post(uri, MediaType.TEXT_XML, MediaType.TEXT_PLAIN, xmlData);
+      verify(restconfService, times(6)).invokeRpc(eq(uriPath), any(CompositeNode.class));
+  }
+  
+    @Test
+    public void testGetConfigMediaTypes() throws UnsupportedEncodingException {
+        String uriPrefix = "/config/";
+        String uriPath = "ietf-interfaces:interfaces";
+        String uri = createUri(uriPrefix, uriPath);
+        when(restconfService.readConfigurationData(uriPath)).thenReturn(null);
+        get(uri, Draft02.MediaTypes.DATA+JSON);
+        verify(restconfService, times(1)).readConfigurationData(uriPath);
+        get(uri, Draft02.MediaTypes.DATA+XML);
+        verify(restconfService, times(2)).readConfigurationData(uriPath);
+        get(uri, MediaType.APPLICATION_JSON);
+        verify(restconfService, times(3)).readConfigurationData(uriPath);
+        get(uri, MediaType.APPLICATION_XML);
+        verify(restconfService, times(4)).readConfigurationData(uriPath);
+        get(uri, MediaType.TEXT_XML);
+        verify(restconfService, times(5)).readConfigurationData(uriPath);
+        
+        // negative tests
+        get(uri, MediaType.TEXT_PLAIN);
+        verify(restconfService, times(5)).readConfigurationData(uriPath);
+    }
+    
+    @Test
+    public void testGetOperationalMediaTypes() throws UnsupportedEncodingException {
+        String uriPrefix = "/operational/";
+        String uriPath = "ietf-interfaces:interfaces";
+        String uri = createUri(uriPrefix, uriPath);
+        when(restconfService.readOperationalData(uriPath)).thenReturn(null);
+        get(uri, Draft02.MediaTypes.DATA+JSON);
+        verify(restconfService, times(1)).readOperationalData(uriPath);
+        get(uri, Draft02.MediaTypes.DATA+XML);
+        verify(restconfService, times(2)).readOperationalData(uriPath);
+        get(uri, MediaType.APPLICATION_JSON);
+        verify(restconfService, times(3)).readOperationalData(uriPath);
+        get(uri, MediaType.APPLICATION_XML);
+        verify(restconfService, times(4)).readOperationalData(uriPath);
+        get(uri, MediaType.TEXT_XML);
+        verify(restconfService, times(5)).readOperationalData(uriPath);
+        
+        // negative tests
+        get(uri, MediaType.TEXT_PLAIN);
+        verify(restconfService, times(5)).readOperationalData(uriPath);
+    }
+    
+    @Test
+    public void testPutConfigMediaTypes() throws UnsupportedEncodingException {
+        String uriPrefix = "/config/";
+        String uriPath = "ietf-interfaces:interfaces";
+        String uri = createUri(uriPrefix, uriPath);
+        when(restconfService.updateConfigurationData(eq(uriPath), any(CompositeNode.class))).thenReturn(null);
+        put(uri, null, Draft02.MediaTypes.DATA+JSON, jsonData);
+        verify(restconfService, times(1)).updateConfigurationData(eq(uriPath), any(CompositeNode.class));
+        put(uri, null, Draft02.MediaTypes.DATA+XML, xmlData);
+        verify(restconfService, times(2)).updateConfigurationData(eq(uriPath), any(CompositeNode.class));
+        put(uri, null, MediaType.APPLICATION_JSON, jsonData);
+        verify(restconfService, times(3)).updateConfigurationData(eq(uriPath), any(CompositeNode.class));
+        put(uri, null, MediaType.APPLICATION_XML, xmlData);
+        verify(restconfService, times(4)).updateConfigurationData(eq(uriPath), any(CompositeNode.class));
+        put(uri, null, MediaType.TEXT_XML, xmlData);
+        verify(restconfService, times(5)).updateConfigurationData(eq(uriPath), any(CompositeNode.class));
+        put(uri, "fooMediaType", MediaType.TEXT_XML, xmlData);
+        verify(restconfService, times(6)).updateConfigurationData(eq(uriPath), any(CompositeNode.class));
+    }
+    
+    @Test
+    public void testPostConfigWithPathMediaTypes() throws UnsupportedEncodingException {
+        String uriPrefix = "/config/";
+        String uriPath = "ietf-interfaces:interfaces";
+        String uri = createUri(uriPrefix, uriPath);
+        when(restconfService.createConfigurationData(eq(uriPath), any(CompositeNode.class))).thenReturn(null);
+        post(uri, null, Draft02.MediaTypes.DATA+JSON, jsonData);
+        verify(restconfService, times(1)).createConfigurationData(eq(uriPath), any(CompositeNode.class));
+        post(uri, null, Draft02.MediaTypes.DATA+XML, xmlData);
+        verify(restconfService, times(2)).createConfigurationData(eq(uriPath), any(CompositeNode.class));
+        post(uri, null, MediaType.APPLICATION_JSON, jsonData);
+        verify(restconfService, times(3)).createConfigurationData(eq(uriPath), any(CompositeNode.class));
+        post(uri, null, MediaType.APPLICATION_XML, xmlData);
+        verify(restconfService, times(4)).createConfigurationData(eq(uriPath), any(CompositeNode.class));
+        post(uri, null, MediaType.TEXT_XML, xmlData);
+        verify(restconfService, times(5)).createConfigurationData(eq(uriPath), any(CompositeNode.class));
+        post(uri, "fooMediaType", MediaType.TEXT_XML, xmlData);
+        verify(restconfService, times(6)).createConfigurationData(eq(uriPath), any(CompositeNode.class));
+    }
+    
+    @Test
+    public void testPostConfigMediaTypes() throws UnsupportedEncodingException {
+        String uriPrefix = "/config/";
+        String uri = createUri(uriPrefix, "");
+        when(restconfService.createConfigurationData(any(CompositeNode.class))).thenReturn(null);
+        post(uri, null, Draft02.MediaTypes.DATA+JSON, jsonData);
+        verify(restconfService, times(1)).createConfigurationData(any(CompositeNode.class));
+        post(uri, null, Draft02.MediaTypes.DATA+XML, xmlData);
+        verify(restconfService, times(2)).createConfigurationData(any(CompositeNode.class));
+        post(uri, null, MediaType.APPLICATION_JSON, jsonData);
+        verify(restconfService, times(3)).createConfigurationData(any(CompositeNode.class));
+        post(uri, null, MediaType.APPLICATION_XML, xmlData);
+        verify(restconfService, times(4)).createConfigurationData(any(CompositeNode.class));
+        post(uri, null, MediaType.TEXT_XML, xmlData);
+        verify(restconfService, times(5)).createConfigurationData(any(CompositeNode.class));
+        post(uri, "fooMediaType", MediaType.TEXT_XML, xmlData);
+        verify(restconfService, times(6)).createConfigurationData(any(CompositeNode.class));
+    }
+    
+    @Test
+    public void testDeleteConfigMediaTypes() throws UnsupportedEncodingException {
+        String uriPrefix = "/config/";
+        String uriPath = "ietf-interfaces:interfaces";
+        String uri = createUri(uriPrefix, uriPath);
+        when(restconfService.deleteConfigurationData(eq(uriPath))).thenReturn(null);
+        target(uri).request("fooMediaType").delete();
+        verify(restconfService, times(1)).deleteConfigurationData(uriPath);
+    }
+    
+    private int get(String uri, String acceptMediaType) {
+        return target(uri).request(acceptMediaType).get().getStatus();
+    }
+    
+    private int put(String uri, String acceptMediaType, String contentTypeMediaType, String data) {
+        if (acceptMediaType == null) {
+            return target(uri).request().put(Entity.entity(data, contentTypeMediaType)).getStatus();
+        }
+        return target(uri).request(acceptMediaType).put(Entity.entity(data, contentTypeMediaType)).getStatus();
+    }
+    
+    private int post(String uri, String acceptMediaType, String contentTypeMediaType, String data) {
+        if (acceptMediaType == null) {
+            if (contentTypeMediaType == null || data == null) {
+                return target(uri).request().post(null).getStatus();
+            }
+            return target(uri).request().post(Entity.entity(data, contentTypeMediaType)).getStatus();
+        }
+        if (contentTypeMediaType == null || data == null) {
+            return target(uri).request(acceptMediaType).post(null).getStatus();
+        }
+        return target(uri).request(acceptMediaType).post(Entity.entity(data, contentTypeMediaType)).getStatus();
+    }
+
+}
index dccf0d3..c6d0a93 100644 (file)
@@ -73,7 +73,8 @@ public class RestConfigDataTest extends JerseyTest {
         restconfImpl.setControllerContext(controllerContext);
     }
 
-    @Test
+//    @Test
+    // TODO 
     public void createConfigurationDataTest() throws UnsupportedEncodingException, ParseException {
         initMocking();
         String URI_1 = createUri("/config", "");
@@ -141,7 +142,8 @@ public class RestConfigDataTest extends JerseyTest {
         assertEquals("Bad format URI", identifier, instanceIdCaptor.getValue().getPath().toString());
     }
     
-    @Test
+//    @Test
+    // TODO
     public void testExistingData() throws UnsupportedEncodingException {
         initMocking();
         String URI_1 = createUri("/config", "");
index 814c8a3..4b36d63 100644 (file)
@@ -11,7 +11,6 @@ import java.io.FileNotFoundException;
 import java.io.UnsupportedEncodingException;
 import java.util.Set;
 import java.util.concurrent.Future;
-import java.util.logging.Level;
 
 import javax.ws.rs.core.Application;
 import javax.ws.rs.core.MediaType;
@@ -19,7 +18,6 @@ import javax.ws.rs.core.Response;
 
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.test.JerseyTest;
-import org.glassfish.jersey.test.TestProperties;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
@@ -38,7 +36,6 @@ public class RestDeleteOperationTest extends JerseyTest {
     private static ControllerContext controllerContext;
     private static BrokerFacade brokerFacade;
     private static RestconfImpl restconfImpl;
-    private static final MediaType MEDIA_TYPE_DRAFT02 = new MediaType("application", "yang.data+xml");
 
     @BeforeClass
     public static void init() throws FileNotFoundException {
@@ -56,13 +53,10 @@ public class RestDeleteOperationTest extends JerseyTest {
     @Override
     protected Application configure() {
         /* enable/disable Jersey logs to console */
-        /*
-         * enable(TestProperties.LOG_TRAFFIC);
-         */
-        enable(TestProperties.DUMP_ENTITY);
-        enable(TestProperties.RECORD_LOG_LEVEL);
-        set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
-
+//        enable(TestProperties.LOG_TRAFFIC);
+//        enable(TestProperties.DUMP_ENTITY);
+//        enable(TestProperties.RECORD_LOG_LEVEL);
+//        set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
         ResourceConfig resourceConfig = new ResourceConfig();
         resourceConfig = resourceConfig.registerInstances(restconfImpl, StructuredDataToXmlProvider.INSTANCE,
                 XmlToCompositeNodeProvider.INSTANCE);
@@ -70,24 +64,22 @@ public class RestDeleteOperationTest extends JerseyTest {
     }
 
     @Test
-    public void testDeleteConfigurationData() throws UnsupportedEncodingException, FileNotFoundException {
-        String uri2 = createUri("/config/", "test-interface:interfaces");
-
-        RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(
-                TransactionStatus.COMMITED).build();
-        Future<RpcResult<TransactionStatus>> dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build();
+    public void deleteConfigStatusCodes() throws UnsupportedEncodingException {
+        String uri = createUri("/config/", "test-interface:interfaces");
+        Future<RpcResult<TransactionStatus>> dummyFuture = createFuture(TransactionStatus.COMMITED);
         when(brokerFacade.commitConfigurationDataDelete(any(InstanceIdentifier.class))).thenReturn(dummyFuture);
-
-        Response response = target(uri2).request(MEDIA_TYPE_DRAFT02).delete();
+        Response response = target(uri).request(MediaType.APPLICATION_XML).delete();
         assertEquals(200, response.getStatus());
-
-        rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(TransactionStatus.FAILED).build();
-        dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build();
-
+        
+        dummyFuture = createFuture(TransactionStatus.FAILED);
         when(brokerFacade.commitConfigurationDataDelete(any(InstanceIdentifier.class))).thenReturn(dummyFuture);
-
-        response = target(uri2).request(MEDIA_TYPE_DRAFT02).delete();
+        response = target(uri).request(MediaType.APPLICATION_XML).delete();
         assertEquals(500, response.getStatus());
     }
+    
+    private Future<RpcResult<TransactionStatus>> createFuture(TransactionStatus statusName) {
+        RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(statusName).build();
+        return DummyFuture.builder().rpcResult(rpcResult).build();
+    }
 
 }
index d997a8a..ebc8a09 100644 (file)
@@ -4,7 +4,6 @@ import static org.junit.Assert.assertEquals;
 import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
-import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.JSON;
 import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.XML;
 import static org.opendaylight.controller.sal.restconf.impl.test.RestOperationUtils.createUri;
 
@@ -14,7 +13,6 @@ import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.ArrayList;