Merge "Addressing a flow programming issues on controler fail-over scenario in a...
authorGiovanni Meo <gmeo@cisco.com>
Thu, 9 Jan 2014 19:15:36 +0000 (19:15 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 9 Jan 2014 19:15:36 +0000 (19:15 +0000)
150 files changed:
opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/ClusterManager.java
opendaylight/clustering/stub/src/main/java/org/opendaylight/controller/clustering/stub/internal/ClusterManagerCommon.java
opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/AbstractConfigTest.java
opendaylight/config/pom.xml
opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTracker.java
opendaylight/containermanager/api/src/main/java/org/opendaylight/controller/containermanager/ContainerFlowConfig.java
opendaylight/distribution/opendaylight/src/main/resources/configuration/RSA.pk [moved from opendaylight/netconf/netconf-ssh/src/main/resources/RSA.pk with 100% similarity]
opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini
opendaylight/distribution/opendaylight/src/main/resources/run.sh
opendaylight/forwardingrulesmanager/api/src/main/java/org/opendaylight/controller/forwardingrulesmanager/FlowEntry.java
opendaylight/hosttracker/implementation/src/test/java/org/opendaylight/controller/hosttracker/internal/HostTrackerTest.java
opendaylight/md-sal/compatibility/sal-compatibility/pom.xml
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ComponentActivator.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FlowProgrammerAdapter.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FromSalConversionsUtils.java
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/InventoryAndReadAdapter.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDFlowMapping.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/NodeMapping.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ToSalConversionsUtils.java
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyAdapter.xtend [new file with mode: 0644]
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyCommitHandler.xtend [new file with mode: 0644]
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyMapping.xtend [new file with mode: 0644]
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyProvider.xtend [new file with mode: 0644]
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyTransaction.xtend [new file with mode: 0644]
opendaylight/md-sal/model/model-flow-base/pom.xml
opendaylight/md-sal/model/model-flow-base/src/main/yang/match-types.yang
opendaylight/md-sal/model/pom.xml
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java
opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/PutAugmentationTest.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountInstance.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountProvisionInstance.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointImpl.java
opendaylight/md-sal/sal-netconf-connector/pom.xml
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.xtend
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.xtend
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/XmlDocumentUtils.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/YangModelInputStreamAdapter.java [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/src/main/yang/odl-sal-netconf-connector-cfg.yang
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProvider.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlMapper.java
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/RestCodec.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonBasicYangTypesTest.java [moved from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonBasicYangTypesTest.java with 90% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonChoiceCaseTest.java [moved from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonChoiceCaseTest.java with 86% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonBasicDataTypesTest.java [moved from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonBasicDataTypesTest.java with 56% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIdentityrefTest.java [moved from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonIdentityrefTest.java with 56% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIncorrectTopLevelTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonLeafrefType.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonNotExistingLeafTypeTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithAugmentTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonLeafrefType.java [deleted file]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonWithAugmentTest.java [deleted file]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlNotExistingLeafTypeTest.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/CnSnToXmlTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithChoiceTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonIdentityrefToCnSnTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonLeafrefToCnSnTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonToCnSnTest.java
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/DummyType.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ReadConfAndOperDataTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestCodecExceptionsTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestconfImplTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/TestUtils.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlProvidersTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/YangAndXmlAndDataSchemaLoader.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlLeafrefToCnSnTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlToCnSnTest.java
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/invalid-top-level-element/invalid-top-level-element.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/list/list-types-module [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/choice/module-with-choice.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/yang/basic-module.yang
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/leafref/json/data.json [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/leafref/leafref-module [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/1/simple-list1.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/simple-list1.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/2/simple-list2.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/simple-list2.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/unsupported-json-format.json [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/leafref/leafref-module [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/leafref/xml/data.xml [new file with mode: 0644]
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateCommiter.java
opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/utils/LLDPDiscoveryUtils.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributesConstants.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectNameAttributeResolvingStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java [new file with mode: 0644]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java [new file with mode: 0644]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/AbstractEditConfigStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java [new file with mode: 0644]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/NoneEditConfigStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/RemoveEditConfigStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/util/Util.java
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandler.java
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/Util.java
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/PropertiesProviderBaseImpl.java
opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClient.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CapabilityProviderImpl.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerDispatcher.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiatorFactory.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/util/NetconfUtil.java
opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/NetconfDispatcherImplTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java [new file with mode: 0644]
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java
opendaylight/netconf/netconf-it/src/test/resources/RSA.pk [new file with mode: 0644]
opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriority.java
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/osgi/NetconfSSHActivator.java
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProviderInterface.java
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/threads/SocketThread.java
opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/SSHServerTest.java
opendaylight/netconf/netconf-ssh/src/test/resources/RSA.pk [new file with mode: 0644]
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/AbstractNetconfSessionNegotiator.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/osgi/NetconfConfigUtil.java
opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_addServiceNameOnTest.xml [new file with mode: 0644]
opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_expectedResult.xml
opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_none.xml
opendaylight/netconf/pom.xml
opendaylight/northbound/commons/src/test/java/org/opendaylight/controller/northbound/commons/exception/CommonsNorthboundExceptionTest.java
opendaylight/northbound/integrationtest/src/test/java/org/opendaylight/controller/northbound/integrationtest/NorthboundIT.java
opendaylight/samples/loadbalancer/src/test/java/org/opendaylight/controller/samples/loadbalancer/internal/LoadBalancerTest.java
opendaylight/web/root/src/main/java/org/opendaylight/controller/web/DaylightWeb.java
opendaylight/web/root/src/main/resources/WEB-INF/web.xml

index fcf71a90ac5c3ae96940861df4296dd14dc8ef7e..65e7720dd3141734951cb7d51e2b69bf8619df7b 100644 (file)
@@ -68,7 +68,7 @@ public class ClusterManager implements IClusterServices {
     private HashSet<IListenRoleChange> roleChangeListeners;
     private ViewChangedListener cacheManagerListener;
 
-    private static String loopbackAddress = "127.0.0.1";
+    private static String loopbackAddress = InetAddress.getLoopbackAddress().getHostAddress();
 
     // defaultTransactionTimeout is 60 seconds
     private static int DEFAULT_TRANSACTION_TIMEOUT = 60;
index fe73e240f995acf3ff2b00dead4e9771bdb98fd5..f27e6f069f62e747a51d95992a484a9e2618ced1 100644 (file)
@@ -43,7 +43,7 @@ public abstract class ClusterManagerCommon implements IClusterServicesCommon {
     private ConcurrentMap<String, ConcurrentMap<?, ?>> caches = new ConcurrentHashMap<String, ConcurrentMap<?, ?>>();
 
     protected ClusterManagerCommon() throws UnknownHostException {
-        loopbackAddress = InetAddress.getByName("127.0.0.1");
+        loopbackAddress = InetAddress.getLoopbackAddress();
     }
 
     /**
index 81b0921660539b822b4c0f3216b704f052500210..028d7d1f40d83077dd9fe5359fed4b12d349d3b2 100644 (file)
@@ -8,7 +8,6 @@
 package org.opendaylight.controller.config.manager.impl;
 
 import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
 import junit.framework.Assert;
 import org.junit.After;
 import org.mockito.Matchers;
@@ -26,6 +25,8 @@ import org.opendaylight.controller.config.util.ConfigRegistryJMXClient;
 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import javax.management.InstanceAlreadyExistsException;
 import javax.management.MBeanServer;
@@ -38,7 +39,6 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.Dictionary;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
 import static org.junit.Assert.assertEquals;
@@ -66,8 +66,16 @@ public abstract class AbstractConfigTest extends
     protected BundleContext mockedContext = mock(BundleContext.class);
     protected ServiceRegistration<?> mockedServiceRegistration;
 
-    protected  Map<Class, BundleContextServiceRegistrationHandler> getBundleContextServiceRegistrationHandlers() {
-        return Maps.newHashMap();
+    private static final Logger logger = LoggerFactory.getLogger(AbstractConfigTest.class);
+
+    // Default handler for OSGi service registration
+    private static final BundleContextServiceRegistrationHandler noopServiceRegHandler = new BundleContextServiceRegistrationHandler() {
+        @Override
+        public void handleServiceRegistration(Object serviceInstance) {}
+    };
+
+    protected BundleContextServiceRegistrationHandler getBundleContextServiceRegistrationHandler(Class<?> serviceType) {
+        return noopServiceRegHandler;
     }
 
     // this method should be called in @Before
@@ -166,9 +174,8 @@ public abstract class AbstractConfigTest extends
     protected ObjectName createTestConfigBean(
             ConfigTransactionJMXClient transaction, String implementationName,
             String name) throws InstanceAlreadyExistsException {
-        ObjectName nameCreated = transaction.createModule(implementationName,
+        return transaction.createModule(implementationName,
                 name);
-        return nameCreated;
     }
 
     protected void assertBeanCount(int i, String configMXBeanName) {
@@ -204,26 +211,42 @@ public abstract class AbstractConfigTest extends
     }
 
     private class RegisterServiceAnswer implements Answer {
+
         @Override
         public Object answer(InvocationOnMock invocation) throws Throwable {
             Object[] args = invocation.getArguments();
 
-            Preconditions.checkArgument(args.length == 3);
+            Preconditions.checkArgument(args.length == 3, "Unexpected arguments size (expected 3 was %s)", args.length);
 
-            Preconditions.checkArgument(args[0] instanceof Class);
-            Class<?> serviceType = (Class<?>) args[0];
+            Object serviceTypeRaw = args[0];
             Object serviceInstance = args[1];
 
-            BundleContextServiceRegistrationHandler serviceRegistrationHandler = getBundleContextServiceRegistrationHandlers()
-                    .get(serviceType);
+            if (serviceTypeRaw instanceof Class) {
+                Class<?> serviceType = (Class<?>) serviceTypeRaw;
+                invokeServiceHandler(serviceInstance, serviceType);
+
+            } else if(serviceTypeRaw instanceof String[]) {
+                for (String className : (String[]) serviceTypeRaw) {
+                    try {
+                        Class<?> serviceType = Class.forName(className);
+                        invokeServiceHandler(serviceInstance, serviceType);
+                    } catch (ClassNotFoundException e) {
+                        logger.warn("Not handling service registration of type {} ", className, e);
+                    }
+                }
 
-            Preconditions.checkArgument(serviceType.isAssignableFrom(serviceInstance.getClass()));
+            } else
+                logger.debug("Not handling service registration of type {}, Unknown type", serviceTypeRaw);
+
+            return mockedServiceRegistration;
+        }
+
+        private void invokeServiceHandler(Object serviceInstance, Class<?> serviceType) {
+            BundleContextServiceRegistrationHandler serviceRegistrationHandler = getBundleContextServiceRegistrationHandler(serviceType);
 
             if (serviceRegistrationHandler != null) {
                 serviceRegistrationHandler.handleServiceRegistration(serviceType.cast(serviceInstance));
             }
-
-            return mockedServiceRegistration;
         }
     }
 }
index eba5e07c0f40cc3a2b0732dd4fab563934cb9426..9f9bca9d9885f878e1851cccb30c7c1313416544 100644 (file)
@@ -61,7 +61,7 @@
         <java.version.source>1.7</java.version.source>
         <java.version.target>1.7</java.version.target>
         <junit.version>4.10</junit.version>
-        <maven.bundle.version>2.3.7</maven.bundle.version>
+        <maven.bundle.version>2.4.0</maven.bundle.version>
         <osgi.version>5.0.0</osgi.version>
         <jacoco.version>0.6.2.201302030002</jacoco.version>
         <slf4j.version>1.7.2</slf4j.version>
index 9356dd3752331f2f34fcc33b5df87151081a04b7..0d704a8f6aa49825da36d62b011d9294479fbb3d 100644 (file)
@@ -186,7 +186,15 @@ public class ExtenderYangTracker extends BundleTracker<Object> implements YangSt
                     yangStoreSnapshot.countModuleMXBeanEntries(), multimap.values().size());
             return yangStoreSnapshot;
         } catch (RuntimeException e) {
-            throw new YangStoreException("Unable to parse yang files from following URLs: " + multimap, e);
+            StringBuffer causeStr = new StringBuffer();
+            Throwable cause = e;
+            while (cause != null) {
+                causeStr.append(e.getMessage());
+                causeStr.append("\n");
+                cause = e.getCause();
+            }
+            throw new YangStoreException("Unable to parse yang files. \n" + causeStr.toString() +
+                    "URLs: " + multimap, e);
         }
     }
 
index 9740a9259833c0ef9d60ad821eaea1e0ee723aef..9d65ad343c4c540e2d93d750524becac00a3e9b8 100644 (file)
@@ -15,7 +15,9 @@ import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
@@ -308,9 +310,10 @@ public class ContainerFlowConfig implements Serializable {
     }
 
     /**
-     * Match Source IP Address.
+     * Match the set of these vlans with that of flowSpec's vlans.
      *
-     * @param flowSpec Flow Specification
+     * @param flowSpec
+     *            Flow Specification
      * @return true, if successful
      */
     private boolean matchDlVlan(ContainerFlowConfig flowSpec) {
@@ -320,7 +323,8 @@ public class ContainerFlowConfig implements Serializable {
         if (dlVlan == null || flowSpec.dlVlan == null) {
             return false;
         }
-        return dlVlan.equals(flowSpec.dlVlan);
+
+        return this.getVlanList().equals(flowSpec.getVlanList());
     }
 
     /**
@@ -404,18 +408,34 @@ public class ContainerFlowConfig implements Serializable {
     }
 
     /**
-     * Returns the vlan id number
+     * Returns the vlan id number for all vlans specified
      *
-     * @return the vlan id number
+     * @return the vlan id number for all vlans specified
      */
-    public Short getVlanId() {
-        Short vlan = 0;
+    public Set<Short> getVlanList() {
+        /*
+         * example: Vlan = "1,3,5-12"
+         * elemArray = ["1" "3" "5-12"]
+         * elem[2] = "5-12" --> limits = ["5" "12"]
+         * vlanList = [1 3 5 6 7 8 9 10 11 12]
+         */
+        Set<Short> vlanList = new HashSet<Short>();
         try {
-            vlan = Short.parseShort(dlVlan);
+            String[] elemArray = dlVlan.split(",");
+            for (String elem : elemArray) {
+                if (elem.contains("-")) {
+                    String[] limits = elem.split("-");
+                    for (short j = Short.valueOf(limits[0]); j <= Short.valueOf(limits[1]); j++) {
+                        vlanList.add(Short.valueOf(j));
+                    }
+                } else {
+                    vlanList.add(Short.valueOf(elem));
+                }
+            }
         } catch (NumberFormatException e) {
 
         }
-        return vlan;
+        return vlanList;
     }
 
     /**
@@ -617,13 +637,25 @@ public class ContainerFlowConfig implements Serializable {
         if (dlVlan != null) {
             short vlanId = 0;
             try {
-                vlanId = Short.parseShort(dlVlan);
+                String[] elemArray = dlVlan.split(",");
+                for (String elem : elemArray) {
+                    if (elem.contains("-")) {
+                        String[] limits = elem.split("-");
+                        if (Short.parseShort(limits[0]) < 0
+                                || Short.parseShort(limits[0]) >= Short.parseShort(limits[1])
+                                || Short.parseShort(limits[1]) > 0xfff) {
+                            return new Status(StatusCode.BADREQUEST, "Invalid vlan id");
+                        }
+                    } else {
+                        vlanId = Short.parseShort(elem);
+                        if (vlanId < 0 || vlanId > 0xfff) {
+                            return new Status(StatusCode.BADREQUEST, "Invalid vlan id");
+                        }
+                    }
+                }
             } catch (NumberFormatException e) {
                 return new Status(StatusCode.BADREQUEST, "Invalid vlan id");
             }
-            if (vlanId < 0 || vlanId > 0xfff) {
-                return new Status(StatusCode.BADREQUEST, "Invalid vlan id");
-            }
         }
         return new Status(StatusCode.SUCCESS);
     }
@@ -706,20 +738,46 @@ public class ContainerFlowConfig implements Serializable {
 
     /**
      * Returns the matches.
-     * If unidirectional flag is set, there will be only one match in the list
-     * If unidirectional flag is unset there will be two matches in the list,
+     * If unidirectional flag is set, there will be only one match per vlan in the list
+     * If unidirectional flag is unset there will be two matches per vlan in the list,
      * only if the specified flow has an intrinsic direction.
      * For Ex. if the cFlow only has the protocol field configured, no matter
-     * if unidirectional flag is set or not, only one match will be returned
+     * if unidirectional flag is set or not, only one match per vlan will be returned
      * The client just has to iterate over the returned list
      * @return the matches
      */
     public List<Match> getMatches() {
         List<Match> matches = new ArrayList<Match>();
-        Match match = new Match();
 
         if (this.dlVlan != null && !this.dlVlan.isEmpty()) {
-            match.setField(MatchType.DL_VLAN, this.getVlanId());
+            for(Short vlan:getVlanList()){
+                Match match = getMatch(vlan);
+                matches.add(match);
+            }
+        }
+        else{
+            Match match = getMatch(null);
+            matches.add(match);
+        }
+
+        if (!ContainerFlowConfig.unidirectional) {
+            List<Match> forwardMatches = new ArrayList<Match>(matches);
+            for (Match match : forwardMatches) {
+                Match reverse = match.reverse();
+                if (!match.equals(reverse)) {
+                    matches.add(reverse);
+                }
+            }
+        }
+
+        return matches;
+    }
+
+    private Match getMatch(Short vlan){
+        Match match = new Match();
+
+        if (vlan != null) {
+            match.setField(MatchType.DL_VLAN, vlan);
         }
         if (this.nwSrc != null && !this.nwSrc.trim().isEmpty()) {
             String parts[] = this.nwSrc.split("/");
@@ -756,15 +814,7 @@ public class ContainerFlowConfig implements Serializable {
         if (this.tpDst != null && !this.tpDst.trim().isEmpty()) {
             match.setField(MatchType.TP_DST, Integer.valueOf(tpDst).shortValue());
         }
-
-        matches.add(match);
-        if(!ContainerFlowConfig.unidirectional) {
-            Match reverse = match.reverse();
-            if (!match.equals(reverse)) {
-                matches.add(reverse);
-            }
-        }
-        return matches;
+        return match;
     }
 
     /*
index 8ffaff45c7487bb7a78e59c1818ca640c8d0fc58..995e4076c275b3eb76f65913e4ce4ffd6b1de080 100644 (file)
@@ -21,6 +21,8 @@ netconf.tcp.client.port=8383
 
 netconf.ssh.address=0.0.0.0
 netconf.ssh.port=1830
+netconf.ssh.pk.path = ./configuration/RSA.pk
+
 
 netconf.config.persister.active=1,2
 # read startup configuration
index 3a29f63b81a5ab0d442fae2b6e0c75003d6c2e68..ffe53afd4d5393de8e065a1708caf41893e3e726 100755 (executable)
@@ -164,6 +164,8 @@ FWCLASSPATH=${FWCLASSPATH},file:${basedir}/lib/org.eclipse.virgo.kernel.equinox.
 CLASSPATH=${CLASSPATH}:${basedir}/lib/org.eclipse.equinox.launcher-1.3.0.v20120522-1813.jar
 FWCLASSPATH=${FWCLASSPATH},file:${basedir}/lib/org.eclipse.equinox.launcher-1.3.0.v20120522-1813.jar
 
+cd $basedir
+
 if [ "${stopdaemon}" -eq 1 ]; then
     if [ -e "${pidfile}" ]; then
         daemonpid=`cat "${pidfile}"`
index 83106a391cb7bdc00ff0911fa703e7dee1c1c2f4..d9a0891c2ad812b855641c48155235633328ff51 100644 (file)
@@ -122,7 +122,7 @@ public class FlowEntry implements Cloneable, Serializable {
         }
 
         if (flow == null) {
-            return (other.flow == null) ? true : false;
+            return other.flow == null;
         } else if (other.flow == null) {
             return false;
         }
index d7c60e67a91dfa85213343e41e3f495bacf83e55..e222fcd7e42cdb23b5a0850f6b55fd6834deba8a 100644 (file)
@@ -25,7 +25,6 @@ public class HostTrackerTest extends TestCase {
 \r
         HostTracker hostTracker = null;\r
         hostTracker = new HostTracker();\r
-        Assert.assertFalse(hostTracker == null);\r
 \r
         InetAddress hostIP = InetAddress.getByName("192.168.0.8");\r
         IHostId id  = IPHostId.fromIP(hostIP);\r
@@ -44,7 +43,6 @@ public class HostTrackerTest extends TestCase {
     public void testHostTracker() throws UnknownHostException {\r
         HostTracker hostTracker = null;\r
         hostTracker = new HostTracker();\r
-        Assert.assertFalse(hostTracker == null);\r
 \r
         InetAddress hostIP_1 = InetAddress.getByName("192.168.0.8");\r
         IHostId id1 = IPHostId.fromIP(hostIP_1);\r
index 15a9a689b3da5975dc6a6a0f1597cb3990e6a1ea..f72e5b9bfa9e660541de018f1b372f5104c1dab5 100644 (file)
       <artifactId>model-flow-statistics</artifactId>
       <version>1.0-SNAPSHOT</version>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller.model</groupId>
+      <artifactId>model-topology</artifactId>
+      <version>1.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-binding-util</artifactId>
+      <version>1.0-SNAPSHOT</version>
+    </dependency>
   </dependencies>
   <packaging>bundle</packaging>
 
index 95acbcdb1338e10827d76c4d5d19718094db83d0..d7a345cfc86198ead50ff1a937eadf0dd1348d21 100644 (file)
@@ -1,37 +1,41 @@
 package org.opendaylight.controller.sal.compatibility
 
-import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
-import org.opendaylight.controller.sal.core.Node
-import org.opendaylight.controller.sal.core.NodeConnector
-import static org.opendaylight.controller.sal.compatibility.NodeMapping.*
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey
-import org.apache.felix.dm.Component
 import java.util.Arrays
 import java.util.Dictionary
 import java.util.Hashtable
-import org.opendaylight.controller.sal.utils.GlobalConstants
+import org.apache.felix.dm.Component
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker
-import org.opendaylight.controller.sal.flowprogrammer.IPluginInFlowProgrammerService
-import org.opendaylight.controller.sal.inventory.IPluginInInventoryService
-import org.opendaylight.controller.sal.reader.IPluginInReadService
-import org.opendaylight.controller.sal.flowprogrammer.IPluginOutFlowProgrammerService
-import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService
+import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer
 import org.opendaylight.controller.sal.binding.api.NotificationService
 import org.opendaylight.controller.sal.binding.api.data.DataBrokerService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.controller.sal.compatibility.topology.TopologyAdapter
+import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase
+import org.opendaylight.controller.sal.core.Node
+import org.opendaylight.controller.sal.core.NodeConnector
+import org.opendaylight.controller.sal.discovery.IDiscoveryService
+import org.opendaylight.controller.sal.flowprogrammer.IPluginInFlowProgrammerService
+import org.opendaylight.controller.sal.flowprogrammer.IPluginOutFlowProgrammerService
+import org.opendaylight.controller.sal.inventory.IPluginInInventoryService
+import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService
 import org.opendaylight.controller.sal.packet.IPluginOutDataPacketService
-import org.osgi.framework.BundleContext
+import org.opendaylight.controller.sal.reader.IPluginInReadService
 import org.opendaylight.controller.sal.reader.IPluginOutReadService
-import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService
-import org.opendaylight.controller.sal.discovery.IDiscoveryService
+import org.opendaylight.controller.sal.topology.IPluginInTopologyService
 import org.opendaylight.controller.sal.topology.IPluginOutTopologyService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryService
+import org.opendaylight.controller.sal.utils.GlobalConstants
+import org.opendaylight.controller.sal.utils.INodeConnectorFactory
+import org.opendaylight.controller.sal.utils.INodeFactory
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryService
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.osgi.framework.BundleContext
+
+import static org.opendaylight.controller.sal.compatibility.NodeMapping.*
+import org.opendaylight.controller.sal.compatibility.topology.TopologyProvider
 
 class ComponentActivator extends ComponentActivatorAbstractBase implements BindingAwareConsumer {
 
@@ -47,10 +51,16 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi
     DataPacketAdapter dataPacket = new DataPacketAdapter;
 
     @Property
-    org.opendaylight.controller.sal.utils.INodeFactory nodeFactory = new MDSalNodeFactory
+    INodeFactory nodeFactory = new MDSalNodeFactory
 
     @Property
-    org.opendaylight.controller.sal.utils.INodeConnectorFactory nodeConnectorFactory = new MDSalNodeConnectorFactory
+    INodeConnectorFactory nodeConnectorFactory = new MDSalNodeConnectorFactory
+    
+    @Property
+    TopologyAdapter topology = new TopologyAdapter
+    
+    @Property
+    TopologyProvider tpProvider = new TopologyProvider()
 
 
     override protected init() {
@@ -72,6 +82,7 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi
 
         // Registration of Flow Service
         flow.delegate = session.getRpcService(SalFlowService)
+        flow.dataBrokerService = session.getSALService(DataBrokerService);
         subscribe.registerNotificationListener(flow);
 
         // Data Packet Service
@@ -84,13 +95,16 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi
         inventory.nodeConnectorStatisticsService = session.getRpcService(OpendaylightPortStatisticsService);
         inventory.topologyDiscovery = session.getRpcService(FlowTopologyDiscoveryService);
                inventory.dataProviderService = session.getSALService(DataProviderService)
+               topology.dataService = session.getSALService(DataProviderService)
+               tpProvider.dataService = session.getSALService(DataProviderService)
+               tpProvider.start();
 
         subscribe.registerNotificationListener(dataPacket)
 
     }
 
     override protected getGlobalImplementations() {
-        return Arrays.asList(this, flow, inventory, dataPacket, nodeFactory, nodeConnectorFactory)
+        return Arrays.asList(this, flow, inventory, dataPacket, nodeFactory, nodeConnectorFactory,topology,tpProvider)
     }
 
     override protected configureGlobalInstance(Component c, Object imp) {
@@ -98,11 +112,11 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi
     }
 
     private def dispatch configure(MDSalNodeFactory imp, Component it) {
-        setInterface(org.opendaylight.controller.sal.utils.INodeFactory.name, properties);
+        setInterface(INodeFactory.name, properties);
     }
 
     private def dispatch configure(MDSalNodeConnectorFactory imp, Component it) {
-        setInterface(org.opendaylight.controller.sal.utils.INodeConnectorFactory.name, properties);
+        setInterface(INodeConnectorFactory.name, properties);
     }
 
     private def dispatch configure(ComponentActivator imp, Component it) {
@@ -143,17 +157,29 @@ class ComponentActivator extends ComponentActivatorAbstractBase implements Bindi
             .setService(IPluginOutInventoryService) //
             .setCallbacks("setInventoryPublisher", "setInventoryPublisher") //
             .setRequired(false))
+        add(
+            createServiceDependency() //
+            .setService(IDiscoveryService) //
+            .setCallbacks("setDiscoveryPublisher", "setDiscoveryPublisher") //
+            .setRequired(false))
+        
+    }
+    
+    private def dispatch configure (TopologyAdapter imp, Component it) {
+        setInterface(Arrays.asList(IPluginInTopologyService.name), properties)
         add(
             createServiceDependency() //
             .setService(IPluginOutTopologyService) //
             .setCallbacks("setTopologyPublisher", "setTopologyPublisher") //
             .setRequired(false))
+    }
+    
+    private def dispatch configure (TopologyProvider imp, Component it) {
         add(
             createServiceDependency() //
-            .setService(IDiscoveryService) //
-            .setCallbacks("setDiscoveryPublisher", "setDiscoveryPublisher") //
+            .setService(IPluginOutTopologyService) //
+            .setCallbacks("setTopologyPublisher", "setTopologyPublisher") //
             .setRequired(false))
-        
     }
 
     private def Dictionary<String, Object> properties() {
index 2eae511e02975e6aa23f9d2a09091fa186ab3764..450c7f1f239c4634b994fd6b71b941492321d8b4 100644 (file)
@@ -18,7 +18,24 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.Node
 import org.opendaylight.yangtools.yang.common.RpcResult
 import org.slf4j.LoggerFactory
 
-import static org.opendaylight.controller.sal.compatibility.MDFlowMapping.*
+import org.opendaylight.controller.sal.binding.api.data.DataBrokerService
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus
+import org.opendaylight.controller.md.sal.common.api.data.DataModification
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
+import org.opendaylight.yangtools.yang.binding.DataObject
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId
+
+
+import static extension org.opendaylight.controller.sal.compatibility.MDFlowMapping.*
 
 import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.*
 import static extension org.opendaylight.controller.sal.compatibility.ToSalConversionsUtils.*
@@ -29,64 +46,52 @@ class FlowProgrammerAdapter implements IPluginInFlowProgrammerService, SalFlowLi
 
     @Property
     private SalFlowService delegate;
+
+    @Property
+    private DataBrokerService dataBrokerService;
     
     @Property
     private IPluginOutFlowProgrammerService flowProgrammerPublisher;
 
     override addFlow(Node node, Flow flow) {
-        val input = addFlowInput(node, flow);
-        val future = delegate.addFlow(input);
-        try {
-            val result = future.get();
-            return toStatus(result); // how get status from result? conversion?
-        } catch (Exception e) {
-            return processException(e);
-        }
+        return addFlowAsync(node,flow,0)
     }
 
     override modifyFlow(Node node, Flow oldFlow, Flow newFlow) {
-        val input = updateFlowInput(node, oldFlow, newFlow);
-        val future = delegate.updateFlow(input);
-        try {
-            val result = future.get();
-            return toStatus(result);
-        } catch (Exception e) {
-            return processException(e);
-        }
+        return modifyFlowAsync(node, oldFlow,newFlow,0)
     }
 
     override removeFlow(Node node, Flow flow) {
-        val input = removeFlowInput(node, flow);
-        val future = delegate.removeFlow(input);
-
-        try {
-            val result = future.get();
-            return toStatus(result);
-        } catch (Exception e) {
-            return processException(e);
-        }
+        return removeFlowAsync(node, flow,0);
     }
 
     override addFlowAsync(Node node, Flow flow, long rid) {
-        val input = addFlowInput(node, flow);
-        delegate.addFlow(input);
-        return new Status(StatusCode.SUCCESS);
+        writeFlow(flow.toMDFlow, new NodeKey(new NodeId(node.getNodeIDString())));
+        return toStatus(true);
     }
 
     override modifyFlowAsync(Node node, Flow oldFlow, Flow newFlow, long rid) {
-        val input = updateFlowInput(node, oldFlow, newFlow);
-        delegate.updateFlow(input);
-        return new Status(StatusCode.SUCCESS);
+        writeFlow(newFlow.toMDFlow, new NodeKey(new NodeId(node.getNodeIDString())));
+        return toStatus(true);
     }
 
-    override removeFlowAsync(Node node, Flow flow, long rid) {
-        val input = removeFlowInput(node, flow);
-        delegate.removeFlow(input);
-        return new Status(StatusCode.SUCCESS);
+    override removeFlowAsync(Node node, Flow adflow, long rid) {
+        val flow = adflow.toMDFlow;
+        val modification = this._dataBrokerService.beginTransaction();
+        val flowPath = InstanceIdentifier.builder(Nodes)
+                .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, new NodeKey(new NodeId(node.getNodeIDString())))
+                .augmentation(FlowCapableNode)
+                .child(Table, new TableKey(flow.getTableId()))
+                .child(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow, new FlowKey(flow.id))
+                .build;
+        modification.removeConfigurationData(flowPath);
+        val commitFuture = modification.commit();
+        return toStatus(true);
     }
 
     override removeAllFlows(Node node) {
-        throw new UnsupportedOperationException("Not present in MD-SAL");
+        // I know this looks like a copout... but its exactly what the legacy OFplugin did
+        return new Status(StatusCode.SUCCESS);
     }
 
     override syncSendBarrierMessage(Node node) {
@@ -101,13 +106,38 @@ class FlowProgrammerAdapter implements IPluginInFlowProgrammerService, SalFlowLi
         return null;
     }
 
-    public static def toStatus(RpcResult<?> result) {
-        if (result.isSuccessful()) {
+    private static def toStatus(boolean successful) {
+        if (successful) {
             return new Status(StatusCode.SUCCESS);
         } else {
             return new Status(StatusCode.INTERNALERROR);
         }
     }
+
+
+    private def writeFlow(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow flow, NodeKey nodeKey) {
+        val modification = this._dataBrokerService.beginTransaction();
+        val flowPath = InstanceIdentifier.builder(Nodes)
+                .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, nodeKey)
+                .augmentation(FlowCapableNode)
+                .child(Table, new TableKey(flow.getTableId()))
+                .child(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow, new FlowKey(flow.id))
+                .build;
+        modification.putConfigurationData(flowPath, flow);
+        val commitFuture = modification.commit();
+        try {
+            val result = commitFuture.get();
+            val status = result.getResult();
+        } catch (InterruptedException e) {
+            LOG.error(e.getMessage(), e);
+        } catch (ExecutionException e) {
+            LOG.error(e.getMessage(), e);
+        }
+    }
+
+    public static def toStatus(RpcResult<?> result) {
+        return toStatus(result.isSuccessful());
+    }
     
     private static dispatch def Status processException(InterruptedException e) {
         LOG.error("Interruption occured during processing flow",e);
index 4e6e49eac70cefd3576754d542e159c649fa457b..eba4aa901bdc1d2496a485c9676024bb01002f3b 100644 (file)
@@ -12,6 +12,7 @@ import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
 
+import org.opendaylight.controller.sal.core.NodeConnector;
 import org.opendaylight.controller.sal.match.Match;
 import org.opendaylight.controller.sal.match.MatchField;
 import org.opendaylight.controller.sal.match.MatchType;
@@ -26,6 +27,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.addr
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv6Builder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanPcp;
@@ -83,6 +85,7 @@ public class FromSalConversionsUtils {
             targetBuilder.setVlanMatch(vlanMatch(sourceMatch));
             targetBuilder.setLayer3Match(layer3Match(sourceMatch));
             targetBuilder.setLayer4Match(layer4Match(sourceMatch));
+            targetBuilder.setInPort(inPortMatch(sourceMatch));
 
             return targetBuilder.build();
         }
@@ -90,6 +93,14 @@ public class FromSalConversionsUtils {
 
     }
 
+    private static NodeConnectorId inPortMatch(Match sourceMatch) {
+        MatchField inPort = sourceMatch.getField(MatchType.IN_PORT);
+        if(inPort != null && inPort.getValue() != null && (inPort.getValue() instanceof NodeConnector)) {
+            return new NodeConnectorId(((NodeConnector) inPort.getValue()).getNodeConnectorIdAsString());
+        }
+        return null;
+    }
+
     private static Layer4Match layer4Match(final Match sourceMatch) {
         MatchField nwProto = sourceMatch.getField(MatchType.NW_PROTO);
         Short nwProtocolSource = null;
@@ -121,8 +132,10 @@ public class FromSalConversionsUtils {
             sctpMatchBuilder.setSctpDestinationPort(new PortNumber(
                     destinationPort));
         }
-
-        return sctpMatchBuilder.build();
+        if(sourcePort != null || destinationPort != null) {
+            return sctpMatchBuilder.build();
+        }
+        return null;
     }
 
     private static Layer4Match Layer4MatchAsUdp(final Match sourceMatch) {
@@ -140,8 +153,10 @@ public class FromSalConversionsUtils {
             udpMatchBuilder.setUdpDestinationPort(new PortNumber(
                     destinationPort));
         }
-
-        return udpMatchBuilder.build();
+        if(sourcePort != null || destinationPort != null) {
+            return udpMatchBuilder.build();
+        }
+        return null;
     }
 
     private static Layer4Match Layer4MatchAsTcp(final Match sourceMatch) {
@@ -158,8 +173,10 @@ public class FromSalConversionsUtils {
             tcpMatchBuilder.setTcpDestinationPort(new PortNumber(
                     destinationPort));
         }
-
-        return tcpMatchBuilder.build();
+        if(sourcePort != null || destinationPort != null) {
+            return tcpMatchBuilder.build();
+        }
+        return null;
     }
 
     private static Integer transportPort(final Match sourceMatch,
@@ -189,8 +206,10 @@ public class FromSalConversionsUtils {
             vlanMatchBuild.setVlanPcp(new VlanPcp((short) ((byte) vlanPriority
                     .getValue())));
         }
-
-        return vlanMatchBuild.build();
+        if((vlan != null && vlan.getValue() != null) || (vlanPriority != null && vlanPriority.getValue() != null)) {
+            return vlanMatchBuild.build();
+        }
+        return null;
     }
 
     private static IpMatch ipMatch(final Match sourceMatch) {
@@ -208,21 +227,24 @@ public class FromSalConversionsUtils {
             targetIpMatchBuild.setIpProtocol((short) ((byte) protocol
                     .getValue()));
         }
-
-        return targetIpMatchBuild.build();
-
+        if((networkTos != null && networkTos.getValue() != null) || (protocol != null && protocol.getValue() != null)) {
+            return targetIpMatchBuild.build();
+        }
+        return null;
     }
 
     private static EthernetMatch ethernetMatch(final Match sourceMatch) {
         final EthernetMatchBuilder targetEthMatchBuild = new EthernetMatchBuilder();
-
-        EthernetSourceBuilder ethSourBuild = new EthernetSourceBuilder()
-                .setAddress(ethernetSourceAddress(sourceMatch));
-        targetEthMatchBuild.setEthernetSource(ethSourBuild.build());
-
-        EthernetDestinationBuilder ethDestBuild = new EthernetDestinationBuilder()
-                .setAddress(ethernetDestAddress(sourceMatch));
-        targetEthMatchBuild.setEthernetDestination(ethDestBuild.build());
+        if(sourceMatch.getField(DL_SRC) != null && sourceMatch.getField(DL_SRC).getValue() != null) {
+            EthernetSourceBuilder ethSourBuild = new EthernetSourceBuilder()
+                    .setAddress(ethernetSourceAddress(sourceMatch));
+            targetEthMatchBuild.setEthernetSource(ethSourBuild.build());
+        }
+        if(sourceMatch.getField(DL_DST) != null && sourceMatch.getField(DL_DST).getValue() != null) {
+            EthernetDestinationBuilder ethDestBuild = new EthernetDestinationBuilder()
+                    .setAddress(ethernetDestAddress(sourceMatch));
+            targetEthMatchBuild.setEthernetDestination(ethDestBuild.build());
+        }
 
         final MatchField dataLinkType = sourceMatch.getField(MatchType.DL_TYPE);
         if (dataLinkType != null && dataLinkType.getValue() != null) {
@@ -232,7 +254,12 @@ public class FromSalConversionsUtils {
                     .setType(etherType);
             targetEthMatchBuild.setEthernetType(ethType.build());
         }
-        return targetEthMatchBuild.build();
+        if((sourceMatch.getField(DL_SRC) != null && sourceMatch.getField(DL_SRC).getValue() != null) || 
+                (sourceMatch.getField(DL_DST) != null && sourceMatch.getField(DL_DST).getValue() != null)|| 
+                dataLinkType != null ) {
+            return targetEthMatchBuild.build();            
+        } 
+        return null;
     }
 
     private static MacAddress ethernetSourceAddress(final Match sourceMatch) {
@@ -258,7 +285,7 @@ public class FromSalConversionsUtils {
         }
 
         if ((inetSourceAddress instanceof Inet4Address)
-                && (inetDestAddress instanceof Inet4Address)) {
+                || (inetDestAddress instanceof Inet4Address)) {
             MatchField dataLinkType = sourceMatch.getField(DL_TYPE);
             Short dLType = null;
             if (dataLinkType != null && dataLinkType.getValue() != null) {
@@ -273,7 +300,7 @@ public class FromSalConversionsUtils {
                         (Inet4Address) inetDestAddress);
             }
         } else if ((inetSourceAddress instanceof Inet6Address)
-                && (inetDestAddress instanceof Inet6Address)) {
+                || (inetDestAddress instanceof Inet6Address)) {
             return setLayer3MatchAsIpv6((Inet6Address) inetSourceAddress,
                     (Inet6Address) inetDestAddress);
         }
@@ -327,15 +354,18 @@ public class FromSalConversionsUtils {
     private static Layer3Match setLayer3MatchAsIpv4(
             final Inet4Address inetSourceAddress,
             final Inet4Address inetDestAddress) {
-        String inetSrcAddressString = InetAddresses
-                .toAddrString(inetSourceAddress);
-        String inetDstAddressString = InetAddresses
-                .toAddrString(inetDestAddress);
-
         Ipv4MatchBuilder layer4MatchBuild = new Ipv4MatchBuilder();
-        layer4MatchBuild.setIpv4Source(new Ipv4Prefix(inetSrcAddressString));
-        layer4MatchBuild
-                .setIpv4Destination(new Ipv4Prefix(inetDstAddressString));
+        if(inetSourceAddress != null) {
+            String inetSrcAddressString = InetAddresses
+                    .toAddrString(inetSourceAddress);
+            layer4MatchBuild.setIpv4Source(new Ipv4Prefix(inetSrcAddressString));
+        }
+        if(inetDestAddress != null) {
+            String inetDstAddressString = InetAddresses
+                    .toAddrString(inetDestAddress);
+            layer4MatchBuild
+            .setIpv4Destination(new Ipv4Prefix(inetDstAddressString));
+        }       
         return layer4MatchBuild.build();
 
     }
@@ -343,15 +373,18 @@ public class FromSalConversionsUtils {
     private static Layer3Match setLayer3MatchAsIpv6(
             final Inet6Address inetSourceAddress,
             final Inet6Address inetDestAddress) {
-        String inetSrcAddressString = InetAddresses
-                .toAddrString(inetSourceAddress);
-        String inetDstAddressString = InetAddresses
-                .toAddrString(inetDestAddress);
         Ipv6MatchBuilder layer6MatchBuild = new Ipv6MatchBuilder();
-
-        layer6MatchBuild.setIpv6Source(new Ipv6Prefix(inetSrcAddressString));
-        layer6MatchBuild
-                .setIpv6Destination(new Ipv6Prefix(inetDstAddressString));
+        if(inetSourceAddress != null) {
+            String inetSrcAddressString = InetAddresses
+                    .toAddrString(inetSourceAddress);
+            layer6MatchBuild.setIpv6Source(new Ipv6Prefix(inetSrcAddressString));
+        }
+        if(inetDestAddress != null) {
+            String inetDstAddressString = InetAddresses
+                    .toAddrString(inetDestAddress);    
+            layer6MatchBuild
+                    .setIpv6Destination(new Ipv6Prefix(inetDstAddressString));
+        }
         return layer6MatchBuild.build();
     }
     
index 2124185b6c297906d617cbef74d9481e6367ace9..56ca1b609cf2c6eeb6d5dfe669b660319d4d792d 100644 (file)
@@ -1,83 +1,76 @@
 package org.opendaylight.controller.sal.compatibility
 
-import org.opendaylight.controller.sal.reader.IPluginInReadService
-import org.opendaylight.controller.sal.core.NodeConnector
+import java.util.ArrayList
+import java.util.Collections
+import java.util.List
+import org.opendaylight.controller.sal.binding.api.data.DataBrokerService
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.controller.sal.core.Edge
 import org.opendaylight.controller.sal.core.Node
-import org.opendaylight.controller.sal.flowprogrammer.Flow
 import org.opendaylight.controller.sal.core.NodeTable
-import org.opendaylight.controller.sal.binding.api.data.DataBrokerService
-
-import static extension org.opendaylight.controller.sal.common.util.Arguments.*
-import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.*
+import org.opendaylight.controller.sal.core.UpdateType
+import org.opendaylight.controller.sal.flowprogrammer.Flow
+import org.opendaylight.controller.sal.inventory.IPluginInInventoryService
+import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService
+import org.opendaylight.controller.sal.reader.FlowOnNode
+import org.opendaylight.controller.sal.reader.IPluginInReadService
+import org.opendaylight.controller.sal.reader.IPluginOutReadService
+import org.opendaylight.controller.sal.reader.NodeConnectorStatistics
+import org.opendaylight.controller.sal.reader.NodeDescription
+import org.opendaylight.controller.sal.reader.NodeTableStatistics
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsUpdate
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdate
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesInputBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInputBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsListener
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService
-import org.opendaylight.controller.sal.reader.NodeConnectorStatistics
-import org.opendaylight.controller.sal.reader.FlowOnNode
-import org.opendaylight.controller.sal.reader.NodeDescription
-import org.slf4j.LoggerFactory
-import java.util.ArrayList
-import org.opendaylight.controller.sal.inventory.IPluginInInventoryService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryListener
-import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsData
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsUpdate
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsInputBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsListener
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.statistics.FlowTableStatistics
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.Link
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRemoved
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated
-import java.util.Collections
-import org.opendaylight.controller.sal.core.UpdateType
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRemoved
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdated
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.controller.sal.topology.IPluginOutTopologyService
-import org.opendaylight.controller.sal.topology.IPluginInTopologyService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryListener
-import org.opendaylight.controller.sal.core.Edge
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.Link
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkDiscovered
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkOverutilized
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkRemoved
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkUtilizationNormal
-import org.opendaylight.controller.sal.topology.TopoEdgeUpdate
-import org.opendaylight.controller.sal.discovery.IDiscoveryService
-import org.opendaylight.controller.sal.reader.IPluginOutReadService
-import java.util.List
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsListener
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsListener
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsListener
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsUpdate
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdate
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsUpdate
-import org.opendaylight.controller.sal.reader.NodeTableStatistics
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryListener
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatistics
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsData
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsInputBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsInputBuilder
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetNodeConnectorStatisticsInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId
 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdate
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInputBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsListener
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService
+import org.opendaylight.yangtools.yang.binding.DataObject
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.slf4j.LoggerFactory
+
+import static extension org.opendaylight.controller.sal.common.util.Arguments.*
+import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.*
+import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
+import java.util.concurrent.ConcurrentHashMap
+import java.util.Map
 
-class InventoryAndReadAdapter implements IPluginInTopologyService,
-                                                                                        IPluginInReadService,
+class InventoryAndReadAdapter implements IPluginInReadService,
                                                                                         IPluginInInventoryService,
                                                                                         OpendaylightInventoryListener,
-                                                                                        FlowTopologyDiscoveryListener,
                                                                                         OpendaylightFlowStatisticsListener,
                                                                                         OpendaylightFlowTableStatisticsListener,
                                                                                         OpendaylightPortStatisticsListener {
@@ -103,9 +96,6 @@ class InventoryAndReadAdapter implements IPluginInTopologyService,
     @Property
     IPluginOutInventoryService inventoryPublisher;
 
-    @Property
-    IPluginOutTopologyService topologyPublisher;
-
     @Property
     FlowTopologyDiscoveryService topologyDiscovery;
     
@@ -125,7 +115,7 @@ class InventoryAndReadAdapter implements IPluginInTopologyService,
         return dataProviderService.beginTransaction;
     }
 
-    override getTransmitRate(NodeConnector connector) {
+    override getTransmitRate(org.opendaylight.controller.sal.core.NodeConnector connector) {
         val nodeConnector = readFlowCapableNodeConnector(connector.toNodeConnectorRef);
         return nodeConnector.currentSpeed
     }
@@ -188,10 +178,10 @@ class InventoryAndReadAdapter implements IPluginInTopologyService,
                        for (dsNodeConnector : dsNode.nodeConnector){
                                val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
                                                                        .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(node))
-                                                                       .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector, dsNodeConnector.key)
+                                                                       .child(NodeConnector, dsNodeConnector.key)
                                                                        .toInstance();
                                
-                               val nodeConnectorFromDS = provider.readConfigurationData(nodeConnectorRef) as org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+                               val nodeConnectorFromDS = provider.readConfigurationData(nodeConnectorRef) as NodeConnector;
                                
                                if(nodeConnectorFromDS != null){
                                        val nodeConnectorStatsFromDs = nodeConnectorFromDS.getAugmentation(FlowCapableNodeConnectorStatisticsData) as FlowCapableNodeConnectorStatistics;
@@ -278,16 +268,16 @@ class InventoryAndReadAdapter implements IPluginInTopologyService,
        
     }
 
-    override readNodeConnector(NodeConnector connector, boolean cached) {
+    override readNodeConnector(org.opendaylight.controller.sal.core.NodeConnector connector, boolean cached) {
        var NodeConnectorStatistics  nodeConnectorStatistics = null;
        
                val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
                                                                        .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, InventoryMapping.toNodeKey(connector.node))
-                                                                       .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector, InventoryMapping.toNodeConnectorKey(connector))
+                                                                       .child(NodeConnector, InventoryMapping.toNodeConnectorKey(connector))
                                                                        .toInstance();
                val provider = this.startChange();
                                
-               val nodeConnectorFromDS = provider.readConfigurationData(nodeConnectorRef) as org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+               val nodeConnectorFromDS = provider.readConfigurationData(nodeConnectorRef) as NodeConnector;
                                
                if(nodeConnectorFromDS != null){
                        val nodeConnectorStatsFromDs = nodeConnectorFromDS.getAugmentation(FlowCapableNodeConnectorStatisticsData) as FlowCapableNodeConnectorStatistics;
@@ -344,32 +334,25 @@ class InventoryAndReadAdapter implements IPluginInTopologyService,
     }
 
     override onNodeConnectorUpdated(NodeConnectorUpdated update) {
-        val properties = new java.util.HashSet<org.opendaylight.controller.sal.core.Property>();
-
-
-        val org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> identifier = update.nodeConnectorRef.value as org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>;
         var updateType = UpdateType.CHANGED;
-        if ( this._dataService.readOperationalData(identifier) == null ){
+        if ( this._dataService.readOperationalData(update.nodeConnectorRef.value as InstanceIdentifier<? extends DataObject>) == null ){
             updateType = UpdateType.ADDED;
         }
 
         var nodeConnector = update.nodeConnectorRef.toADNodeConnector
 
-
-        properties.add(new org.opendaylight.controller.sal.core.Name(nodeConnector.ID.toString()));
-
-        inventoryPublisher.updateNodeConnector(nodeConnector , updateType , properties);
+        inventoryPublisher.updateNodeConnector(nodeConnector , updateType , update.toADNodeConnectorProperties);
     }
 
     override onNodeUpdated(NodeUpdated notification) {
         val properties = Collections.<org.opendaylight.controller.sal.core.Property>emptySet();
-        val org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> identifier = notification.nodeRef.value  as org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>;
+        val InstanceIdentifier<? extends DataObject> identifier = notification.nodeRef.value  as InstanceIdentifier<? extends DataObject>;
 
         var updateType = UpdateType.CHANGED;
         if ( this._dataService.readOperationalData(identifier) == null ){
             updateType = UpdateType.ADDED;
         }
-        inventoryPublisher.updateNode(notification.nodeRef.toADNode, updateType, properties);
+        inventoryPublisher.updateNode(notification.nodeRef.toADNode, updateType, notification.toADNodeProperties);
         
                //Notify the listeners of IPluginOutReadService
         
@@ -380,15 +363,64 @@ class InventoryAndReadAdapter implements IPluginInTopologyService,
     }
 
     override getNodeProps() {
-
-        // FIXME: Read from MD-SAL inventory service
-        return null;
+        val props = new ConcurrentHashMap<Node, Map<String, org.opendaylight.controller.sal.core.Property>>()
+        
+        val nodes = readAllMDNodes()
+        for (node : nodes.node ) {
+            val fcn = node.getAugmentation(FlowCapableNode)
+            if(fcn != null) {
+                val perNodeProps = fcn.toADNodeProperties(node.id)
+                val perNodePropMap = new ConcurrentHashMap<String, org.opendaylight.controller.sal.core.Property>
+                if(perNodeProps != null ) {
+                    for(perNodeProp : perNodeProps) {
+                        perNodePropMap.put(perNodeProp.name,perNodeProp)
+                    }
+                }
+                props.put(new Node(MD_SAL_TYPE, node.id.toADNodeId),perNodePropMap)
+            }
+        }
+        return props;
+    }
+    
+    private def readAllMDNodes() {
+        val nodesRef = InstanceIdentifier.builder(Nodes)
+            .toInstance
+        val reader = TypeSafeDataReader.forReader(dataService)
+        return reader.readOperationalData(nodesRef)
+    }
+    
+    private def readAllMDNodeConnectors(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node node) {
+        val nodeRef = InstanceIdentifier.builder(Nodes)
+            .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(node.id))
+            .toInstance
+        val reader = TypeSafeDataReader.forReader(dataService)
+        return reader.readOperationalData(nodeRef).nodeConnector
     }
 
     override getNodeConnectorProps(Boolean refresh) {
-
-        // FIXME: Read from MD-SAL Invcentory Service
-        return null;
+        // Note, because the MD-SAL has a unified data store, we can ignore the Boolean refresh, as we have no secondary 
+        // data store to refresh from
+        val props = new ConcurrentHashMap<org.opendaylight.controller.sal.core.NodeConnector, Map<String, org.opendaylight.controller.sal.core.Property>>()
+        val nodes = readAllMDNodes()
+        for (node : nodes.node) {
+            val ncs = node.readAllMDNodeConnectors
+            if(ncs != null) {
+                for( nc : ncs ) {
+                    val fcnc = nc.getAugmentation(FlowCapableNodeConnector)
+                    if(fcnc != null) {
+                        val ncps = fcnc.toADNodeConnectorProperties
+                        val ncpsm = new ConcurrentHashMap<String, org.opendaylight.controller.sal.core.Property>
+                        if(ncps != null) {
+                            for(p : ncps) {
+                                ncpsm.put(p.name,p)
+                            }
+                        }  
+                        props.put(nc.id.toADNodeConnector(node.id),ncpsm)
+                    }
+                }
+            }
+        }
+        return props
     }
 
     private def FlowCapableNode readFlowCapableNode(NodeRef ref) {
@@ -401,7 +433,7 @@ class InventoryAndReadAdapter implements IPluginInTopologyService,
     private def FlowCapableNodeConnector readFlowCapableNodeConnector(NodeConnectorRef ref) {
         val dataObject = dataService.readOperationalData(ref.value as InstanceIdentifier<? extends DataObject>);
         val node = dataObject.checkInstanceOf(
-            org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector);
+            NodeConnector);
         return node.getAugmentation(FlowCapableNodeConnector);
     }
 
@@ -429,7 +461,7 @@ class InventoryAndReadAdapter implements IPluginInTopologyService,
                        
                        val nodeConnectorRef = InstanceIdentifier.builder(Nodes)
                                                                .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node,new NodeKey(nodeId))
-                                                               .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector,new NodeConnectorKey(nodeConnectorId)).toInstance;
+                                                               .child(NodeConnector,new NodeConnectorKey(nodeConnectorId)).toInstance;
                        
                        nodeConnector = NodeMapping.toADNodeConnector(new NodeConnectorRef(nodeConnectorRef));
                        
@@ -437,7 +469,7 @@ class InventoryAndReadAdapter implements IPluginInTopologyService,
     }
 
        private def toNodeTableStatistics(
-               org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.statistics.FlowTableStatistics tableStats,
+               FlowTableStatistics tableStats,
                Short tableId,Node node){
                var it = new NodeTableStatistics();
                
@@ -460,28 +492,6 @@ class InventoryAndReadAdapter implements IPluginInTopologyService,
         
         return it;
        }
-
-    override sollicitRefresh() {
-        topologyDiscovery.solicitRefresh
-    }
-    
-    override onLinkDiscovered(LinkDiscovered notification) {
-        val update = new TopoEdgeUpdate(notification.toADEdge,Collections.emptySet(),UpdateType.ADDED);
-        topologyPublisher.edgeUpdate(Collections.singletonList(update))
-    }
-    
-    override onLinkOverutilized(LinkOverutilized notification) {
-        topologyPublisher.edgeOverUtilized(notification.toADEdge)
-    }
-    
-    override onLinkRemoved(LinkRemoved notification) {
-        val update = new TopoEdgeUpdate(notification.toADEdge,Collections.emptySet(),UpdateType.REMOVED);
-        topologyPublisher.edgeUpdate(Collections.singletonList(update))
-    }
-    
-    override onLinkUtilizationNormal(LinkUtilizationNormal notification) {
-        topologyPublisher.edgeUtilBackToNormal(notification.toADEdge)
-    }
     
     
     def Edge toADEdge(Link link) {
index 2f458c41ddfc8dce40325338fe015ba41e8c4118..b0f6065bac751a25ceb57d6d1bde65ed9550f6cb 100644 (file)
@@ -105,6 +105,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instru
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId
 
 public class MDFlowMapping {
 
@@ -129,14 +130,37 @@ public class MDFlowMapping {
         }
         instructions = targetActions.toApplyInstruction();
         match = sourceFlow.match.toMatch();
+        tableId = new Integer(0).shortValue
         return it.build();
 
     }
     
+    public static def toMDFlow(Flow sourceFlow) {
+       if (sourceFlow == null)
+            throw new IllegalArgumentException();
+       val it = new FlowBuilder();
+       hardTimeout = sourceFlow.hardTimeout as int
+       idleTimeout = sourceFlow.idleTimeout as int
+       cookie = BigInteger.valueOf(sourceFlow.id)
+       priority = sourceFlow.priority as int
+       id = new FlowId(sourceFlow.id)
+    
+       val sourceActions = sourceFlow.actions;
+       val targetActions = new ArrayList<Action>();
+       for (sourceAction : sourceActions) {
+           targetActions.add(sourceAction.toAction());
+       }
+       instructions = targetActions.toApplyInstruction();
+       match = sourceFlow.match.toMatch();
+       tableId = new Integer(0).shortValue
+       return it.build();
+    }
+    
     public static def Instructions toApplyInstruction(ArrayList<Action> actions) {
         val it = new InstructionsBuilder;
         val applyActions = new InstructionBuilder;
         applyActions.instruction = new ApplyActionsCaseBuilder().setApplyActions(new ApplyActionsBuilder().setAction(actions).build()).build()
+        applyActions.setOrder(new Integer(0))
         instruction = Collections.<Instruction>singletonList(applyActions.build)
         return it.build;
     }
@@ -144,12 +168,14 @@ public class MDFlowMapping {
     public static def removeFlowInput(Node sourceNode, Flow sourceFlow) {
         val source = flowAdded(sourceFlow);
         val it = new RemoveFlowInputBuilder(source as org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow);
+        node = sourceNode.toNodeRef()
         return it.build();
     }
 
     public static def addFlowInput(Node sourceNode, Flow sourceFlow) {
         val source = flowAdded(sourceFlow);
         val it = new AddFlowInputBuilder(source as org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow);
+        it.setNode(sourceNode.toNodeRef)
         return it.build();
     }
 
index 6bfee578abc0ce56d78ce7aaa432bd4cee7aecd6..4378e7dffece701592936ce85dba77884c6ce8d8 100644 (file)
@@ -7,6 +7,7 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableIt
 
 import static com.google.common.base.Preconditions.*;
 import static extension org.opendaylight.controller.sal.common.util.Arguments.*;
+import static extension org.opendaylight.controller.sal.compatibility.ToSalConversionsUtils.*;
 
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef
@@ -16,39 +17,121 @@ import org.opendaylight.controller.sal.core.ConstructionException
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId
-
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnectorUpdated
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortFeatures
+import org.opendaylight.controller.sal.core.Bandwidth
+import org.opendaylight.controller.sal.core.AdvertisedBandwidth
+import org.opendaylight.controller.sal.core.SupportedBandwidth
+import org.opendaylight.controller.sal.core.PeerBandwidth
+import org.opendaylight.controller.sal.core.Name
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortConfig
+import org.opendaylight.controller.sal.core.Config
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.flow.capable.port.State
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdated
+import java.util.HashSet
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeUpdated
+import org.opendaylight.controller.sal.core.Tables
+import java.util.List
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FeatureCapability
+import org.opendaylight.controller.sal.core.Buffers
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityFlowStats
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityTableStats
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityIpReasm
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityPortStats
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityStp
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityQueueStats
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowFeatureCapabilityArpMatchIp
+import org.opendaylight.controller.sal.core.Capabilities
+import org.opendaylight.controller.sal.core.MacAddress
+import java.util.Date
+import org.opendaylight.controller.sal.core.TimeStamp
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowNodeConnector
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowNode
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector
 
 public class NodeMapping {
 
     public static val MD_SAL_TYPE = "MD_SAL";
     private static val NODE_CLASS = org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-    private static val NODECONNECTOR_CLASS = org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+    private static val NODECONNECTOR_CLASS = org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.
+        NodeConnector;
 
     private new() {
         throw new UnsupportedOperationException("Utility class. Instantiation is not allowed.");
     }
 
     public static def toADNode(InstanceIdentifier<?> node) throws ConstructionException {
+        return node.toNodeId.toADNode
+    }
+
+    public static def toADNode(NodeId id) {
+        return new Node(MD_SAL_TYPE, id.toADNodeId);
+    }
+
+    public static def toNodeId(InstanceIdentifier<?> node) {
         checkNotNull(node);
         checkNotNull(node.getPath());
         checkArgument(node.getPath().size() >= 2);
         val arg = node.getPath().get(1);
         val item = arg.checkInstanceOf(IdentifiableItem);
         val nodeKey = item.getKey().checkInstanceOf(NodeKey);
-        return new Node(MD_SAL_TYPE, nodeKey.getId().getValue().toString());
+        return nodeKey.id
+    }
+
+    public static def toADNodeId(NodeId nodeId) {
+        checkNotNull(nodeId);
+        return nodeId.value
     }
 
     public static def toADNodeConnector(NodeConnectorRef source) throws ConstructionException {
         checkNotNull(source);
         val InstanceIdentifier<?> path = checkNotNull(source.getValue());
-        val node = path.toADNode();
         checkArgument(path.path.size() >= 3);
         val arg = path.getPath().get(2);
         val item = arg.checkInstanceOf(IdentifiableItem);
         val connectorKey = item.getKey().checkInstanceOf(NodeConnectorKey);
-        return new NodeConnector(MD_SAL_TYPE, connectorKey.getId().getValue().toString(), node);
+        return connectorKey.id.toADNodeConnector(path.toNodeId)
     }
     
+    public static def toADNodeConnector(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId ncid,
+        org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId nid) {
+            return new NodeConnector(ncid.toNodeConnectorType(nid),
+            ncid.toADNodeConnectorId(nid), nid.toADNode);
+     }
+
+    public static def toNodeConnectorType(NodeConnectorId ncId, NodeId nodeId) {
+        if (ncId.equals(nodeId.toLocalNodeConnectorId)) {
+            return NodeConnector.NodeConnectorIDType.SWSTACK
+        } else if (ncId.equals(nodeId.toNormalNodeConnectorId)) {
+            return NodeConnector.NodeConnectorIDType.HWPATH
+        } else if (ncId.equals(nodeId.toControllerNodeConnectorId)) {
+            return NodeConnector.NodeConnectorIDType.CONTROLLER
+        }
+        return MD_SAL_TYPE
+    }
+
+    public static def toADNodeConnectorId(NodeConnectorId nodeConnectorId, NodeId nodeId) {
+        if (nodeConnectorId.equals(nodeId.toLocalNodeConnectorId) ||
+            nodeConnectorId.equals(nodeId.toNormalNodeConnectorId) ||
+            nodeConnectorId.equals(nodeId.toControllerNodeConnectorId)) {
+            return NodeConnector.SPECIALNODECONNECTORID
+        }
+        return nodeConnectorId.value
+    }
+
+    public static def toControllerNodeConnectorId(NodeId node) {
+        return new NodeConnectorId(node.value + ":" + 4294967293L)
+    }
+
+    public static def toLocalNodeConnectorId(NodeId node) {
+        return new NodeConnectorId(node.value + ":" + 4294967294L)
+    }
+
+    public static def toNormalNodeConnectorId(NodeId node) {
+        return new NodeConnectorId(node.value + ":" + 4294967290L)
+    }
+
     public static def toNodeRef(Node node) {
         checkArgument(MD_SAL_TYPE.equals(node.getType()));
         var nodeId = node.ID.checkInstanceOf(String)
@@ -56,12 +139,23 @@ public class NodeMapping {
         val nodePath = InstanceIdentifier.builder().node(Nodes).child(NODE_CLASS, nodeKey).toInstance();
         return new NodeRef(nodePath);
     }
-    
+
     public static def toNodeConnectorRef(NodeConnector nodeConnector) {
         val node = nodeConnector.node.toNodeRef();
         val nodePath = node.getValue() as InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node>
-        var nodeConnectorId = nodeConnector.ID.checkInstanceOf(String)
-        val connectorKey = new NodeConnectorKey(new NodeConnectorId(nodeConnectorId));
+        var NodeConnectorId nodeConnectorId
+        if (nodeConnector.ID.equals(NodeConnector.SPECIALNODECONNECTORID)) {
+            if (nodeConnector.type.equals(NodeConnector.NodeConnectorIDType.SWSTACK)) {
+                nodeConnectorId = nodePath.toNodeId.toLocalNodeConnectorId
+            } else if (nodeConnector.type.equals(NodeConnector.NodeConnectorIDType.HWPATH)) {
+                nodeConnectorId = nodePath.toNodeId.toNormalNodeConnectorId
+            } else if (nodeConnector.type.equals(NodeConnector.NodeConnectorIDType.CONTROLLER)) {
+                nodeConnectorId = nodePath.toNodeId.toControllerNodeConnectorId
+            }
+        } else {
+            nodeConnectorId = new NodeConnectorId(nodeConnector.ID.checkInstanceOf(String))
+        }
+        val connectorKey = new NodeConnectorKey(nodeConnectorId);
         val path = InstanceIdentifier.builder(nodePath).child(NODECONNECTOR_CLASS, connectorKey).toInstance();
         return new NodeConnectorRef(path);
     }
@@ -69,5 +163,195 @@ public class NodeMapping {
     public static def toADNode(NodeRef node) throws ConstructionException {
         return toADNode(node.getValue());
     }
-    
+
+    public static def toADNodeConnectorProperties(NodeConnectorUpdated nc) {
+        val fcncu = nc.getAugmentation(FlowCapableNodeConnectorUpdated)
+        if (fcncu != null) {
+            return fcncu.toADNodeConnectorProperties
+        }
+        return new HashSet<org.opendaylight.controller.sal.core.Property>();
+    }
+
+    public static def toADNodeConnectorProperties(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector nc) {
+        val fcnc = nc.getAugmentation(FlowCapableNodeConnector)
+        if (fcnc != null) {
+            return fcnc.toADNodeConnectorProperties
+        }
+        return new HashSet<org.opendaylight.controller.sal.core.Property>();
+    }
+
+    public static def toADNodeConnectorProperties(FlowNodeConnector fcncu) {
+        val props = new HashSet<org.opendaylight.controller.sal.core.Property>();
+        if (fcncu != null) {
+            if (fcncu.currentFeature != null && fcncu.currentFeature.toAdBandwidth != null) {
+                props.add(fcncu.currentFeature.toAdBandwidth)
+            }
+            if (fcncu.advertisedFeatures != null && fcncu.advertisedFeatures.toAdAdvertizedBandwidth != null) {
+                props.add(fcncu.advertisedFeatures.toAdAdvertizedBandwidth)
+            }
+            if (fcncu.supported != null && fcncu.supported.toAdSupportedBandwidth != null) {
+                props.add(fcncu.supported.toAdSupportedBandwidth)
+            }
+            if (fcncu.peerFeatures != null && fcncu.peerFeatures.toAdPeerBandwidth != null) {
+                props.add(fcncu.peerFeatures.toAdPeerBandwidth)
+            }
+            if (fcncu.name != null && fcncu.name.toAdName != null) {
+                props.add(fcncu.name.toAdName)
+            }
+            if (fcncu.configuration != null && fcncu.configuration.toAdConfig != null) {
+                props.add(fcncu.configuration.toAdConfig)
+            }
+            if (fcncu.state != null && fcncu.state.toAdState != null) {
+                props.add(fcncu.state.toAdState)
+            }
+        }
+        return props
+    }
+
+    public static def toAdName(String name) {
+        return new Name(name)
+    }
+
+    public static def toAdConfig(PortConfig pc) {
+        var Config config;
+        if (pc.PORTDOWN) {
+            config = new Config(Config.ADMIN_DOWN)
+        } else {
+            config = new Config(Config.ADMIN_UP)
+        }
+        return config
+    }
+
+    public static def toAdState(State s) {
+        var org.opendaylight.controller.sal.core.State state
+        if (s.linkDown) {
+            state = new org.opendaylight.controller.sal.core.State(org.opendaylight.controller.sal.core.State.EDGE_DOWN)
+        } else {
+            state = new org.opendaylight.controller.sal.core.State(org.opendaylight.controller.sal.core.State.EDGE_UP)
+        }
+        return state
+    }
+
+    public static def toAdBandwidth(PortFeatures pf) {
+        var Bandwidth bw = null
+        if (pf.is_10mbHd || pf.is_10mbFd) {
+            bw = new Bandwidth(Bandwidth.BW10Mbps)
+        } else if (pf.is_100mbHd || pf.is_100mbFd) {
+            bw = new Bandwidth(Bandwidth.BW100Mbps)
+        } else if (pf.is_1gbHd || pf.is_1gbFd) {
+            bw = new Bandwidth(Bandwidth.BW1Gbps)
+        } else if (pf.is_1gbFd) {
+            bw = new Bandwidth(Bandwidth.BW10Gbps)
+        } else if (pf.is_10gbFd) {
+            bw = new Bandwidth(Bandwidth.BW10Gbps)
+        } else if (pf.is_40gbFd) {
+            bw = new Bandwidth(Bandwidth.BW40Gbps)
+        } else if (pf.is_100gbFd) {
+            bw = new Bandwidth(Bandwidth.BW100Gbps)
+        } else if (pf.is_1tbFd) {
+            bw = new Bandwidth(Bandwidth.BW1Tbps)
+        }
+        return bw;
+    }
+
+    public static def toAdAdvertizedBandwidth(PortFeatures pf) {
+        var AdvertisedBandwidth abw
+        val bw = pf.toAdBandwidth
+        if (bw != null) {
+            abw = new AdvertisedBandwidth(bw.value)
+        }
+        return abw
+    }
+
+    public static def toAdSupportedBandwidth(PortFeatures pf) {
+        var SupportedBandwidth sbw
+        val bw = pf.toAdBandwidth
+        if (bw != null) {
+            sbw = new SupportedBandwidth(bw.value)
+        }
+        return sbw
+    }
+
+    public static def toAdPeerBandwidth(PortFeatures pf) {
+        var PeerBandwidth pbw
+        val bw = pf.toAdBandwidth
+        if (bw != null) {
+            pbw = new PeerBandwidth(bw.value)
+        }
+        return pbw
+    }
+
+    public static def toADNodeProperties(NodeUpdated nu) {
+        val fcnu = nu.getAugmentation(FlowCapableNodeUpdated)
+        if (fcnu != null) {
+            return fcnu.toADNodeProperties(nu.id)
+        }
+        return new HashSet<org.opendaylight.controller.sal.core.Property>();
+
+    }
+
+    public static def toADNodeProperties(FlowNode fcnu, NodeId id) {
+        val props = new HashSet<org.opendaylight.controller.sal.core.Property>();
+        if (fcnu != null) {
+            props.add(toADTimestamp)
+
+            // props.add(fcnu.supportedActions.toADActions) - TODO
+            if (id != null) {
+                props.add(id.toADMacAddress)
+            }
+            if (fcnu.switchFeatures != null) {
+                if (fcnu.switchFeatures.maxTables != null) {
+                    props.add(fcnu.switchFeatures.maxTables.toADTables)
+                }
+                if (fcnu.switchFeatures.capabilities != null) {
+                    props.add(fcnu.switchFeatures.capabilities.toADCapabiliities)
+                }
+                if (fcnu.switchFeatures.maxBuffers != null) {
+                    props.add(fcnu.switchFeatures.maxBuffers.toADBuffers)
+                }
+            }
+        }
+        return props;
+    }
+
+    public static def toADTimestamp() {
+        val date = new Date();
+        val timestamp = new TimeStamp(date.time, "connectedSince")
+        return timestamp;
+    }
+
+    public static def toADMacAddress(NodeId id) {
+        return new MacAddress(Long.parseLong(id.value.replaceAll("openflow:", "")).longValue.bytesFromDpid)
+    }
+
+    public static def toADTables(Short tables) {
+        return new Tables(tables.byteValue)
+    }
+
+    public static def toADCapabiliities(List<Class<? extends FeatureCapability>> capabilities) {
+        var int b
+        for (capability : capabilities) {
+            if (capability.equals(FlowFeatureCapabilityFlowStats)) {
+                b = Capabilities.CapabilitiesType.FLOW_STATS_CAPABILITY.value.bitwiseOr(b)
+            } else if (capability.equals(FlowFeatureCapabilityTableStats)) {
+                b = Capabilities.CapabilitiesType.TABLE_STATS_CAPABILITY.value.bitwiseOr(b)
+            } else if (capability.equals(FlowFeatureCapabilityPortStats)) {
+                b = Capabilities.CapabilitiesType.PORT_STATS_CAPABILITY.value.bitwiseOr(b)
+            } else if (capability.equals(FlowFeatureCapabilityStp)) {
+                b = Capabilities.CapabilitiesType.STP_CAPABILITY.value.bitwiseOr(b)
+            } else if (capability.equals(FlowFeatureCapabilityIpReasm)) {
+                b = Capabilities.CapabilitiesType.IP_REASSEM_CAPABILITY.value.bitwiseOr(b)
+            } else if (capability.equals(FlowFeatureCapabilityQueueStats)) {
+                b = Capabilities.CapabilitiesType.QUEUE_STATS_CAPABILITY.value.bitwiseOr(b)
+            } else if (capability.equals(FlowFeatureCapabilityArpMatchIp)) {
+                b = Capabilities.CapabilitiesType.ARP_MATCH_IP_CAPABILITY.value.bitwiseOr(b)
+            }
+        }
+        return new Capabilities(b)
+    }
+
+    public static def toADBuffers(Long buffers) {
+        return new Buffers(buffers.intValue)
+    }
+
 }
index 37bb2778584dc6deb08add85d63eee4ca9489acd..46fd62f3f2790dbd7223b9cba53af42284c57ef1 100644 (file)
@@ -43,6 +43,7 @@ import org.opendaylight.controller.sal.action.SetVlanCfi;
 import org.opendaylight.controller.sal.action.SetVlanId;
 import org.opendaylight.controller.sal.action.SetVlanPcp;
 import org.opendaylight.controller.sal.action.SwPath;
+import org.opendaylight.controller.sal.core.Capabilities;
 import org.opendaylight.controller.sal.core.NodeConnector;
 import org.opendaylight.controller.sal.flowprogrammer.Flow;
 import org.opendaylight.controller.sal.match.Match;
@@ -85,6 +86,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.acti
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.Address;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv6;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FeatureCapability;
 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.list.Instruction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
@@ -563,7 +565,7 @@ public class ToSalConversionsUtils {
         }
     }
 
-    private static byte[] bytesFrom(MacAddress address) {
+    public static byte[] bytesFrom(MacAddress address) {
         String[] mac = address.getValue().split(":");
         byte[] macAddress = new byte[6]; // mac.length == 6 bytes
         for (int i = 0; i < mac.length; i++) {
@@ -571,4 +573,15 @@ public class ToSalConversionsUtils {
         }
         return macAddress;
     }
+    
+    public static byte[] bytesFromDpid(long dpid) {
+        byte[] mac = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+        for (short i = 0; i < 6; i++) {
+            mac[5 - i] = (byte) dpid;
+            dpid >>= 8;
+        }
+
+        return mac;
+    }
 }
diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyAdapter.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyAdapter.xtend
new file mode 100644 (file)
index 0000000..bd2590f
--- /dev/null
@@ -0,0 +1,30 @@
+package org.opendaylight.controller.sal.compatibility.topology
+
+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.yangtools.yang.binding.InstanceIdentifier
+
+import static extension org.opendaylight.controller.sal.compatibility.topology.TopologyMapping.*
+
+class TopologyAdapter implements IPluginInTopologyService {
+    
+    @Property
+    DataProviderService dataService;
+    
+    @Property
+    IPluginOutTopologyService topologyPublisher;
+    
+    override sollicitRefresh() {
+        val path = InstanceIdentifier.builder(NetworkTopology).child(Topology,new TopologyKey(new TopologyId("flow:1"))).toInstance;
+        val reader = TypeSafeDataReader.forReader(dataService)
+        val topology = reader.readOperationalData(path)
+        topologyPublisher.edgeUpdate(topology.toADEdgeUpdates(reader))
+    }
+    
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyCommitHandler.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyCommitHandler.xtend
new file mode 100644 (file)
index 0000000..7d05ce6
--- /dev/null
@@ -0,0 +1,62 @@
+package org.opendaylight.controller.sal.compatibility.topology
+
+import com.google.common.collect.FluentIterable
+import java.util.concurrent.CopyOnWriteArrayList
+import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
+import org.opendaylight.controller.md.sal.common.api.data.DataModification
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.controller.sal.core.UpdateType
+import org.opendaylight.controller.sal.topology.IPluginOutTopologyService
+import org.opendaylight.controller.sal.topology.TopoEdgeUpdate
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.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.yangtools.yang.binding.DataObject
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import static extension org.opendaylight.controller.sal.compatibility.topology.TopologyMapping.*
+import org.slf4j.LoggerFactory
+
+class TopologyCommitHandler implements DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> {
+    static val LOG = LoggerFactory.getLogger(TopologyCommitHandler);
+    @Property
+    IPluginOutTopologyService topologyPublisher;
+    
+    @Property
+    DataProviderService dataService;
+    
+    new(DataProviderService dataService) {
+        _topologyPublisher = topologyPublisher
+        _dataService = dataService
+    }
+    
+    override requestCommit(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
+        val msg = new CopyOnWriteArrayList<TopoEdgeUpdate>()
+        try {
+            val reader = TypeSafeDataReader.forReader(dataService)
+            val topologyPath = InstanceIdentifier.builder(NetworkTopology).child(Topology, new TopologyKey(new TopologyId("flow:1"))).toInstance
+            val topology = reader.readOperationalData(topologyPath)
+            val adds = FluentIterable.from(modification.createdOperationalData.entrySet)
+                .filter[value instanceof Link]
+                .transform[(value as Link).toAdEdge(topology).toTopoEdgeUpdate(UpdateType.ADDED,reader)]
+                .toList
+            val updates = FluentIterable.from(modification.updatedOperationalData.entrySet)
+                .filter[!modification.createdOperationalData.containsKey(key) && (value instanceof Link)]
+                .transform[(value as Link).toAdEdge(topology).toTopoEdgeUpdate(UpdateType.ADDED,reader)] // Evidently the ADSAL does not expect edge 'CHANGED"
+                .toList
+            val removes = FluentIterable.from(modification.removedOperationalData)
+                .transform[reader.readOperationalData(it as InstanceIdentifier<DataObject>)]
+                .filter[it instanceof Link]
+                .transform[(it as Link).toAdEdge(topology).toTopoEdgeUpdate(UpdateType.REMOVED,reader)]
+                .toList
+            msg.addAll(adds)
+            msg.addAll(updates)
+            msg.addAll(removes)
+         } catch (Exception e) {
+            LOG.error("Exception caught",e)
+         }
+        return new TopologyTransaction(modification,topologyPublisher,dataService,msg)
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyMapping.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyMapping.xtend
new file mode 100644 (file)
index 0000000..62983cc
--- /dev/null
@@ -0,0 +1,71 @@
+package org.opendaylight.controller.sal.compatibility.topology
+
+import com.google.common.collect.FluentIterable
+import java.util.Collections
+import java.util.List
+import java.util.concurrent.CopyOnWriteArrayList
+import org.opendaylight.controller.sal.core.ConstructionException
+import org.opendaylight.controller.sal.core.Edge
+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 static com.google.common.base.Preconditions.*
+import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.*
+import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector
+
+class TopologyMapping {
+    
+    private new() {
+        throw new UnsupportedOperationException("Utility class. Instantiation is not allowed.");
+    }
+    
+    public static def toADEdgeUpdates(Topology topology,TypeSafeDataReader reader) {
+        val List<TopoEdgeUpdate> result = new CopyOnWriteArrayList<TopoEdgeUpdate>()
+        return FluentIterable.from(topology.link).transform[toAdEdge(topology).toTopoEdgeUpdate(reader)].copyInto(result)
+    }
+    
+    public static def toAdEdge(Link link,Topology topology) {
+        val adSrc = link.source.sourceTp.toADNodeConnector(link.source.sourceNode)
+        val adDst = link.destination.destTp.toADNodeConnector(link.destination.destNode)
+        return new Edge(adSrc,adDst); 
+    }
+    
+    public static def toTopoEdgeUpdate(Edge e,TypeSafeDataReader reader) {
+        return toTopoEdgeUpdate(e,UpdateType.ADDED,reader)
+    }
+    
+    public static def toTopoEdgeUpdate(Edge e,UpdateType type,TypeSafeDataReader reader) {
+        return new TopoEdgeUpdate(e,e.toAdEdgeProperties(reader),type)
+    }
+    
+    public static def toAdEdgeProperties(Edge e,TypeSafeDataReader reader) {
+        val nc = reader.readOperationalData(e.tailNodeConnector.toNodeConnectorRef.value as InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector>)
+        return nc.toADNodeConnectorProperties     
+    }
+    
+    public static def toADNodeId(NodeId nodeId) {
+        checkNotNull(nodeId);
+        return nodeId.value
+    }
+    public static def toADNodeConnector(TpId source,NodeId nodeId) throws ConstructionException {
+        checkNotNull(source);
+        return new NodeConnector(MD_SAL_TYPE,source.toADNodeConnectorId,nodeId.toADNode)
+    }
+    
+    public static def toADNodeConnectorId(TpId nodeConnectorId) {
+        return nodeConnectorId.value
+    }
+    
+    public static def toADNode(NodeId nodeId) {
+        checkNotNull(nodeId);
+        return new Node(MD_SAL_TYPE,nodeId.toADNodeId);       
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyProvider.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyProvider.xtend
new file mode 100644 (file)
index 0000000..1fde282
--- /dev/null
@@ -0,0 +1,48 @@
+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.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.slf4j.LoggerFactory
+
+class TopologyProvider implements AutoCloseable{
+    static val LOG = LoggerFactory.getLogger(TopologyProvider);
+    TopologyCommitHandler commitHandler
+    
+    @Property
+    IPluginOutTopologyService topologyPublisher;
+    
+    @Property
+    DataProviderService dataService;
+    
+    Registration<DataCommitHandler<InstanceIdentifier<? extends DataObject>,DataObject>> commitHandlerRegistration;
+    
+    def void start() {
+        commitHandler = new TopologyCommitHandler(dataService)
+        commitHandler.setTopologyPublisher(topologyPublisher)
+        val InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(NetworkTopology)
+            .child(Topology,new TopologyKey(new TopologyId("flow:1")))
+            .child(Link)
+            .toInstance();
+        commitHandlerRegistration = dataService.registerCommitHandler(path,commitHandler);
+        LOG.info("TopologyProvider started")
+    }
+    
+    override close() throws Exception {
+        commitHandlerRegistration.close
+    }
+    
+    def setTopologyPublisher(IPluginOutTopologyService topologyPublisher) {
+        _topologyPublisher = topologyPublisher;
+        commitHandler.setTopologyPublisher(topologyPublisher);
+    }
+    
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyTransaction.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyTransaction.xtend
new file mode 100644 (file)
index 0000000..33927ff
--- /dev/null
@@ -0,0 +1,66 @@
+package org.opendaylight.controller.sal.compatibility.topology
+
+import java.util.Collections
+import java.util.List
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction
+import org.opendaylight.controller.md.sal.common.api.data.DataModification
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService
+import org.opendaylight.controller.sal.topology.IPluginOutTopologyService
+import org.opendaylight.controller.sal.topology.TopoEdgeUpdate
+import org.opendaylight.yangtools.yang.binding.DataObject
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yangtools.yang.common.RpcResult
+import org.slf4j.LoggerFactory
+
+class TopologyTransaction implements DataCommitTransaction<InstanceIdentifier<?extends DataObject>, DataObject> {
+    static val LOG = LoggerFactory.getLogger(TopologyTransaction);
+    @Property
+    val DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification;
+    
+    @Property
+    IPluginOutTopologyService topologyPublisher;
+    
+    @Property
+    DataProviderService dataService;
+    @Property
+    List<TopoEdgeUpdate> edgeUpdates;
+    
+    new(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification,IPluginOutTopologyService topologyPublisher,
+        DataProviderService dataService,List<TopoEdgeUpdate> edgeUpdates) {
+        _modification = modification;
+        _topologyPublisher = topologyPublisher
+        _dataService = dataService
+        _edgeUpdates = edgeUpdates
+    }
+    override finish() throws IllegalStateException {
+        
+        if(topologyPublisher != null && _edgeUpdates != null && !edgeUpdates.empty) {
+            topologyPublisher.edgeUpdate(edgeUpdates)
+        }
+         
+         return new RpcResultTo()
+    }
+    
+    override getModification() {
+        return _modification;
+    }
+    
+    override rollback() throws IllegalStateException {
+        // NOOP
+    }
+}
+class RpcResultTo implements RpcResult<Void> {
+    
+    override getErrors() {
+        return Collections.emptySet
+    }
+    
+    override getResult() {
+        return null;
+    }
+    
+    override isSuccessful() {
+        return true;
+    }
+    
+}
\ No newline at end of file
index 13ffa3f91002121c17dc71abb1d748ffe90f906f..1c21effd05ac1c9e93f26b187b32760046b4390e 100644 (file)
             <artifactId>opendaylight-l2-types</artifactId>
             <version>2013.08.27.0</version>
         </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>model-inventory</artifactId>
+            <version>${project.version}</version>
+        </dependency>
     </dependencies>
     <packaging>bundle</packaging>
 </project>
index 1ed1b6827bdc6ace925576b207b7d818d27ac8b5..31736d2737dbcd7358ef264587de0910153afb63 100644 (file)
@@ -5,6 +5,7 @@ module opendaylight-match-types {
     import ietf-inet-types {prefix inet; revision-date "2010-09-24";}
     import ietf-yang-types {prefix yang; revision-date "2010-09-24";}
     import opendaylight-l2-types {prefix l2t;revision-date "2013-08-27";}
+    import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}
 
     revision "2013-10-26" {
         description "Initial revision of macth types";
@@ -270,11 +271,11 @@ module opendaylight-match-types {
     
     grouping match {
         leaf in-port {
-            type uint32;
+            type inv:node-connector-id;
         }
         
         leaf in-phy-port {
-            type uint32;
+            type inv:node-connector-id;
         }
         
         container "metadata" {
index c5f1dddc344b0e239595d7ae55ac6aa3dbd1bf99..571e9d8df2a66f2ea7e48b7aebc03c7e4a338320 100644 (file)
@@ -19,7 +19,7 @@
 
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-        <bundle.plugin.version>2.3.7</bundle.plugin.version>
+        <bundle.plugin.version>2.4.0</bundle.plugin.version>
     </properties>
 
     <modules>
@@ -40,7 +40,7 @@
                 <configuration>
                     <instructions>
                         <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
-                        <Import-Package>*,org.opendaylight.yangtools.yang.binding.annotations</Import-Package>
+                        <Import-Package>org.opendaylight.yangtools.yang.binding.annotations, *</Import-Package>
                     </instructions>
                 </configuration>
             </plugin>
                                     <codeGeneratorClass>org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl</codeGeneratorClass>
                                     <outputBaseDir>target/site/models</outputBaseDir>
                                 </generator>
+                                <generator>
+                                    <codeGeneratorClass>org.opendaylight.yangtools.yang.wadl.generator.maven.WadlGenerator</codeGeneratorClass>
+                                    <outputBaseDir>target/site/models</outputBaseDir>
+                                </generator>
                             </codeGenerators>
                             <inspectDependencies>true</inspectDependencies>
                         </configuration>
index daa3914cf73fd717c63cb2c3e251dc175ffe1191..0a769921d80410742cb22b4ad7ee8cc0e9920f0a 100644 (file)
@@ -115,32 +115,32 @@ public class BindingIndependentConnector implements //
     public DataObject readOperationalData(InstanceIdentifier<? extends DataObject> path) {
         try {
             org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
-
             CompositeNode result = biDataService.readOperationalData(biPath);
-            Class<? extends DataObject> targetType = path.getTargetType();
-
-            if (Augmentation.class.isAssignableFrom(targetType)) {
-                path = mappingService.fromDataDom(biPath);
-                Class<? extends Augmentation<?>> augmentType = (Class<? extends Augmentation<?>>) targetType;
-                DataObject parentTo = mappingService.dataObjectFromDataDom(path, result);
-                if (parentTo instanceof Augmentable<?>) {
-                    return (DataObject) ((Augmentable) parentTo).getAugmentation(augmentType);
-                }
-
-            }
-            return mappingService.dataObjectFromDataDom(path, result);
-
+            return potentialAugmentationRead(path,biPath,result);
         } catch (DeserializationException e) {
             throw new IllegalStateException(e);
         }
     }
 
+    private DataObject potentialAugmentationRead(InstanceIdentifier<? extends DataObject> path, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath, CompositeNode result) throws DeserializationException {
+        Class<? extends DataObject> targetType = path.getTargetType();
+        if (Augmentation.class.isAssignableFrom(targetType)) {
+            path = mappingService.fromDataDom(biPath);
+            Class<? extends Augmentation<?>> augmentType = (Class<? extends Augmentation<?>>) targetType;
+            DataObject parentTo = mappingService.dataObjectFromDataDom(path, result);
+            if (parentTo instanceof Augmentable<?>) {
+                return (DataObject) ((Augmentable) parentTo).getAugmentation(augmentType);
+            }
+        }
+        return mappingService.dataObjectFromDataDom(path, result);
+    }
+
     @Override
     public DataObject readConfigurationData(InstanceIdentifier<? extends DataObject> path) {
         try {
             org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
             CompositeNode result = biDataService.readConfigurationData(biPath);
-            return mappingService.dataObjectFromDataDom(path, result);
+            return potentialAugmentationRead(path,biPath,result);
         } catch (DeserializationException e) {
             throw new IllegalStateException(e);
         }
index 96d0361b1dd5194e9665ab89a80c774e64d5cb4a..d9b16af469727f80e66d608dfb576a936ddfa8c9 100644 (file)
@@ -12,6 +12,8 @@ import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnectorBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.flow.node.SupportedActions;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.flow.node.SupportedActionsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.flow.node.supported.actions.ActionType;
@@ -130,8 +132,60 @@ public class PutAugmentationTest extends AbstractDataServiceTest implements Data
         assertBindingIndependentVersion(NODE_INSTANCE_ID_BI);
         testNodeRemove();
     }
+    
+    @Test
+    public void putNodeWithAugmentation() throws Exception {
+        
+        NodeBuilder nodeBuilder = new NodeBuilder();
+        nodeBuilder.setId(new NodeId(NODE_ID));
+        nodeBuilder.setKey(NODE_KEY);
+        FlowCapableNodeBuilder fnub = new FlowCapableNodeBuilder();
+        fnub.setHardware("Hardware Foo");
+        fnub.setManufacturer("Manufacturer Foo");
+        fnub.setSerialNumber("Serial Foo");
+        fnub.setDescription("Description Foo");
+        fnub.setSoftware("JUnit emulated");
+        FlowCapableNode fnu = fnub.build();
+        
+        nodeBuilder.addAugmentation(FlowCapableNode.class, fnu);
+        DataModificationTransaction baseTransaction = baDataService.beginTransaction();
+        baseTransaction.putOperationalData(NODE_INSTANCE_ID_BA, nodeBuilder.build());
+        RpcResult<TransactionStatus> result = baseTransaction.commit().get();
+        assertEquals(TransactionStatus.COMMITED, result.getResult());
+        
+        FlowCapableNode readedAugmentation = (FlowCapableNode) baDataService.readOperationalData(InstanceIdentifier.builder(NODE_INSTANCE_ID_BA).augmentation(FlowCapableNode.class).toInstance());
+        assertNotNull(readedAugmentation);
+        assertEquals(fnu.getHardware(), readedAugmentation.getHardware());
+        
+        testPutNodeConnectorWithAugmentation();
+        testNodeRemove();
+    }
 
     
+    private void testPutNodeConnectorWithAugmentation() throws Exception {
+        NodeConnectorKey ncKey = new NodeConnectorKey(new NodeConnectorId("test:0:0"));
+        InstanceIdentifier<NodeConnector> ncPath = InstanceIdentifier.builder(NODE_INSTANCE_ID_BA)
+        .child(NodeConnector.class, ncKey).toInstance();
+        InstanceIdentifier<FlowCapableNodeConnector> ncAugmentPath = InstanceIdentifier.builder(ncPath)
+        .augmentation(FlowCapableNodeConnector.class).toInstance();
+        
+        NodeConnectorBuilder nc = new NodeConnectorBuilder();
+        nc.setKey(ncKey);
+        
+        FlowCapableNodeConnectorBuilder fncb = new FlowCapableNodeConnectorBuilder();
+        fncb.setName("Baz");
+        nc.addAugmentation(FlowCapableNodeConnector.class, fncb.build());
+        
+        DataModificationTransaction baseTransaction = baDataService.beginTransaction();
+        baseTransaction.putOperationalData(ncPath, nc.build());
+        RpcResult<TransactionStatus> result = baseTransaction.commit().get();
+        assertEquals(TransactionStatus.COMMITED, result.getResult());
+        
+        FlowCapableNodeConnector readedAugmentation = (FlowCapableNodeConnector) baDataService.readOperationalData(ncAugmentPath);
+        assertNotNull(readedAugmentation);
+        assertEquals(fncb.getName(), readedAugmentation.getName());
+    }
+
     private void testNodeRemove() throws Exception {
         DataModificationTransaction transaction = baDataService.beginTransaction();
         transaction.removeOperationalData(NODE_INSTANCE_ID_BA);
index 1596165601a0155dfda3cb8c1160c8c4baf41e1e..910c7cb62365d01ca43e6d30dec43966f1a8f233 100644 (file)
@@ -16,8 +16,11 @@ import org.opendaylight.controller.sal.core.api.notify.NotificationService;
 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.model.api.SchemaContext;
 
 public interface MountInstance extends NotificationService, DataBrokerService {
 
     Future<RpcResult<CompositeNode>> rpc(QName type, CompositeNode input);
+    
+    SchemaContext getSchemaContext();
 }
index 92542bc3455e497a6082fe64cf6607a290b30723..e5fc4b7aa4a1338c666034db88be0113302cff67 100644 (file)
@@ -3,6 +3,8 @@ package org.opendaylight.controller.sal.core.api.mount;
 import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
 import org.opendaylight.controller.sal.core.api.data.DataProviderService;
 import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService;
+import com.google.common.base.Optional;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 public interface MountProvisionInstance extends //
         MountInstance,//
@@ -10,4 +12,6 @@ public interface MountProvisionInstance extends //
         RpcProvisionRegistry,//
         DataProviderService {
 
+    void setSchemaContext(SchemaContext optional);
+
 }
index 7509a38a1429308029f25bcc85d90a32b6ed8f2d..ab5b145064c828cfa083f74a21beff4e66e9074a 100644 (file)
@@ -31,6 +31,7 @@ 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;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 public class MountPointImpl implements MountProvisionInstance {
 
@@ -42,6 +43,8 @@ public class MountPointImpl implements MountProvisionInstance {
     
     private final InstanceIdentifier mountPath;
 
+    private SchemaContext schemaContext;
+
     public MountPointImpl(InstanceIdentifier path) {
         this.mountPath = path;
         rpcs = new RpcRouterImpl("");
@@ -163,6 +166,14 @@ public class MountPointImpl implements MountProvisionInstance {
         // NOOP
     }
     
+    public SchemaContext getSchemaContext() {
+        return schemaContext;
+    }
+
+    public void setSchemaContext(SchemaContext schemaContext) {
+        this.schemaContext = schemaContext;
+    }
+
     class ReadWrapper implements DataReader<InstanceIdentifier, CompositeNode> {
         
         
index fe613565a6232b608ab91ed33e014b327c4a4e2a..2323b09f996d040360f19e0d9206865bac3ff658 100644 (file)
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-binding-broker-impl</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+           <groupId>org.opendaylight.controller</groupId>
+           <artifactId>sal-binding-broker-impl</artifactId>
+           <version>1.0-SNAPSHOT</version>
+           <type>test-jar</type>
+           <scope>test</scope>
+        </dependency>
+        <dependency>
+        <groupId>org.opendaylight.controller</groupId>
+        <artifactId>ietf-netconf-monitoring</artifactId>
+        <version>0.2.3-SNAPSHOT</version>
+        </dependency>
         <dependency>
             <groupId>org.opendaylight.yangtools.model</groupId>
             <artifactId>ietf-inet-types</artifactId>
index 55a1fbfe486a03f033ba961586675cb21beea2d6..f5d592c00715772a87483d09e0ab96d0c4f99697 100644 (file)
@@ -12,8 +12,12 @@ package org.opendaylight.controller.config.yang.md.sal.connector.netconf;
 import io.netty.channel.EventLoopGroup;
 import io.netty.util.concurrent.GlobalEventExecutor;
 
+import java.io.File;
+import java.io.InputStream;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 
 import javax.net.ssl.SSLContext;
 
@@ -24,6 +28,10 @@ import org.opendaylight.controller.netconf.util.handler.ssh.authentication.Login
 import org.opendaylight.controller.sal.connect.netconf.NetconfDevice;
 import org.opendaylight.protocol.framework.ReconnectStrategy;
 import org.opendaylight.protocol.framework.TimedReconnectStrategy;
+import org.opendaylight.yangtools.yang.model.util.repo.AbstractCachingSchemaSourceProvider;
+import org.opendaylight.yangtools.yang.model.util.repo.FilesystemSchemaCachingProvider;
+import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider;
+import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProviders;
 import org.osgi.framework.BundleContext;
 
 import static com.google.common.base.Preconditions.*;
@@ -37,6 +45,8 @@ import com.google.common.net.InetAddresses;
 public final class NetconfConnectorModule extends org.opendaylight.controller.config.yang.md.sal.connector.netconf.AbstractNetconfConnectorModule
 {
 
+    private static ExecutorService GLOBAL_PROCESSING_EXECUTOR = null;
+    private static AbstractCachingSchemaSourceProvider<String, InputStream> GLOBAL_NETCONF_SOURCE_PROVIDER = null;
     private BundleContext bundleContext;
 
     public NetconfConnectorModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
@@ -74,31 +84,56 @@ public final class NetconfConnectorModule extends org.opendaylight.controller.co
         } else {
             addressValue = getAddress().getIpv6Address().getValue();
         }
-        
         */
         ReconnectStrategy strategy = new TimedReconnectStrategy(GlobalEventExecutor.INSTANCE, attemptMsTimeout, 1000, 1.0, null,
                 Long.valueOf(connectionAttempts), null);
         
-        
-        device.setStrategy(strategy);
+        device.setReconnectStrategy(strategy);
         
         InetAddress addr = InetAddresses.forString(addressValue);
         InetSocketAddress socketAddress = new InetSocketAddress(addr , getPort().intValue());
+
+        
+        device.setProcessingExecutor(getGlobalProcessingExecutor());
+        
         device.setSocketAddress(socketAddress);
+        device.setEventExecutor(getEventExecutorDependency());
+        device.setDispatcher(createDispatcher());
+        device.setSchemaSourceProvider(getGlobalNetconfSchemaProvider(bundleContext));
         
+        getDomRegistryDependency().registerProvider(device, bundleContext);
+        device.start();
+        return device;
+    }
+
+    private ExecutorService getGlobalProcessingExecutor() {
+        if(GLOBAL_PROCESSING_EXECUTOR == null) {
+            
+            GLOBAL_PROCESSING_EXECUTOR = Executors.newCachedThreadPool();
+            
+        }
+        return GLOBAL_PROCESSING_EXECUTOR;
+    }
+
+    private synchronized AbstractCachingSchemaSourceProvider<String, InputStream> getGlobalNetconfSchemaProvider(BundleContext bundleContext) {
+        if(GLOBAL_NETCONF_SOURCE_PROVIDER == null) {
+            String storageFile = "cache/schema";
+            File directory = bundleContext.getDataFile(storageFile);
+            SchemaSourceProvider<String> defaultProvider = SchemaSourceProviders.noopProvider();
+            GLOBAL_NETCONF_SOURCE_PROVIDER = FilesystemSchemaCachingProvider.createFromStringSourceProvider(defaultProvider, directory);
+        }
+        return GLOBAL_NETCONF_SOURCE_PROVIDER;
+    }
+
+    private NetconfClientDispatcher createDispatcher() {
         EventLoopGroup bossGroup = getBossThreadGroupDependency();
         EventLoopGroup workerGroup = getWorkerThreadGroupDependency();
-        NetconfClientDispatcher dispatcher = null;
         if(getTcpOnly()) {
-            dispatcher = new NetconfClientDispatcher( bossGroup, workerGroup);
+            return new NetconfClientDispatcher( bossGroup, workerGroup);
         } else {
             AuthenticationHandler authHandler = new LoginPassword(getUsername(),getPassword());
-            dispatcher = new NetconfSshClientDispatcher(authHandler , bossGroup, workerGroup);
+            return new NetconfSshClientDispatcher(authHandler , bossGroup, workerGroup);
         }
-        getDomRegistryDependency().registerProvider(device, bundleContext);
-        
-        device.start(dispatcher);
-        return device;
     }
 
     public void setBundleContext(BundleContext bundleContext) {
index 7c4bf5facad6a3dd94b0f1bd6a73e301a7820143..bfe352ad41322cf78404426a5582afc22a4e074d 100644 (file)
@@ -25,13 +25,43 @@ import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
 import org.opendaylight.protocol.framework.ReconnectStrategy
 import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
 import org.opendaylight.controller.md.sal.common.api.data.DataModification
+import com.google.common.collect.FluentIterable
+import org.opendaylight.yangtools.yang.model.api.SchemaContext
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl
+import java.io.InputStream
+import org.slf4j.LoggerFactory
+import org.slf4j.Logger
+import org.opendaylight.controller.netconf.client.AbstractNetconfClientNotifySessionListener
+import org.opendaylight.controller.netconf.client.NetconfClientSession
+import org.opendaylight.controller.netconf.api.NetconfMessage
+import io.netty.util.concurrent.EventExecutor
 
-class NetconfDevice implements 
-    Provider, // 
-    DataReader<InstanceIdentifier, CompositeNode>, //
-    DataCommitHandler<InstanceIdentifier, CompositeNode>, //
-    RpcImplementation, //
-    AutoCloseable {
+import java.util.Map
+import java.util.Set
+import com.google.common.collect.ImmutableMap
+
+import org.opendaylight.yangtools.yang.model.util.repo.AbstractCachingSchemaSourceProvider
+import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider
+import com.google.common.base.Optional
+import com.google.common.collect.ImmutableList
+import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProviders
+import static com.google.common.base.Preconditions.*;
+import java.util.concurrent.ExecutorService
+import java.util.concurrent.Future
+import org.opendaylight.controller.netconf.client.NetconfClientSessionListener
+import io.netty.util.concurrent.Promise
+import org.opendaylight.controller.netconf.util.xml.XmlElement
+import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants
+import java.util.concurrent.ExecutionException
+import java.util.concurrent.locks.ReentrantLock
+
+class NetconfDevice implements Provider, // 
+DataReader<InstanceIdentifier, CompositeNode>, //
+DataCommitHandler<InstanceIdentifier, CompositeNode>, //
+RpcImplementation, //
+AutoCloseable {
 
     var NetconfClient client;
 
@@ -41,35 +71,97 @@ class NetconfDevice implements
     @Property
     var MountProvisionInstance mountInstance;
 
+    @Property
+    var EventExecutor eventExecutor;
+
+    @Property
+    var ExecutorService processingExecutor;
+
     @Property
     var InstanceIdentifier path;
 
     @Property
-    var ReconnectStrategy strategy;
+    var ReconnectStrategy reconnectStrategy;
+
+    @Property
+    var AbstractCachingSchemaSourceProvider<String, InputStream> schemaSourceProvider;
+
+    private NetconfDeviceSchemaContextProvider schemaContextProvider
+
+    protected val Logger logger
 
     Registration<DataReader<InstanceIdentifier, CompositeNode>> operReaderReg
     Registration<DataReader<InstanceIdentifier, CompositeNode>> confReaderReg
     Registration<DataCommitHandler<InstanceIdentifier, CompositeNode>> commitHandlerReg
-    
+
     val String name
     MountProvisionService mountService
+
+    int messegeRetryCount = 5;
+
+    int messageTimeoutCount = 5 * 1000;
+
+    Set<QName> cachedCapabilities
+
+    @Property
+    var NetconfClientDispatcher dispatcher
     
-    
+    static val InstanceIdentifier ROOT_PATH = InstanceIdentifier.builder().toInstance();
+
     public new(String name) {
         this.name = name;
+        this.logger = LoggerFactory.getLogger(NetconfDevice.name + "#" + name);
         this.path = InstanceIdentifier.builder(INVENTORY_PATH).nodeWithKey(INVENTORY_NODE,
             Collections.singletonMap(INVENTORY_ID, name)).toInstance;
     }
 
-    def start(NetconfClientDispatcher dispatcher) {
-        client = NetconfClient.clientFor(name, socketAddress, strategy, dispatcher);
-        confReaderReg = mountInstance.registerConfigurationReader(path, this);
-        operReaderReg = mountInstance.registerOperationalReader(path, this);
-        //commitHandlerReg = mountInstance.registerCommitHandler(path,this);
+    def start() {
+        checkState(dispatcher != null, "Dispatcher must be set.");
+        checkState(schemaSourceProvider != null, "Schema Source Provider must be set.")
+        checkState(eventExecutor != null, "Event executor must be set.");
+
+        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);
+        }
+        return processingExecutor.submit(task) as Future<Void>;
+
+    //commitHandlerReg = mountInstance.registerCommitHandler(path,this);
+    }
+
+    def Optional<SchemaContext> getSchemaContext() {
+        if (schemaContextProvider == null) {
+            return Optional.absent();
+        }
+        return schemaContextProvider.currentContext;
+    }
+
+    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 (initialCapabilities.contains(NetconfMapping.IETF_NETCONF_MONITORING_MODULE)) {
+                delegate = new NetconfDeviceSchemaSourceProvider(this);
+            } else {
+                logger.info("Device does not support IETF Netconf Monitoring.", socketAddress);
+                delegate = SchemaSourceProviders.<String>noopProvider();
+            }
+            val sourceProvider = schemaSourceProvider.createInstanceFor(delegate);
+            schemaContextProvider = new NetconfDeviceSchemaContextProvider(this, sourceProvider);
+            schemaContextProvider.createContextFromCapabilities(initialCapabilities);
+            if (mountInstance != null && schemaContext.isPresent) {
+                mountInstance.schemaContext = schemaContext.get();
+            }
+        ]
     }
 
     override readConfigurationData(InstanceIdentifier path) {
-        val result = invokeRpc(NETCONF_GET_CONFIG_QNAME, wrap(NETCONF_GET_CONFIG_QNAME, CONFIG_SOURCE_RUNNING, path.toFilterStructure()));
+        val result = invokeRpc(NETCONF_GET_CONFIG_QNAME,
+            wrap(NETCONF_GET_CONFIG_QNAME, CONFIG_SOURCE_RUNNING, path.toFilterStructure()));
         val data = result.result.getFirstCompositeByName(NETCONF_DATA_QNAME);
         return data?.findNode(path) as CompositeNode;
     }
@@ -83,10 +175,17 @@ class NetconfDevice implements
     override getSupportedRpcs() {
         Collections.emptySet;
     }
+    
+    def createSubscription(String streamName) {
+        val it = ImmutableCompositeNode.builder()
+        QName = NETCONF_CREATE_SUBSCRIPTION_QNAME
+        addLeaf("stream",streamName);
+        invokeRpc(QName,toInstance())
+    }
 
     override invokeRpc(QName rpc, CompositeNode input) {
         val message = rpc.toRpcMessage(input);
-        val result = client.sendMessage(message);
+        val result = client.sendMessage(message, messegeRetryCount, messageTimeoutCount);
         return result.toRpcResult();
     }
 
@@ -96,30 +195,28 @@ class NetconfDevice implements
 
     override onSessionInitiated(ProviderSession session) {
         val dataBroker = session.getService(DataBrokerService);
-        
-        
-        
+
         val transaction = dataBroker.beginTransaction
-        if(transaction.operationalNodeNotExisting) {
-            transaction.putOperationalData(path,nodeWithId)
+        if (transaction.operationalNodeNotExisting) {
+            transaction.putOperationalData(path, nodeWithId)
         }
-        if(transaction.configurationNodeNotExisting) {
-            transaction.putConfigurationData(path,nodeWithId)
+        if (transaction.configurationNodeNotExisting) {
+            transaction.putConfigurationData(path, nodeWithId)
         }
         transaction.commit().get();
         mountService = session.getService(MountProvisionService);
-        mountInstance = mountService.createOrGetMountPoint(path);
+        mountInstance = mountService?.createOrGetMountPoint(path);
     }
-    
+
     def getNodeWithId() {
-        val id = new SimpleNodeTOImpl(INVENTORY_ID,null,name);
-        return new CompositeNodeTOImpl(INVENTORY_NODE,null,Collections.singletonList(id));
+        val id = new SimpleNodeTOImpl(INVENTORY_ID, null, name);
+        return new CompositeNodeTOImpl(INVENTORY_NODE, null, Collections.singletonList(id));
     }
-    
+
     def boolean configurationNodeNotExisting(DataModificationTransaction transaction) {
         return null === transaction.readConfigurationData(path);
     }
-    
+
     def boolean operationalNodeNotExisting(DataModificationTransaction transaction) {
         return null === transaction.readOperationalData(path);
     }
@@ -133,9 +230,9 @@ class NetconfDevice implements
             } else if (current instanceof CompositeNode) {
                 val currentComposite = (current as CompositeNode);
 
-                current = currentComposite.getFirstCompositeByName(arg.nodeType);
+                current = currentComposite.getFirstCompositeByName(arg.nodeType.withoutRevision());
                 if (current == null) {
-                    current = currentComposite.getFirstSimpleByName(arg.nodeType);
+                    current = currentComposite.getFirstSimpleByName(arg.nodeType.withoutRevision());
                 }
                 if (current == null) {
                     return null;
@@ -149,6 +246,25 @@ class NetconfDevice implements
         throw new UnsupportedOperationException("TODO: auto-generated method stub")
     }
 
+    def getInitialCapabilities() {
+        val capabilities = client?.capabilities;
+        if (capabilities == null) {
+            return null;
+        }
+        if (cachedCapabilities == null) {
+            cachedCapabilities = FluentIterable.from(capabilities).filter[
+                contains("?") && contains("module=") && contains("revision=")].transform [
+                val parts = split("\\?");
+                val namespace = parts.get(0);
+                val queryParams = FluentIterable.from(parts.get(1).split("&"));
+                val revision = queryParams.findFirst[startsWith("revision=")].replaceAll("revision=", "");
+                val moduleName = queryParams.findFirst[startsWith("module=")].replaceAll("module=", "");
+                return QName.create(namespace, revision, moduleName);
+            ].toSet();
+        }
+        return cachedCapabilities;
+    }
+
     override close() {
         confReaderReg?.close()
         operReaderReg?.close()
@@ -156,3 +272,165 @@ class NetconfDevice implements
     }
 
 }
+
+package class NetconfDeviceListener extends NetconfClientSessionListener {
+
+    val NetconfDevice device
+    val EventExecutor eventExecutor
+
+    new(NetconfDevice device,EventExecutor eventExecutor) {
+        this.device = device
+        this.eventExecutor = eventExecutor
+    }
+
+    var Promise<NetconfMessage> messagePromise;
+    val promiseLock = new ReentrantLock;
+    
+    override onMessage(NetconfClientSession session, NetconfMessage message) {
+        if (isNotification(message)) {
+            onNotification(session, message);
+        } else try {
+            promiseLock.lock
+            if (messagePromise != null) {
+                messagePromise.setSuccess(message);
+                messagePromise = null;
+            }
+        } finally {
+            promiseLock.unlock
+        }
+    }
+
+    /**
+     * Method intended to customize notification processing.
+     * 
+     * @param session
+     *            {@see
+     *            NetconfClientSessionListener#onMessage(NetconfClientSession,
+     *            NetconfMessage)}
+     * @param message
+     *            {@see
+     *            NetconfClientSessionListener#onMessage(NetconfClientSession,
+     *            NetconfMessage)}
+     */
+    def void onNotification(NetconfClientSession session, NetconfMessage message) {
+        device.logger.debug("Received NETCONF notification.",message);
+        val domNotification = message?.toCompositeNode?.notificationBody;
+        if(domNotification != null) {
+            device?.mountInstance?.publish(domNotification);
+        }
+    }
+    
+    private static def CompositeNode getNotificationBody(CompositeNode node) {
+        for(child : node.children) {
+            if(child instanceof CompositeNode) {
+                return child as CompositeNode;
+            }
+        }
+    }
+
+    override getLastMessage(int attempts, int attemptMsDelay) throws InterruptedException {
+        val promise = promiseReply();
+        val messageAvailable = promise.await(attempts + attemptMsDelay);
+        if (messageAvailable) {
+            try {
+                return promise.get();
+            } catch (ExecutionException e) {
+                throw new IllegalStateException(e);
+            }
+        }
+
+        throw new IllegalStateException("Unsuccessful after " + attempts + " attempts.");
+
+    // throw new TimeoutException("Message was not received on time.");
+    }
+
+    def Promise<NetconfMessage> promiseReply() {
+        promiseLock.lock
+        try {
+        if (messagePromise == null) {
+            messagePromise = eventExecutor.newPromise();
+            return messagePromise;
+        }
+        return messagePromise;
+        } finally {
+            promiseLock.unlock
+        }
+    }
+
+    def boolean isNotification(NetconfMessage message) {
+        val xmle = XmlElement.fromDomDocument(message.getDocument());
+        return XmlNetconfConstants.NOTIFICATION_ELEMENT_NAME.equals(xmle.getName());
+    }
+}
+
+package class NetconfDeviceSchemaContextProvider {
+
+    @Property
+    val NetconfDevice device;
+
+    @Property
+    val SchemaSourceProvider<InputStream> sourceProvider;
+
+    @Property
+    var Optional<SchemaContext> currentContext;
+
+    new(NetconfDevice device, SchemaSourceProvider<InputStream> sourceProvider) {
+        _device = device
+        _sourceProvider = sourceProvider
+    }
+
+    def createContextFromCapabilities(Iterable<QName> capabilities) {
+
+        val modelsToParse = ImmutableMap.<QName, InputStream>builder();
+        for (cap : capabilities) {
+            val source = sourceProvider.getSchemaSource(cap.localName, Optional.fromNullable(cap.formattedRevision));
+            if (source.present) {
+                modelsToParse.put(cap, source.get());
+            }
+        }
+        val context = tryToCreateContext(modelsToParse.build);
+        currentContext = Optional.fromNullable(context);
+    }
+
+    def SchemaContext tryToCreateContext(Map<QName, InputStream> modelsToParse) {
+        val parser = new YangParserImpl();
+        try {
+            val models = parser.parseYangModelsFromStreams(ImmutableList.copyOf(modelsToParse.values));
+            val result = parser.resolveSchemaContext(models);
+            return result;
+        } catch (Exception e) {
+            device.logger.debug("Error occured during parsing YANG schemas", e);
+            return null;
+        }
+    }
+}
+
+package class NetconfDeviceSchemaSourceProvider implements SchemaSourceProvider<String> {
+
+    val NetconfDevice device;
+
+    new(NetconfDevice device) {
+        this.device = device;
+    }
+
+    override getSchemaSource(String moduleName, Optional<String> revision) {
+        val it = ImmutableCompositeNode.builder() //
+        setQName(QName::create(NetconfState.QNAME, "get-schema")) //
+        addLeaf("format", "yang")
+        addLeaf("identifier", moduleName)
+        if (revision.present) {
+            addLeaf("version", revision.get())
+        }
+
+        device.logger.info("Loading YANG schema source for {}:{}", moduleName, revision)
+        val schemaReply = device.invokeRpc(getQName(), toInstance());
+
+        if (schemaReply.successful) {
+            val schemaBody = schemaReply.result.getFirstSimpleByName(
+                QName::create(NetconfState.QNAME.namespace, null, "data"))?.value;
+            device.logger.info("YANG Schema successfully received for: {}:{}", moduleName, revision);
+            return Optional.of(schemaBody as String);
+        }
+        return Optional.absent();
+    }
+}
index 78f6d59f77ed2b2a7025b578d6090929ceead2dd..794b58294eeb13d54ad8385e4f75dac3e3f5c695 100644 (file)
@@ -20,51 +20,63 @@ import org.w3c.dom.Element
 import org.opendaylight.controller.sal.common.util.Rpcs
 import java.util.List
 import com.google.common.collect.ImmutableList
+import org.opendaylight.yangtools.yang.data.api.SimpleNode
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode
 
 class NetconfMapping {
 
     public static val NETCONF_URI = URI.create("urn:ietf:params:xml:ns:netconf:base:1.0")
-    public static val NETCONF_QNAME = new QName(NETCONF_URI,null,"netconf");
-    public static val NETCONF_RPC_QNAME = new QName(NETCONF_QNAME,"rpc");
-    public static val NETCONF_GET_QNAME = new QName(NETCONF_QNAME,"get");
-    public static val NETCONF_GET_CONFIG_QNAME = new QName(NETCONF_QNAME,"get-config");
-    public static val NETCONF_SOURCE_QNAME = new QName(NETCONF_QNAME,"source");
-    public static val NETCONF_RUNNING_QNAME = new QName(NETCONF_QNAME,"running");
-    public static val NETCONF_RPC_REPLY_QNAME = new QName(NETCONF_QNAME,"rpc-reply");
-    public static val NETCONF_OK_QNAME = new QName(NETCONF_QNAME,"ok");
-    public static val NETCONF_DATA_QNAME = new QName(NETCONF_QNAME,"data");
+    public static val NETCONF_MONITORING_URI = "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring"
+    public static val NETCONF_NOTIFICATION_URI = URI.create("urn:ietf:params:xml:ns:netconf:notification:1.0")
     
-     static List<Node<?>> RUNNING = Collections.<Node<?>>singletonList(new SimpleNodeTOImpl(NETCONF_RUNNING_QNAME,null,null));
-    public static val CONFIG_SOURCE_RUNNING = new CompositeNodeTOImpl(NETCONF_SOURCE_QNAME,null,RUNNING);
-
-    static val messageId = new AtomicInteger(0);
     
-   
+    public static val NETCONF_QNAME = QName.create(NETCONF_URI, null, "netconf");
+    public static val NETCONF_RPC_QNAME = QName.create(NETCONF_QNAME, "rpc");
+    public static val NETCONF_GET_QNAME = QName.create(NETCONF_QNAME, "get");
+    public static val NETCONF_FILTER_QNAME = QName.create(NETCONF_QNAME, "filter");
+    public static val NETCONF_TYPE_QNAME = QName.create(NETCONF_QNAME, "type");
+    public static val NETCONF_GET_CONFIG_QNAME = QName.create(NETCONF_QNAME, "get-config");
+    public static val NETCONF_SOURCE_QNAME = QName.create(NETCONF_QNAME, "source");
+    public static val NETCONF_RUNNING_QNAME = QName.create(NETCONF_QNAME, "running");
+    public static val NETCONF_RPC_REPLY_QNAME = QName.create(NETCONF_QNAME, "rpc-reply");
+    public static val NETCONF_OK_QNAME = QName.create(NETCONF_QNAME, "ok");
+    public static val NETCONF_DATA_QNAME = QName.create(NETCONF_QNAME, "data");
+    public static val NETCONF_CREATE_SUBSCRIPTION_QNAME = QName.create(NETCONF_NOTIFICATION_URI,null,"create-subscription");
+    public static val NETCONF_CANCEL_SUBSCRIPTION_QNAME = QName.create(NETCONF_NOTIFICATION_URI,null,"cancel-subscription");
+    public static val IETF_NETCONF_MONITORING_MODULE = QName.create(NETCONF_MONITORING_URI, "2010-10-04","ietf-netconf-monitoring");
 
+    static List<Node<?>> RUNNING = Collections.<Node<?>>singletonList(
+        new SimpleNodeTOImpl(NETCONF_RUNNING_QNAME, null, null));
+    public static val CONFIG_SOURCE_RUNNING = new CompositeNodeTOImpl(NETCONF_SOURCE_QNAME, null, RUNNING);
 
+    static val messageId = new AtomicInteger(0);
 
     static def Node<?> toFilterStructure(InstanceIdentifier identifier) {
         var Node<?> previous = null;
-        for (component : identifier.path.reverse) {
+        if(identifier.path.empty) {
+            return null;
+        }
+        
+        for (component : identifier.path.reverseView) {
             val Node<?> current = component.toNode(previous);
             previous = current;
         }
-        return previous;
+        return filter("subtree",previous);
     }
-    
+
     static def dispatch Node<?> toNode(NodeIdentifierWithPredicates argument, Node<?> node) {
         val list = new ArrayList<Node<?>>();
-        forarg : argument.keyValues.entrySet) {
-            list.add = new SimpleNodeTOImpl(arg.key,null,arg.value);
+        for (arg : argument.keyValues.entrySet) {
+            list.add = new SimpleNodeTOImpl(arg.key, null, arg.value);
         }
-        return new CompositeNodeTOImpl(argument.nodeType,null,list)
+        return new CompositeNodeTOImpl(argument.nodeType, null, list)
     }
-    
+
     static def dispatch Node<?> toNode(PathArgument argument, Node<?> node) {
-        if(node != null) {
-            return new CompositeNodeTOImpl(argument.nodeType,null,Collections.singletonList(node));
+        if (node != null) {
+            return new CompositeNodeTOImpl(argument.nodeType, null, Collections.singletonList(node));
         } else {
-            return new SimpleNodeTOImpl(argument.nodeType,null,null);
+            return new SimpleNodeTOImpl(argument.nodeType, null, null);
         }
     }
 
@@ -73,40 +85,62 @@ class NetconfMapping {
     }
 
     static def NetconfMessage toRpcMessage(QName rpc, CompositeNode node) {
-        val rpcPayload = wrap(NETCONF_RPC_QNAME,node);
+        val rpcPayload = wrap(NETCONF_RPC_QNAME, flattenInput(node));
         val w3cPayload = NodeUtils.buildShadowDomTree(rpcPayload);
-        w3cPayload.documentElement.setAttribute("message-id","m-"+ messageId.andIncrement);
+        w3cPayload.documentElement.setAttribute("message-id", "m-" + messageId.andIncrement);
         return new NetconfMessage(w3cPayload);
     }
+    
+    def static flattenInput(CompositeNode node) {
+        val inputQName = QName.create(node.nodeType,"input");
+        val input = node.getFirstCompositeByName(inputQName);
+        if(input == null) return node;
+        if(input instanceof CompositeNode) {
+            
+            val nodes = ImmutableList.builder() //
+                .addAll(input.children) //
+                .addAll(node.children.filter[nodeType != inputQName]) //
+                .build()
+            return ImmutableCompositeNode.create(node.nodeType,nodes);
+        } 
+        
+    }
 
     static def RpcResult<CompositeNode> toRpcResult(NetconfMessage message) {
         val rawRpc = message.document.toCompositeNode() as CompositeNode;
+
         //rawRpc.
-        
-        return Rpcs.getRpcResult(true,rawRpc,Collections.emptySet());
+        return Rpcs.getRpcResult(true, rawRpc, Collections.emptySet());
     }
-    
-    
-    static def wrap(QName name,Node<?> node) {
-        if(node != null) {
-            return new CompositeNodeTOImpl(name,null,Collections.singletonList(node));
-        }
-        else {
-            return new CompositeNodeTOImpl(name,null,Collections.emptyList());
+
+    static def wrap(QName name, Node<?> node) {
+        if (node != null) {
+            return new CompositeNodeTOImpl(name, null, Collections.singletonList(node));
+        } else {
+            return new CompositeNodeTOImpl(name, null, Collections.emptyList());
         }
     }
-    
-        static def wrap(QName name,Node<?> additional,Node<?> node) {
-        if(node != null) {
-            return new CompositeNodeTOImpl(name,null,ImmutableList.of(additional,node));
+
+    static def wrap(QName name, Node<?> additional, Node<?> node) {
+        if (node != null) {
+            return new CompositeNodeTOImpl(name, null, ImmutableList.of(additional, node));
+        } else {
+            return new CompositeNodeTOImpl(name, null, ImmutableList.of(additional));
         }
-        else {
-            return new CompositeNodeTOImpl(name,null,ImmutableList.of(additional));
+    }
+
+    static def filter(String type, Node<?> node) {
+        val it = ImmutableCompositeNode.builder(); //
+        setQName(NETCONF_FILTER_QNAME);
+        setAttribute(NETCONF_TYPE_QNAME,type);
+        if (node != null) {
+            return add(node).toInstance();
+        } else {
+            return toInstance();
         }
     }
-    
-    
+
     public static def Node<?> toCompositeNode(Document document) {
-        return XmlDocumentUtils.toCompositeNode(document) as Node<?>
+        return XmlDocumentUtils.toNode(document) as Node<?>
     }
 }
index 3f6b4e1f4cd9dd75fd1fcb59a3f504970618a7bf..e151fca00969d9bc5e4e29fbe81bc04ca1173c7d 100644 (file)
@@ -13,10 +13,12 @@ import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
 
+import com.google.common.base.Strings;
+
 public class XmlDocumentUtils {
 
-    public static CompositeNode toCompositeNode(Document doc) {
-        return (CompositeNode) toCompositeNode(doc.getDocumentElement());
+    public static Node<?> toNode(Document doc) {
+        return toCompositeNode(doc.getDocumentElement());
     }
 
     private static Node<?> toCompositeNode(Element element) {
@@ -29,7 +31,7 @@ public class XmlDocumentUtils {
 
         List<Node<?>> values = new ArrayList<>();
         NodeList nodes = element.getChildNodes();
-        boolean isSimpleObject = false;
+        boolean isSimpleObject = true;
         String value = null;
         for (int i = 0; i < nodes.getLength(); i++) {
             org.w3c.dom.Node child = nodes.item(i);
@@ -37,11 +39,10 @@ public class XmlDocumentUtils {
                 isSimpleObject = false;
                 values.add(toCompositeNode((Element) child));
             }
-            if (!isSimpleObject && child instanceof org.w3c.dom.Text) {
+            if (isSimpleObject && child instanceof org.w3c.dom.Text) {
                 value = element.getTextContent();
-                if (value.matches(".*\\w.*")) {
+                if (!Strings.isNullOrEmpty(value)) {
                     isSimpleObject = true;
-                    break;
                 }
             }
         }
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/YangModelInputStreamAdapter.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/YangModelInputStreamAdapter.java
new file mode 100644 (file)
index 0000000..0c0070c
--- /dev/null
@@ -0,0 +1,88 @@
+package org.opendaylight.controller.sal.connect.netconf;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringBufferInputStream;
+import java.io.StringReader;
+
+import org.opendaylight.yangtools.concepts.Delegator;
+import org.opendaylight.yangtools.yang.common.QName;
+
+/**
+ * 
+ *
+ */
+public class YangModelInputStreamAdapter extends InputStream implements Delegator<InputStream> {
+
+    final String source;
+    final QName moduleIdentifier;
+    final InputStream delegate;
+    
+    
+    
+    private YangModelInputStreamAdapter(String source, QName moduleIdentifier, InputStream delegate) {
+        super();
+        this.source = source;
+        this.moduleIdentifier = moduleIdentifier;
+        this.delegate = delegate;
+    }
+
+    public int read() throws IOException {
+        return delegate.read();
+    }
+
+    public int hashCode() {
+        return delegate.hashCode();
+    }
+
+    public int read(byte[] b) throws IOException {
+        return delegate.read(b);
+    }
+
+    public boolean equals(Object obj) {
+        return delegate.equals(obj);
+    }
+
+    public int read(byte[] b, int off, int len) throws IOException {
+        return delegate.read(b, off, len);
+    }
+
+    public long skip(long n) throws IOException {
+        return delegate.skip(n);
+    }
+
+    public int available() throws IOException {
+        return delegate.available();
+    }
+
+    public void close() throws IOException {
+        delegate.close();
+    }
+
+    public void mark(int readlimit) {
+        delegate.mark(readlimit);
+    }
+
+    public void reset() throws IOException {
+        delegate.reset();
+    }
+
+    public boolean markSupported() {
+        return delegate.markSupported();
+    }
+
+    @Override
+    public InputStream getDelegate() {
+        return delegate;
+    }
+
+    @Override
+    public String toString() {
+        return "YangModelInputStreamAdapter [moduleIdentifier=" + moduleIdentifier + ", delegate=" + delegate + "]";
+    }
+
+    public static YangModelInputStreamAdapter create(QName name, String module) {
+        InputStream stringInput = new StringBufferInputStream(module);
+        return new YangModelInputStreamAdapter(null, name, stringInput );
+    }
+}
index 923851411090a9c93f9b0cf1d59e9be1a197a92b..2fae7ee021d0bc074861e38b6b50fd042ac4a402 100644 (file)
@@ -81,6 +81,14 @@ module odl-sal-netconf-connector-cfg {
                     }
                 }
             }
+
+            container event-executor {
+                uses config:service-ref {
+                    refine type {
+                        config:required-identity netty:netty-event-executor;
+                    }
+                }
+            }
         }
     }
 }
\ No newline at end of file
index fb7872f8bcd4e1efdf27be0183fd20176651ac33..8b1bdef8ba71b9be2f72d8d9158a412d9d79a84e 100644 (file)
@@ -43,7 +43,7 @@ class JsonMapper {
 
     private final Set<LeafListSchemaNode> foundLeafLists = new HashSet<>();
     private final Set<ListSchemaNode> foundLists = new HashSet<>();
-    private final Logger logger = LoggerFactory.getLogger(JsonMapper.class); 
+    private final Logger logger = LoggerFactory.getLogger(JsonMapper.class);
 
     public void write(JsonWriter writer, CompositeNode data, DataNodeContainer schema) throws IOException {
         Preconditions.checkNotNull(writer);
@@ -184,16 +184,23 @@ class JsonMapper {
 
         TypeDefinition<?> baseType = RestUtil.resolveBaseTypeFrom(type);
 
+        if (node.getValue() == null && !(baseType instanceof EmptyTypeDefinition)) {
+            logger.debug("While generationg JSON output null value was found for type "
+                    + baseType.getClass().getSimpleName() + ".");
+        }
+
         // TODO check InstanceIdentifierTypeDefinition
         if (baseType instanceof IdentityrefTypeDefinition) {
             if (node.getValue() instanceof QName) {
                 IdentityValuesDTO valueDTO = (IdentityValuesDTO) RestCodec.from(baseType).serialize(node.getValue());
                 IdentityValue valueFromDTO = valueDTO.getValuesWithNamespaces().get(0);
-                String moduleName = ControllerContext.getInstance().findModuleByNamespace(URI.create(valueFromDTO.getNamespace()));
+                String moduleName = ControllerContext.getInstance().findModuleByNamespace(
+                        URI.create(valueFromDTO.getNamespace()));
                 writer.value(moduleName + ":" + valueFromDTO.getValue());
             } else {
                 logger.debug("Value of " + baseType.getQName().getNamespace() + ":"
-                        + baseType.getQName().getLocalName() + " is not instance of " + QName.class + " but is " + node.getValue().getClass());
+                        + baseType.getQName().getLocalName() + " is not instance of " + QName.class + " but is "
+                        + node.getValue().getClass());
                 writer.value(String.valueOf(node.getValue()));
             }
         } else if (baseType instanceof DecimalTypeDefinition || baseType instanceof IntegerTypeDefinition
index 242f18d240122597bea4d1dac29a4f1a31ea9e31..1bceee88cb9b034ac1f17c6ef1ef2b467a9cbf7b 100644 (file)
@@ -9,6 +9,7 @@ import org.opendaylight.controller.sal.core.api.Provider;
 import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
 import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener;
+import org.opendaylight.controller.sal.core.api.mount.MountService;
 import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
 import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
@@ -37,6 +38,7 @@ public class RestconfProvider implements BundleActivator, Provider, ServiceTrack
         SchemaService schemaService = session.getService(SchemaService.class);
         listenerRegistration = schemaService.registerSchemaServiceListener(ControllerContext.getInstance());
         ControllerContext.getInstance().setSchemas(schemaService.getGlobalContext());
+        ControllerContext.getInstance().setMountService(session.getService(MountService.class));
     }
 
     @Override
index a3d658e7bfec43bca4dc743a460cab8bd6cea9de..0dd4668a749fdd5b50af9e8e72a26d7a4636d009 100644 (file)
 package org.opendaylight.controller.sal.rest.impl;
 
-import java.util.Set;
-
 import javax.activation.UnsupportedDataTypeException;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
 
-import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO;
-import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO.IdentityValue;
-import org.opendaylight.controller.sal.restconf.impl.RestCodec;
-import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.Node;
-import org.opendaylight.yangtools.yang.data.api.SimpleNode;
-import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
-import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.data.api.codec.LeafrefCodec;
+import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
+import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlCodecProvider;
+import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlDocumentUtils;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-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.TypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.YangNode;
-import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.Leafref;
 import org.w3c.dom.Document;
-import org.w3c.dom.Element;
 
-import com.google.common.base.Preconditions;
+import com.google.common.base.Optional;
 
 public class XmlMapper {
-    
-    private final Logger logger = LoggerFactory.getLogger(XmlMapper.class); 
+    private static final LeafrefCodecImpl LEAFREF_DEFAULT_CODEC = new LeafrefCodecImpl(
+            Optional.<LeafrefTypeDefinition> absent());
 
-    public Document write(CompositeNode data, DataNodeContainer schema) throws UnsupportedDataTypeException {
-        Preconditions.checkNotNull(data);
-        Preconditions.checkNotNull(schema);
+    private static class LeafrefCodecImpl extends TypeDefinitionAwareCodec<Object, LeafrefTypeDefinition> implements
+            LeafrefCodec<String> {
 
-        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
-        Document doc = null;
-        try {
-            DocumentBuilder bob = dbf.newDocumentBuilder();
-            doc = bob.newDocument();
-        } catch (ParserConfigurationException e) {
-            return null;
+        protected LeafrefCodecImpl(Optional<LeafrefTypeDefinition> typeDef) {
+            super(typeDef, Object.class);
         }
 
-        if (schema instanceof ContainerSchemaNode || schema instanceof ListSchemaNode) {
-            doc.appendChild(translateToXmlAndReturnRootElement(doc, data, schema));
-            return doc;
-        } else {
-            throw new UnsupportedDataTypeException(
-                    "Schema can be ContainerSchemaNode or ListSchemaNode. Other types are not supported yet.");
+        @Override
+        public String serialize(Object data) {
+            return String.valueOf(data);
         }
-    }
 
-    private Element translateToXmlAndReturnRootElement(Document doc, Node<?> data, YangNode schema)
-            throws UnsupportedDataTypeException {
-        QName dataType = data.getNodeType();
-        Element itemEl = doc.createElementNS(dataType.getNamespace().toString(), dataType.getLocalName());
-        if (data instanceof SimpleNode<?>) {
-            if (schema instanceof LeafListSchemaNode) {
-                writeValueOfNodeByType(itemEl, (SimpleNode<?>) data, ((LeafListSchemaNode) schema).getType(), (DataSchemaNode) schema);
-            } else if (schema instanceof LeafSchemaNode) {
-                writeValueOfNodeByType(itemEl, (SimpleNode<?>) data, ((LeafSchemaNode) schema).getType(), (DataSchemaNode) schema);
-            } else {
-                Object value = data.getValue();
-                if (value != null) {
-                    itemEl.setTextContent(String.valueOf(value));
-                }
-            }
-        } else { // CompositeNode
-            for (Node<?> child : ((CompositeNode) data).getChildren()) {
-                DataSchemaNode childSchema = null;
-                if(schema != null){
-                    childSchema = findFirstSchemaForNode(child, ((DataNodeContainer) schema).getChildNodes());
-                    if (logger.isDebugEnabled()) {
-                        if (childSchema == null) {
-                            logger.debug("Probably the data node \"" + ((child == null) ? "" : child.getNodeType().getLocalName())
-                                    + "\" is not conform to schema");
-                        }
-                    }
-                }
-                itemEl.appendChild(translateToXmlAndReturnRootElement(doc, child, childSchema));
-            }
+        @Override
+        public Object deserialize(String data) {
+            return data;
         }
-        return itemEl;
     }
 
-    private void writeValueOfNodeByType(Element element, SimpleNode<?> node, TypeDefinition<?> type, DataSchemaNode schema) {
-
-        TypeDefinition<?> baseType = RestUtil.resolveBaseTypeFrom(type);
+    private static class XmlCodecProviderImpl implements XmlCodecProvider {
+        @Override
+        public TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>> codecFor(TypeDefinition<?> baseType) {
+            TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>> codec = TypeDefinitionAwareCodec
+                    .from(baseType);
 
-        if (baseType instanceof IdentityrefTypeDefinition) {
-            if (node.getValue() instanceof QName) {
-                IdentityValuesDTO valueDTO = (IdentityValuesDTO) RestCodec.from(type).serialize(node.getValue());
-                IdentityValue value = valueDTO.getValuesWithNamespaces().get(0);
-                String prefix = "x";
-                if (value.getPrefix() != null && !value.getPrefix().isEmpty()) {
-                    prefix = value.getPrefix();
+            if (codec == null) {
+                if (baseType instanceof Leafref) {
+                    return LEAFREF_DEFAULT_CODEC;
                 }
-                element.setAttribute("xmlns:" + prefix, value.getNamespace());
-                element.setTextContent(prefix + ":" + value.getValue());
-            } else {
-                logger.debug("Value of " + baseType.getQName().getNamespace() + ":"
-                        + baseType.getQName().getLocalName() + " is not instance of " + QName.class + " but is " + node.getValue().getClass());
-                element.setTextContent(String.valueOf(node.getValue()));
-            }
-        } else {
-            if (node.getValue() != null) {
-                String value = String.valueOf(RestCodec.from(baseType).serialize(node.getValue()));
-                if (value.equals("null")) {
-                    value = String.valueOf(node.getValue());
-                }
-                element.setTextContent(value);
             }
+            return codec;
         }
     }
 
-    private DataSchemaNode findFirstSchemaForNode(Node<?> node, Set<DataSchemaNode> dataSchemaNode) {
-        if (dataSchemaNode != null && node != null) {
-            for (DataSchemaNode dsn : dataSchemaNode) {
-                if (node.getNodeType().getLocalName().equals(dsn.getQName().getLocalName())) {
-                    return dsn;
-                } else if (dsn instanceof ChoiceNode) {
-                    for (ChoiceCaseNode choiceCase : ((ChoiceNode) dsn).getCases()) {
-                        DataSchemaNode foundDsn = findFirstSchemaForNode(node, choiceCase.getChildNodes());
-                        if (foundDsn != null) {
-                            return foundDsn;
-                        }
-                    }
-                }
-            }
-        }
-        return null;
-    }
+    private static final XmlCodecProvider XML_CODEC_PROVIDER_IMPL = new XmlCodecProviderImpl();
 
+    public Document write(CompositeNode data, DataNodeContainer schema) throws UnsupportedDataTypeException {
+        return XmlDocumentUtils.toDocument(data, schema, XML_CODEC_PROVIDER_IMPL);
+    }
 }
index eec2d452a178c15da2f0c70befa8c1367aae31eb..1a60e14589998adbe8390495fe022d4bd5cc30a6 100644 (file)
@@ -34,13 +34,19 @@ import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition
 import org.slf4j.LoggerFactory
 
 import static com.google.common.base.Preconditions.*
+import org.opendaylight.controller.sal.core.api.mount.MountService
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode
 
 class ControllerContext implements SchemaServiceListener {
     val static LOG = LoggerFactory.getLogger(ControllerContext)
     val static ControllerContext INSTANCE = new ControllerContext
     val static NULL_VALUE = "null"
 
-    var SchemaContext schemas;
+    @Property
+    var SchemaContext globalSchema;
+    
+    @Property
+    var MountService mountService;
 
     private val BiMap<URI, String> uriToModuleName = HashBiMap.create();
     private val Map<String, URI> moduleNameToUri = uriToModuleName.inverse();
@@ -57,7 +63,7 @@ class ControllerContext implements SchemaServiceListener {
     }
 
     private def void checkPreconditions() {
-        if (schemas === null) {
+        if (globalSchema === null) {
             throw new ResponseException(Response.Status.SERVICE_UNAVAILABLE, RestconfProvider::NOT_INITALIZED_MSG)
         }
     }
@@ -75,29 +81,24 @@ class ControllerContext implements SchemaServiceListener {
         if (pathArgs.head.empty) {
             pathArgs.remove(0)
         }
-        val schemaNode = ret.collectPathArguments(pathArgs, restconfInstance.findModule);
+        val schemaNode = ret.collectPathArguments(pathArgs, globalSchema.findModule(pathArgs.head));
         if (schemaNode === null) {
             return null
         }
         return new InstanceIdWithSchemaNode(ret.toInstance, schemaNode)
     }
 
-    private def findModule(String restconfInstance) {
-        checkPreconditions
-        checkNotNull(restconfInstance);
-        val pathArgs = restconfInstance.split("/");
-        if (pathArgs.empty) {
-            return null;
-        }
-        val modulWithFirstYangStatement = pathArgs.filter[s|s.contains(":")].head
-        val startModule = modulWithFirstYangStatement.toModuleName();
-        return getLatestModule(startModule)
+    private static def findModule(SchemaContext context,String argument) {
+        //checkPreconditions
+        checkNotNull(argument);
+        val startModule = argument.toModuleName();
+        return context.getLatestModule(startModule)
     }
 
-    def getLatestModule(String moduleName) {
-        checkPreconditions
+    static def getLatestModule(SchemaContext schema,String moduleName) {
+        checkArgument(schema != null);
         checkArgument(moduleName !== null && !moduleName.empty)
-        val modules = schemas.modules.filter[m|m.name == moduleName]
+        val modules = schema.modules.filter[m|m.name == moduleName]
         var latestModule = modules.head
         for (module : modules) {
             if (module.revision.after(latestModule.revision)) {
@@ -112,7 +113,7 @@ class ControllerContext implements SchemaServiceListener {
         val elements = path.path;
         val ret = new StringBuilder();
         val startQName = elements.get(0).nodeType;
-        val initialModule = schemas.findModuleByNamespaceAndRevision(startQName.namespace, startQName.revision)
+        val initialModule = globalSchema.findModuleByNamespaceAndRevision(startQName.namespace, startQName.revision)
         var node = initialModule as DataSchemaNode;
         for (element : elements) {
             node = node.childByQName(element.nodeType);
@@ -139,7 +140,7 @@ class ControllerContext implements SchemaServiceListener {
         checkPreconditions
         var module = uriToModuleName.get(namespace)
         if (module === null) {
-            val moduleSchemas = schemas.findModuleByNamespace(namespace);
+            val moduleSchemas = globalSchema.findModuleByNamespace(namespace);
             if(moduleSchemas === null) return null
             var latestModule = moduleSchemas.head
             for (m : moduleSchemas) {
@@ -157,7 +158,7 @@ class ControllerContext implements SchemaServiceListener {
     def findNamespaceByModule(String module) {
         var namespace = moduleNameToUri.get(module)
         if (namespace === null) {
-            val moduleSchemas = schemas.modules.filter[it|it.name.equals(module)]
+            val moduleSchemas = globalSchema.modules.filter[it|it.name.equals(module)]
             var latestModule = moduleSchemas.head
             for (m : moduleSchemas) {
                 if (m.revision.after(latestModule.revision)) {
@@ -175,7 +176,7 @@ class ControllerContext implements SchemaServiceListener {
         checkPreconditions
         var module = uriToModuleName.get(qname.namespace)
         if (module === null) {
-            val moduleSchema = schemas.findModuleByNamespaceAndRevision(qname.namespace, qname.revision);
+            val moduleSchema = globalSchema.findModuleByNamespaceAndRevision(qname.namespace, qname.revision);
             if(moduleSchema === null) throw new IllegalArgumentException()
             uriToModuleName.put(qname.namespace, moduleSchema.name)
             module = moduleSchema.name;
@@ -244,25 +245,22 @@ class ControllerContext implements SchemaServiceListener {
         }
         val nodeRef = strings.head;
 
-        val nodeName = nodeRef.toNodeName();
-        val targetNode = parentNode.getDataChildByName(nodeName);
-        if (targetNode === null) {
-            val children = parentNode.childNodes
-            for (child : children) {
-                if (child instanceof ChoiceNode) {
-                    val choice = child as ChoiceNode
-                    for (caze : choice.cases) {
-                        val result = builder.collectPathArguments(strings, caze as DataNodeContainer);
-                        if (result !== null)
-                            return result
-                    }
-                }
-            }
+        val nodeName = nodeRef.toNodeName;
+        var targetNode = parentNode.findInstanceDataChild(nodeName);
+        if (targetNode instanceof ChoiceNode) {
             return null
         }
-        if (targetNode instanceof ChoiceNode) {
+        
+        if (targetNode === null) {
+            // Node is possibly in other mount point
+            val partialPath = builder.toInstance;
+            val mountPointSchema = mountService?.getMountPoint(partialPath)?.schemaContext;
+            if(mountPointSchema != null) {
+                return builder.collectPathArguments(strings, mountPointSchema.findModule(strings.head));
+            }
             return null
         }
+        
 
         // Number of consumed elements
         var consumed = 1;
@@ -302,6 +300,32 @@ class ControllerContext implements SchemaServiceListener {
 
         return targetNode
     }
+    
+    static def DataSchemaNode findInstanceDataChild(DataNodeContainer container, String name) {
+        // FIXME: Add namespace comparison
+        var potentialNode = container.getDataChildByName(name);
+        if(potentialNode.instantiatedDataSchema) {
+            return potentialNode;
+        }
+        val allCases = container.childNodes.filter(ChoiceNode).map[cases].flatten
+        for (caze : allCases) {
+            potentialNode = caze.findInstanceDataChild(name);
+            if(potentialNode != null) {
+                return potentialNode;
+            }
+        }
+        return null;
+    }
+    
+    static def boolean isInstantiatedDataSchema(DataSchemaNode node) {
+        switch node {
+            LeafSchemaNode: return true
+            LeafListSchemaNode: return true
+            ContainerSchemaNode: return true
+            ListSchemaNode: return true
+            default: return false
+        }
+    }
 
     private def void addKeyValue(HashMap<QName, Object> map, DataSchemaNode node, String uriValue) {
         checkNotNull(uriValue);
@@ -319,7 +343,7 @@ class ControllerContext implements SchemaServiceListener {
         map.put(node.QName, decoded);
     }
 
-    private def String toModuleName(String str) {
+    private static def String toModuleName(String str) {
         checkNotNull(str)
         if (str.contains(":")) {
             val args = str.split(":");
@@ -343,7 +367,7 @@ class ControllerContext implements SchemaServiceListener {
     private def QName toQName(String name) {
         val module = name.toModuleName;
         val node = name.toNodeName;
-        val namespace = FluentIterable.from(schemas.modules.sort[o1,o2 | o1.revision.compareTo(o2.revision)]) //
+        val namespace = FluentIterable.from(globalSchema.modules.sort[o1,o2 | o1.revision.compareTo(o2.revision)]) //
             .transform[QName.create(namespace,revision,it.name)].findFirst[module == localName]
         ;
         return QName.create(namespace,node);
@@ -354,7 +378,7 @@ class ControllerContext implements SchemaServiceListener {
     }
 
     override onGlobalContextUpdated(SchemaContext context) {
-        this.schemas = context;
+        this.globalSchema = context;
         for (operation : context.operations) {
             val qname = operation.QName;
             qnameToRpc.put(qname, operation);
index 450ba02b56071412d8aff89030db7b221a128605..40fba88356e89f924e6c2903e7460102a74d818c 100644 (file)
@@ -19,16 +19,16 @@ public class RestCodec {
 
     private RestCodec() {
     }
-    
+
     public static final Codec<Object, Object> from(TypeDefinition<?> typeDefinition) {
         return new ObjectCodec(typeDefinition);
     }
-    
+
     @SuppressWarnings("rawtypes")
     public static final class ObjectCodec implements Codec<Object, Object> {
 
         private final Logger logger = LoggerFactory.getLogger(RestCodec.class);
-        
+
         public static final Codec IDENTITYREF_DEFAULT_CODEC = new IdentityrefCodecImpl();
         public static final Codec LEAFREF_DEFAULT_CODEC = new LeafrefCodecImpl();
 
@@ -37,7 +37,7 @@ public class RestCodec {
         private ObjectCodec(TypeDefinition<?> typeDefinition) {
             type = RestUtil.resolveBaseTypeFrom(typeDefinition);
         }
-        
+
         @SuppressWarnings("unchecked")
         @Override
         public Object deserialize(Object input) {
@@ -47,16 +47,21 @@ public class RestCodec {
                 } else if (type instanceof LeafrefTypeDefinition) {
                     return LEAFREF_DEFAULT_CODEC.deserialize(input);
                 } else {
-                    TypeDefinitionAwareCodec<Object,? extends TypeDefinition<?>> typeAwarecodec = TypeDefinitionAwareCodec.from(type);
+                    TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>> typeAwarecodec = TypeDefinitionAwareCodec
+                            .from(type);
                     if (typeAwarecodec != null) {
                         return typeAwarecodec.deserialize(String.valueOf(input));
                     } else {
-                        logger.debug("Codec for type \"" + type.getQName().getLocalName() + "\" is not implemented yet.");
+                        logger.debug("Codec for type \"" + type.getQName().getLocalName()
+                                + "\" is not implemented yet.");
                         return null;
                     }
                 }
-            } catch (ClassCastException e) { // TODO remove this catch when everyone use codecs
-                logger.error("ClassCastException was thrown when codec is invoked with parameter " + String.valueOf(input), e);
+            } catch (ClassCastException e) { // TODO remove this catch when
+                                             // everyone use codecs
+                logger.error(
+                        "ClassCastException was thrown when codec is invoked with parameter " + String.valueOf(input),
+                        e);
                 return input;
             }
         }
@@ -70,22 +75,27 @@ public class RestCodec {
                 } else if (type instanceof LeafrefTypeDefinition) {
                     return LEAFREF_DEFAULT_CODEC.serialize(input);
                 } else {
-                    TypeDefinitionAwareCodec<Object,? extends TypeDefinition<?>> typeAwarecodec = TypeDefinitionAwareCodec.from(type);
+                    TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>> typeAwarecodec = TypeDefinitionAwareCodec
+                            .from(type);
                     if (typeAwarecodec != null) {
                         return typeAwarecodec.serialize(input);
                     } else {
-                        logger.debug("Codec for type \"" + type.getQName().getLocalName() + "\" is not implemented yet.");
+                        logger.debug("Codec for type \"" + type.getQName().getLocalName()
+                                + "\" is not implemented yet.");
                         return null;
                     }
                 }
-            } catch (ClassCastException e) { // TODO remove this catch when everyone use codecs
-                logger.error("ClassCastException was thrown when codec is invoked with parameter " + String.valueOf(input), e);
+            } catch (ClassCastException e) { // TODO remove this catch when
+                                             // everyone use codecs
+                logger.error(
+                        "ClassCastException was thrown when codec is invoked with parameter " + String.valueOf(input),
+                        e);
                 return input;
             }
         }
-        
+
     }
-    
+
     public static class IdentityrefCodecImpl implements IdentityrefCodec<IdentityValuesDTO> {
 
         @Override
@@ -105,7 +115,7 @@ public class RestCodec {
         }
 
     }
-    
+
     public static class LeafrefCodecImpl implements LeafrefCodec<String> {
 
         @Override
@@ -117,7 +127,7 @@ public class RestCodec {
         public Object deserialize(String data) {
             return data;
         }
-        
+
     }
-    
+
 }
@@ -1,22 +1,44 @@
 package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
 import java.io.IOException;
 import java.io.StringReader;
 import java.util.Map;
 import java.util.Set;
 
+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.XmlToCompositeNodeProvider;
 import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
-import org.opendaylight.controller.sal.restconf.impl.test.structures.*;
-import org.opendaylight.yangtools.yang.data.api.*;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.controller.sal.restconf.impl.test.structures.Cont;
+import org.opendaylight.controller.sal.restconf.impl.test.structures.Lf;
+import org.opendaylight.controller.sal.restconf.impl.test.structures.LfLst;
+import org.opendaylight.controller.sal.restconf.impl.test.structures.Lst;
+import org.opendaylight.controller.sal.restconf.impl.test.structures.LstItem;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.ModifyAction;
+import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode;
 import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
 
 import com.google.gson.stream.JsonReader;
 import com.google.gson.stream.JsonToken;
 
-public class ToJsonBasicYangTypesTest {
+public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
+
+    @BeforeClass
+    public static void initialize() {
+        dataLoad("/cnsn-to-json/simple-yang-types", 1, "simple-yang-types", "cont1");
+    }
 
     /**
      * Test of json output when as input are specified composite node with empty
@@ -24,9 +46,16 @@ public class ToJsonBasicYangTypesTest {
      */
     @Test
     public void compositeNodeAndYangWithJsonReaderEmptyDataTest() {
-        String jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson(prepareCompositeNodeWithEmpties(),
-                "/cnsn-to-json/simple-yang-types", "/cnsn-to-json/simple-yang-types/xml", "simple-yang-types", "cont1");
-        verifyJsonOutputForEmpty(jsonOutput);
+        CompositeNode compositeNode = prepareCompositeNodeWithEmpties();
+        TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName);
+        String jsonOutput = null;
+        try {
+            jsonOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode,
+                    StructuredDataToJsonProvider.INSTANCE);
+        } catch (WebApplicationException | IOException e) {
+        }
+
+        verifyJsonOutputForEmptyData(jsonOutput);
     }
 
     /**
@@ -35,13 +64,21 @@ public class ToJsonBasicYangTypesTest {
      */
     @Test
     public void xmlAndYangTypesWithJsonReaderTest() {
-        String jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson(
-                TestUtils.loadCompositeNode("/cnsn-to-json/simple-yang-types/xml/data.xml"),
-                "/cnsn-to-json/simple-yang-types", "/cnsn-to-json/simple-yang-types/xml", "simple-yang-types", "cont1");
+        CompositeNode compositeNode = TestUtils.readInputToCnSn("/cnsn-to-json/simple-yang-types/xml/data.xml",
+                XmlToCompositeNodeProvider.INSTANCE);
+        TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName);
+        String jsonOutput = null;
+        try {
+            jsonOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode,
+                    StructuredDataToJsonProvider.INSTANCE);
+        } catch (WebApplicationException | IOException e) {
+        }
+
         verifyJsonOutput(jsonOutput);
     }
 
-    private void verifyJsonOutputForEmpty(String jsonOutput) {
+    private void verifyJsonOutputForEmptyData(String jsonOutput) {
+        assertNotNull(jsonOutput);
         StringReader strReader = new StringReader(jsonOutput);
         JsonReader jReader = new JsonReader(strReader);
 
@@ -60,6 +97,7 @@ public class ToJsonBasicYangTypesTest {
     }
 
     private void verifyJsonOutput(String jsonOutput) {
+        assertNotNull(jsonOutput);
         StringReader strReader = new StringReader(jsonOutput);
         JsonReader jReader = new JsonReader(strReader);
 
@@ -8,11 +8,13 @@ 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.XmlToCompositeNodeProvider;
 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;
 
-public class ToJsonChoiceCaseTest extends YangAndXmlAndDataSchemaLoader {
+public class CnSnJsonChoiceCaseTest extends YangAndXmlAndDataSchemaLoader {
 
     @BeforeClass
     public static void initialization() {
@@ -111,10 +113,11 @@ public class ToJsonChoiceCaseTest extends YangAndXmlAndDataSchemaLoader {
     }
 
     private void testWrapper(String xmlPath, String pathToSchemaNode) {
-        CompositeNode compNode = TestUtils.loadCompositeNode(xmlPath);
-        TestUtils.normalizeCompositeNode(compNode, modules, dataSchemaNode, pathToSchemaNode);
+        CompositeNode compNode = TestUtils.readInputToCnSn(xmlPath, XmlToCompositeNodeProvider.INSTANCE);
+        TestUtils.normalizeCompositeNode(compNode, modules, pathToSchemaNode);
         try {
-            TestUtils.writeCompNodeWithSchemaContextToJson(compNode, modules, dataSchemaNode);
+            TestUtils.writeCompNodeWithSchemaContextToOutput(compNode, modules, dataSchemaNode,
+                    StructuredDataToJsonProvider.INSTANCE);
         } catch (WebApplicationException | IOException e) {
             // shouldn't end here
             assertTrue(false);
 package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
 import java.io.IOException;
 import java.io.StringReader;
-import java.math.BigDecimal;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 
 import javax.ws.rs.WebApplicationException;
-import javax.xml.bind.DatatypeConverter;
 
+import org.junit.BeforeClass;
 import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
 import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.*;
-import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 
 import com.google.gson.stream.JsonReader;
 import com.google.gson.stream.JsonToken;
 
-public class ToJsonBasicDataTypesTest {
+public class CnSnToJsonBasicDataTypesTest extends YangAndXmlAndDataSchemaLoader {
+
+    @BeforeClass
+    public static void initialize() {
+        dataLoad("/cnsn-to-json/simple-data-types");
+    }
 
     @Test
     public void simpleYangDataTest() {
-        String jsonOutput = "";
-        CompositeNode compositeNode = TestUtils.loadCompositeNode("/cnsn-to-json/simple-data-types/xml/data.xml");
 
-        Set<Module> modules = TestUtils.resolveModules("/cnsn-to-json/simple-data-types");
-        assertEquals(1, modules.size());
-        Module module = TestUtils.resolveModule(null, modules);
-        assertNotNull(module);
-        DataSchemaNode dataSchemaNode = TestUtils.resolveDataSchemaNode(module, null);
-        assertNotNull(dataSchemaNode);
+        CompositeNode compositeNode = TestUtils.readInputToCnSn("/cnsn-to-json/simple-data-types/xml/data.xml",
+                XmlToCompositeNodeProvider.INSTANCE);
 
-        TestUtils.normalizeCompositeNode(compositeNode, modules, dataSchemaNode, "simple-data-types:cont");
+        String jsonOutput = null;
+
+        TestUtils.normalizeCompositeNode(compositeNode, modules, "simple-data-types:cont");
 
         try {
-            jsonOutput = TestUtils.writeCompNodeWithSchemaContextToJson(compositeNode, modules, dataSchemaNode);
+            jsonOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode,
+                    StructuredDataToJsonProvider.INSTANCE);
         } catch (WebApplicationException | IOException e) {
-            assertTrue(false); // shouldn't get here
         }
+        assertNotNull(jsonOutput);
 
-        System.out.println(jsonOutput);
         verifyJsonOutput(jsonOutput);
     }
 
-    private CompositeNode prepareData() {
-        MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null,
-                ModifyAction.CREATE, null);
-
-        List<Node<?>> childNodes = new ArrayList<>();
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint8Min"), cont, (byte) -128,
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint8Max"), cont, (byte) 127,
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint16Min"), cont, (short) -32768,
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint16Max"), cont, (short) 32767,
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint32Min"), cont,
-                (int) -2147483648, ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint32Max"), cont, (int) 2147483647,
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint64Min"), cont, new Long(
-                "-9223372036854775807"), ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnint64Max"), cont, new Long(
-                "9223372036854775807"), ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnuint8Max"), cont, (short) 255,
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnuint16Max"), cont, (int) 65535,
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfnuint32Max"), cont, new Long(
-                "4294967295"), ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfstr"), cont, "lfstr",
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfstr1"), cont, "",
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfbool1"), cont, Boolean.TRUE,
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfbool2"), cont, Boolean.FALSE,
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfdecimal1"), cont, new BigDecimal(
-                "43.32"), ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfdecimal2"), cont, new BigDecimal(
-                "-0.43"), ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfdecimal3"), cont, new BigDecimal(
-                "43"), ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfdecimal4"), cont, new BigDecimal(
-                "43E3"), ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfdecimal6"), cont, new BigDecimal(
-                "33.12345"), ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfenum"), cont, "enum3",
-                ModifyAction.CREATE, null));
-
-        HashSet<String> bits = new HashSet<String>();
-        bits.add("bit3");
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfbits"), cont, bits,
-                ModifyAction.CREATE, null));
-
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfbinary"), cont, DatatypeConverter
-                .parseBase64Binary("AAaacdabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"),
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfempty"), cont, null,
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion1"), cont, (int) 324,
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion2"), cont, new BigDecimal(
-                "33.3"), ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion3"), cont, "55",
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion4"), cont, Boolean.TRUE,
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion5"), cont, "true",
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion6"), cont, "false",
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion7"), cont, null,
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion8"), cont, "",
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion9"), cont, "",
-                ModifyAction.CREATE, null));
-
-        HashSet<String> bits2 = new HashSet<String>();
-        bits2.add("bt1");
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion10"), cont, bits2,
-                ModifyAction.CREATE, null));
-
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion11"), cont, (short) 33,
-                ModifyAction.CREATE, null));
-        childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfunion12"), cont, Boolean.FALSE,
-                ModifyAction.CREATE, null));
-        try {
-            childNodes.add(NodeFactory.createMutableSimpleNode(TestUtils.buildQName("identityref1"), cont, new QName(
-                    new URI("simple:data:types"), "iden"), ModifyAction.CREATE, null));
-        } catch (URISyntaxException e) {
-        }
-
-        cont.getChildren().addAll(childNodes);
-
-        cont.init();
-
-        return cont;
-    }
-
     private void verifyJsonOutput(String jsonOutput) {
         StringReader strReader = new StringReader(jsonOutput);
         JsonReader jReader = new JsonReader(strReader);
@@ -178,7 +82,6 @@ public class ToJsonBasicDataTypesTest {
     private void jsonReadContElements(JsonReader jReader) throws IOException {
         jReader.beginObject();
         List<String> loadedLfs = new ArrayList<>();
-        boolean exceptForDecimal5Raised = false;
         boolean enumChecked = false;
         boolean bitsChecked = false;
         boolean lfdecimal6Checked = false;
@@ -190,7 +93,6 @@ public class ToJsonBasicDataTypesTest {
         boolean lfbool2Checked = false;
         boolean lfstrChecked = false;
         boolean lfbinaryChecked = false;
-        // boolean lfref1Checked = false;
         boolean lfemptyChecked = false;
         boolean lfstr1Checked = false;
         boolean lfidentityrefChecked = false;
@@ -201,11 +103,7 @@ public class ToJsonBasicDataTypesTest {
             try {
                 peek = jReader.peek();
             } catch (IOException e) {
-                if (keyName.equals("lfdecimal5")) {
-                    exceptForDecimal5Raised = true;
-                } else {
-                    assertTrue("Key " + keyName + " has incorrect value for specifed type", false);
-                }
+                assertTrue("Key " + keyName + " has incorrect value for specifed type", false);
             }
 
             if (keyName.startsWith("lfnint") || keyName.startsWith("lfnuint")) {
@@ -11,12 +11,14 @@ 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.restconf.impl.test.TestUtils;
 import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.*;
 import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
 
-public class ToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader {
+public class CnSnToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader {
 
     @BeforeClass
     public static void initialization() {
@@ -27,7 +29,9 @@ public class ToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader {
     public void identityrefToJsonTest() {
         String json = null;
         try {
-            json = TestUtils.writeCompNodeWithSchemaContextToJson(prepareCompositeNode(), modules, dataSchemaNode);
+            QName valueAsQname = TestUtils.buildQName("name_test", "identityref:module", "2013-12-2");
+            json = TestUtils.writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(valueAsQname), modules,
+                    dataSchemaNode, StructuredDataToJsonProvider.INSTANCE);
         } catch (WebApplicationException | IOException e) {
             // shouldn't end here
             assertTrue(false);
@@ -40,15 +44,35 @@ public class ToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader {
         assertTrue(mtch.matches());
     }
 
-    private CompositeNode prepareCompositeNode() {
+    @Test
+    public void identityrefToJsonWithoutQNameTest() {
+        String json = null;
+        try {
+            String value = "not q name value";
+            json = TestUtils.writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(value), modules,
+                    dataSchemaNode, StructuredDataToJsonProvider.INSTANCE);
+        } catch (WebApplicationException | IOException e) {
+            // shouldn't end here
+            assertTrue(false);
+        }
+        System.out.println(json);
+        assertNotNull(json);
+        Pattern ptrn = Pattern.compile(".*\"lf1\"\\p{Space}*:\\p{Space}*\"not q name value\".*", Pattern.DOTALL);
+        Matcher mtch = ptrn.matcher(json);
+
+        assertTrue(mtch.matches());
+    }
+
+    private CompositeNode prepareCompositeNode(Object value) {
         MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null,
                 ModifyAction.CREATE, null);
         MutableCompositeNode cont1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont1"), cont, null,
                 ModifyAction.CREATE, null);
         cont.getChildren().add(cont1);
 
-        MutableSimpleNode<?> lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1"), cont1,
-                TestUtils.buildQName("name_test", "identityref:module", "2013-12-2"), ModifyAction.CREATE, null);
+        MutableSimpleNode<?> lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1"), cont1, value,
+                ModifyAction.CREATE, null);
+
         cont1.getChildren().add(lf1);
         cont1.init();
         cont.init();
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIncorrectTopLevelTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIncorrectTopLevelTest.java
new file mode 100644 (file)
index 0000000..6b57762
--- /dev/null
@@ -0,0 +1,170 @@
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Set;
+
+import javax.activation.UnsupportedDataTypeException;
+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.XmlToCompositeNodeProvider;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.Status;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.UsesNode;
+import org.opendaylight.yangtools.yang.model.api.YangNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CnSnToJsonIncorrectTopLevelTest extends YangAndXmlAndDataSchemaLoader {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CnSnToJsonIncorrectTopLevelTest.class);
+
+    @BeforeClass
+    public static void initialize() {
+        dataLoad("/cnsn-to-json/simple-data-types");
+    }
+
+    private class IncorrectDataSchema implements DataSchemaNode, DataNodeContainer {
+
+        @Override
+        public String getDescription() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public SchemaPath getPath() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public QName getQName() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public String getReference() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Status getStatus() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public List<UnknownSchemaNode> getUnknownSchemaNodes() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Set<DataSchemaNode> getChildNodes() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public DataSchemaNode getDataChildByName(QName arg0) {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public DataSchemaNode getDataChildByName(String arg0) {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Set<GroupingDefinition> getGroupings() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Set<TypeDefinition<?>> getTypeDefinitions() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public Set<UsesNode> getUses() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public ConstraintDefinition getConstraints() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public YangNode getParent() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public boolean isAddedByUses() {
+            // TODO Auto-generated method stub
+            return false;
+        }
+
+        @Override
+        public boolean isAugmenting() {
+            // TODO Auto-generated method stub
+            return false;
+        }
+
+        @Override
+        public boolean isConfiguration() {
+            // TODO Auto-generated method stub
+            return false;
+        }
+
+    }
+
+    @Test
+    public void incorrectTopLevelElementTest() {
+
+        CompositeNode compositeNode = TestUtils.readInputToCnSn("/cnsn-to-json/simple-data-types/xml/data.xml", XmlToCompositeNodeProvider.INSTANCE);
+        DataSchemaNode incorrectDataSchema = null;
+        incorrectDataSchema = new IncorrectDataSchema();
+
+        TestUtils.normalizeCompositeNode(compositeNode, modules, "simple-data-types:cont");
+
+        boolean exceptionRaised = false;
+        try {
+            TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, incorrectDataSchema,
+                    StructuredDataToJsonProvider.INSTANCE);
+        } catch (UnsupportedDataTypeException e) {
+            exceptionRaised = true;
+        } catch (WebApplicationException | IOException e) {
+            LOG.error("WebApplicationException or IOException was raised");
+        }
+
+        assertTrue(exceptionRaised);
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonLeafrefType.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonLeafrefType.java
new file mode 100644 (file)
index 0000000..3215e81
--- /dev/null
@@ -0,0 +1,103 @@
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+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.XmlToCompositeNodeProvider;
+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;
+
+/**
+ * 
+ * All tests are commented now because leafref isn't supported now
+ * 
+ */
+
+public class CnSnToJsonLeafrefType extends YangAndXmlAndDataSchemaLoader {
+
+    @BeforeClass
+    public static void initialization() {
+        dataLoad("/cnsn-to-json/leafref", 2, "main-module", "cont");
+    }
+
+    @Test
+    public void leafrefAbsolutePathToExistingLeafTest() {
+        String json = toJson("/cnsn-to-json/leafref/xml/data_absolut_ref_to_existing_leaf.xml");
+        validateJson(".*\"lf3\":\\p{Blank}*\"true\".*", json);
+    }
+
+    @Test
+    public void leafrefRelativePathToExistingLeafTest() {
+        String json = toJson("/cnsn-to-json/leafref/xml/data_relativ_ref_to_existing_leaf.xml");
+        validateJson(".*\"lf2\":\\p{Blank}*\"121\".*", json);
+    }
+
+    /**
+     * Tests case when reference to not existing element is present. In this
+     * case value from single node is printed as string.
+     */
+    @Test
+    public void leafrefToNonExistingLeafTest() {
+        String json = toJson("/cnsn-to-json/leafref/xml/data_ref_to_non_existing_leaf.xml");
+        validateJson(".*\"lf5\":\\p{Blank}*\"137\".*", json);
+    }
+
+    /**
+     * Tests case when non leaf element is referenced. In this case value from
+     * single node is printed as string.
+     */
+    @Test
+    public void leafrefToNotLeafTest() {
+        String json = toJson("/cnsn-to-json/leafref/xml/data_ref_to_not_leaf.xml");
+        validateJson(".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lf6\":\\p{Blank}*\"44.33\".*", json);
+    }
+
+    /**
+     * Tests case when leaflist element is refers to leaf.
+     */
+    @Test
+    public void leafrefFromLeafListToLeafTest() {
+        String json = toJson("/cnsn-to-json/leafref/xml/data_relativ_ref_from_leaflist_to_existing_leaf.xml");
+        validateJson(
+                ".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lflst1\":\\p{Blank}*.*\"345\",\\p{Space}*\"346\",\\p{Space}*\"347\".*",
+                json);
+    }
+
+    /**
+     * Tests case when leaflist element is refers to leaf.
+     */
+    @Test
+    public void leafrefFromLeafrefToLeafrefTest() {
+        String json = toJson("/cnsn-to-json/leafref/xml/data_from_leafref_to_leafref.xml");
+        validateJson(".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lf7\":\\p{Blank}*\"200\".*", json);
+    }
+
+    private void validateJson(String regex, String value) {
+        assertNotNull(value);
+        Pattern ptrn = Pattern.compile(regex, Pattern.DOTALL);
+        Matcher mtch = ptrn.matcher(value);
+        assertTrue(mtch.matches());
+    }
+
+    private String toJson(String xmlDataPath) {
+        try {
+            CompositeNode compositeNode = TestUtils.readInputToCnSn(xmlDataPath, XmlToCompositeNodeProvider.INSTANCE);
+            TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName);
+            return TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode,
+                    StructuredDataToJsonProvider.INSTANCE);
+        } catch (WebApplicationException | IOException e) {
+        }
+        return "";
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonNotExistingLeafTypeTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonNotExistingLeafTypeTest.java
new file mode 100644 (file)
index 0000000..e5a317e
--- /dev/null
@@ -0,0 +1,72 @@
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Set;
+
+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.restconf.impl.test.*;
+import org.opendaylight.yangtools.yang.data.api.*;
+import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.impl.LeafSchemaNodeBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CnSnToJsonNotExistingLeafTypeTest extends YangAndXmlAndDataSchemaLoader {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CnSnToJsonNotExistingLeafTypeTest.class);
+
+    @BeforeClass
+    public static void initialize() {
+        dataLoad("/cnsn-to-json/simple-data-types");
+    }
+
+    @Test
+    public void incorrectTopLevelElementTest() {
+
+        String jsonOutput = null;
+        try {
+            jsonOutput = TestUtils
+                    .writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(),
+                            (Set<Module>) Collections.EMPTY_SET, prepareDataSchemaNode(),
+                            StructuredDataToJsonProvider.INSTANCE);
+        } catch (WebApplicationException | IOException e) {
+            LOG.error("WebApplicationException or IOException was raised");
+        }
+        assertNotNull(jsonOutput);
+        assertTrue(jsonOutput.contains("\"lf1\": \"\""));
+    }
+
+    private CompositeNode prepareCompositeNode() {
+        MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(
+                TestUtils.buildQName("cont", "simple:uri", "2012-12-17"), null, null, ModifyAction.CREATE, null);
+        MutableSimpleNode<?> lf1 = NodeFactory.createMutableSimpleNode(
+                TestUtils.buildQName("lf1", "simple:uri", "2012-12-17"), cont, "any value", ModifyAction.CREATE, null);
+        cont.getChildren().add(lf1);
+        cont.init();
+        return cont;
+    }
+
+    private DataSchemaNode prepareDataSchemaNode() {
+        ContainerSchemaNodeBuilder contBuild = new ContainerSchemaNodeBuilder("module", 1, TestUtils.buildQName("cont",
+                "simple:uri", "2012-12-17"), null);
+        LeafSchemaNodeBuilder leafBuild = new LeafSchemaNodeBuilder("module", 2, TestUtils.buildQName("lf1",
+                "simple:uri", "2012-12-17"), null);
+        leafBuild.setType(new DummyType());
+        leafBuild.setConfiguration(true);
+
+        contBuild.addChildNode(leafBuild);
+        return contBuild.build(null);
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithAugmentTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithAugmentTest.java
new file mode 100644 (file)
index 0000000..3c2325c
--- /dev/null
@@ -0,0 +1,51 @@
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+
+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.XmlToCompositeNodeProvider;
+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;
+
+public class CnSnToJsonWithAugmentTest extends YangAndXmlAndDataSchemaLoader {
+
+    @BeforeClass
+    public static void initialize() {
+        dataLoad("/cnsn-to-json/augmentation", 5, "yang", "cont");
+    }
+
+    /**
+     * Test of json output when as input are specified composite node with empty
+     * data + YANG file
+     */
+    @Test
+    public void augmentedElementsToJson() {
+        CompositeNode compositeNode = TestUtils.readInputToCnSn("/cnsn-to-json/augmentation/xml/data.xml",
+                XmlToCompositeNodeProvider.INSTANCE);
+        TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName);
+
+        String jsonOutput = null;
+        try {
+            jsonOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode,
+                    StructuredDataToJsonProvider.INSTANCE);
+        } catch (WebApplicationException | IOException e) {
+        }
+        assertNotNull(jsonOutput);
+
+        assertTrue(jsonOutput.contains("\"augment-leaf:lf2\": \"lf2\""));
+        assertTrue(jsonOutput.contains("\"augment-container:cont1\": {"));
+        assertTrue(jsonOutput.contains("\"augment-container:lf11\": \"lf11\""));
+        assertTrue(jsonOutput.contains("\"augment-list:lst1\": ["));
+        assertTrue(jsonOutput.contains("\"augment-list:lf11\": \"lf1_1\""));
+        assertTrue(jsonOutput.contains("\"augment-list:lf11\": \"lf1_2\""));
+        assertTrue(jsonOutput.contains("\"augment-leaflist:lflst1\": ["));
+    }
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonLeafrefType.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonLeafrefType.java
deleted file mode 100644 (file)
index 1ac81a3..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-import java.util.regex.Matcher;
-
-import javax.ws.rs.WebApplicationException;
-
-import org.junit.*;
-import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
-import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
-
-/**
- * 
- * All tests are commented now because leafref isn't supported now
- * 
- */
-
-public class ToJsonLeafrefType extends YangAndXmlAndDataSchemaLoader {
-
-    @BeforeClass
-    public static void initialization() {
-        dataLoad("/cnsn-to-json/leafref", 2, "main-module", "cont");
-    }
-
-    @Ignore
-    @Test
-    public void leafrefAbsolutePathToExistingLeafTest() {
-        String json = null;
-        try {
-            json = TestUtils.writeCompNodeWithSchemaContextToJson(
-                    TestUtils.loadCompositeNode("/cnsn-to-json/leafref/xml/data_absolut_ref_to_existing_leaf.xml"),
-                    modules, dataSchemaNode);
-        } catch (WebApplicationException | IOException e) {
-            // shouldn't end here
-            assertTrue(false);
-        }
-        assertNotNull(json);
-        java.util.regex.Pattern ptrn = java.util.regex.Pattern.compile(".*\"lf3\":\\p{Blank}*true.*",
-                java.util.regex.Pattern.DOTALL);
-        Matcher mtch = ptrn.matcher(json);
-        assertTrue(mtch.matches());
-    }
-
-    @Ignore
-    @Test
-    public void leafrefRelativePathToExistingLeafTest() {
-        String json = null;
-        try {
-            json = TestUtils.writeCompNodeWithSchemaContextToJson(
-                    TestUtils.loadCompositeNode("/cnsn-to-json/leafref/xml/data_relativ_ref_to_existing_leaf.xml"),
-                    modules, dataSchemaNode);
-        } catch (WebApplicationException | IOException e) {
-            // shouldn't end here
-            assertTrue(false);
-        }
-        assertNotNull(json);
-        java.util.regex.Pattern ptrn = java.util.regex.Pattern.compile(".*\"lf2\":\\p{Blank}*121.*",
-                java.util.regex.Pattern.DOTALL);
-        Matcher mtch = ptrn.matcher(json);
-        assertTrue(mtch.matches());
-    }
-
-    /**
-     * Tests case when reference to not existing element is present. In this
-     * case value from single node is printed as string.
-     */
-    @Ignore
-    @Test
-    public void leafrefToNonExistingLeafTest() {
-        String json = null;
-        try {
-            json = TestUtils.writeCompNodeWithSchemaContextToJson(
-                    TestUtils.loadCompositeNode("/cnsn-to-json/leafref/xml/data_ref_to_non_existing_leaf.xml"),
-                    modules, dataSchemaNode);
-        } catch (WebApplicationException | IOException e) {
-            // shouldn't end here
-            assertTrue(false);
-        }
-        assertNotNull(json);
-        java.util.regex.Pattern ptrn = java.util.regex.Pattern.compile(".*\"lf5\":\\p{Blank}*\"137\".*",
-                java.util.regex.Pattern.DOTALL);
-        Matcher mtch = ptrn.matcher(json);
-        assertTrue(mtch.matches());
-    }
-
-    /**
-     * Tests case when non leaf element is referenced. In this case value from
-     * single node is printed as string.
-     */
-    @Ignore
-    @Test
-    public void leafrefToNotLeafTest() {
-        String json = null;
-        try {
-            json = TestUtils.writeCompNodeWithSchemaContextToJson(
-                    TestUtils.loadCompositeNode("/cnsn-to-json/leafref/xml/data_ref_to_not_leaf.xml"), modules,
-                    dataSchemaNode);
-        } catch (WebApplicationException | IOException e) {
-            // shouldn't end here
-            assertTrue(false);
-        }
-        assertNotNull(json);
-        java.util.regex.Pattern ptrn = java.util.regex.Pattern.compile(
-                ".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lf6\":\\p{Blank}*\"44.33\".*",
-                java.util.regex.Pattern.DOTALL);
-        Matcher mtch = ptrn.matcher(json);
-        assertTrue(mtch.matches());
-    }
-
-    /**
-     * Tests case when leaflist element is refers to leaf.
-     */
-    @Ignore
-    @Test
-    public void leafrefFromLeafListToLeafTest() {
-        String json = null;
-        try {
-            json = TestUtils
-                    .writeCompNodeWithSchemaContextToJson(
-                            TestUtils
-                                    .loadCompositeNode("/cnsn-to-json/leafref/xml/data_relativ_ref_from_leaflist_to_existing_leaf.xml"),
-                            modules, dataSchemaNode);
-        } catch (WebApplicationException | IOException e) {
-            // shouldn't end here
-            assertTrue(false);
-        }
-        assertNotNull(json);
-        java.util.regex.Pattern ptrn = java.util.regex.Pattern
-                .compile(
-                        ".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lflst1\":\\p{Blank}*.*345,\\p{Space}*346,\\p{Space}*347.*",
-                        java.util.regex.Pattern.DOTALL);
-        Matcher mtch = ptrn.matcher(json);
-        assertTrue(mtch.matches());
-    }
-
-    /**
-     * Tests case when leaflist element is refers to leaf.
-     */
-    @Ignore
-    @Test
-    public void leafrefFromLeafrefToLeafrefTest() {
-        String json = null;
-        try {
-            json = TestUtils.writeCompNodeWithSchemaContextToJson(
-                    TestUtils.loadCompositeNode("/cnsn-to-json/leafref/xml/data_from_leafref_to_leafref.xml"), modules,
-                    dataSchemaNode);
-        } catch (WebApplicationException | IOException e) {
-            // shouldn't end here
-            assertTrue(false);
-        }
-        assertNotNull(json);
-        java.util.regex.Pattern ptrn = java.util.regex.Pattern.compile(
-                ".*\"cont-augment-module\\p{Blank}*:\\p{Blank}*lf7\":\\p{Blank}*200.*", java.util.regex.Pattern.DOTALL);
-        Matcher mtch = ptrn.matcher(json);
-        assertTrue(mtch.matches());
-    }
-
-}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonWithAugmentTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonWithAugmentTest.java
deleted file mode 100644 (file)
index 73bd178..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
-
-import static org.junit.Assert.assertTrue;
-
-import org.junit.Test;
-import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-
-public class ToJsonWithAugmentTest {
-
-    /**
-     * Test of json output when as input are specified composite node with empty
-     * data + YANG file
-     */
-    @Test
-    public void augmentedElementsToJson() {
-
-        CompositeNode compositeNode = TestUtils.loadCompositeNode("/cnsn-to-json/augmentation/xml/data.xml");
-        String jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson(compositeNode,
-                "/cnsn-to-json/augmentation", "/cnsn-to-json/augmentation/xml", "yang", "cont");
-
-        assertTrue(jsonOutput.contains("\"augment-leaf:lf2\": \"lf2\""));
-        assertTrue(jsonOutput.contains("\"augment-container:cont1\": {"));
-        assertTrue(jsonOutput.contains("\"augment-container:lf11\": \"lf11\""));
-        assertTrue(jsonOutput.contains("\"augment-list:lst1\": ["));
-        assertTrue(jsonOutput.contains("\"augment-list:lf11\": \"lf1_1\""));
-        assertTrue(jsonOutput.contains("\"augment-list:lf11\": \"lf1_2\""));
-        assertTrue(jsonOutput.contains("\"augment-leaflist:lflst1\": ["));
-    }
-}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlNotExistingLeafTypeTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlNotExistingLeafTypeTest.java
new file mode 100644 (file)
index 0000000..d779b5c
--- /dev/null
@@ -0,0 +1,70 @@
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.xml.test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Set;
+
+import javax.ws.rs.WebApplicationException;
+
+import org.junit.Ignore;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
+import org.opendaylight.controller.sal.restconf.impl.test.DummyType;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.yangtools.yang.data.api.*;
+import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.impl.LeafSchemaNodeBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CnSnToXmlNotExistingLeafTypeTest {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CnSnToXmlNotExistingLeafTypeTest.class);
+
+    @Ignore
+    @Test
+    public void incorrectTopLevelElementTest() {
+
+        boolean nullPointerExceptionRaised = false;
+        try {
+            TestUtils.writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(),
+                    (Set<Module>) Collections.EMPTY_SET, prepareDataSchemaNode(), StructuredDataToXmlProvider.INSTANCE);
+        } catch (WebApplicationException | IOException e) {
+            LOG.error("WebApplicationException or IOException was raised");
+        } catch (NullPointerException e) {
+            nullPointerExceptionRaised = true;
+        }
+        assertTrue(nullPointerExceptionRaised);
+
+    }
+
+    private CompositeNode prepareCompositeNode() {
+        MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(
+                TestUtils.buildQName("cont", "simple:uri", "2012-12-17"), null, null, ModifyAction.CREATE, null);
+        MutableSimpleNode<?> lf1 = NodeFactory.createMutableSimpleNode(
+                TestUtils.buildQName("lf1", "simple:uri", "2012-12-17"), cont, "any value", ModifyAction.CREATE, null);
+        cont.getChildren().add(lf1);
+        cont.init();
+        return cont;
+    }
+
+    private DataSchemaNode prepareDataSchemaNode() {
+        ContainerSchemaNodeBuilder contBuild = new ContainerSchemaNodeBuilder("module", 1, TestUtils.buildQName("cont",
+                "simple:uri", "2012-12-17"), null);
+        LeafSchemaNodeBuilder leafBuild = new LeafSchemaNodeBuilder("module", 2, TestUtils.buildQName("lf1",
+                "simple:uri", "2012-12-17"), null);
+        leafBuild.setType(new DummyType());
+        leafBuild.setConfiguration(true);
+
+        contBuild.addChildNode(leafBuild);
+        return contBuild.build(null);
+
+    }
+
+}
index d04337865a9e549c71838dc749d073218a9130c9..96e03a5a3ca4b8b6b0d619232457a8669f3dae06 100644 (file)
@@ -1,24 +1,21 @@
 package org.opendaylight.controller.sal.restconf.impl.cnsn.to.xml.test;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
-import java.io.StringWriter;
-import java.util.Set;
+import java.io.IOException;
 
-import javax.activation.UnsupportedDataTypeException;
-import javax.xml.transform.*;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
+import javax.ws.rs.WebApplicationException;
+import javax.xml.transform.TransformerFactoryConfigurationError;
 
 import org.junit.BeforeClass;
 import org.junit.Test;
-import org.opendaylight.controller.sal.rest.impl.XmlMapper;
+import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
 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.*;
 import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
 import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
-import org.opendaylight.yangtools.yang.model.api.*;
-import org.w3c.dom.Document;
 
 /**
  * 
@@ -27,25 +24,31 @@ import org.w3c.dom.Document;
  * XML file
  * 
  */
-public class CnSnToXmlTest {
-
-    private static Set<Module> modules;
-    private static DataSchemaNode dataSchemaNode;
-
+public class CnSnToXmlTest extends YangAndXmlAndDataSchemaLoader {
     @BeforeClass
     public static void initialization() {
-        modules = TestUtils.resolveModules("/cnsn-to-xml/yang");
-        assertEquals(2, modules.size());
-        Module module = TestUtils.resolveModule("basic-module", modules);
-        assertNotNull(module);
-        dataSchemaNode = TestUtils.resolveDataSchemaNode(module, "cont");
-        assertNotNull(dataSchemaNode);
-
+        dataLoad("/cnsn-to-xml/yang", 2, "basic-module", "cont");
     }
 
     @Test
     public void snAsYangIdentityrefToXMLTest() {
-        serializeToXml(prepareIdentityrefData(), "<lf11 xmlns:x=\"referenced:module\">x:iden</lf11>");
+        serializeToXml(prepareIdentityrefData(null, true), "<lf11 xmlns:x=\"referenced:module\">x:iden</lf11>");
+    }
+
+    @Test
+    public void snAsYangIdentityrefWithQNamePrefixToXMLTest() {
+        serializeToXml(prepareIdentityrefData("prefix", true),
+                "<lf11 xmlns:prefix=\"referenced:module\">prefix:iden</lf11>");
+    }
+
+    @Test
+    public void snAsYangIdentityrefWithPrefixToXMLTest() {
+        serializeToXml(prepareIdentityrefData("prefix", false), "<lf11>no qname value</lf11>");
+    }
+
+    @Test
+    public void snAsYangLeafrefWithPrefixToXMLTest() {
+        serializeToXml(prepareLeafrefData(), "<lfBoolean>true</lfBoolean>", "<lfLfref>true</lfLfref>");
     }
 
     @Test
@@ -186,22 +189,13 @@ public class CnSnToXmlTest {
 
     private void serializeToXml(CompositeNode compositeNode, String... xmlRepresentation)
             throws TransformerFactoryConfigurationError {
-        XmlMapper xmlMapper = new XmlMapper();
-        String xmlString = null;
-        if (dataSchemaNode instanceof DataNodeContainer) {
-            try {
-                Document doc = xmlMapper.write(compositeNode, (DataNodeContainer) dataSchemaNode);
-                DOMSource domSource = new DOMSource(doc);
-                StringWriter writer = new StringWriter();
-                StreamResult result = new StreamResult(writer);
-                TransformerFactory tf = TransformerFactory.newInstance();
-                Transformer transformer = tf.newTransformer();
-                transformer.transform(domSource, result);
-                xmlString = writer.toString();
-            } catch (UnsupportedDataTypeException | TransformerException e) {
-            }
+        String xmlString = "";
+        try {
+            xmlString = TestUtils.writeCompNodeWithSchemaContextToOutput(compositeNode, modules, dataSchemaNode,
+                    StructuredDataToXmlProvider.INSTANCE);
+        } catch (WebApplicationException | IOException e) {
         }
-        assertNotNull(xmlMapper);
+        assertNotNull(xmlString);
         boolean containSearchedStr = false;
         String strRepresentation = "";
         for (String searchedStr : xmlRepresentation) {
@@ -215,16 +209,21 @@ public class CnSnToXmlTest {
 
     }
 
-    private CompositeNode prepareIdentityrefData() {
+    private CompositeNode prepareIdentityrefData(String prefix, boolean valueAsQName) {
         MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(
                 TestUtils.buildQName("cont", "basic:module", "2013-12-2"), null, null, ModifyAction.CREATE, null);
         MutableCompositeNode cont1 = NodeFactory.createMutableCompositeNode(
                 TestUtils.buildQName("cont1", "basic:module", "2013-12-2"), cont, null, ModifyAction.CREATE, null);
         cont.getChildren().add(cont1);
 
+        Object value = null;
+        if (valueAsQName) {
+            value = TestUtils.buildQName("iden", "referenced:module", "2013-12-2", prefix);
+        } else {
+            value = "no qname value";
+        }
         MutableSimpleNode<Object> lf11 = NodeFactory.createMutableSimpleNode(
-                TestUtils.buildQName("lf11", "basic:module", "2013-12-2"), cont1,
-                TestUtils.buildQName("iden", "referenced:module", "2013-12-2"), ModifyAction.CREATE, null);
+                TestUtils.buildQName("lf11", "basic:module", "2013-12-2"), cont1, value, ModifyAction.CREATE, null);
         cont1.getChildren().add(lf11);
         cont1.init();
         cont.init();
@@ -244,4 +243,19 @@ public class CnSnToXmlTest {
         return cont;
     }
 
+    private CompositeNode prepareLeafrefData() {
+        MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null,
+                ModifyAction.CREATE, null);
+
+        MutableSimpleNode<Object> lfBoolean = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfBoolean"),
+                cont, Boolean.TRUE, ModifyAction.CREATE, null);
+        MutableSimpleNode<Object> lfLfref = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfLfref"), cont,
+                "true", ModifyAction.CREATE, null);
+        cont.getChildren().add(lfBoolean);
+        cont.getChildren().add(lfLfref);
+        cont.init();
+
+        return cont;
+    }
+
 }
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithChoiceTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithChoiceTest.java
new file mode 100644 (file)
index 0000000..a23501c
--- /dev/null
@@ -0,0 +1,64 @@
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.xml.test;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+
+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.test.TestUtils;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.yangtools.yang.data.api.*;
+import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
+
+/**
+ * 
+ * CnSn = Composite node and Simple node data structure Class contains test of
+ * serializing simple nodes data values according data types from YANG schema to
+ * XML file
+ * 
+ */
+public class CnSnToXmlWithChoiceTest extends YangAndXmlAndDataSchemaLoader {
+    @BeforeClass
+    public static void initialization() {
+        dataLoad("/cnsn-to-xml/choice", 1, "module-with-choice", "cont");
+    }
+
+    @Test
+    public void cnSnToXmlWithYangChoice() {
+        String xmlOutput = "";
+        try {
+            xmlOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(
+                    prepareCnStructForYangData("lf1", "String data1"), modules, dataSchemaNode,
+                    StructuredDataToXmlProvider.INSTANCE);
+        } catch (WebApplicationException | IOException e) {
+        }
+
+        assertTrue(xmlOutput.contains("<lf1>String data1</lf1>"));
+
+        try {
+            xmlOutput = TestUtils.writeCompNodeWithSchemaContextToOutput(
+                    prepareCnStructForYangData("lf2", "String data2"), modules, dataSchemaNode,
+                    StructuredDataToXmlProvider.INSTANCE);
+        } catch (WebApplicationException | IOException e) {
+        }
+        assertTrue(xmlOutput.contains("<lf2>String data2</lf2>"));
+
+    }
+
+    private CompositeNode prepareCnStructForYangData(String lfName, Object data) {
+        MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null,
+                ModifyAction.CREATE, null);
+
+        MutableSimpleNode<Object> lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName(lfName), cont, data,
+                ModifyAction.CREATE, null);
+        cont.getChildren().add(lf1);
+        cont.init();
+
+        return cont;
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonIdentityrefToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonIdentityrefToCnSnTest.java
new file mode 100644 (file)
index 0000000..e9b1dbe
--- /dev/null
@@ -0,0 +1,74 @@
+package org.opendaylight.controller.sal.restconf.impl.json.to.cnsn.test;
+
+import static org.junit.Assert.*;
+
+import java.util.List;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.*;
+
+public class JsonIdentityrefToCnSnTest extends YangAndXmlAndDataSchemaLoader {
+
+    @BeforeClass
+    public static void initialize() {
+        dataLoad("/json-to-cnsn/identityref", 2, "identityref-module", "cont");
+    }
+
+    @Test
+    public void jsonIdentityrefToCompositeNode() {
+        CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/identityref/json/data.json", false,
+                JsonToCompositeNodeProvider.INSTANCE);
+        assertNotNull(compositeNode);
+
+        TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName);
+
+        assertEquals("cont", compositeNode.getNodeType().getLocalName());
+
+        List<Node<?>> childs = compositeNode.getChildren();
+        assertEquals(1, childs.size());
+        Node<?> nd = childs.iterator().next();
+        assertTrue(nd instanceof CompositeNode);
+        assertEquals("cont1", nd.getNodeType().getLocalName());
+
+        childs = ((CompositeNode) nd).getChildren();
+        assertEquals(4, childs.size());
+        SimpleNode<?> lf11 = null;
+        SimpleNode<?> lf12 = null;
+        SimpleNode<?> lf13 = null;
+        SimpleNode<?> lf14 = null;
+        for (Node<?> child : childs) {
+            assertTrue(child instanceof SimpleNode);
+            if (child.getNodeType().getLocalName().equals("lf11")) {
+                lf11 = (SimpleNode<?>) child;
+            } else if (child.getNodeType().getLocalName().equals("lf12")) {
+                lf12 = (SimpleNode<?>) child;
+            } else if (child.getNodeType().getLocalName().equals("lf13")) {
+                lf13 = (SimpleNode<?>) child;
+            } else if (child.getNodeType().getLocalName().equals("lf14")) {
+                lf14 = (SimpleNode<?>) child;
+            }
+        }
+
+        assertTrue(lf11.getValue() instanceof QName);
+        assertEquals("iden", ((QName) lf11.getValue()).getLocalName());
+        assertEquals("identity:module", ((QName) lf11.getValue()).getNamespace().toString());
+
+        assertTrue(lf12.getValue() instanceof QName);
+        assertEquals("iden_local", ((QName) lf12.getValue()).getLocalName());
+        assertEquals("identityref:module", ((QName) lf12.getValue()).getNamespace().toString());
+
+        assertTrue(lf13.getValue() instanceof QName);
+        assertEquals("iden_local", ((QName) lf13.getValue()).getLocalName());
+        assertEquals("identityref:module", ((QName) lf13.getValue()).getNamespace().toString());
+
+        assertTrue(lf14.getValue() instanceof QName);
+        assertEquals("iden_local", ((QName) lf14.getValue()).getLocalName());
+        assertEquals("identity:module", ((QName) lf14.getValue()).getNamespace().toString());
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonLeafrefToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonLeafrefToCnSnTest.java
new file mode 100644 (file)
index 0000000..2bb42d9
--- /dev/null
@@ -0,0 +1,48 @@
+package org.opendaylight.controller.sal.restconf.impl.json.to.cnsn.test;
+
+import static org.junit.Assert.*;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
+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.*;
+
+public class JsonLeafrefToCnSnTest extends YangAndXmlAndDataSchemaLoader {
+
+    @BeforeClass
+    public static void initialize() {
+        dataLoad("/json-to-cnsn/leafref");
+    }
+
+    /**
+     * JSON values which represents leafref are always loaded to simple node as
+     * string
+     */
+    @Test
+    public void jsonIdentityrefToCompositeNode() {
+        CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/leafref/json/data.json", false,
+                JsonToCompositeNodeProvider.INSTANCE);
+        assertNotNull(compositeNode);
+        TestUtils.normalizeCompositeNode(compositeNode, modules, searchedModuleName + ":" + searchedDataSchemaName);
+
+        assertEquals("cont", compositeNode.getNodeType().getLocalName());
+
+        SimpleNode<?> lf2 = null;
+        for (Node<?> childNode : compositeNode.getChildren()) {
+            if (childNode instanceof SimpleNode) {
+                if (childNode.getNodeType().getLocalName().equals("lf2")) {
+                    lf2 = (SimpleNode<?>) childNode;
+                    break;
+                }
+            }
+        }
+
+        assertNotNull(lf2);
+        assertTrue(lf2.getValue() instanceof String);
+        assertEquals("121", (String) lf2.getValue());
+
+    }
+
+}
index b02ea9a3a28fe439efc1d04341449bf28bd5e28f..f2c0c29bc4372b6b54eeec0dc3bf9d9805f36663 100644 (file)
@@ -1,9 +1,10 @@
 package org.opendaylight.controller.sal.restconf.impl.json.to.cnsn.test;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
-import java.io.*;
-import java.net.URISyntaxException;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
@@ -12,10 +13,12 @@ import javax.ws.rs.WebApplicationException;
 import org.junit.Test;
 import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
 import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.ResponseException;
 import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.*;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.api.SimpleNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -28,7 +31,7 @@ public class JsonToCnSnTest {
 
     @Test
     public void simpleListTest() {
-        simpleTest("/json-to-cnsn/simple-list.json", "/json-to-cnsn/simple-list-yang", "lst", "simple:list:yang1",
+        simpleTest("/json-to-cnsn/simple-list.json", "/json-to-cnsn/simple-list-yang/1", "lst", "simple:list:yang1",
                 "simple-list-yang1");
     }
 
@@ -43,7 +46,8 @@ public class JsonToCnSnTest {
      */
     @Test
     public void multipleItemsInLeafList() {
-        CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/multiple-leaflist-items.json", true);
+        CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/multiple-leaflist-items.json", true,
+                JsonToCompositeNodeProvider.INSTANCE);
         assertNotNull(compositeNode);
         assertEquals(3, compositeNode.getChildren().size());
 
@@ -76,9 +80,10 @@ public class JsonToCnSnTest {
      */
     @Test
     public void multipleItemsInListTest() {
-        CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/multiple-items-in-list.json", true);
-        assertNotNull(compositeNode);
+        CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/multiple-items-in-list.json", true,
+                JsonToCompositeNodeProvider.INSTANCE);
 
+        assertNotNull(compositeNode);
         assertEquals("lst", compositeNode.getNodeType().getLocalName());
 
         verityMultipleItemsInList(compositeNode);
@@ -86,7 +91,8 @@ public class JsonToCnSnTest {
 
     @Test
     public void nullArrayToSimpleNodeWithNullValueTest() {
-        CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/array-with-null.json", true);
+        CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/array-with-null.json", true,
+                JsonToCompositeNodeProvider.INSTANCE);
         assertNotNull(compositeNode);
         assertEquals("cont", compositeNode.getNodeType().getLocalName());
 
@@ -103,7 +109,8 @@ public class JsonToCnSnTest {
     public void incorrectTopLevelElementsTest() {
         Throwable cause1 = null;
         try {
-            compositeContainerFromJson("/json-to-cnsn/wrong-top-level1.json", true);
+            TestUtils
+                    .readInputToCnSn("/json-to-cnsn/wrong-top-level1.json", true, JsonToCompositeNodeProvider.INSTANCE);
         } catch (WebApplicationException e) {
             cause1 = e;
         }
@@ -117,7 +124,8 @@ public class JsonToCnSnTest {
 
         Throwable cause2 = null;
         try {
-            compositeContainerFromJson("/json-to-cnsn/wrong-top-level2.json", true);
+            TestUtils
+                    .readInputToCnSn("/json-to-cnsn/wrong-top-level2.json", true, JsonToCompositeNodeProvider.INSTANCE);
         } catch (WebApplicationException e) {
             cause2 = e;
         }
@@ -126,7 +134,8 @@ public class JsonToCnSnTest {
 
         Throwable cause3 = null;
         try {
-            compositeContainerFromJson("/json-to-cnsn/wrong-top-level3.json", true);
+            TestUtils
+                    .readInputToCnSn("/json-to-cnsn/wrong-top-level3.json", true, JsonToCompositeNodeProvider.INSTANCE);
         } catch (WebApplicationException e) {
             cause3 = e;
         }
@@ -145,7 +154,8 @@ public class JsonToCnSnTest {
      */
     @Test
     public void emptyDataReadTest() {
-        CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/empty-data.json", true);
+        CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/empty-data.json", true,
+                JsonToCompositeNodeProvider.INSTANCE);
 
         assertNotNull(compositeNode);
 
@@ -158,7 +168,7 @@ public class JsonToCnSnTest {
 
         String reason = null;
         try {
-            compositeContainerFromJson("/json-to-cnsn/empty-data1.json", true);
+            TestUtils.readInputToCnSn("/json-to-cnsn/empty-data1.json", true, JsonToCompositeNodeProvider.INSTANCE);
         } catch (JsonSyntaxException e) {
             reason = e.getMessage();
         }
@@ -176,24 +186,20 @@ public class JsonToCnSnTest {
     @Test
     public void notSupplyNamespaceIfAlreadySupplied() {
 
-        CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/simple-list.json");
+        CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/simple-list.json", false,
+                JsonToCompositeNodeProvider.INSTANCE);
         assertNotNull(compositeNode);
 
-        DataSchemaNode dataSchemaNode1 = null;
-        DataSchemaNode dataSchemaNode2 = null;
-        try {
-            dataSchemaNode1 = TestUtils.obtainSchemaFromYang("/json-to-cnsn/simple-list-yang", "simple-list-yang1");
-            dataSchemaNode2 = TestUtils.obtainSchemaFromYang("/json-to-cnsn/simple-list-yang", "simple-list-yang2");
-        } catch (FileNotFoundException e) {
-            LOG.error(e.getMessage());
-            assertTrue(false);
-        }
-        assertNotNull(dataSchemaNode1);
-        assertNotNull(dataSchemaNode2);
-
         // supplement namespaces according to first data schema -
         // "simple:data:types1"
-        TestUtils.supplementNamespace(dataSchemaNode1, compositeNode);
+        Set<Module> modules1 = new HashSet<>();
+        Set<Module> modules2 = new HashSet<>();
+        modules1 = TestUtils.loadModulesFrom("/json-to-cnsn/simple-list-yang/1");
+        modules2 = TestUtils.loadModulesFrom("/json-to-cnsn/simple-list-yang/2");
+        assertNotNull(modules1);
+        assertNotNull(modules2);
+
+        TestUtils.normalizeCompositeNode(compositeNode, modules1, "simple-list-yang1:lst");
 
         assertTrue(compositeNode instanceof CompositeNodeWrapper);
         CompositeNode compNode = ((CompositeNodeWrapper) compositeNode).unwrap();
@@ -201,26 +207,27 @@ public class JsonToCnSnTest {
         assertEquals("lst", compNode.getNodeType().getLocalName());
         verifyCompositeNode(compNode, "simple:list:yang1");
 
-        // dataSchemaNode2 should't be taken into account, because compNode
-        // isn't CompositeNodeWrapper
-        TestUtils.supplementNamespace(dataSchemaNode2, compNode);
-        verifyCompositeNode(compNode, "simple:list:yang1");
+        String exceptionMessage = "";
+        try {
+            TestUtils.normalizeCompositeNode(compositeNode, modules2, "simple-list-yang2:lst");
+        } catch (ResponseException e) {
+            exceptionMessage = String.valueOf(e.getResponse().getEntity());
+        }
+        assertTrue(exceptionMessage
+                .contains("Data has bad format\nIf data is in XML format then namespace for lst should be simple:list:yang2.\n If data is in Json format then module name for lst should be simple-list-yang2."));
 
     }
 
     @Test
     public void jsonIdentityrefToCompositeNode() {
-        CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/identityref/json/data.json");
+        CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/identityref/json/data.json", false,
+                JsonToCompositeNodeProvider.INSTANCE);
         assertNotNull(compositeNode);
 
-        Set<Module> modules = TestUtils.resolveModules("/json-to-cnsn/identityref");
+        Set<Module> modules = TestUtils.loadModulesFrom("/json-to-cnsn/identityref");
         assertEquals(2, modules.size());
-        Module module = TestUtils.resolveModule("identityref-module", modules);
-        assertNotNull(module);
-        DataSchemaNode dataSchemaNode = TestUtils.resolveDataSchemaNode(module, null);
-        assertNotNull(dataSchemaNode);
 
-        TestUtils.normalizeCompositeNode(compositeNode, modules, dataSchemaNode, "identityref-module:cont");
+        TestUtils.normalizeCompositeNode(compositeNode, modules, "identityref-module:cont");
 
         assertEquals("cont", compositeNode.getNodeType().getLocalName());
 
@@ -268,19 +275,14 @@ public class JsonToCnSnTest {
 
     private void simpleTest(String jsonPath, String yangPath, String topLevelElementName, String namespace,
             String moduleName) {
-        CompositeNode compositeNode = compositeContainerFromJson(jsonPath);
+        CompositeNode compositeNode = TestUtils.readInputToCnSn(jsonPath, false, JsonToCompositeNodeProvider.INSTANCE);
         assertNotNull(compositeNode);
 
-        DataSchemaNode dataSchemaNode = null;
-        try {
-            dataSchemaNode = TestUtils.obtainSchemaFromYang(yangPath, moduleName);
-        } catch (FileNotFoundException e) {
-            LOG.error(e.getMessage());
-            assertTrue(false);
-        }
-        assertNotNull(dataSchemaNode);
+        Set<Module> modules = null;
+        modules = TestUtils.loadModulesFrom(yangPath);
+        assertNotNull(modules);
 
-        TestUtils.supplementNamespace(dataSchemaNode, compositeNode);
+        TestUtils.normalizeCompositeNode(compositeNode, modules, moduleName + ":" + topLevelElementName);
 
         assertTrue(compositeNode instanceof CompositeNodeWrapper);
         CompositeNode compNode = ((CompositeNodeWrapper) compositeNode).unwrap();
@@ -331,7 +333,8 @@ public class JsonToCnSnTest {
         boolean lflst1_2Found = false;
         boolean lf1Found = false;
 
-        assertEquals(namespace, compositeNode.getNodeType().getNamespace().toString());
+        // assertEquals(namespace,
+        // compositeNode.getNodeType().getNamespace().toString());
 
         for (Node<?> node : compositeNode.getChildren()) {
             if (node.getNodeType().getLocalName().equals("cont1")) {
@@ -369,34 +372,16 @@ public class JsonToCnSnTest {
         assertTrue(lf1Found);
     }
 
-    private CompositeNode compositeContainerFromJson(String jsonPath) {
-        return compositeContainerFromJson(jsonPath, false);
-    }
-
-    private CompositeNode compositeContainerFromJson(String jsonPath, boolean dummyNamespaces)
-            throws WebApplicationException {
-
-        JsonToCompositeNodeProvider jsonToCompositeNodeProvider = JsonToCompositeNodeProvider.INSTANCE;
-        InputStream jsonStream = JsonToCnSnTest.class.getResourceAsStream(jsonPath);
+    @Test
+    public void unsupportedDataFormatTest() {
+        String exceptionMessage = "";
         try {
-            CompositeNode compositeNode = jsonToCompositeNodeProvider
-                    .readFrom(null, null, null, null, null, jsonStream);
-            assertTrue(compositeNode instanceof CompositeNodeWrapper);
-            if (dummyNamespaces) {
-                try {
-                    TestUtils.addDummyNamespaceToAllNodes((CompositeNodeWrapper) compositeNode);
-                    return ((CompositeNodeWrapper) compositeNode).unwrap();
-                } catch (URISyntaxException e) {
-                    LOG.error(e.getMessage());
-                    assertTrue(e.getMessage(), false);
-                }
-            }
-            return compositeNode;
-        } catch (IOException e) {
-            LOG.error(e.getMessage());
-            assertTrue(e.getMessage(), false);
+            TestUtils.readInputToCnSn("/json-to-cnsn/unsupported-json-format.json", true,
+                    JsonToCompositeNodeProvider.INSTANCE);
+        } catch (WebApplicationException e) {
+            exceptionMessage = e.getCause().getMessage();
         }
-        return null;
+        assertTrue(exceptionMessage.contains("Root element of Json has to be Object"));
     }
 
 }
index 39c0d3b34f67159e7de8a1c1fc4a73809ae648b8..c68fcb90714567849192db25d9dc676e43f700a9 100644 (file)
@@ -1,12 +1,20 @@
 package org.opendaylight.controller.sal.restconf.impl.test;
 
-import static org.junit.Assert.*;
+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.BeforeClass;
 import org.junit.Test;
+import org.opendaylight.controller.sal.core.api.mount.MountInstance;
+import org.opendaylight.controller.sal.core.api.mount.MountService;
 import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
 import org.opendaylight.controller.sal.restconf.impl.InstanceIdWithSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
@@ -19,14 +27,16 @@ public class ControllerContextTest {
 
     @BeforeClass
     public static void init() throws FileNotFoundException {
-        Set<Module> allModules = TestUtils.loadModules(ControllerContextTest.class.getResource("/full-versions/yangs").getPath());
+        Set<Module> allModules = TestUtils.loadModulesFrom("/full-versions/yangs");
+        assertNotNull(allModules);
         SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules);
         controllerContext.setSchemas(schemaContext);
     }
 
     @Test
     public void testToInstanceIdentifierList() throws FileNotFoundException {
-        InstanceIdWithSchemaNode instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:userWithoutClass/foo");
+        InstanceIdWithSchemaNode instanceIdentifier = controllerContext
+                .toInstanceIdentifier("simple-nodes:userWithoutClass/foo");
         assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "userWithoutClass");
 
         instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:userWithoutClass/foo/full-name");
@@ -49,28 +59,63 @@ public class ControllerContextTest {
 
     }
 
+    @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);
+        }
+
+    }
+
     @Test
     public void testToInstanceIdentifierContainer() throws FileNotFoundException {
         InstanceIdWithSchemaNode instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:users");
         assertEquals(instanceIdentifier.getSchemaNode().getQName().getLocalName(), "users");
         assertTrue(instanceIdentifier.getSchemaNode() instanceof ContainerSchemaNode);
-        assertEquals(2, ((ContainerSchemaNode)instanceIdentifier.getSchemaNode()).getChildNodes().size());
+        assertEquals(2, ((ContainerSchemaNode) instanceIdentifier.getSchemaNode()).getChildNodes().size());
     }
 
     @Test
     public void testToInstanceIdentifierChoice() throws FileNotFoundException {
         InstanceIdWithSchemaNode instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:food/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);
-        
+
         instanceIdentifier = controllerContext.toInstanceIdentifier("simple-nodes:food/snack/sports-arena");
         assertNull(instanceIdentifier);
-        
+
     }
 
 }
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/DummyType.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/DummyType.java
new file mode 100644 (file)
index 0000000..0876584
--- /dev/null
@@ -0,0 +1,64 @@
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import java.util.List;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.*;
+
+public class DummyType implements TypeDefinition<DummyType> {
+    QName dummyQName = TestUtils.buildQName("dummy type", "simple:uri", "2012-12-17");
+
+    @Override
+    public QName getQName() {
+        return dummyQName;
+    }
+
+    @Override
+    public SchemaPath getPath() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getDescription() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getReference() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Status getStatus() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public List<UnknownSchemaNode> getUnknownSchemaNodes() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public DummyType getBaseType() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getUnits() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Object getDefaultValue() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+}
index d58b7e9dab0cecac48f4d5641dd2b6ff9bc8ba3a..2370035861759584655b0f104516c231f3a6419c 100644 (file)
@@ -7,15 +7,25 @@ import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-import java.net.*;
-import java.util.*;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Set;
 
-import org.junit.*;
+import org.junit.BeforeClass;
+import org.junit.Test;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
-import org.opendaylight.controller.sal.restconf.impl.*;
-import org.opendaylight.yangtools.yang.common.*;
-import org.opendaylight.yangtools.yang.data.api.*;
+import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
+import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
+import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
+import org.opendaylight.controller.sal.restconf.impl.StructuredData;
+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.ModifyAction;
+import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
 import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
 import org.opendaylight.yangtools.yang.model.api.Module;
 
@@ -33,7 +43,7 @@ public class InvokeRpcMethodTest {
 
     @BeforeClass
     public static void initialization() {
-        modules = TestUtils.resolveModules("/invoke-rpc");
+        modules = TestUtils.loadModulesFrom("/invoke-rpc");
         assertEquals(1, modules.size());
         Module module = TestUtils.resolveModule("invoke-rpc-module", modules);
         assertNotNull(module);
index cac77eb368d1423fa91c33a304e0695d208c4e2a..f2eea9dbd24214d3b7a776a62680e64d8c7797e7 100644 (file)
@@ -1,6 +1,7 @@
 package org.opendaylight.controller.sal.restconf.impl.test;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -45,8 +46,8 @@ public class ReadConfAndOperDataTest extends JerseyTest {
 
     @BeforeClass
     public static void init() throws FileNotFoundException {
-        Set<Module> allModules = TestUtils.loadModules(RestconfImplTest.class.getResource("/full-versions/yangs")
-                .getPath());
+        Set<Module> allModules = TestUtils.loadModulesFrom("/full-versions/yangs");
+        assertNotNull(allModules);
         SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules);
         controllerContext = ControllerContext.getInstance();
         controllerContext.setSchemas(schemaContext);
@@ -69,15 +70,16 @@ public class ReadConfAndOperDataTest extends JerseyTest {
 
         String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/eth0");
 
-        CompositeNode loadedCompositeNode = TestUtils.loadCompositeNodeWithXmlTreeBuilder("/parts/ietf-interfaces_interfaces.xml");
+        CompositeNode loadedCompositeNode = TestUtils.readInputToCnSn("/parts/ietf-interfaces_interfaces.xml", true,
+                XmlToCompositeNodeProvider.INSTANCE);
         when(brokerFacade.readConfigurationData(any(InstanceIdentifier.class))).thenReturn(loadedCompositeNode);
 
         Response response = target(uri).request(MEDIA_TYPE_DRAFT02).get();
         assertEquals(200, response.getStatus());
-        
+
         uri = createUri("/config/", "ietf-interfaces:interfaces/interface/example");
         when(brokerFacade.readConfigurationData(any(InstanceIdentifier.class))).thenReturn(null);
-        
+
         response = target(uri).request(MEDIA_TYPE_DRAFT02).get();
         assertEquals(404, response.getStatus());
     }
@@ -86,15 +88,17 @@ public class ReadConfAndOperDataTest extends JerseyTest {
     public void testReadOperationalData() throws UnsupportedEncodingException, FileNotFoundException {
         String uri = createUri("/operational/", "ietf-interfaces:interfaces/interface/eth0");
 
-        CompositeNode loadedCompositeNode = TestUtils.loadCompositeNodeWithXmlTreeBuilder("/parts/ietf-interfaces_interfaces.xml");
+        CompositeNode loadedCompositeNode = TestUtils.readInputToCnSn("/parts/ietf-interfaces_interfaces.xml", true,
+                XmlToCompositeNodeProvider.INSTANCE);
+
         when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(loadedCompositeNode);
 
         Response response = target(uri).request(MEDIA_TYPE_DRAFT02).get();
         assertEquals(200, response.getStatus());
-        
+
         uri = createUri("/config/", "ietf-interfaces:interfaces/interface/example");
         when(brokerFacade.readConfigurationData(any(InstanceIdentifier.class))).thenReturn(null);
-        
+
         response = target(uri).request(MEDIA_TYPE_DRAFT02).get();
         assertEquals(404, response.getStatus());
     }
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestCodecExceptionsTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestCodecExceptionsTest.java
new file mode 100644 (file)
index 0000000..fcc4c02
--- /dev/null
@@ -0,0 +1,33 @@
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+
+import org.junit.Test;
+import org.opendaylight.controller.sal.restconf.impl.RestCodec;
+import org.opendaylight.yangtools.concepts.Codec;
+import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.BitsType;
+
+public class RestCodecExceptionsTest {
+
+    @Test
+    public void serializeExceptionTest() {
+        Codec<Object, Object> codec = RestCodec.from(new BitsType(null));
+        String serializedValue = (String) codec.serialize("incorrect value"); // set
+                                                                              // expected
+        assertEquals("incorrect value", serializedValue);
+    }
+
+    @Test
+    public void deserializeExceptionTest() {
+        IdentityrefTypeDefinition mockedIidentityrefType = mock(IdentityrefTypeDefinition.class);
+
+        Codec<Object, Object> codec = RestCodec.from(mockedIidentityrefType);
+        String serializedValue = (String) codec.deserialize("incorrect value"); // IdentityValuesDTO
+                                                                                // object
+        // expected
+        assertEquals("incorrect value", serializedValue);
+    }
+
+}
index 41cc0ddb5130f0fc49e4b76f51e9d423f25fd47a..c15cd530823fd06a49321946c1fe8e33bdaf4e9a 100644 (file)
@@ -1,17 +1,20 @@
 package org.opendaylight.controller.sal.restconf.impl.test;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import java.io.FileNotFoundException;
-import java.io.InputStream;
 import java.util.Set;
 
 import org.junit.BeforeClass;
 import org.junit.Test;
-import org.opendaylight.controller.sal.restconf.impl.*;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
+import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
+import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
+import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.model.api.Module;
@@ -23,8 +26,8 @@ public class RestconfImplTest {
 
     @BeforeClass
     public static void init() throws FileNotFoundException {
-        Set<Module> allModules = TestUtils.loadModules(RestconfImplTest.class.getResource("/full-versions/yangs")
-                .getPath());
+        Set<Module> allModules = TestUtils.loadModulesFrom("/full-versions/yangs");
+        assertNotNull(allModules);
         SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules);
         ControllerContext controllerContext = ControllerContext.getInstance();
         controllerContext.setSchemas(schemaContext);
@@ -33,8 +36,7 @@ public class RestconfImplTest {
 
     @Test
     public void testExample() throws FileNotFoundException {
-        InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
-        CompositeNode loadedCompositeNode = TestUtils.loadCompositeNodeWithXmlTreeBuilder(xmlStream);
+        CompositeNode loadedCompositeNode = TestUtils.readInputToCnSn("/parts/ietf-interfaces_interfaces.xml", XmlToCompositeNodeProvider.INSTANCE);
         BrokerFacade brokerFacade = mock(BrokerFacade.class);
         when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(loadedCompositeNode);
         assertEquals(loadedCompositeNode, brokerFacade.readOperationalData(null));
index 366d99dbcb88a3dcb18f55c826b0b1c2dcc09b93..4295c29a22cea2f538d0006d94c70957163fabf9 100644 (file)
@@ -1,32 +1,50 @@
 package org.opendaylight.controller.sal.restconf.impl.test;
 
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-import java.io.*;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.sql.Date;
-import java.util.*;
-import java.util.concurrent.Future;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
 
 import javax.ws.rs.WebApplicationException;
-import javax.xml.parsers.*;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.transform.*;
+import javax.ws.rs.ext.MessageBodyReader;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
 
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.sal.rest.impl.*;
-import org.opendaylight.controller.sal.restconf.impl.*;
+import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
+import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
+import org.opendaylight.controller.sal.restconf.impl.NodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
+import org.opendaylight.controller.sal.restconf.impl.StructuredData;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.*;
-import org.opendaylight.yangtools.yang.data.impl.XmlTreeBuilder;
-import org.opendaylight.yangtools.yang.model.api.*;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser;
 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
 import org.slf4j.Logger;
@@ -38,11 +56,11 @@ import com.google.common.base.Preconditions;
 
 public final class TestUtils {
 
-    private static final Logger logger = LoggerFactory.getLogger(TestUtils.class);
+    private static final Logger LOG = LoggerFactory.getLogger(TestUtils.class);
 
     private final static YangModelParser parser = new YangParserImpl();
 
-    public static Set<Module> loadModules(String resourceDirectory) throws FileNotFoundException {
+    private static Set<Module> loadModules(String resourceDirectory) throws FileNotFoundException {
         final File testDir = new File(resourceDirectory);
         final String[] fileList = testDir.list();
         final List<File> testFiles = new ArrayList<File>();
@@ -58,34 +76,40 @@ public final class TestUtils {
         return parser.parseYangModels(testFiles);
     }
 
+    public static Set<Module> loadModulesFrom(String yangPath) {
+        try {
+            return TestUtils.loadModules(TestUtils.class.getResource(yangPath).getPath());
+        } catch (FileNotFoundException e) {
+            LOG.error("Yang files at path: " + yangPath + " weren't loaded.");
+        }
+
+        return null;
+    }
+
     public static SchemaContext loadSchemaContext(Set<Module> modules) {
         return parser.resolveSchemaContext(modules);
     }
 
     public static SchemaContext loadSchemaContext(String resourceDirectory) throws FileNotFoundException {
-        return parser.resolveSchemaContext(loadModules(resourceDirectory));
+        return parser.resolveSchemaContext(loadModulesFrom(resourceDirectory));
     }
 
     public static Module findModule(Set<Module> modules, String moduleName) {
-        Module result = null;
         for (Module module : modules) {
             if (module.getName().equals(moduleName)) {
-                result = module;
-                break;
+                return module;
             }
         }
-        return result;
+        return null;
     }
 
-
-
     public static Document loadDocumentFrom(InputStream inputStream) {
         try {
             DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
             DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
             return docBuilder.parse(inputStream);
         } catch (SAXException | IOException | ParserConfigurationException e) {
-            logger.error("Error during loading Document from XML", e);
+            LOG.error("Error during loading Document from XML", e);
             return null;
         }
     }
@@ -107,288 +131,84 @@ public final class TestUtils {
             return new String(charData, "UTF-8");
         } catch (IOException | TransformerException e) {
             String msg = "Error during transformation of Document into String";
-            logger.error(msg, e);
+            LOG.error(msg, e);
             return msg;
         }
 
     }
 
-    public static String convertCompositeNodeDataAndYangToJson(CompositeNode compositeNode, String yangPath,
-            String outputPath, String searchedModuleName, String searchedDataSchemaName) {
-        Set<Module> modules = resolveModules(yangPath);
-        Module module = resolveModule(searchedModuleName, modules);
-        DataSchemaNode dataSchemaNode = resolveDataSchemaNode(module, searchedDataSchemaName);
-
-        normalizeCompositeNode(compositeNode, modules, dataSchemaNode, searchedModuleName + ":"
-                + searchedDataSchemaName);
-
-        try {
-            return writeCompNodeWithSchemaContextToJson(compositeNode, modules, dataSchemaNode);
-        } catch (WebApplicationException | IOException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
-        return null;
-
-    }
-
-    public static void normalizeCompositeNode(CompositeNode compositeNode, Set<Module> modules,
-            DataSchemaNode dataSchemaNode, String schemaNodePath) {
+    /**
+     * 
+     * Fill missing data (namespaces) and build correct data type in
+     * {@code compositeNode} according to {@code dataSchemaNode}. The method
+     * {@link RestconfImpl#createConfigurationData createConfigurationData} is
+     * used because it contains calling of method {code normalizeNode}
+     */
+    public static void normalizeCompositeNode(CompositeNode compositeNode, Set<Module> modules, String schemaNodePath) {
         RestconfImpl restconf = RestconfImpl.getInstance();
         ControllerContext.getInstance().setSchemas(TestUtils.loadSchemaContext(modules));
 
-        TestUtils.prepareMockForRestconfBeforeNormalization(modules, dataSchemaNode, restconf);
+        prepareMocksForRestconf(modules, restconf);
         restconf.createConfigurationData(schemaNodePath, compositeNode);
     }
 
+    /**
+     * Searches module with name {@code searchedModuleName} in {@code modules}.
+     * If module name isn't specified and module set has only one element then
+     * this element is returned.
+     * 
+     */
     public static Module resolveModule(String searchedModuleName, Set<Module> modules) {
-        assertNotNull("modules can't be null.", modules);
-        Module module = null;
+        assertNotNull("Modules can't be null.", modules);
         if (searchedModuleName != null) {
             for (Module m : modules) {
                 if (m.getName().equals(searchedModuleName)) {
-                    module = m;
-                    break;
+                    return m;
                 }
             }
         } else if (modules.size() == 1) {
-            module = modules.iterator().next();
+            return modules.iterator().next();
         }
-        return module;
-    }
-
-    public static Set<Module> resolveModules(String yangPath) {
-        Set<Module> modules = null;
-
-        try {
-            modules = TestUtils.loadModules(TestUtils.class.getResource(yangPath).getPath());
-        } catch (FileNotFoundException e) {
-            e.printStackTrace();
-        }
-
-        return modules;
+        return null;
     }
 
-    public static DataSchemaNode resolveDataSchemaNode(Module module, String searchedDataSchemaName) {
-        assertNotNull("Module is missing", module);
+    public static DataSchemaNode resolveDataSchemaNode(String searchedDataSchemaName, Module module) {
+        assertNotNull("Module can't be null", module);
 
-        DataSchemaNode dataSchemaNode = null;
         if (searchedDataSchemaName != null) {
             for (DataSchemaNode dsn : module.getChildNodes()) {
                 if (dsn.getQName().getLocalName().equals(searchedDataSchemaName)) {
-                    dataSchemaNode = dsn;
+                    return dsn;
                 }
             }
         } else if (module.getChildNodes().size() == 1) {
-            dataSchemaNode = module.getChildNodes().iterator().next();
+            return module.getChildNodes().iterator().next();
         }
-        return dataSchemaNode;
-    }
-
-    public static String writeCompNodeWithSchemaContextToJson(CompositeNode compositeNode, Set<Module> modules,
-            DataSchemaNode dataSchemaNode) throws IOException, WebApplicationException {
-        String jsonResult;
-
-        assertNotNull(dataSchemaNode);
-        assertNotNull("Composite node can't be null", compositeNode);
-        ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
-
-        ControllerContext.getInstance().setSchemas(loadSchemaContext(modules));
-
-        StructuredDataToJsonProvider structuredDataToJsonProvider = StructuredDataToJsonProvider.INSTANCE;
-        structuredDataToJsonProvider.writeTo(new StructuredData(compositeNode, dataSchemaNode), null, null, null, null,
-                null, byteArrayOS);
-
-        jsonResult = byteArrayOS.toString();
-
-        return jsonResult;
-    }
-
-    public static CompositeNode loadCompositeNode(String xmlDataPath) {
-        InputStream xmlStream = TestUtils.class.getResourceAsStream(xmlDataPath);
-        CompositeNode compositeNode = null;
-        try {
-            XmlReader xmlReader = new XmlReader();
-            compositeNode = xmlReader.read(xmlStream);
-
-        } catch (UnsupportedFormatException | XMLStreamException e) {
-            e.printStackTrace();
-        }
-        return compositeNode;
-    }
-
-    static void outputToFile(ByteArrayOutputStream outputStream, String outputDir) throws IOException {
-        FileOutputStream fileOS = null;
-        try {
-            String path = TestUtils.class.getResource(outputDir).getPath();
-            File outFile = new File(path + "/data.json");
-            fileOS = new FileOutputStream(outFile);
-            try {
-                fileOS.write(outputStream.toByteArray());
-            } catch (IOException e) {
-                e.printStackTrace();
-            }
-            fileOS.close();
-        } catch (FileNotFoundException e1) {
-            e1.printStackTrace();
-        }
-    }
-
-    static String readJsonFromFile(String path, boolean removeWhiteChars) {
-        FileReader fileReader = getFileReader(path);
-
-        StringBuilder strBuilder = new StringBuilder();
-        char[] buffer = new char[1000];
-
-        while (true) {
-            int loadedCharNum;
-            try {
-                loadedCharNum = fileReader.read(buffer);
-            } catch (IOException e) {
-                break;
-            }
-            if (loadedCharNum == -1) {
-                break;
-            }
-            strBuilder.append(buffer, 0, loadedCharNum);
-        }
-        try {
-            fileReader.close();
-        } catch (IOException e) {
-            System.out.println("The file wasn't closed");
-        }
-        String rawStr = strBuilder.toString();
-        if (removeWhiteChars) {
-            rawStr = rawStr.replace("\n", "");
-            rawStr = rawStr.replace("\r", "");
-            rawStr = rawStr.replace("\t", "");
-            rawStr = removeSpaces(rawStr);
-        }
-
-        return rawStr;
-    }
-
-    private static FileReader getFileReader(String path) {
-        String fullPath = TestUtils.class.getResource(path).getPath();
-        assertNotNull("Path to file can't be null.", fullPath);
-        File file = new File(fullPath);
-        assertNotNull("File can't be null", file);
-        FileReader fileReader = null;
-        try {
-            fileReader = new FileReader(file);
-        } catch (FileNotFoundException e) {
-            e.printStackTrace();
-        }
-        assertNotNull("File reader can't be null.", fileReader);
-        return fileReader;
-    }
-
-    private static String removeSpaces(String rawStr) {
-        StringBuilder strBuilder = new StringBuilder();
-        int i = 0;
-        int quoteCount = 0;
-        while (i < rawStr.length()) {
-            if (rawStr.substring(i, i + 1).equals("\"")) {
-                quoteCount++;
-            }
-
-            if (!rawStr.substring(i, i + 1).equals(" ") || (quoteCount % 2 == 1)) {
-                strBuilder.append(rawStr.charAt(i));
-            }
-            i++;
-        }
-
-        return strBuilder.toString();
+        return null;
     }
 
-    public static QName buildQName(String name, String uri, String date) {
+    public static QName buildQName(String name, String uri, String date, String prefix) {
         try {
             URI u = new URI(uri);
             Date dt = null;
             if (date != null) {
                 dt = Date.valueOf(date);
             }
-            return new QName(u, dt, name);
+            return new QName(u, dt, prefix, name);
         } catch (URISyntaxException e) {
             return null;
         }
     }
 
-    public static QName buildQName(String name) {
-        return buildQName(name, "", null);
-    }
-
-    public static void supplementNamespace(DataSchemaNode dataSchemaNode, CompositeNode compositeNode) {
-        RestconfImpl restconf = RestconfImpl.getInstance();
-
-        InstanceIdWithSchemaNode instIdAndSchema = new InstanceIdWithSchemaNode(mock(InstanceIdentifier.class),
-                dataSchemaNode);
-
-        ControllerContext controllerContext = mock(ControllerContext.class);
-        BrokerFacade broker = mock(BrokerFacade.class);
-
-        RpcResult<TransactionStatus> rpcResult = new DummyRpcResult.Builder<TransactionStatus>().result(
-                TransactionStatus.COMMITED).build();
-        Future<RpcResult<TransactionStatus>> future = DummyFuture.builder().rpcResult(rpcResult).build();
-        when(controllerContext.toInstanceIdentifier(any(String.class))).thenReturn(instIdAndSchema);
-        when(broker.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(
-                future);
-
-        restconf.setControllerContext(controllerContext);
-        restconf.setBroker(broker);
-
-        // method is called only because it contains call of method which
-        // supplement namespaces to compositeNode
-        restconf.createConfigurationData("something", compositeNode);
-    }
-
-    public static DataSchemaNode obtainSchemaFromYang(String yangFolder) throws FileNotFoundException {
-        return obtainSchemaFromYang(yangFolder, null);
+    public static QName buildQName(String name, String uri, String date) {
+        return buildQName(name, uri, date, null);
     }
 
-    public static DataSchemaNode obtainSchemaFromYang(String yangFolder, String moduleName)
-            throws FileNotFoundException {
-        Set<Module> modules = null;
-        modules = TestUtils.loadModules(TestUtils.class.getResource(yangFolder).getPath());
-
-        if (modules == null) {
-            return null;
-        }
-        if (modules.size() < 1) {
-            return null;
-        }
-
-        Module moduleRes = null;
-        if (modules.size() > 1) {
-            if (moduleName == null) {
-                return null;
-            } else {
-                for (Module module : modules) {
-                    if (module.getName().equals(moduleName)) {
-                        moduleRes = module;
-                    }
-                }
-                if (moduleRes == null) {
-                    return null;
-                }
-            }
-        } else {
-            moduleRes = modules.iterator().next();
-        }
-
-        if (moduleRes.getChildNodes() == null) {
-            return null;
-        }
-
-        if (moduleRes.getChildNodes().size() != 1) {
-            return null;
-        }
-        DataSchemaNode dataSchemaNode = moduleRes.getChildNodes().iterator().next();
-        return dataSchemaNode;
-
+    public static QName buildQName(String name) {
+        return buildQName(name, "", null);
     }
 
-    public static void addDummyNamespaceToAllNodes(NodeWrapper<?> wrappedNode) throws URISyntaxException {
+    private static void addDummyNamespaceToAllNodes(NodeWrapper<?> wrappedNode) throws URISyntaxException {
         wrappedNode.setNamespace(new URI(""));
         if (wrappedNode instanceof CompositeNodeWrapper) {
             for (NodeWrapper<?> childNodeWrapper : ((CompositeNodeWrapper) wrappedNode).getValues()) {
@@ -397,56 +217,63 @@ public final class TestUtils {
         }
     }
 
-    public static void prepareMockForRestconfBeforeNormalization(Set<Module> modules, DataSchemaNode dataSchemaNode,
-            RestconfImpl restconf) {
-        ControllerContext instance = ControllerContext.getInstance();
-        instance.setSchemas(TestUtils.loadSchemaContext(modules));
-        restconf.setControllerContext(ControllerContext.getInstance());
-
+    private static void prepareMocksForRestconf(Set<Module> modules, RestconfImpl restconf) {
+        ControllerContext controllerContext = ControllerContext.getInstance();
         BrokerFacade mockedBrokerFacade = mock(BrokerFacade.class);
+
+        controllerContext.setSchemas(TestUtils.loadSchemaContext(modules));
+
         when(mockedBrokerFacade.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class)))
                 .thenReturn(
                         new DummyFuture.Builder().rpcResult(
                                 new DummyRpcResult.Builder<TransactionStatus>().result(TransactionStatus.COMMITED)
                                         .build()).build());
+
+        restconf.setControllerContext(controllerContext);
         restconf.setBroker(mockedBrokerFacade);
     }
-    
-    static CompositeNode loadCompositeNodeWithXmlTreeBuilder(String xmlDataPath) {
-        InputStream xmlStream = TestUtils.class.getResourceAsStream(xmlDataPath);
-        CompositeNode compositeNode = null;
+
+    public static CompositeNode readInputToCnSn(String path, boolean dummyNamespaces,
+            MessageBodyReader<CompositeNode> reader) throws WebApplicationException {
+
+        InputStream inputStream = TestUtils.class.getResourceAsStream(path);
         try {
-            compositeNode = TestUtils.loadCompositeNodeWithXmlTreeBuilder(xmlStream);
-        } catch (FileNotFoundException e) {
-            e.printStackTrace();
+            CompositeNode compositeNode = reader.readFrom(null, null, null, null, null, inputStream);
+            assertTrue(compositeNode instanceof CompositeNodeWrapper);
+            if (dummyNamespaces) {
+                try {
+                    TestUtils.addDummyNamespaceToAllNodes((CompositeNodeWrapper) compositeNode);
+                    return ((CompositeNodeWrapper) compositeNode).unwrap();
+                } catch (URISyntaxException e) {
+                    LOG.error(e.getMessage());
+                    assertTrue(e.getMessage(), false);
+                }
+            }
+            return compositeNode;
+        } catch (IOException e) {
+            LOG.error(e.getMessage());
+            assertTrue(e.getMessage(), false);
         }
-        return compositeNode;
-        
-        
-        
+        return null;
     }
-    
-    
-    public static CompositeNode loadCompositeNodeWithXmlTreeBuilder(InputStream xmlInputStream) throws FileNotFoundException {
-        if (xmlInputStream == null) {
-            throw new IllegalArgumentException();
-        }
-        Node<?> dataTree;
-        try {
-            dataTree = XmlTreeBuilder.buildDataTree(xmlInputStream);
-        } catch (XMLStreamException e) {
-            logger.error("Error during building data tree from XML", e);
-            return null;
-        }
-        if (dataTree == null) {
-            logger.error("data tree is null");
-            return null;
-        }
-        if (dataTree instanceof SimpleNode) {
-            logger.error("RPC XML was resolved as SimpleNode");
-            return null;
-        }
-        return (CompositeNode) dataTree;
-    }        
 
+    public static CompositeNode readInputToCnSn(String path, MessageBodyReader<CompositeNode> reader) {
+        return readInputToCnSn(path, false, reader);
+    }
+
+    public static String writeCompNodeWithSchemaContextToOutput(CompositeNode compositeNode, Set<Module> modules,
+            DataSchemaNode dataSchemaNode, MessageBodyWriter<StructuredData> messageBodyWriter) throws IOException,
+            WebApplicationException {
+
+        assertNotNull(dataSchemaNode);
+        assertNotNull("Composite node can't be null", compositeNode);
+        ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
+
+        ControllerContext.getInstance().setSchemas(loadSchemaContext(modules));
+
+        messageBodyWriter.writeTo(new StructuredData(compositeNode, dataSchemaNode), null, null, null, null, null,
+                byteArrayOS);
+
+        return byteArrayOS.toString();
+    }
 }
index 4cea120d4d1896f498394e176184d1b63e3b262c..b18f526a237c4c841758fcace2c4903bd28a68ae 100644 (file)
@@ -1,6 +1,7 @@
 package org.opendaylight.controller.sal.restconf.impl.test;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -35,7 +36,6 @@ import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
 import org.opendaylight.controller.sal.restconf.impl.*;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.*;
-import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
@@ -51,8 +51,8 @@ public class XmlProvidersTest extends JerseyTest {
 
     @BeforeClass
     public static void init() throws FileNotFoundException {
-        Set<Module> allModules = TestUtils.loadModules(RestconfImplTest.class.getResource("/full-versions/yangs")
-                .getPath());
+        Set<Module> allModules = TestUtils.loadModulesFrom("/full-versions/yangs");
+        assertNotNull(allModules);
         SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules);
         controllerContext = ControllerContext.getInstance();
         controllerContext.setSchemas(schemaContext);
index 7e3da0e4b4bd98ee8a6a04442001b91e10da37ad..3d24c6ba67ec1fc3a18ea1e290988f1e52fc8289 100644 (file)
@@ -4,24 +4,32 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 
 import java.util.Set;
-import org.opendaylight.yangtools.yang.model.api.*;
+
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
 
 public abstract class YangAndXmlAndDataSchemaLoader {
 
     protected static Set<Module> modules;
     protected static DataSchemaNode dataSchemaNode;
+    protected static String searchedModuleName;
+    protected static String searchedDataSchemaName;
+    protected static String schemaNodePath;
 
     protected static void dataLoad(String yangPath) {
         dataLoad(yangPath, 1, null, null);
     }
 
     protected static void dataLoad(String yangPath, int modulesNumber, String moduleName, String dataSchemaName) {
-        modules = TestUtils.resolveModules(yangPath);
+        modules = TestUtils.loadModulesFrom(yangPath);
         assertEquals(modulesNumber, modules.size());
         Module module = TestUtils.resolveModule(moduleName, modules);
+        searchedModuleName = module == null ? "" : module.getName();
         assertNotNull(module);
-        dataSchemaNode = TestUtils.resolveDataSchemaNode(module, dataSchemaName);
+        dataSchemaNode = TestUtils.resolveDataSchemaNode(dataSchemaName, module);
+        searchedDataSchemaName = dataSchemaNode == null ? "" : dataSchemaNode.getQName().getLocalName();
         assertNotNull(dataSchemaNode);
+        schemaNodePath = searchedModuleName + ":" + searchedDataSchemaName;
     }
 
 }
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlLeafrefToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlLeafrefToCnSnTest.java
new file mode 100644 (file)
index 0000000..beff572
--- /dev/null
@@ -0,0 +1,351 @@
+package org.opendaylight.controller.sal.restconf.impl.xml.to.cnsn.test;
+
+import static org.junit.Assert.*;
+
+import java.util.List;
+import java.util.Set;
+
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.*;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class XmlLeafrefToCnSnTest {
+    private static final Logger LOG = LoggerFactory.getLogger(XmlLeafrefToCnSnTest.class);
+
+    /**
+     * top level element represents container. second level element is list with
+     * two elements.
+     */
+    @Test
+    public void testXmlDataContainer() {
+        CompositeNode compNode = TestUtils.readInputToCnSn("/xml-to-cnsn/data-container.xml", false,
+                XmlToCompositeNodeProvider.INSTANCE);
+        assertNotNull(compNode);
+        Set<Module> modules = TestUtils.loadModulesFrom("/xml-to-cnsn/data-container-yang");
+
+        assertNotNull(modules);
+        TestUtils.normalizeCompositeNode(compNode, modules, "data-container-yang:cont");
+
+        String nameSpace = "data:container:yang";
+        assertEquals(nameSpace, compNode.getNodeType().getNamespace().toString());
+
+        verifyNullAndEmptyStringSingleNode(compNode, nameSpace);
+        verifyCommonPartAOfXml(compNode, "", nameSpace);
+    }
+
+    private void verifyNullAndEmptyStringSingleNode(CompositeNode compNode, String nameSpace) {
+        assertEquals("cont", compNode.getNodeType().getLocalName());
+
+        SimpleNode<?> lf2 = null;
+        SimpleNode<?> lf3 = null;
+        int found = 0;
+        for (Node<?> child : compNode.getChildren()) {
+            if (found == 0x3)
+                break;
+            if (child instanceof SimpleNode<?>) {
+                SimpleNode<?> childSimple = (SimpleNode<?>) child;
+                if (childSimple.getNodeType().getLocalName().equals("lf3")) {
+                    lf3 = childSimple;
+                    found = found | (1 << 0);
+                } else if (childSimple.getNodeType().getLocalName().equals("lf2")) {
+                    lf2 = childSimple;
+                    found = found | (1 << 1);
+                }
+            }
+            assertEquals(nameSpace, child.getNodeType().getNamespace().toString());
+        }
+
+        assertEquals("", lf2.getValue());
+        assertEquals(null, lf3.getValue());
+    }
+
+    @Test
+    public void testXmlDataList() {
+        CompositeNode compNode = TestUtils.readInputToCnSn("/xml-to-cnsn/data-list.xml", false,
+                XmlToCompositeNodeProvider.INSTANCE);
+        assertNotNull(compNode);
+
+        Set<Module> modules = TestUtils.loadModulesFrom("/xml-to-cnsn/data-list-yang");
+        assertNotNull(modules);
+
+        TestUtils.normalizeCompositeNode(compNode, modules, "data-container-yang:cont");
+
+        String nameSpaceList = "data:list:yang";
+        String nameSpaceCont = "data:container:yang";
+        assertEquals(nameSpaceCont, compNode.getNodeType().getNamespace().toString());
+        assertEquals("cont", compNode.getNodeType().getLocalName());
+        assertEquals(3, compNode.getChildren().size());
+        CompositeNode lst1_1 = null;
+        CompositeNode lst1_2 = null;
+        int loopCount = 0;
+        for (Node<?> node : compNode.getChildren()) {
+            if (node.getNodeType().getLocalName().equals("lf1")) {
+                assertEquals(nameSpaceList, node.getNodeType().getNamespace().toString());
+                assertTrue(node instanceof SimpleNode<?>);
+                assertEquals("lf1", node.getValue());
+            } else {
+                assertTrue(node instanceof CompositeNode);
+                switch (loopCount++) {
+                case 0:
+                    lst1_1 = (CompositeNode) node;
+                    break;
+                case 1:
+                    lst1_2 = (CompositeNode) node;
+                    break;
+                }
+                assertEquals(nameSpaceCont, node.getNodeType().getNamespace().toString());
+            }
+        }
+        // lst1_1
+        verifyCommonPartAOfXml(lst1_1, "1", nameSpaceCont);
+        // :lst1_1
+
+        // lst1_2
+        SimpleNode<?> lflst11 = null;
+        CompositeNode cont11 = null;
+        for (Node<?> node : lst1_2.getChildren()) {
+            String nodeName = node.getNodeType().getLocalName();
+            if (nodeName.equals("lflst11")) {
+                assertTrue(node instanceof SimpleNode<?>);
+                lflst11 = (SimpleNode<?>) node;
+
+            } else if (nodeName.equals("cont11")) {
+                assertTrue(node instanceof CompositeNode);
+                cont11 = (CompositeNode) node;
+            }
+            assertEquals(nameSpaceCont, compNode.getNodeType().getNamespace().toString());
+        }
+        assertEquals("221", lflst11.getValue());
+
+        assertEquals(1, cont11.getChildren().size());
+        assertTrue(cont11.getChildren().get(0) instanceof SimpleNode<?>);
+        SimpleNode<?> cont11_lf111 = (SimpleNode<?>) cont11.getChildren().get(0);
+        assertEquals(nameSpaceCont, cont11_lf111.getNodeType().getNamespace().toString());
+        assertEquals("lf111", cont11_lf111.getNodeType().getLocalName());
+        assertEquals((short) 100, cont11_lf111.getValue());
+        // :lst1_2
+
+    }
+
+    @Test
+    public void testXmlEmptyData() {
+        CompositeNode compNode = TestUtils.readInputToCnSn("/xml-to-cnsn/empty-data.xml", true,
+                XmlToCompositeNodeProvider.INSTANCE);
+        assertEquals("cont", compNode.getNodeType().getLocalName());
+        SimpleNode<?> lf1 = null;
+        SimpleNode<?> lflst1_1 = null;
+        SimpleNode<?> lflst1_2 = null;
+        CompositeNode lst1 = null;
+        int lflst1Count = 0;
+        for (Node<?> node : compNode.getChildren()) {
+            if (node.getNodeType().getLocalName().equals("lf1")) {
+                assertTrue(node instanceof SimpleNode<?>);
+                lf1 = (SimpleNode<?>) node;
+            } else if (node.getNodeType().getLocalName().equals("lflst1")) {
+                assertTrue(node instanceof SimpleNode<?>);
+
+                switch (lflst1Count++) {
+                case 0:
+                    lflst1_1 = (SimpleNode<?>) node;
+                    break;
+                case 1:
+                    lflst1_2 = (SimpleNode<?>) node;
+                    break;
+                }
+            } else if (node.getNodeType().getLocalName().equals("lst1")) {
+                assertTrue(node instanceof CompositeNode);
+                lst1 = (CompositeNode) node;
+            }
+        }
+
+        assertNotNull(lf1);
+        assertNotNull(lflst1_1);
+        assertNotNull(lflst1_2);
+        assertNotNull(lst1);
+
+        assertEquals("", lf1.getValue());
+        assertEquals("", lflst1_1.getValue());
+        assertEquals("", lflst1_2.getValue());
+        assertEquals(1, lst1.getChildren().size());
+        assertEquals("lf11", lst1.getChildren().get(0).getNodeType().getLocalName());
+
+        assertTrue(lst1.getChildren().get(0) instanceof SimpleNode<?>);
+        assertEquals("", lst1.getChildren().get(0).getValue());
+
+    }
+
+    /**
+     * Test case like this <lf11 xmlns:x="namespace">x:identity</lf11>
+     */
+    @Test
+    public void testIdentityrefNmspcInElement() {
+        testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-nmspc-in-element.xml", "/xml-to-cnsn/identityref",
+                "identityref-module", "cont", 2, "iden", "identity:module");
+    }
+
+    /**
+     * 
+     * Test case like <lf11 xmlns="namespace1"
+     * xmlns:x="namespace">identity</lf11>
+     */
+
+    @Test
+    public void testIdentityrefDefaultNmspcInElement() {
+        testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-default-nmspc-in-element.xml",
+                "/xml-to-cnsn/identityref/yang-augments", "general-module", "cont", 3, "iden", "identityref:module");
+    }
+
+    /**
+     * 
+     * Test case like <cont1 xmlns="namespace1"> <lf11
+     * xmlns:x="namespace">identity</lf11> </cont1>
+     */
+    @Test
+    public void testIdentityrefDefaultNmspcInParrentElement() {
+        testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-default-nmspc-in-parrent-element.xml",
+                "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "identityref:module");
+    }
+
+    /**
+     * 
+     * Test case like <cont1 xmlns="namespace1" xmlns:x="namespace">
+     * <lf11>x:identity</lf11> </cont1>
+     */
+    @Test
+    public void testIdentityrefNmspcInParrentElement() {
+        testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-nmspc-in-parrent-element.xml",
+                "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "z:namespace");
+
+    }
+
+    /**
+     * 
+     * Test case like (without namespace in xml) <cont1> <lf11>x:identity</lf11>
+     * </cont1>
+     */
+    @Test
+    public void testIdentityrefNoNmspcValueWithPrefix() {
+        testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-no-nmspc-value-with-prefix.xml",
+                "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "x:iden", "identityref:module");
+    }
+
+    /**
+     * 
+     * Test case like (without namespace in xml) <cont1> <lf11>identity</lf11>
+     * </cont1>
+     */
+    @Test
+    public void testIdentityrefNoNmspcValueWithoutPrefix() {
+        testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-no-nmspc-value-without-prefix.xml",
+                "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "identityref:module");
+    }
+
+    private void verifyCommonPartAOfXml(CompositeNode compNode, String suf, String nameSpace) {
+        SimpleNode<?> lf1suf = null;
+        SimpleNode<?> lflst1suf_1 = null;
+        SimpleNode<?> lflst1suf_2 = null;
+        SimpleNode<?> lflst1suf_3 = null;
+        CompositeNode cont1suf = null;
+        CompositeNode lst1suf = null;
+
+        int lflstCount = 0;
+
+        for (Node<?> node : compNode.getChildren()) {
+            String localName = node.getNodeType().getLocalName();
+            if (localName.equals("lf1" + suf)) {
+                assertTrue(node instanceof SimpleNode<?>);
+                lf1suf = (SimpleNode<?>) node;
+            } else if (localName.equals("lflst1" + suf)) {
+                assertTrue(node instanceof SimpleNode<?>);
+                switch (lflstCount++) {
+                case 0:
+                    lflst1suf_1 = (SimpleNode<?>) node;
+                    break;
+                case 1:
+                    lflst1suf_2 = (SimpleNode<?>) node;
+                    break;
+                case 2:
+                    lflst1suf_3 = (SimpleNode<?>) node;
+                    break;
+                }
+            } else if (localName.equals("lst1" + suf)) {
+                assertTrue(node instanceof CompositeNode);
+                lst1suf = (CompositeNode) node;
+            } else if (localName.equals("cont1" + suf)) {
+                assertTrue(node instanceof CompositeNode);
+                cont1suf = (CompositeNode) node;
+            }
+            assertEquals(nameSpace, node.getNodeType().getNamespace().toString());
+        }
+
+        assertNotNull(lf1suf);
+        assertNotNull(lflst1suf_1);
+        assertNotNull(lflst1suf_2);
+        assertNotNull(lflst1suf_3);
+        assertNotNull(lst1suf);
+        assertNotNull(cont1suf);
+
+        assertEquals("str0", lf1suf.getValue());
+        assertEquals("121", lflst1suf_1.getValue());
+        assertEquals("131", lflst1suf_2.getValue());
+        assertEquals("str1", lflst1suf_3.getValue());
+
+        assertEquals(1, lst1suf.getChildren().size());
+
+        assertTrue(lst1suf.getChildren().get(0) instanceof SimpleNode<?>);
+        SimpleNode<?> lst11_lf11 = (SimpleNode<?>) lst1suf.getChildren().get(0);
+        assertEquals(nameSpace, lst11_lf11.getNodeType().getNamespace().toString());
+        assertEquals("lf11" + suf, lst11_lf11.getNodeType().getLocalName());
+        assertEquals("str2", lst11_lf11.getValue());
+
+        assertTrue(cont1suf.getChildren().get(0) instanceof SimpleNode<?>);
+        SimpleNode<?> cont1_lf11 = (SimpleNode<?>) cont1suf.getChildren().get(0);
+        assertEquals(nameSpace, cont1_lf11.getNodeType().getNamespace().toString());
+        assertEquals("lf11" + suf, cont1_lf11.getNodeType().getLocalName());
+        assertEquals((short) 100, cont1_lf11.getValue());
+    }
+
+    private void testIdentityrefToCnSn(String xmlPath, String yangPath, String moduleName, String schemaName,
+            int moduleCount, String resultLocalName, String resultNamespace) {
+        CompositeNode compositeNode = TestUtils.readInputToCnSn(xmlPath, false, XmlToCompositeNodeProvider.INSTANCE);
+        assertNotNull(compositeNode);
+
+        Set<Module> modules = TestUtils.loadModulesFrom(yangPath);
+        assertEquals(moduleCount, modules.size());
+
+        TestUtils.normalizeCompositeNode(compositeNode, modules, moduleName + ":" + schemaName);
+
+        SimpleNode<?> lf11 = getLf11(compositeNode);
+        assertTrue(lf11.getValue() instanceof QName);
+        QName qName = (QName) lf11.getValue();
+        assertEquals(resultLocalName, qName.getLocalName());
+        assertEquals(resultNamespace, qName.getNamespace().toString());
+    }
+
+    private SimpleNode<?> getLf11(CompositeNode compositeNode) {
+        assertEquals("cont", compositeNode.getNodeType().getLocalName());
+
+        List<Node<?>> childs = compositeNode.getChildren();
+        assertEquals(1, childs.size());
+        Node<?> nd = childs.iterator().next();
+        assertTrue(nd instanceof CompositeNode);
+        assertEquals("cont1", nd.getNodeType().getLocalName());
+
+        childs = ((CompositeNode) nd).getChildren();
+        SimpleNode<?> lf11 = null;
+        for (Node<?> child : childs) {
+            assertTrue(child instanceof SimpleNode);
+            if (child.getNodeType().getLocalName().equals("lf11")) {
+                lf11 = (SimpleNode<?>) child;
+            }
+        }
+        assertNotNull(lf11);
+        return lf11;
+    }
+
+}
index 50ab0857b79534ea1e61b956b58391d6fde87897..7c7df56133abd44e67a9a912a2e603bc817b9ed4 100644 (file)
@@ -2,391 +2,43 @@ package org.opendaylight.controller.sal.restconf.impl.xml.to.cnsn.test;
 
 import static org.junit.Assert.*;
 
-import java.io.*;
-import java.net.URISyntaxException;
-import java.util.List;
-import java.util.Set;
-
-import javax.ws.rs.WebApplicationException;
-
+import org.junit.BeforeClass;
 import org.junit.Test;
 import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
-import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
 import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
-import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
 import org.opendaylight.yangtools.yang.data.api.*;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class XmlToCnSnTest {
-    private static final Logger LOG = LoggerFactory.getLogger(XmlToCnSnTest.class);
-
-    /**
-     * top level element represents container. second level element is list with
-     * two elements.
-     */
-    @Test
-    public void testXmlDataContainer() {
-        CompositeNode compNode = compositeNodeFromXml("/xml-to-cnsn/data-container.xml", false);
-        assertNotNull(compNode);
-        DataSchemaNode dataSchemaNode = null;
-        try {
-            dataSchemaNode = TestUtils.obtainSchemaFromYang("/xml-to-cnsn/data-container-yang");
-        } catch (FileNotFoundException e) {
-            LOG.error(e.getMessage());
-            assertTrue(false);
-        }
-
-        assertNotNull(dataSchemaNode);
-        TestUtils.supplementNamespace(dataSchemaNode, compNode);
-
-        String nameSpace = "data:container:yang";
-        assertEquals(nameSpace, compNode.getNodeType().getNamespace().toString());
-
-        verifyNullAndEmptyStringSingleNode(compNode, nameSpace);
-        verifyCommonPartAOfXml(compNode, "", nameSpace);
-    }
-
-    private void verifyNullAndEmptyStringSingleNode(CompositeNode compNode, String nameSpace) {
-        assertEquals("cont", compNode.getNodeType().getLocalName());
 
-        SimpleNode<?> lf2 = null;
-        SimpleNode<?> lf3 = null;
-        int found = 0;
-        for (Node<?> child : compNode.getChildren()) {
-            if (found == 0x3)
-                break;
-            if (child instanceof SimpleNode<?>) {
-                SimpleNode<?> childSimple = (SimpleNode<?>) child;
-                if (childSimple.getNodeType().getLocalName().equals("lf3")) {
-                    lf3 = childSimple;
-                    found = found | (1 << 0);
-                } else if (childSimple.getNodeType().getLocalName().equals("lf2")) {
-                    lf2 = childSimple;
-                    found = found | (1 << 1);
-                }
-            }
-            assertEquals(nameSpace, child.getNodeType().getNamespace().toString());
-        }
+public class XmlToCnSnTest extends YangAndXmlAndDataSchemaLoader {
 
-        assertEquals("", lf2.getValue());
-        assertEquals(null, lf3.getValue());
+    @BeforeClass
+    public static void initialize() {
+        dataLoad("/xml-to-cnsn/leafref");
     }
 
     @Test
-    public void testXmlDataList() {
-        CompositeNode compNode = compositeNodeFromXml("/xml-to-cnsn/data-list.xml", false);
-        assertNotNull(compNode);
-
-        DataSchemaNode dataSchemaNode = null;
-        try {
-            dataSchemaNode = TestUtils.obtainSchemaFromYang("/xml-to-cnsn/data-list-yang", "data-container-yang");
-        } catch (FileNotFoundException e) {
-            LOG.error(e.getMessage());
-        }
+    public void testXmlLeafrefToCnSn() {
+        CompositeNode compositeNode = TestUtils.readInputToCnSn("/xml-to-cnsn/leafref/xml/data.xml", false,
+                XmlToCompositeNodeProvider.INSTANCE);
+        assertNotNull(compositeNode);
         assertNotNull(dataSchemaNode);
-        TestUtils.supplementNamespace(dataSchemaNode, compNode);
-
-        String nameSpaceList = "data:list:yang";
-        String nameSpaceCont = "data:container:yang";
-        assertEquals(nameSpaceCont, compNode.getNodeType().getNamespace().toString());
-        assertEquals("cont", compNode.getNodeType().getLocalName());
-        assertEquals(3, compNode.getChildren().size());
-        CompositeNode lst1_1 = null;
-        CompositeNode lst1_2 = null;
-        int loopCount = 0;
-        for (Node<?> node : compNode.getChildren()) {
-            if (node.getNodeType().getLocalName().equals("lf1")) {
-                assertEquals(nameSpaceList, node.getNodeType().getNamespace().toString());
-                assertTrue(node instanceof SimpleNode<?>);
-                assertEquals("lf1", node.getValue());
-            } else {
-                assertTrue(node instanceof CompositeNode);
-                switch (loopCount++) {
-                case 0:
-                    lst1_1 = (CompositeNode) node;
-                    break;
-                case 1:
-                    lst1_2 = (CompositeNode) node;
-                    break;
-                }
-                assertEquals(nameSpaceCont, node.getNodeType().getNamespace().toString());
-            }
-        }
-        // lst1_1
-        verifyCommonPartAOfXml(lst1_1, "1", nameSpaceCont);
-        // :lst1_1
-
-        // lst1_2
-        SimpleNode<?> lflst11 = null;
-        CompositeNode cont11 = null;
-        for (Node<?> node : lst1_2.getChildren()) {
-            String nodeName = node.getNodeType().getLocalName();
-            if (nodeName.equals("lflst11")) {
-                assertTrue(node instanceof SimpleNode<?>);
-                lflst11 = (SimpleNode<?>) node;
-
-            } else if (nodeName.equals("cont11")) {
-                assertTrue(node instanceof CompositeNode);
-                cont11 = (CompositeNode) node;
-            }
-            assertEquals(nameSpaceCont, compNode.getNodeType().getNamespace().toString());
-        }
-        assertEquals("221", lflst11.getValue());
-
-        assertEquals(1, cont11.getChildren().size());
-        assertTrue(cont11.getChildren().get(0) instanceof SimpleNode<?>);
-        SimpleNode<?> cont11_lf111 = (SimpleNode<?>) cont11.getChildren().get(0);
-        assertEquals(nameSpaceCont, cont11_lf111.getNodeType().getNamespace().toString());
-        assertEquals("lf111", cont11_lf111.getNodeType().getLocalName());
-        assertEquals((short) 100, cont11_lf111.getValue());
-        // :lst1_2
-
-    }
-
-    @Test
-    public void testXmlEmptyData() {
-        CompositeNode compNode = compositeNodeFromXml("/xml-to-cnsn/empty-data.xml", true);
-        assertEquals("cont", compNode.getNodeType().getLocalName());
-        SimpleNode<?> lf1 = null;
-        SimpleNode<?> lflst1_1 = null;
-        SimpleNode<?> lflst1_2 = null;
-        CompositeNode lst1 = null;
-        int lflst1Count = 0;
-        for (Node<?> node : compNode.getChildren()) {
-            if (node.getNodeType().getLocalName().equals("lf1")) {
-                assertTrue(node instanceof SimpleNode<?>);
-                lf1 = (SimpleNode<?>) node;
-            } else if (node.getNodeType().getLocalName().equals("lflst1")) {
-                assertTrue(node instanceof SimpleNode<?>);
-
-                switch (lflst1Count++) {
-                case 0:
-                    lflst1_1 = (SimpleNode<?>) node;
-                    break;
-                case 1:
-                    lflst1_2 = (SimpleNode<?>) node;
-                    break;
-                }
-            } else if (node.getNodeType().getLocalName().equals("lst1")) {
-                assertTrue(node instanceof CompositeNode);
-                lst1 = (CompositeNode) node;
-            }
-        }
-
-        assertNotNull(lf1);
-        assertNotNull(lflst1_1);
-        assertNotNull(lflst1_2);
-        assertNotNull(lst1);
-
-        assertEquals("", lf1.getValue());
-        assertEquals("", lflst1_1.getValue());
-        assertEquals("", lflst1_2.getValue());
-        assertEquals(1, lst1.getChildren().size());
-        assertEquals("lf11", lst1.getChildren().get(0).getNodeType().getLocalName());
-
-        assertTrue(lst1.getChildren().get(0) instanceof SimpleNode<?>);
-        assertEquals("", lst1.getChildren().get(0).getValue());
-
-    }
-
-    /**
-     * Test case like this <lf11 xmlns:x="namespace">x:identity</lf11>
-     */
-    @Test
-    public void testIdentityrefNmspcInElement() {
-        testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-nmspc-in-element.xml", "/xml-to-cnsn/identityref",
-                "identityref-module", "cont", 2, "iden", "identity:module");
-    }
+        TestUtils.normalizeCompositeNode(compositeNode, modules, schemaNodePath);
 
-    /**
-     * 
-     * Test case like <lf11 xmlns="namespace1"
-     * xmlns:x="namespace">identity</lf11>
-     */
-
-    @Test
-    public void testIdentityrefDefaultNmspcInElement() {
-        testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-default-nmspc-in-element.xml",
-                "/xml-to-cnsn/identityref/yang-augments", "general-module", "cont", 3, "iden", "identityref:module");
-    }
-
-    /**
-     * 
-     * Test case like <cont1 xmlns="namespace1"> <lf11
-     * xmlns:x="namespace">identity</lf11> </cont1>
-     */
-    @Test
-    public void testIdentityrefDefaultNmspcInParrentElement() {
-        testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-default-nmspc-in-parrent-element.xml",
-                "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "identityref:module");
-    }
-
-    /**
-     * 
-     * Test case like <cont1 xmlns="namespace1" xmlns:x="namespace">
-     * <lf11>x:identity</lf11> </cont1>
-     */
-    @Test
-    public void testIdentityrefNmspcInParrentElement() {
-        testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-nmspc-in-parrent-element.xml",
-                "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "z:namespace");
-
-    }
-
-    /**
-     * 
-     * Test case like (without namespace in xml) <cont1> <lf11>x:identity</lf11>
-     * </cont1>
-     */
-    @Test
-    public void testIdentityrefNoNmspcValueWithPrefix() {
-        testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-no-nmspc-value-with-prefix.xml",
-                "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "x:iden", "identityref:module");
-    }
-
-    /**
-     * 
-     * Test case like (without namespace in xml) <cont1> <lf11>identity</lf11>
-     * </cont1>
-     */
-    @Test
-    public void testIdentityrefNoNmspcValueWithoutPrefix() {
-        testIdentityrefToCnSn("/xml-to-cnsn/identityref/xml/data-no-nmspc-value-without-prefix.xml",
-                "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "identityref:module");
-    }
-
-    private void verifyCommonPartAOfXml(CompositeNode compNode, String suf, String nameSpace) {
-        SimpleNode<?> lf1suf = null;
-        SimpleNode<?> lflst1suf_1 = null;
-        SimpleNode<?> lflst1suf_2 = null;
-        SimpleNode<?> lflst1suf_3 = null;
-        CompositeNode cont1suf = null;
-        CompositeNode lst1suf = null;
-
-        int lflstCount = 0;
+        assertEquals("cont", compositeNode.getNodeType().getLocalName());
 
-        for (Node<?> node : compNode.getChildren()) {
-            String localName = node.getNodeType().getLocalName();
-            if (localName.equals("lf1" + suf)) {
-                assertTrue(node instanceof SimpleNode<?>);
-                lf1suf = (SimpleNode<?>) node;
-            } else if (localName.equals("lflst1" + suf)) {
-                assertTrue(node instanceof SimpleNode<?>);
-                switch (lflstCount++) {
-                case 0:
-                    lflst1suf_1 = (SimpleNode<?>) node;
-                    break;
-                case 1:
-                    lflst1suf_2 = (SimpleNode<?>) node;
-                    break;
-                case 2:
-                    lflst1suf_3 = (SimpleNode<?>) node;
+        SimpleNode<?> lf2 = null;
+        for (Node<?> childNode : compositeNode.getChildren()) {
+            if (childNode instanceof SimpleNode) {
+                if (childNode.getNodeType().getLocalName().equals("lf2")) {
+                    lf2 = (SimpleNode<?>) childNode;
                     break;
                 }
-            } else if (localName.equals("lst1" + suf)) {
-                assertTrue(node instanceof CompositeNode);
-                lst1suf = (CompositeNode) node;
-            } else if (localName.equals("cont1" + suf)) {
-                assertTrue(node instanceof CompositeNode);
-                cont1suf = (CompositeNode) node;
             }
-            assertEquals(nameSpace, node.getNodeType().getNamespace().toString());
         }
 
-        assertNotNull(lf1suf);
-        assertNotNull(lflst1suf_1);
-        assertNotNull(lflst1suf_2);
-        assertNotNull(lflst1suf_3);
-        assertNotNull(lst1suf);
-        assertNotNull(cont1suf);
-
-        assertEquals("str0", lf1suf.getValue());
-        assertEquals("121", lflst1suf_1.getValue());
-        assertEquals("131", lflst1suf_2.getValue());
-        assertEquals("str1", lflst1suf_3.getValue());
-
-        assertEquals(1, lst1suf.getChildren().size());
-
-        assertTrue(lst1suf.getChildren().get(0) instanceof SimpleNode<?>);
-        SimpleNode<?> lst11_lf11 = (SimpleNode<?>) lst1suf.getChildren().get(0);
-        assertEquals(nameSpace, lst11_lf11.getNodeType().getNamespace().toString());
-        assertEquals("lf11" + suf, lst11_lf11.getNodeType().getLocalName());
-        assertEquals("str2", lst11_lf11.getValue());
-
-        assertTrue(cont1suf.getChildren().get(0) instanceof SimpleNode<?>);
-        SimpleNode<?> cont1_lf11 = (SimpleNode<?>) cont1suf.getChildren().get(0);
-        assertEquals(nameSpace, cont1_lf11.getNodeType().getNamespace().toString());
-        assertEquals("lf11" + suf, cont1_lf11.getNodeType().getLocalName());
-        assertEquals((short) 100, cont1_lf11.getValue());
-    }
-
-    private CompositeNode compositeNodeFromXml(String xmlPath, boolean dummyNamespaces) {
-        XmlToCompositeNodeProvider xmlToCompositeNodeProvider = XmlToCompositeNodeProvider.INSTANCE;
-        try {
-            InputStream xmlStream = XmlToCnSnTest.class.getResourceAsStream(xmlPath);
-            CompositeNode compositeNode = xmlToCompositeNodeProvider.readFrom(null, null, null, null, null, xmlStream);
-            if (dummyNamespaces) {
-                try {
-                    TestUtils.addDummyNamespaceToAllNodes((CompositeNodeWrapper) compositeNode);
-                    return ((CompositeNodeWrapper) compositeNode).unwrap();
-                } catch (URISyntaxException e) {
-                    LOG.error(e.getMessage());
-                    assertTrue(e.getMessage(), false);
-                }
-            }
-            return compositeNode;
-
-        } catch (WebApplicationException | IOException e) {
-            LOG.error(e.getMessage());
-            assertTrue(false);
-        }
-        return null;
-    }
-
-    private void testIdentityrefToCnSn(String xmlPath, String yangPath, String moduleName, String schemaName,
-            int moduleCount, String resultLocalName, String resultNamespace) {
-        CompositeNode compositeNode = compositeNodeFromXml(xmlPath, false);
-        assertNotNull(compositeNode);
-
-        Set<Module> modules = TestUtils.resolveModules(yangPath);
-        assertEquals(moduleCount, modules.size());
-        Module module = TestUtils.resolveModule(moduleName, modules);
-        assertNotNull(module);
-        DataSchemaNode dataSchemaNode = TestUtils.resolveDataSchemaNode(module, null);
-        assertNotNull(dataSchemaNode);
-
-        TestUtils.normalizeCompositeNode(compositeNode, modules, dataSchemaNode, moduleName + ":" + schemaName);
-
-        SimpleNode<?> lf11 = getLf11(compositeNode);
-        assertTrue(lf11.getValue() instanceof QName);
-        QName qName = (QName) lf11.getValue();
-        assertEquals(resultLocalName, qName.getLocalName());
-        assertEquals(resultNamespace, qName.getNamespace().toString());
-
-    }
-
-    private SimpleNode<?> getLf11(CompositeNode compositeNode) {
-        assertEquals("cont", compositeNode.getNodeType().getLocalName());
-
-        List<Node<?>> childs = compositeNode.getChildren();
-        assertEquals(1, childs.size());
-        Node<?> nd = childs.iterator().next();
-        assertTrue(nd instanceof CompositeNode);
-        assertEquals("cont1", nd.getNodeType().getLocalName());
-
-        childs = ((CompositeNode) nd).getChildren();
-        SimpleNode<?> lf11 = null;
-        for (Node<?> child : childs) {
-            assertTrue(child instanceof SimpleNode);
-            if (child.getNodeType().getLocalName().equals("lf11")) {
-                lf11 = (SimpleNode<?>) child;
-            }
-        }
-        assertNotNull(lf11);
-        return lf11;
+        assertNotNull(lf2);
+        assertTrue(lf2.getValue() instanceof String);
+        assertEquals("121", (String) lf2.getValue());
     }
 
 }
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/invalid-top-level-element/invalid-top-level-element.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/invalid-top-level-element/invalid-top-level-element.yang
new file mode 100644 (file)
index 0000000..a9df486
--- /dev/null
@@ -0,0 +1,13 @@
+module invalid-top-level-element {
+  namespace "invalid:top:level:element";  
+
+  prefix "intoleel";
+   revision 2013-12-17 {    
+  }
+  
+
+    leaf lf {
+        type string;
+    }
+
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/list/list-types-module b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/list/list-types-module
new file mode 100644 (file)
index 0000000..9bdea81
--- /dev/null
@@ -0,0 +1,274 @@
+module simple-data-types {
+  namespace "simple:data:types";  
+
+  prefix "smpdtp";
+  revision 2013-11-12 {    
+  }
+  
+  identity iden {
+  }
+  
+  typedef tpdfempty {
+       type empty;
+  }
+  
+  typedef tpdfbit {
+       type bits {
+               bit b1;
+               bit b2;
+               bit b3;
+       }
+  }
+  
+  typedef tpdfun4 {
+       type boolean;
+  }
+  
+  typedef tpdfun3 {
+       type union {
+               type tpdfbit;
+               type tpdfempty;
+       }
+  }  
+  
+  typedef tpdfun2 {
+       type union {
+               type tpdfun3;
+               type tpdfun4;
+       }
+  }
+  
+  typedef tpdfun1 {
+       type union {
+               type uint8;
+               type decimal64 {
+                       fraction-digits 2;
+               }
+       }
+  }
+  
+  container cont {
+         leaf lfnint8Min {
+               type int8; 
+         }
+         leaf lfnint8Max {
+               type int8; 
+         }
+         leaf lfnint16Min {
+               type int16; 
+         }
+         leaf lfnint16Max {
+               type int16; 
+         }
+         leaf lfnint32Min {
+               type int32; 
+         }
+         leaf lfnint32Max {
+               type int32; 
+         }
+         leaf lfnint64Min {
+               type int64; 
+         }
+         leaf lfnint64Max {
+               type int64; 
+         }
+         
+         leaf lfnuint8Max {
+               type uint8; 
+         }
+         leaf lfnuint16Max {
+               type uint16; 
+         }
+         leaf lfnuint32Max {
+               type uint32; 
+         }
+         leaf lfuint64Max {
+               type uint64; 
+         }
+         leaf lfstr {
+               type string;
+         }       
+         leaf lfstr1 {
+               type string;
+         }       
+         leaf lfbool1 {
+               type boolean;
+         }       
+         leaf lfbool2 {
+               type boolean;
+         }       
+         leaf lfbool3 {
+               type boolean;
+         }       
+         leaf lfdecimal1 {
+               type decimal64 {
+                       fraction-digits 2;
+               }       
+         }       
+         leaf lfdecimal2 {
+               type decimal64 {
+                       fraction-digits 2;
+               }       
+         }       
+         leaf lfdecimal3 {
+               type decimal64 {
+                       fraction-digits 2;
+               }       
+         }      
+          
+         leaf lfdecimal4 {
+               type decimal64 {
+                       fraction-digits 2;
+               }       
+         }
+                 
+         
+         leaf lfdecimal6 {
+               type decimal64 {
+                       fraction-digits 2;
+               }       
+         }       
+
+    leaf lfenum {
+      type enumeration {
+        enum enum1;
+        enum enum2;
+        enum enum3;
+        enum enum4;
+      }
+    }
+
+    leaf lfbits {
+      type bits {
+        bit bit1;
+        bit bit2;
+        bit bit3;
+        bit bit4;
+      }
+    }  
+    
+    leaf lfbinary {
+       type binary;
+    }  
+    
+    leaf lfref1 {                  //reference to string type
+       type leafref {
+               path "../lfstr";
+       }
+    }
+    
+    leaf lfref2 {                  //reference to number type
+       type leafref {
+               path "../lfnint8Max";
+       }
+    }
+    
+    leaf lfempty {
+       type empty;
+    }
+    
+    leaf lfunion1 {
+       type union {
+               type uint16;
+               type string;
+       }
+    }
+    leaf lfunion2 {
+       type union {
+               type decimal64 {
+                               fraction-digits 2;              
+               }
+               type string;
+       }
+    }
+    
+    leaf lfunion3 {
+       type union {
+               type empty;
+               type string;
+       }
+    }
+    
+    leaf lfunion4 {
+       type union {
+               type boolean;
+               type string;
+       }
+    }
+    
+    leaf lfunion5 {
+       type union {
+               type uint16;
+               type string;
+       }
+    }
+    
+    leaf lfunion6 {
+       type union {
+               type uint16;
+               type empty;
+       }
+    }
+    
+    leaf lfunion7 {
+               type tpdfun3;
+    }
+    
+    leaf lfunion8 {
+       type union {
+               type uint16;
+               type string;
+       }
+    }
+    
+    leaf lfunion9 {
+       type union {
+               type uint16;
+               type boolean;                   
+       }
+    }
+    
+    leaf lfunion10 {
+       type union {
+               type bits {
+                       bit bt1;
+                       bit bt2;
+               }
+               type boolean;                   
+       }
+    }
+    
+    leaf lfunion11 {
+               type union {
+                       type tpdfun1;
+                       type tpdfun2;
+               }
+    }
+    
+    leaf lfunion12 {
+               type tpdfun2;
+    }
+    
+    leaf lfunion13 {
+        type tpdfbit;    
+    }
+        
+    leaf lfunion14 {
+        type union {
+            type enumeration {
+                enum zero;
+                enum one;
+            }
+            type uint16;
+        }    
+    }    
+    
+    leaf identityref1 {
+        type identityref {
+            base iden;
+        }
+    }
+         
+         
+  }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/choice/module-with-choice.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/choice/module-with-choice.yang
new file mode 100644 (file)
index 0000000..8454784
--- /dev/null
@@ -0,0 +1,25 @@
+module module-with-choice {
+  namespace "module:with:choice";  
+
+  prefix "mowicho";
+  
+  revision 2013-12-18 {    
+  }
+  
+
+  container cont {
+    choice choA {
+        case caA1 {
+            leaf lf1 {
+                type string;
+            }
+        }
+        case caA2 {
+            leaf lf2 {
+                type string;
+            }
+        } 
+    }
+  }    
+         
+}
\ No newline at end of file
index 7023c94f2f0df55d00efaf6c675629a184deba78..81d77329c69eaa74d28c19d942ec1b2593a538ec 100644 (file)
@@ -91,6 +91,12 @@ module basic-module {
                  }
                }
                
+               leaf lfLfref {
+                 type leafref {
+                     path "/cont/lfBoolean";
+                 }    
+               }
+               
        }
          
 }
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/leafref/json/data.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/leafref/json/data.json
new file mode 100644 (file)
index 0000000..235666e
--- /dev/null
@@ -0,0 +1,6 @@
+{
+    "cont":{
+        "lf1":121,
+        "lf2":121
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/leafref/leafref-module b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/leafref/leafref-module
new file mode 100644 (file)
index 0000000..8ca9f09
--- /dev/null
@@ -0,0 +1,19 @@
+module leafref-module {
+  namespace "leafref:module";  
+
+  prefix "lfrfmo";
+  revision 2013-11-18 {    
+  }
+
+    container cont {
+        leaf lf1 {
+            type int32;
+        }
+        leaf lf2 {
+            type leafref {
+                path "/cont/lf1"; 
+            }
+        }
+    }
+  
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/unsupported-json-format.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/unsupported-json-format.json
new file mode 100644 (file)
index 0000000..abc6267
--- /dev/null
@@ -0,0 +1 @@
+fffff
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/leafref/leafref-module b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/leafref/leafref-module
new file mode 100644 (file)
index 0000000..8ca9f09
--- /dev/null
@@ -0,0 +1,19 @@
+module leafref-module {
+  namespace "leafref:module";  
+
+  prefix "lfrfmo";
+  revision 2013-11-18 {    
+  }
+
+    container cont {
+        leaf lf1 {
+            type int32;
+        }
+        leaf lf2 {
+            type leafref {
+                path "/cont/lf1"; 
+            }
+        }
+    }
+  
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/leafref/xml/data.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/leafref/xml/data.xml
new file mode 100644 (file)
index 0000000..06200a6
--- /dev/null
@@ -0,0 +1,4 @@
+<cont>
+    <lf1>121</lf1>
+    <lf2>121</lf2>
+</cont>
\ No newline at end of file
index 30f98cedd330ee1fac7933824e3fb8da46e57de8..aa6e99a03f978a4604fe72ea4ba36307a6bdaa80 100644 (file)
@@ -847,9 +847,7 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList
         }
         if (storedFlow.getInPort()== null) {
             if (statsFlow.getInPort() != null) {
-                if(statsFlow.getInPort()!= 0){
-                    return false;
-                }
+                return false;
             }
         } else if(!storedFlow.getInPort().equals(statsFlow.getInPort())) {
             return false;
index d5dee32e40ef74e49fb80fb9e9eba284917a6c2b..c0bcbaa8ad1684daa531f7594898f016d154069d 100644 (file)
@@ -1,7 +1,6 @@
 package org.opendaylight.md.controller.topology.lldp.utils;
 
 import java.nio.charset.Charset;
-import java.util.List;
 
 import org.opendaylight.controller.sal.packet.Ethernet;
 import org.opendaylight.controller.sal.packet.LLDP;
@@ -46,10 +45,6 @@ public class LLDPDiscoveryUtils {
             LLDP lldp = (LLDP) ethPkt.getPayload();
     
             try {
-                List<LLDPTLV> optionalTLVList = lldp.getOptionalTLVList();
-                if (optionalTLVList == null) {
-                    return null;
-                }
                 NodeId srcNodeId = null;
                 NodeConnectorId srcNodeConnectorId = null;
                 for (LLDPTLV lldptlv : lldp.getOptionalTLVList()) {
@@ -61,12 +56,13 @@ public class LLDPDiscoveryUtils {
                         srcNodeId = new NodeId(srcNodeIdString);
                     }
                 }
-                
-                InstanceIdentifier<NodeConnector> srcInstanceId = InstanceIdentifier.builder(Nodes.class)
-                        .child(Node.class,new NodeKey(srcNodeId))
-                        .child(NodeConnector.class, new NodeConnectorKey(srcNodeConnectorId))
-                        .toInstance();
-                return new NodeConnectorRef(srcInstanceId);
+                if(srcNodeId != null && srcNodeConnectorId != null) {
+                    InstanceIdentifier<NodeConnector> srcInstanceId = InstanceIdentifier.builder(Nodes.class)
+                            .child(Node.class,new NodeKey(srcNodeId))
+                            .child(NodeConnector.class, new NodeConnectorKey(srcNodeConnectorId))
+                            .toInstance();
+                    return new NodeConnectorRef(srcInstanceId);
+                }
             } catch (Exception e) {
                 LOG.warn("Caught exception ", e);
             }
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributesConstants.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributesConstants.java
deleted file mode 100644 (file)
index 23cdabf..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes;
-
-public class AttributesConstants {
-
-    /**
-     * Property placed into object names for dependencies to preserve reference name
-     */
-    public static final String REF_NAME_ON_PROPERTY_KEY = "X-refName";
-}
index a1f46dde54ff078596b709e12e0eeeb8914e7056..dbc1b48d4f9abebe5fc89c306f65b68fcee924d2 100644 (file)
@@ -43,7 +43,6 @@ public class AttributeConfigElement {
         resolvedValue = attributeResolvingStrategy.parseAttribute(attrName, value);
         Optional<?> resolvedDefault = attributeResolvingStrategy.parseAttribute(attrName, dafaultValue);
         resolvedDefaultValue = resolvedDefault.isPresent() ? resolvedDefault.get() : null;
-
     }
 
     public static AttributeConfigElement create(Object nullableDefault, Object value) {
index fb385221c8877b9ffceadf53cd355f8c78197811..506d7d61c347016ef76a6601500ed773762dafb0 100644 (file)
@@ -16,7 +16,7 @@ import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribu
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributeIfcSwitchStatement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 
 import javax.management.openmbean.ArrayType;
 import javax.management.openmbean.CompositeType;
@@ -27,9 +27,9 @@ import java.util.Map.Entry;
 
 public class ObjectMapper extends AttributeIfcSwitchStatement<AttributeMappingStrategy<?, ? extends OpenType<?>>> {
 
-    private final Services dependencyTracker;
+    private final ServiceRegistryWrapper dependencyTracker;
 
-    public ObjectMapper(Services depTracker) {
+    public ObjectMapper(ServiceRegistryWrapper depTracker) {
         this.dependencyTracker = depTracker;
     }
 
index 842634163607315bd018d00d43c29b1db2dd83d0..83e8086eef2507b648d918cf4592d9d7c553c1b6 100644 (file)
@@ -10,8 +10,8 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attri
 
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributesConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
 
 import javax.management.ObjectName;
@@ -20,11 +20,11 @@ import javax.management.openmbean.SimpleType;
 public class ObjectNameAttributeMappingStrategy extends
         AbstractAttributeMappingStrategy<ObjectNameAttributeMappingStrategy.MappedDependency, SimpleType<?>> {
 
-    private final Services tracker;
+    private final ServiceRegistryWrapper tracker;
     private final String serviceName;
     private final String namespace;
 
-    public ObjectNameAttributeMappingStrategy(SimpleType<?> openType, Services dependencyTracker, String serviceName, String namespace) {
+    public ObjectNameAttributeMappingStrategy(SimpleType<?> openType, ServiceRegistryWrapper dependencyTracker, String serviceName, String namespace) {
         super(openType);
         this.tracker = dependencyTracker;
         this.serviceName = serviceName;
@@ -44,10 +44,7 @@ public class ObjectNameAttributeMappingStrategy extends
 
         ObjectName on = (ObjectName) value;
 
-        String expectedRefName = on.getKeyProperty(AttributesConstants.REF_NAME_ON_PROPERTY_KEY);
-
-        String refName = expectedRefName == null ? tracker.getRefName(namespace, serviceName, on, Optional.<String> absent())
-                : tracker.getRefName(namespace, serviceName, on, Optional.of(expectedRefName));
+        String refName = ObjectNameUtil.getReferenceName(on);
 
         return Optional.of(new MappedDependency(namespace, serviceName, refName));
     }
index d8f0e2357ea0fb57063121b2758aca908b553eb5..57a44d8af0ec2d11cb30f3a86393ac015bac814c 100644 (file)
@@ -9,11 +9,8 @@
 package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving;
 
 import com.google.common.base.Optional;
-import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributesConstants;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.mapping.ObjectNameAttributeMappingStrategy;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services.ServiceInstance;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -23,10 +20,10 @@ import javax.management.openmbean.SimpleType;
 
 public class ObjectNameAttributeResolvingStrategy extends AbstractAttributeResolvingStrategy<ObjectName, SimpleType<?>> {
 
-    private final Services serviceTracker;
+    private final ServiceRegistryWrapper serviceTracker;
     private static final Logger logger = LoggerFactory.getLogger(ObjectNameAttributeResolvingStrategy.class);
 
-    ObjectNameAttributeResolvingStrategy(Services serviceTracker) {
+    ObjectNameAttributeResolvingStrategy(ServiceRegistryWrapper serviceTracker) {
         super(SimpleType.OBJECTNAME);
         this.serviceTracker = serviceTracker;
     }
@@ -45,9 +42,7 @@ public class ObjectNameAttributeResolvingStrategy extends AbstractAttributeResol
         String namespace = mappedDep.getNamespace();
         logger.trace("Getting service instance by service name {} : {} and ref name {}", namespace, serviceName, refName);
 
-        ServiceInstance byRefName = serviceTracker.getByServiceAndRefName(namespace, serviceName, refName);
-        ObjectName on = ObjectNameUtil.createReadOnlyModuleON(byRefName.getModuleName(), byRefName.getInstanceName());
-        on = ObjectNameUtil.createON(on.toString() + "," + AttributesConstants.REF_NAME_ON_PROPERTY_KEY + "=" + refName);
+        ObjectName on = serviceTracker.getByServiceAndRefName(namespace, serviceName, refName);
 
         logger.debug("Attribute {} : {} parsed to type {}", attrName, value, getOpenType());
         return Optional.of(on);
index a3e2813fa0d383f6db78c6a2c2d52e32d03dc5e1..82c8c1ec6b537f2ca25cc585dfe4c795cd2b7350 100644 (file)
@@ -15,7 +15,7 @@ import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribu
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute;
 import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributeIfcSwitchStatement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 
 import javax.management.openmbean.ArrayType;
 import javax.management.openmbean.CompositeType;
@@ -26,9 +26,9 @@ import java.util.Map.Entry;
 
 public class ObjectResolver extends AttributeIfcSwitchStatement<AttributeResolvingStrategy<?, ? extends OpenType<?>>> {
 
-    private final Services serviceTracker;
+    private final ServiceRegistryWrapper serviceTracker;
 
-    public ObjectResolver(Services serviceTracker) {
+    public ObjectResolver(ServiceRegistryWrapper serviceTracker) {
         this.serviceTracker = serviceTracker;
     }
 
index 3a5fa1170fec28922155e8e7b2748eb7393448b5..ec73cd6068662f825e9d115457174c05ef49726d 100644 (file)
@@ -14,7 +14,6 @@ import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Multimap;
-import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType;
 import org.opendaylight.controller.netconf.util.xml.XmlElement;
@@ -99,7 +98,7 @@ public class Config {
     // }
 
     public Element toXml(Set<ObjectName> instancesToMap, Optional<String> maybeNamespace, Document document,
-            Element dataElement, Services serviceTracker) {
+            Element dataElement, ServiceRegistryWrapper serviceTracker) {
 
         Map<String, Map<String, Collection<ObjectName>>> moduleToInstances = getMappedInstances(instancesToMap,
                 moduleConfigs);
@@ -120,81 +119,84 @@ public class Config {
                 ModuleConfig mapping = moduleConfigs.get(moduleNamespace).get(moduleMappingEntry.getKey());
 
                 if (moduleMappingEntry.getValue().isEmpty()) {
-                    addEmptyModulesCommented(document, modulesElement, moduleNamespace, moduleMappingEntry);
-                } else {
-                    for (ObjectName objectName : moduleMappingEntry.getValue()) {
-                        modulesElement
-                                .appendChild(mapping.toXml(objectName, serviceTracker, document, moduleNamespace));
-                    }
+                    continue;
+                }
+
+                for (ObjectName objectName : moduleMappingEntry.getValue()) {
+                    modulesElement.appendChild(mapping.toXml(objectName, serviceTracker, document, moduleNamespace));
                 }
 
             }
         }
 
-        root.appendChild(serviceTracker.toXml(serviceTracker.getMappedServices(), document));
+        root.appendChild(Services.toXml(serviceTracker, document));
 
         return root;
     }
 
-    // TODO remove commented modules from output
-    private void addEmptyModulesCommented(Document document, Element root, String moduleNamespace,
-            Entry<String, Collection<ObjectName>> moduleMappingEntry) {
-        Element emptyModule = document.createElement(XmlNetconfConstants.MODULE_KEY);
-
-        Element typeElement = XmlUtil.createTextElement(document, XmlNetconfConstants.TYPE_KEY,
-                moduleMappingEntry.getKey());
-        emptyModule.appendChild(typeElement);
-
-        root.appendChild(document.createComment(XmlUtil.toString(emptyModule, false)));
-    }
-
     // TODO refactor, replace string representing namespace with namespace class
     // TODO refactor, replace Map->Multimap with e.g. ConfigElementResolved
     // class
-    public ConfigElementResolved fromXml(XmlElement xml,
-                                         EditStrategyType defaultEditStrategyType, ServiceReferenceReadableRegistry taClient) {
-        Map<String, Multimap<String, ModuleElementResolved>> retVal = Maps.newHashMap();
 
-        List<XmlElement> recognisedChildren = Lists.newArrayList();
+    public Map<String, Multimap<String, ModuleElementResolved>> fromXmlModulesResolved(XmlElement xml, EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) {
+        Optional<XmlElement> modulesElement = getModulesElement(xml);
+        List<XmlElement> moduleElements = getModulesElementList(modulesElement);
 
-        Services serviceTracker = fromXmlServices(xml, recognisedChildren, taClient);
-        List<XmlElement> moduleElements = fromXmlModules(xml, recognisedChildren);
-
-        xml.checkUnrecognisedElements(recognisedChildren);
+        Map<String, Multimap<String, ModuleElementResolved>> retVal = Maps.newHashMap();
 
         for (XmlElement moduleElement : moduleElements) {
-            resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType);
-        }
+            ResolvingStrategy<ModuleElementResolved> resolvingStrategy = new ResolvingStrategy<ModuleElementResolved>() {
+                @Override
+                public ModuleElementResolved resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, ServiceRegistryWrapper serviceTracker, String instanceName, String moduleNamespace, EditStrategyType defaultStrategy) {
+                    return moduleMapping.fromXml(moduleElement, serviceTracker,
+                            instanceName, moduleNamespace, defaultStrategy);
+                }
+            };
 
-        return new ConfigElementResolved(retVal, serviceTracker);
+            resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType, resolvingStrategy);
+        }
+        return retVal;
     }
 
-    public static class ConfigElementResolved {
+    /**
+     * return a map containing namespace -> moduleName -> instanceName map. Attribute parsing is omitted.
+     */
+    public Map<String, Multimap<String, ModuleElementDefinition>> fromXmlModulesMap(XmlElement xml,
+            EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) {
+        Optional<XmlElement> modulesElement = getModulesElement(xml);
+        List<XmlElement> moduleElements = getModulesElementList(modulesElement);
 
-        private final Map<String, Multimap<String, ModuleElementResolved>> resolvedModules;
-        private final Services services;
+        Map<String, Multimap<String, ModuleElementDefinition>> retVal = Maps.newHashMap();
 
-        public ConfigElementResolved(Map<String, Multimap<String, ModuleElementResolved>> retVal, Services serviceTracker) {
-            this.resolvedModules = retVal;
-            this.services = serviceTracker;
-        }
+        for (XmlElement moduleElement : moduleElements) {
+            ResolvingStrategy<ModuleElementDefinition> resolvingStrategy = new ResolvingStrategy<ModuleElementDefinition>() {
+                @Override
+                public ModuleElementDefinition resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement,
+                        ServiceRegistryWrapper serviceTracker, String instanceName, String moduleNamespace,
+                        EditStrategyType defaultStrategy) {
+                    // TODO: add check for conflicts between global and local
+                    // edit strategy
+                    String perInstanceEditStrategy = moduleElement.getAttribute(XmlNetconfConstants.OPERATION_ATTR_KEY,
+                            XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
+                    return new ModuleElementDefinition(instanceName, perInstanceEditStrategy, defaultStrategy);
+                }
+            };
 
-        public Map<String, Multimap<String, ModuleElementResolved>> getResolvedModules() {
-            return resolvedModules;
+            resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType, resolvingStrategy);
         }
+        return retVal;
+    }
 
-        public Services getServices() {
-            return services;
-        }
+    private static Optional<XmlElement> getModulesElement(XmlElement xml) {
+        return xml.getOnlyChildElementOptionally(XmlNetconfConstants.MODULES_KEY,
+                    XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
     }
 
-    private List<XmlElement> fromXmlModules(XmlElement xml, List<XmlElement> recognisedChildren) {
-        Optional<XmlElement> modulesElement = xml.getOnlyChildElementOptionally(XmlNetconfConstants.MODULES_KEY,
-                XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
+    private List<XmlElement> getModulesElementList(Optional<XmlElement> modulesElement) {
         List<XmlElement> moduleElements;
+
         if (modulesElement.isPresent()) {
             moduleElements = modulesElement.get().getChildElementsWithSameNamespace(XmlNetconfConstants.MODULE_KEY);
-            recognisedChildren.add(modulesElement.get());
             modulesElement.get().checkUnrecognisedElements(moduleElements);
         } else {
             moduleElements = Lists.newArrayList();
@@ -202,8 +204,8 @@ public class Config {
         return moduleElements;
     }
 
-    private void resolveModule(Map<String, Multimap<String, ModuleElementResolved>> retVal, Services serviceTracker,
-            XmlElement moduleElement, EditStrategyType defaultStrategy) {
+    private <T> void resolveModule(Map<String, Multimap<String, T>> retVal, ServiceRegistryWrapper serviceTracker,
+            XmlElement moduleElement, EditStrategyType defaultStrategy, ResolvingStrategy<T> resolvingStrategy) {
         XmlElement typeElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY);
         Entry<String, String> prefixToNamespace = typeElement.findNamespaceOfTextContent();
         String moduleNamespace = prefixToNamespace.getValue();
@@ -215,35 +217,49 @@ public class Config {
 
         ModuleConfig moduleMapping = getModuleMapping(moduleNamespace, instanceName, factoryName);
 
-        Multimap<String, ModuleElementResolved> innerMap = retVal.get(moduleNamespace);
+        Multimap<String, T> innerMap = retVal.get(moduleNamespace);
         if (innerMap == null) {
             innerMap = HashMultimap.create();
             retVal.put(moduleNamespace, innerMap);
         }
 
-        ModuleElementResolved moduleElementResolved = moduleMapping.fromXml(moduleElement, serviceTracker,
+        T resolvedElement = resolvingStrategy.resolveElement(moduleMapping, moduleElement, serviceTracker,
                 instanceName, moduleNamespace, defaultStrategy);
 
-        innerMap.put(factoryName, moduleElementResolved);
+        innerMap.put(factoryName, resolvedElement);
     }
 
-    private Services fromXmlServices(XmlElement xml, List<XmlElement> recognisedChildren,
-                                     ServiceReferenceReadableRegistry taClient) {
-        Optional<XmlElement> servicesElement = xml.getOnlyChildElementOptionally(XmlNetconfConstants.SERVICES_KEY,
-                XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
+    public Services fromXmlServices(XmlElement xml) {
+        Optional<XmlElement> servicesElement = getServicesElement(xml);
 
-        Map<String, Map<String, Map<String, String>>> mappedServices;
+        Services services;
         if (servicesElement.isPresent()) {
-            mappedServices = Services.fromXml(servicesElement.get());
-            recognisedChildren.add(servicesElement.get());
+            services = Services.fromXml(servicesElement.get());
         } else {
-            mappedServices = new HashMap<>();
+            services = new Services();
         }
-        Services services = Services.resolveServices(mappedServices, taClient);
 
         return services;
     }
 
+    private static Optional<XmlElement> getServicesElement(XmlElement xml) {
+        return xml.getOnlyChildElementOptionally(XmlNetconfConstants.SERVICES_KEY,
+                    XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
+    }
+
+    public static void checkUnrecognisedChildren(XmlElement parent) {
+        Optional<XmlElement> servicesOpt = getServicesElement(parent);
+        Optional<XmlElement> modulesOpt = getModulesElement(parent);
+
+        List<XmlElement> recognised = Lists.newArrayList();
+        if(servicesOpt.isPresent())
+            recognised.add(servicesOpt.get());
+        if(modulesOpt.isPresent())
+            recognised.add(modulesOpt.get());
+
+        parent.checkUnrecognisedElements(recognised);
+    }
+
     private String getFactoryName(String factoryNameWithPrefix, String prefixOrEmptyString) {
         checkState(
                 factoryNameWithPrefix.startsWith(prefixOrEmptyString),
@@ -271,4 +287,8 @@ public class Config {
         return moduleMapping;
     }
 
+    private interface ResolvingStrategy<T> {
+        public T resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, ServiceRegistryWrapper serviceTracker,
+                String instanceName, String moduleNamespace, EditStrategyType defaultStrategy);
+    }
 }
index aae1636165c07c6822fbadf10ddfeafad2d28653..b8870e51ce8bd0907655054a0b9c4566e1343cf4 100644 (file)
@@ -52,7 +52,7 @@ public final class InstanceConfig {
         this.configRegistryClient = configRegistryClient;
     }
 
-    private Map<String, Object> getMappedConfiguration(ObjectName on, Services depTracker) {
+    private Map<String, Object> getMappedConfiguration(ObjectName on, ServiceRegistryWrapper depTracker) {
 
         // TODO make field, mappingStrategies can be instantiated only once
         Map<String, AttributeMappingStrategy<?, ? extends OpenType<?>>> mappingStrategies = new ObjectMapper(depTracker)
@@ -84,7 +84,7 @@ public final class InstanceConfig {
         return toXml;
     }
 
-    public Element toXml(ObjectName on, Services depTracker, String namespace, Document document, Element rootElement) {
+    public Element toXml(ObjectName on, ServiceRegistryWrapper depTracker, String namespace, Document document, Element rootElement) {
 
         Element cfgElement = rootElement;
 
@@ -104,7 +104,7 @@ public final class InstanceConfig {
         return cfgElement;
     }
 
-    private void resolveConfiguration(InstanceConfigElementResolved mappedConfig, Services depTracker) {
+    private void resolveConfiguration(InstanceConfigElementResolved mappedConfig, ServiceRegistryWrapper depTracker) {
 
         // TODO make field, resolvingStrategies can be instantiated only once
         Map<String, AttributeResolvingStrategy<?, ? extends OpenType<?>>> resolvingStrategies = new ObjectResolver(
@@ -128,7 +128,7 @@ public final class InstanceConfig {
         }
     }
 
-    public InstanceConfigElementResolved fromXml(XmlElement moduleElement, Services services, String moduleNamespace,
+    public InstanceConfigElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper services, String moduleNamespace,
             EditStrategyType defaultStrategy, Multimap<String, String> providedServices) {
         Map<String, AttributeConfigElement> retVal = Maps.newHashMap();
 
index 55cb60bed5e7df0268908b160650ecd46101e137..0bb4191bf2f33817d4bd395e3f29c0110139835b 100644 (file)
@@ -28,7 +28,7 @@ public class InstanceConfigElementResolved {
     private final Multimap<String, String> providedServices;
 
     public InstanceConfigElementResolved(String currentStrategy, Map<String, AttributeConfigElement> configuration, EditStrategyType defaultStrategy, Multimap<String, String> providedServices) {
-        EditStrategyType valueOf = checkStrategy(currentStrategy, defaultStrategy);
+        EditStrategyType valueOf = parseStrategy(currentStrategy, defaultStrategy);
         this.editStrategy = valueOf;
         this.configuration = configuration;
         this.providedServices = providedServices;
@@ -41,19 +41,19 @@ public class InstanceConfigElementResolved {
     }
 
 
-    EditStrategyType checkStrategy(String currentStrategy, EditStrategyType defaultStrategy) {
-        EditStrategyType valueOf = EditStrategyType.valueOf(currentStrategy);
+    static EditStrategyType parseStrategy(String currentStrategy, EditStrategyType defaultStrategy) {
+        EditStrategyType parsedStrategy = EditStrategyType.valueOf(currentStrategy);
         if (defaultStrategy.isEnforcing()) {
             Preconditions
                     .checkArgument(
-                            valueOf == defaultStrategy,
+                            parsedStrategy == defaultStrategy,
                             "With "
                                     + defaultStrategy
                                     + " as "
                                     + EditConfigXmlParser.DEFAULT_OPERATION_KEY
                                     + " operations on module elements are not permitted since the default option is restrictive");
         }
-        return valueOf;
+        return parsedStrategy;
     }
 
 
index 2ac6fe0a9bb650116e5f3591fb35cdf8655ee311..48ff835a451e789d51826c4a9c65ba4241d3329b 100644 (file)
@@ -53,7 +53,7 @@ public class ModuleConfig {
         return providedServices;
     }
 
-    public Element toXml(ObjectName instanceON, Services depTracker, Document document, String namespace) {
+    public Element toXml(ObjectName instanceON, ServiceRegistryWrapper depTracker, Document document, String namespace) {
         Element root = document.createElement(XmlNetconfConstants.MODULE_KEY);
         // Xml.addNamespaceAttr(document, root, namespace);
 
@@ -84,7 +84,7 @@ public class ModuleConfig {
 
     }
 
-    public ModuleElementResolved fromXml(XmlElement moduleElement, Services depTracker, String instanceName,
+    public ModuleElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper depTracker, String instanceName,
             String moduleNamespace, EditStrategyType defaultStrategy) {
 
         InstanceConfigElementResolved ice = instanceConfig.fromXml(moduleElement, depTracker, moduleNamespace, defaultStrategy, providedServices);
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java
new file mode 100644 (file)
index 0000000..9111701
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * 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.netconf.confignetconfconnector.mapping.config;
+
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigStrategy;
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType;
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.MissingInstanceHandlingStrategy;
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.NoneEditConfigStrategy;
+
+public class ModuleElementDefinition {
+
+    public static final NoneEditConfigStrategy NONE_EDIT_CONFIG_STRATEGY = new NoneEditConfigStrategy();
+    public static final MissingInstanceHandlingStrategy MISSING_INSTANCE_HANDLING_STRATEGY = new MissingInstanceHandlingStrategy();
+
+    private final String instanceName;
+    private final EditStrategyType editStrategy;
+
+    public ModuleElementDefinition(String instanceName, String currentStrategy, EditStrategyType defaultStrategy) {
+        this.instanceName = instanceName;
+        if (currentStrategy == null || currentStrategy.isEmpty())
+            this.editStrategy = defaultStrategy;
+        else
+            this.editStrategy = InstanceConfigElementResolved.parseStrategy(currentStrategy, defaultStrategy);
+    }
+
+    public String getInstanceName() {
+        return instanceName;
+    }
+
+    public EditStrategyType getEditStrategyType() {
+        return editStrategy;
+    }
+
+    public EditConfigStrategy getEditStrategy() {
+        switch (editStrategy) {
+            case delete :
+            case remove :
+            case none : return NONE_EDIT_CONFIG_STRATEGY;
+            default : return MISSING_INSTANCE_HANDLING_STRATEGY;
+        }
+    }
+}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java
new file mode 100644 (file)
index 0000000..7df6712
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * 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.netconf.confignetconfconnector.mapping.config;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.ObjectName;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class ServiceRegistryWrapper {
+
+    private ServiceReferenceReadableRegistry configServiceRefRegistry;
+
+    private long suffix = 1;
+
+    public ServiceRegistryWrapper(ServiceReferenceReadableRegistry configServiceRefRegistry) {
+        this.configServiceRefRegistry = configServiceRefRegistry;
+    }
+
+
+    public boolean hasRefName(String namespace, String serviceName, ObjectName on) {
+        String qname = configServiceRefRegistry.getServiceInterfaceName(namespace, serviceName);
+        Map<String, ObjectName> forQName = configServiceRefRegistry.getServiceMapping().get(qname);
+        if(forQName==null) return false;
+        return forQName.values().contains(on);
+    }
+
+    public ObjectName getByServiceAndRefName(String namespace, String serviceName, String refName) {
+        Map<String, Map<String, String>> serviceNameToRefNameToInstance = getMappedServices().get(namespace);
+
+        Preconditions.checkArgument(serviceNameToRefNameToInstance != null, "No serviceInstances mapped to " + namespace);
+
+        Map<String, String> refNameToInstance = serviceNameToRefNameToInstance.get(serviceName);
+        Preconditions.checkArgument(refNameToInstance != null, "No serviceInstances mapped to " + serviceName + " , "
+                + serviceNameToRefNameToInstance.keySet());
+
+        String instanceId = refNameToInstance.get(refName);
+        Preconditions.checkArgument(instanceId != null, "No serviceInstances mapped to " + serviceName + ":"
+                + refName + ", " + serviceNameToRefNameToInstance.keySet());
+
+        Services.ServiceInstance serviceInstance = Services.ServiceInstance.fromString(instanceId);
+        Preconditions.checkArgument(serviceInstance != null, "No serviceInstance mapped to " + refName
+                + " under service name " + serviceName + " , " + refNameToInstance.keySet());
+
+        String qNameOfService = configServiceRefRegistry.getServiceInterfaceName(namespace, serviceName);
+        try {
+            return configServiceRefRegistry.getServiceReference(qNameOfService, refName);
+        } catch (InstanceNotFoundException e) {
+            throw new IllegalArgumentException("No serviceInstance mapped to " + refName
+                    + " under service name " + serviceName + " , " + refNameToInstance.keySet(), e);
+
+        }
+    }
+
+    public Map<String, Map<String, Map<String, String>>> getMappedServices() {
+        Map<String, Map<String, Map<String, String>>> retVal = Maps.newHashMap();
+
+        Map<String, Map<String, ObjectName>> serviceMapping = configServiceRefRegistry.getServiceMapping();
+        for (String serviceQName : serviceMapping.keySet())
+            for (String refName : serviceMapping.get(serviceQName).keySet()) {
+
+                ObjectName on = serviceMapping.get(serviceQName).get(refName);
+                Services.ServiceInstance si = Services.ServiceInstance.fromObjectName(on);
+
+                // FIXME use QName's new String constructor, after it is fixed
+//                QName qname;
+//                try {
+//                    qname = new QName(serviceQName);
+//                } catch (ParseException e) {
+//                    throw new IllegalStateException("Unable to parse qname of a service " + serviceQName, e);
+//                }
+                Pattern p = Pattern.compile("\\(([^\\(\\?]+)\\?[^\\?\\)]*\\)([^\\)]+)");
+                Matcher matcher = p.matcher(serviceQName);
+                Preconditions.checkArgument(matcher.matches());
+                String namespace = matcher.group(1);
+                String localName = matcher.group(2);
+
+//                String namespace = qname.getNamespace().toString();
+                Map<String, Map<String, String>> serviceToRefs = retVal.get(namespace);
+                if(serviceToRefs==null) {
+                    serviceToRefs = Maps.newHashMap();
+                    retVal.put(namespace, serviceToRefs);
+                }
+
+//                String localName = qname.getLocalName();
+                Map<String, String> refsToSis = serviceToRefs.get(localName);
+                if(refsToSis==null) {
+                    refsToSis = Maps.newHashMap();
+                    serviceToRefs.put(localName, refsToSis);
+                }
+
+                Preconditions.checkState(refsToSis.containsKey(refName) == false,
+                        "Duplicate reference name %s for service %s:%s, now for instance %s", refName, namespace,
+                        localName, on);
+                refsToSis.put(refName, si.toString());
+            }
+
+        return retVal;
+    }
+
+    @VisibleForTesting
+    public String getNewDefaultRefName(String namespace, String serviceName, String moduleName, String instanceName) {
+        String refName;
+        refName = "ref_" + instanceName;
+
+        Map<String, Map<String, String>> serviceNameToRefNameToInstance = getMappedServices().get(namespace);
+
+        Map<String, String> refNameToInstance;
+        if(serviceNameToRefNameToInstance == null || serviceNameToRefNameToInstance.containsKey(serviceName) == false) {
+            refNameToInstance = Collections.emptyMap();
+        } else
+            refNameToInstance = serviceNameToRefNameToInstance.get(serviceName);
+
+        final Set<String> refNamesAsSet = toSet(refNameToInstance.keySet());
+        if (refNamesAsSet.contains(refName)) {
+            refName = findAvailableRefName(refName, refNamesAsSet);
+        }
+
+        return refName;
+    }
+
+
+    private Set<String> toSet(Collection<String> values) {
+        Set<String> refNamesAsSet = Sets.newHashSet();
+
+        for (String refName : values) {
+            boolean resultAdd = refNamesAsSet.add(refName);
+            Preconditions.checkState(resultAdd,
+                    "Error occurred building services element, reference name {} was present twice", refName);
+        }
+
+        return refNamesAsSet;
+    }
+
+    private String findAvailableRefName(String refName, Set<String> refNamesAsSet) {
+        String intitialRefName = refName;
+
+        while (true) {
+            refName = intitialRefName + "_" + suffix++;
+            if (refNamesAsSet.contains(refName) == false)
+                return refName;
+        }
+    }
+}
index 77f3cf283fc2daf77c18766c4a9dacd4185f2536..7de7ea8c7169086afe4aa6ce1a2cf858718d20e3 100644 (file)
@@ -8,14 +8,8 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config;
 
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
-import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Sets;
-import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.ObjectNameAttributeReadingStrategy;
 import org.opendaylight.controller.netconf.util.xml.XmlElement;
@@ -27,12 +21,9 @@ import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
 import javax.management.ObjectName;
-import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
-import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -45,124 +36,8 @@ public final class Services {
     public static final String TYPE_KEY = "type";
     public static final String SERVICE_KEY = "service";
 
-    private long suffix = 1;
-
     private final Map<String /*Namespace*/, Map<String/* ServiceName */, Map<String/* refName */, ServiceInstance>>> namespaceToServiceNameToRefNameToInstance = Maps
             .newHashMap();
-    private ServiceReferenceReadableRegistry configServiceRefRegistry;
-
-    public Services(ServiceReferenceReadableRegistry configServiceRefRegistry) {
-        this.configServiceRefRegistry = configServiceRefRegistry;
-    }
-
-    @VisibleForTesting
-    public String getNewDefaultRefName(String namespace, String serviceName, String moduleName, String instanceName) {
-        String refName;
-        refName = "ref_" + instanceName;
-
-        Map<String, Map<String, String>> serviceNameToRefNameToInstance = getMappedServices().get(namespace);
-
-        Map<String, String> refNameToInstance;
-        if(serviceNameToRefNameToInstance == null || serviceNameToRefNameToInstance.containsKey(serviceName) == false) {
-            refNameToInstance = Collections.emptyMap();
-        } else
-            refNameToInstance = serviceNameToRefNameToInstance.get(serviceName);
-
-        final Set<String> refNamesAsSet = toSet(refNameToInstance.keySet());
-        if (refNamesAsSet.contains(refName)) {
-            refName = findAvailableRefName(refName, refNamesAsSet);
-        }
-
-        return refName;
-    }
-
-    private Set<String> toSet(Collection<String> values) {
-        Set<String> refNamesAsSet = Sets.newHashSet();
-
-        for (String refName : values) {
-            boolean resultAdd = refNamesAsSet.add(refName);
-            Preconditions.checkState(resultAdd,
-                    "Error occurred building services element, reference name {} was present twice", refName);
-        }
-
-        return refNamesAsSet;
-    }
-
-    public ServiceInstance getByServiceAndRefName(String namespace, String serviceName, String refName) {
-        Map<String, Map<String, String>> serviceNameToRefNameToInstance = getMappedServices().get(namespace);
-
-        Preconditions.checkArgument(serviceNameToRefNameToInstance != null, "No serviceInstances mapped to " + namespace);
-
-        Map<String, String> refNameToInstance = serviceNameToRefNameToInstance.get(serviceName);
-        Preconditions.checkArgument(refNameToInstance != null, "No serviceInstances mapped to " + serviceName + " , "
-                + serviceNameToRefNameToInstance.keySet());
-
-        String instanceId = refNameToInstance.get(refName);
-        Preconditions.checkArgument(instanceId != null, "No serviceInstances mapped to " + serviceName + ":"
-                + refName + ", " + serviceNameToRefNameToInstance.keySet());
-
-        ServiceInstance serviceInstance = ServiceInstance.fromString(instanceId);
-        Preconditions.checkArgument(serviceInstance != null, "No serviceInstance mapped to " + refName
-                + " under service name " + serviceName + " , " + refNameToInstance.keySet());
-        return serviceInstance;
-    }
-
-    // TODO hide getMappedServices, call it explicitly in toXml
-
-    public Map<String, Map<String, Map<String, String>>> getMappedServices() {
-        Map<String, Map<String, Map<String, String>>> retVal = Maps.newHashMap();
-
-        for (String namespace : namespaceToServiceNameToRefNameToInstance.keySet()) {
-
-            Map<String, Map<String, ServiceInstance>> serviceNameToRefNameToInstance = namespaceToServiceNameToRefNameToInstance
-                    .get(namespace);
-            Map<String, Map<String, String>> innerRetVal = Maps.newHashMap();
-
-            for (String serviceName : serviceNameToRefNameToInstance.keySet()) {
-
-                Map<String, String> innerInnerRetVal = Maps.newHashMap();
-                for (Entry<String, ServiceInstance> refNameToSi : serviceNameToRefNameToInstance.get(serviceName).entrySet()) {
-                    innerInnerRetVal.put(refNameToSi.getKey(), refNameToSi.getValue().toString());
-                }
-                innerRetVal.put(serviceName, innerInnerRetVal);
-            }
-            retVal.put(namespace, innerRetVal);
-        }
-
-        Map<String, Map<String, ObjectName>> serviceMapping = configServiceRefRegistry.getServiceMapping();
-        for (String serviceQName : serviceMapping.keySet())
-            for (String refName : serviceMapping.get(serviceQName).keySet()) {
-
-                ObjectName on = serviceMapping.get(serviceQName).get(refName);
-                ServiceInstance si = ServiceInstance.fromObjectName(on);
-
-                // FIXME use QName's new String constructor, after its implemented
-                Pattern p = Pattern.compile("\\(([^\\(\\?]+)\\?[^\\?\\)]*\\)([^\\)]+)");
-                Matcher matcher = p.matcher(serviceQName);
-                Preconditions.checkArgument(matcher.matches());
-                String namespace = matcher.group(1);
-                String localName = matcher.group(2);
-
-                Map<String, Map<String, String>> serviceToRefs = retVal.get(namespace);
-                if(serviceToRefs==null) {
-                    serviceToRefs = Maps.newHashMap();
-                    retVal.put(namespace, serviceToRefs);
-                }
-
-                Map<String, String> refsToSis = serviceToRefs.get(localName);
-                if(refsToSis==null) {
-                    refsToSis = Maps.newHashMap();
-                    serviceToRefs.put(localName, refsToSis);
-                }
-
-                Preconditions.checkState(refsToSis.containsKey(refName) == false,
-                        "Duplicate reference name %s for service %s:%s, now for instance %s", refName, namespace,
-                        localName, on);
-                refsToSis.put(refName, si.toString());
-            }
-
-        return retVal;
-    }
 
     /**
      *
@@ -171,10 +46,8 @@ public final class Services {
         return namespaceToServiceNameToRefNameToInstance;
     }
 
-    // TODO hide resolveServices, call it explicitly in fromXml
-
-    public static Services resolveServices(Map<String, Map<String, Map<String, String>>> mappedServices, ServiceReferenceReadableRegistry taClient) {
-        Services tracker = new Services(taClient);
+    private static Services resolveServices(Map<String, Map<String, Map<String, String>>> mappedServices) {
+        Services tracker = new Services();
 
         for (Entry<String, Map<String, Map<String, String>>> namespaceEntry : mappedServices.entrySet()) {
             String namespace = namespaceEntry.getKey();
@@ -210,7 +83,7 @@ public final class Services {
 
     // TODO support edit strategies on services
 
-    public static Map<String, Map<String, Map<String, String>>> fromXml(XmlElement xml) {
+    public static Services fromXml(XmlElement xml) {
         Map<String, Map<String, Map<String, String>>> retVal = Maps.newHashMap();
 
         List<XmlElement> services = xml.getChildElements(SERVICE_KEY);
@@ -250,23 +123,14 @@ public final class Services {
             }
         }
 
-        return retVal;
-    }
-
-    private String findAvailableRefName(String refName, Set<String> refNamesAsSet) {
-        String intitialRefName = refName;
-
-        while (true) {
-            refName = intitialRefName + "_" + suffix++;
-            if (refNamesAsSet.contains(refName) == false)
-                return refName;
-        }
+        return resolveServices(retVal);
     }
 
-    public Element toXml(Map<String, Map<String, Map<String, String>>> mappedServices, Document document) {
+    public static Element toXml(ServiceRegistryWrapper serviceRegistryWrapper, Document document) {
         Element root = document.createElement(XmlNetconfConstants.SERVICES_KEY);
         XmlUtil.addNamespaceAttr(root, XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
 
+        Map<String, Map<String, Map<String, String>>> mappedServices = serviceRegistryWrapper.getMappedServices();
         for (String namespace : mappedServices.keySet()) {
 
             for (Entry<String, Map<String, String>> serviceEntry : mappedServices.get(namespace).entrySet()) {
@@ -294,51 +158,6 @@ public final class Services {
         return root;
     }
 
-    public String getRefName(String namespace, String serviceName, ObjectName on, Optional<String> expectedRefName) {
-        Optional<String> refNameOptional = getRefNameOptional(namespace, serviceName, on, expectedRefName);
-        Preconditions.checkState(refNameOptional.isPresent(), "No reference names mapped to %s, %s, %s", namespace,
-                serviceName, on);
-        return refNameOptional.get();
-    }
-
-    public Optional<String> getRefNameOptional(String namespace, String serviceName, ObjectName on,
-            Optional<String> expectedRefName) {
-        Map<String, Map<String, String>> services = getMappedServices().get(namespace);
-
-        if(services == null) return Optional.absent();
-        Map<String, String> refs = services.get(serviceName);
-
-        if(refs == null) return Optional.absent();
-        Multimap<ServiceInstance, String> reverted = revertMap(refs);
-
-        ServiceInstance serviceInstance = ServiceInstance.fromObjectName(on);
-        Collection<String> references = reverted.get(serviceInstance);
-
-        if (expectedRefName.isPresent() && references.contains(expectedRefName.get())) {
-            logger.debug("Returning expected ref name {} for {}", expectedRefName.get(), on);
-            return expectedRefName;
-        } else if (references.size() > 0) {
-            String next = references.iterator().next();
-            logger.debug("Returning random ref name {} for {}", next, on);
-            return Optional.of(next);
-        } else
-            return Optional.absent();
-    }
-
-    private Multimap<ServiceInstance, String> revertMap(Map<String, String> refs) {
-        Multimap<ServiceInstance, String> multimap = HashMultimap.create();
-
-        for (Entry<String, String> e : refs.entrySet()) {
-            multimap.put(ServiceInstance.fromString(e.getValue()), e.getKey());
-        }
-
-        return multimap;
-    }
-
-    public boolean hasRefName(String key, String value, ObjectName on) {
-        return getRefNameOptional(key, value, on, Optional.<String>absent()).isPresent();
-    }
-
     public static final class ServiceInstance {
         public ServiceInstance(String moduleName, String instanceName) {
             this.moduleName = moduleName;
index 70b10d00191cd04c01e83dee8be44fd0c4db0f9d..6a0d7508c849ee12c16e0d742fd7dfcadae5fe65 100644 (file)
@@ -88,7 +88,6 @@ public class InstanceRuntime {
 
     public Element toXml(ObjectName rootOn, Set<ObjectName> childRbeOns, Document document, String instanceIndex,
                          Element parentElement, String namespace) {
-        // TODO namespace
         Element xml = instanceMapping.toXml(rootOn, null, namespace, document, parentElement);
 
         if (instanceIndex != null) {
index 11e97ebdbb9fc27c63e87d71c9962bcc494217ce..4936d1dbcda833b7fb5fdfe904d8b5e1493f6b34 100644 (file)
@@ -10,7 +10,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.runti
 
 import com.google.common.collect.Sets;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
@@ -41,7 +41,7 @@ public class ModuleRuntime {
     }
 
     public Element toXml(String namespace, Collection<ObjectName> runtimeBeanOns,
-                         Document document, ModuleConfig moduleConfig, ObjectName configBeanON, Services serviceTracker) {
+                         Document document, ModuleConfig moduleConfig, ObjectName configBeanON, ServiceRegistryWrapper serviceTracker) {
 
         Element moduleElement = moduleConfig.toXml(configBeanON, serviceTracker, document, namespace);
 
index 89c782c51c86e6acda56b426e6d76a70c2bc0c30..129143835fd024e53c290509662f968f9e691b6c 100644 (file)
@@ -11,11 +11,10 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.runti
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Multimap;
-import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Config;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.w3c.dom.Document;
@@ -61,9 +60,7 @@ public class Runtime {
         return retVal;
     }
 
-    public Element toXml(Set<ObjectName> instancesToMap, Set<ObjectName> configBeans, Document document, ServiceReferenceReadableRegistry serviceRegistry) {
-        Services serviceTracker = new Services(serviceRegistry);
-
+    public Element toXml(Set<ObjectName> instancesToMap, Set<ObjectName> configBeans, Document document, ServiceRegistryWrapper serviceRegistry) {
         Element root = document.createElement(XmlNetconfConstants.DATA_KEY);
 
         Element modulesElement = document.createElement(XmlNetconfConstants.MODULES_KEY);
@@ -88,11 +85,11 @@ public class Runtime {
                     Element runtimeXml;
                     ModuleConfig moduleConfig = moduleConfigs.get(localNamespace).get(moduleName);
                     if(instanceToRbe==null || instanceToRbe.containsKey(instanceName) == false) {
-                        runtimeXml = moduleConfig.toXml(instanceON, serviceTracker, document, localNamespace);
+                        runtimeXml = moduleConfig.toXml(instanceON, serviceRegistry, document, localNamespace);
                     } else {
                         ModuleRuntime moduleRuntime = moduleRuntimes.get(localNamespace).get(moduleName);
                         runtimeXml = moduleRuntime.toXml(localNamespace, instanceToRbe.get(instanceName), document,
-                                moduleConfig, instanceON, serviceTracker);
+                                moduleConfig, instanceON, serviceRegistry);
                     }
                     modulesElement.appendChild(runtimeXml);
                 }
index 65df965afd1e08167c63f70ba0c56159a085d2db..1d37fcd49378de3d577db338b034f987634f9518 100644 (file)
@@ -10,7 +10,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed
 
 import org.opendaylight.controller.config.util.ConfigTransactionClient;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -24,7 +24,7 @@ public abstract class AbstractEditConfigStrategy implements EditConfigStrategy {
 
     @Override
     public void executeConfiguration(String module, String instance, Map<String, AttributeConfigElement> configuration,
-                                     ConfigTransactionClient ta, Services services) {
+                                     ConfigTransactionClient ta, ServiceRegistryWrapper services) {
 
         try {
             ObjectName on = ta.lookupConfigBean(module, instance);
@@ -36,10 +36,13 @@ public abstract class AbstractEditConfigStrategy implements EditConfigStrategy {
 
     }
 
+    // TODO split missing instances handling strategies from edit config strategies in this hierarchy = REFACTOR
+    // edit configs should not handle missing
+
     abstract void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
-                                        String module, String instance, Services services);
+                                        String module, String instance, ServiceRegistryWrapper services);
 
     abstract void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
-                                  ObjectName objectName, Services services);
+                                  ObjectName objectName, ServiceRegistryWrapper services);
 
 }
index 12beaf8f8e19ff29048cb12c426c372ff047d14c..13e8c30211539485e0ac91ca1eb0ec06704e8409 100644 (file)
@@ -12,7 +12,7 @@ import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Multimap;
 import org.opendaylight.controller.config.util.ConfigTransactionClient;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -36,12 +36,12 @@ public class DeleteEditConfigStrategy extends AbstractEditConfigStrategy {
 
     @Override
     void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
-                               String module, String instance, Services services) {
+                               String module, String instance, ServiceRegistryWrapper services) {
         throw new IllegalStateException("Unable to delete " + module + ":" + instance + " , ServiceInstance not found");
     }
 
     @Override
-    void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, Services services) {
+    void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) {
         try {
             ta.destroyModule(on);
             logger.debug("ServiceInstance {} deleted successfully", on);
index 1bb1d9bfba7babf8fa2dc504909e4f89b6730530..709573c2414c3249917aae4e03851e0f9ada4da8 100644 (file)
@@ -25,6 +25,7 @@ import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfigElementResolved;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementDefinition;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementResolved;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
@@ -105,8 +106,8 @@ public class EditConfig extends AbstractConfigNetconfOperation {
         logger.debug("Test phase for {} operation successful", EditConfigXmlParser.EDIT_CONFIG);
     }
 
-    private void test(ConfigRegistryClient configRegistryClient,
-                      EditConfigExecution execution, EditStrategyType editStrategyType) {
+    private void test(ConfigRegistryClient configRegistryClient, EditConfigExecution execution,
+            EditStrategyType editStrategyType) {
         ObjectName taON = transactionProvider.getTestTransaction();
         try {
 
@@ -115,8 +116,11 @@ public class EditConfig extends AbstractConfigNetconfOperation {
                 transactionProvider.wipeTestTransaction(taON);
             }
 
-            setOnTransaction(configRegistryClient, execution.getResolvedXmlElements(), execution.getServices(), taON);
-            // TODO add service reference persistance testing here
+            ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON);
+
+            handleMisssingInstancesOnTransaction(ta, execution);
+            setServicesOnTransaction(ta, execution);
+            setOnTransaction(ta, execution);
             transactionProvider.validateTestTransaction(taON);
         } finally {
             transactionProvider.abortTestTransaction(taON);
@@ -132,14 +136,16 @@ public class EditConfig extends AbstractConfigNetconfOperation {
             transactionProvider.wipeTransaction();
         }
 
-        setOnTransaction(configRegistryClient, editConfigExecution.getResolvedXmlElements(),
-                editConfigExecution.getServices(), taON);
-        setServicesOnTransaction(configRegistryClient, editConfigExecution.getServices(), taON);
+        ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON);
+
+        handleMisssingInstancesOnTransaction(ta, editConfigExecution);
+        setServicesOnTransaction(ta, editConfigExecution);
+        setOnTransaction(ta, editConfigExecution);
     }
 
-    private void setServicesOnTransaction(ConfigRegistryClient configRegistryClient, Services services,
-                ObjectName taON) {
-        ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON);
+    private void setServicesOnTransaction(ConfigTransactionClient ta, EditConfigExecution execution) {
+
+        Services services = execution.getServices();
 
         Map<String, Map<String, Map<String, Services.ServiceInstance>>> namespaceToServiceNameToRefNameToInstance = services
                 .getNamespaceToServiceNameToRefNameToInstance();
@@ -153,9 +159,10 @@ public class EditConfig extends AbstractConfigNetconfOperation {
 
                 for (String refName : refNameToInstance.keySet()) {
                     ObjectName on = refNameToInstance.get(refName).getObjectName(ta.getTransactionName());
-                    // TODO check for duplicates
                     try {
-                        ta.saveServiceReference(qnameOfService, refName, on);
+                        ObjectName saved = ta.saveServiceReference(qnameOfService, refName, on);
+                        logger.debug("Saving service {} with on {} under name {} with service on {}", qnameOfService,
+                                on, refName, saved);
                     } catch (InstanceNotFoundException e) {
                         throw new IllegalStateException("Unable to save ref name " + refName + " for instance " + on, e);
                     }
@@ -168,11 +175,10 @@ public class EditConfig extends AbstractConfigNetconfOperation {
         return ta.getServiceInterfaceName(namespace, serviceName);
     }
 
-    private void setOnTransaction(ConfigRegistryClient configRegistryClient,
-                                  Map<String, Multimap<String, ModuleElementResolved>> resolvedXmlElements, Services services, ObjectName taON) {
-        ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON);
+    private void setOnTransaction(ConfigTransactionClient ta, EditConfigExecution execution) {
+
+        for (Multimap<String, ModuleElementResolved> modulesToResolved : execution.getResolvedXmlElements(ta).values()) {
 
-        for (Multimap<String, ModuleElementResolved> modulesToResolved : resolvedXmlElements.values()) {
             for (Entry<String, ModuleElementResolved> moduleToResolved : modulesToResolved.entries()) {
                 String moduleName = moduleToResolved.getKey();
 
@@ -181,7 +187,22 @@ public class EditConfig extends AbstractConfigNetconfOperation {
 
                 InstanceConfigElementResolved ice = moduleElementResolved.getInstanceConfigElementResolved();
                 EditConfigStrategy strategy = ice.getEditStrategy();
-                strategy.executeConfiguration(moduleName, instanceName, ice.getConfiguration(), ta, services);
+                strategy.executeConfiguration(moduleName, instanceName, ice.getConfiguration(), ta, execution.getServiceRegistryWrapper(ta));
+            }
+        }
+    }
+
+    private void handleMisssingInstancesOnTransaction(ConfigTransactionClient ta,
+            EditConfigExecution execution) {
+
+        for (Multimap<String,ModuleElementDefinition> modulesToResolved : execution.getModulesDefinition(ta).values()) {
+            for (Entry<String, ModuleElementDefinition> moduleToResolved : modulesToResolved.entries()) {
+                String moduleName = moduleToResolved.getKey();
+
+                ModuleElementDefinition moduleElementDefinition = moduleToResolved.getValue();
+
+                EditConfigStrategy strategy = moduleElementDefinition.getEditStrategy();
+                strategy.executeConfiguration(moduleName, moduleElementDefinition.getInstanceName(), null, ta, execution.getServiceRegistryWrapper(ta));
             }
         }
     }
@@ -189,32 +210,38 @@ public class EditConfig extends AbstractConfigNetconfOperation {
     public static Config getConfigMapping(ConfigRegistryClient configRegistryClient,
             Map<String/* Namespace from yang file */,
                     Map<String /* Name of module entry from yang file */, ModuleMXBeanEntry>> mBeanEntries) {
-        Map<String, Map<String, ModuleConfig>> factories = transform(configRegistryClient, mBeanEntries);
+        Map<String, Map<String, ModuleConfig>> factories = transformMbeToModuleConfigs(configRegistryClient, mBeanEntries);
 
         return new Config(factories);
     }
 
-    // TODO refactor
-    private static Map<String/* Namespace from yang file */,
-            Map<String /* Name of module entry from yang file */, ModuleConfig>> transform
-    (final ConfigRegistryClient configRegistryClient, Map<String/* Namespace from yang file */,
+    public static Map<String/* Namespace from yang file */,
+            Map<String /* Name of module entry from yang file */, ModuleConfig>> transformMbeToModuleConfigs
+            (final ConfigRegistryClient configRegistryClient, Map<String/* Namespace from yang file */,
                     Map<String /* Name of module entry from yang file */, ModuleMXBeanEntry>> mBeanEntries) {
-        return Maps.transformEntries(mBeanEntries,
-                new Maps.EntryTransformer<String, Map<String, ModuleMXBeanEntry>, Map<String, ModuleConfig>>() {
-
-                    @Override
-                    public Map<String, ModuleConfig> transformEntry(String arg0, Map<String, ModuleMXBeanEntry> arg1) {
-                        return Maps.transformEntries(arg1,
-                                new Maps.EntryTransformer<String, ModuleMXBeanEntry, ModuleConfig>() {
-
-                                    @Override
-                                    public ModuleConfig transformEntry(String key, ModuleMXBeanEntry moduleMXBeanEntry) {
-                                        return new ModuleConfig(key, new InstanceConfig(configRegistryClient, moduleMXBeanEntry
-                                                .getAttributes()), moduleMXBeanEntry.getProvidedServices().values());
-                                    }
-                                });
-                    }
-                });
+
+        Map<String, Map<String, ModuleConfig>> namespaceToModuleNameToModuleConfig = Maps.newHashMap();
+
+        for (String namespace : mBeanEntries.keySet()) {
+            for (Entry<String, ModuleMXBeanEntry> moduleNameToMbe : mBeanEntries.get(namespace).entrySet()) {
+                String moduleName = moduleNameToMbe.getKey();
+                ModuleMXBeanEntry moduleMXBeanEntry = moduleNameToMbe.getValue();
+
+                ModuleConfig moduleConfig = new ModuleConfig(moduleName, new InstanceConfig(configRegistryClient,
+                        moduleMXBeanEntry.getAttributes()), moduleMXBeanEntry
+                        .getProvidedServices().values());
+
+                Map<String, ModuleConfig> moduleNameToModuleConfig = namespaceToModuleNameToModuleConfig.get(namespace);
+                if(moduleNameToModuleConfig == null) {
+                    moduleNameToModuleConfig = Maps.newHashMap();
+                    namespaceToModuleNameToModuleConfig.put(namespace, moduleNameToModuleConfig);
+                }
+
+                moduleNameToModuleConfig.put(moduleName, moduleConfig);
+            }
+        }
+
+        return namespaceToModuleNameToModuleConfig;
     }
 
     @Override
index 23166e8cca5c6e0d4c6fbc955de83de8db94a6f3..cebcb0239bc81cda1d7ef6a83bc0f15b8c3bdd90 100644 (file)
@@ -10,13 +10,13 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed
 
 import org.opendaylight.controller.config.util.ConfigTransactionClient;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 
 import java.util.Map;
 
 public interface EditConfigStrategy {
 
     void executeConfiguration(String module, String instance, Map<String, AttributeConfigElement> configuration,
-                              ConfigTransactionClient ta, Services services);
+                              ConfigTransactionClient ta, ServiceRegistryWrapper services);
 
 }
index 81327133b82a440c9b7599672134e7b63fd00f49..e481bbe57f68bf4d043a8365362ce2c90ab46893 100644 (file)
@@ -14,10 +14,11 @@ import com.google.common.base.Preconditions;
 import com.google.common.collect.Multimap;
 import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
 import org.opendaylight.controller.config.util.ConfigRegistryClient;
-import org.opendaylight.controller.config.util.ConfigTransactionClient;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Config;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementDefinition;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementResolved;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.Datastore;
 import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
@@ -26,7 +27,6 @@ import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.management.ObjectName;
 import java.util.Arrays;
 import java.util.Map;
 
@@ -98,11 +98,7 @@ public class EditConfigXmlParser {
 
         XmlElement configElement = xml.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.CONFIG_KEY);
 
-        ObjectName taON = transactionProvider.getOrCreateTransaction();
-        ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON);
-
-        return new EditConfigXmlParser.EditConfigExecution(cfgMapping, configElement, testOption,
-                ta, editStrategyType);
+        return new EditConfigXmlParser.EditConfigExecution(cfgMapping, configElement, testOption, editStrategyType);
     }
 
     @VisibleForTesting
@@ -132,15 +128,17 @@ public class EditConfigXmlParser {
     @VisibleForTesting
     static class EditConfigExecution {
 
-        private final Map<String, Multimap<String, ModuleElementResolved>> resolvedXmlElements;
         private final TestOption testOption;
         private final EditStrategyType defaultEditStrategyType;
         private final Services services;
-
-        EditConfigExecution(Config configResolver, XmlElement configElement, TestOption testOption, ServiceReferenceReadableRegistry ta, EditStrategyType defaultStrategy) {
-            Config.ConfigElementResolved configElementResolved = configResolver.fromXml(configElement, defaultStrategy, ta);
-            this.resolvedXmlElements = configElementResolved.getResolvedModules();
-            this.services = configElementResolved.getServices();
+        private final Config configResolver;
+        private final XmlElement configElement;
+
+        EditConfigExecution(Config configResolver, XmlElement configElement, TestOption testOption, EditStrategyType defaultStrategy) {
+            Config.checkUnrecognisedChildren(configElement);
+            this.configResolver = configResolver;
+            this.configElement = configElement;
+            this.services = configResolver.fromXmlServices(configElement);
             this.testOption = testOption;
             this.defaultEditStrategyType = defaultStrategy;
         }
@@ -153,8 +151,17 @@ public class EditConfigXmlParser {
             return testOption == TestOption.set || testOption == TestOption.testThenSet;
         }
 
-        Map<String, Multimap<String, ModuleElementResolved>> getResolvedXmlElements() {
-            return resolvedXmlElements;
+        Map<String, Multimap<String, ModuleElementResolved>> getResolvedXmlElements(ServiceReferenceReadableRegistry serviceRegistry) {
+            return configResolver.fromXmlModulesResolved(configElement, defaultEditStrategyType, getServiceRegistryWrapper(serviceRegistry));
+        }
+
+        ServiceRegistryWrapper getServiceRegistryWrapper(ServiceReferenceReadableRegistry serviceRegistry) {
+            // TODO cache service registry
+            return new ServiceRegistryWrapper(serviceRegistry);
+        }
+
+        Map<String, Multimap<String,ModuleElementDefinition>> getModulesDefinition(ServiceReferenceReadableRegistry serviceRegistry) {
+            return configResolver.fromXmlModulesMap(configElement, defaultEditStrategyType, getServiceRegistryWrapper(serviceRegistry));
         }
 
         EditStrategyType getDefaultStrategy() {
index 06befb0565067592b58465782d66caa74a568100..f2e2b193a8f1b7d90380c3cee6916a1a9b0514c1 100644 (file)
@@ -10,14 +10,14 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed
 
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Multimap;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.config.util.ConfigTransactionClient;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.management.Attribute;
-import javax.management.InstanceAlreadyExistsException;
 import javax.management.InstanceNotFoundException;
 import javax.management.ObjectName;
 import java.util.Map;
@@ -38,22 +38,13 @@ public class MergeEditConfigStrategy extends AbstractEditConfigStrategy {
 
     @Override
     void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
-                               String module, String instance, Services services) {
-        ObjectName on = null;
-        try {
-            on = ta.createModule(module, instance);
-            logger.info("New instance for {} {} created under name {}", module, instance, on);
-            addRefNames(services, providedServices, module, instance, ta, on);
-            executeStrategy(configuration, ta, on, services);
-        } catch (InstanceAlreadyExistsException e1) {
-            throw new IllegalStateException("Unable to create instance for " + module + " : " + instance);
-        } catch (InstanceNotFoundException e) {
-            throw new IllegalStateException("Unable to save default ref name for instance " + on, e);
-        }
+            String module, String instance, ServiceRegistryWrapper services) {
+        throw new IllegalStateException(
+                "Unable to handle missing instance, no missing instances should appear at this point, missing: "
+                        + module + ":" + instance);
     }
 
-    private void addRefNames(Services services, Multimap<String, String> providedServices, String module,
-            String instance, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException {
+    private void addRefNames(ServiceRegistryWrapper services, Multimap<String, String> providedServices, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException {
         for (Entry<String, String> namespaceToService : providedServices.entries()) {
 
             if(services.hasRefName(namespaceToService.getKey(),
@@ -61,14 +52,20 @@ public class MergeEditConfigStrategy extends AbstractEditConfigStrategy {
                 continue;
 
             String refName = services.getNewDefaultRefName(namespaceToService.getKey(), namespaceToService.getValue(),
-                    module, instance);
+                    ObjectNameUtil.getFactoryName(on), ObjectNameUtil.getInstanceName(on));
             ta.saveServiceReference(
                     ta.getServiceInterfaceName(namespaceToService.getKey(), namespaceToService.getValue()), refName, on);
         }
     }
 
     @Override
-    void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, Services services) {
+    void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) {
+        try {
+            addRefNames(services, providedServices, ta, on);
+        } catch (InstanceNotFoundException e) {
+            throw new IllegalStateException("Unable to save default ref name for instance " + on, e);
+        }
+
         for (Entry<String, AttributeConfigElement> configAttributeEntry : configuration.entrySet()) {
             try {
                 AttributeConfigElement ace = configAttributeEntry.getValue();
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java
new file mode 100644 (file)
index 0000000..8ed9eb8
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * 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.netconf.confignetconfconnector.operations.editconfig;
+
+import org.opendaylight.controller.config.util.ConfigTransactionClient;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.ObjectName;
+import java.util.Map;
+
+public class MissingInstanceHandlingStrategy extends AbstractEditConfigStrategy {
+
+    private static final Logger logger = LoggerFactory.getLogger(MissingInstanceHandlingStrategy.class);
+
+    @Override
+    void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
+            String module, String instance, ServiceRegistryWrapper services) {
+        ObjectName on = null;
+        try {
+            on = ta.createModule(module, instance);
+            logger.info("New instance for {} {} created under name {}", module, instance, on);
+        } catch (InstanceAlreadyExistsException e1) {
+            throw new IllegalStateException("Unable to create instance for " + module + " : " + instance);
+        }
+    }
+
+    @Override
+    void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
+            ObjectName objectName, ServiceRegistryWrapper services) {
+        return;
+    }
+}
index 8347c6b88e23325fa579527a5f30785a99216b7d..bd182a4267280021ef2c6a66f50db98af020c26b 100644 (file)
@@ -8,21 +8,21 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
 
-import java.util.Map;
-
 import org.opendaylight.controller.config.util.ConfigTransactionClient;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.Map;
+
 public class NoneEditConfigStrategy implements EditConfigStrategy {
 
     private static final Logger logger = LoggerFactory.getLogger(NoneEditConfigStrategy.class);
 
     @Override
     public void executeConfiguration(String module, String instance, Map<String, AttributeConfigElement> configuration,
-                                     ConfigTransactionClient ta, Services services) {
+                                     ConfigTransactionClient ta, ServiceRegistryWrapper services) {
         logger.debug("Skipping configuration element for {}:{}", module, instance);
     }
 
index 64f082da40773b4a6dab473bed7e45722847ffca..df1f65372aea4068fdea45fde41c20c4217a9181 100644 (file)
@@ -10,7 +10,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed
 
 import org.opendaylight.controller.config.util.ConfigTransactionClient;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -22,7 +22,7 @@ public class RemoveEditConfigStrategy extends DeleteEditConfigStrategy {
 
     @Override
     void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
-                               String module, String instance, Services services) {
+                               String module, String instance, ServiceRegistryWrapper services) {
         logger.warn("Unable to delete {}:{}, ServiceInstance not found", module, instance);
     }
 }
index 43d852e76a32f3b35a8bee016b6ca4ab4f8c6d04..4976244eae57cb6eadfec806620a10f43a2387d4 100644 (file)
@@ -10,14 +10,14 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed
 
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Multimap;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
 import org.opendaylight.controller.config.util.ConfigTransactionClient;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.management.Attribute;
-import javax.management.InstanceAlreadyExistsException;
 import javax.management.InstanceNotFoundException;
 import javax.management.ObjectName;
 import java.util.Map;
@@ -39,23 +39,13 @@ public class ReplaceEditConfigStrategy extends AbstractEditConfigStrategy {
 
     @Override
     void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
-                               String module, String instance, Services services) {
-        ObjectName on = null;
-        try {
-            on = ta.createModule(module, instance);
-            logger.debug("New instance for {} {} created under name {}", module, instance, on);
-            addRefNames(services, providedServices, module, instance, ta, on);
-            executeStrategy(configuration, ta, on, services);
-        } catch (InstanceAlreadyExistsException e) {
-            logger.warn("Error creating instance {}:{}, replace failed", module, instance, e);
-            throw new IllegalStateException("Unable to create new instance for " + module + " : " + instance, e);
-        } catch (InstanceNotFoundException e) {
-            throw new IllegalStateException("Unable to save default ref name for instance " + on, e);
-        }
+                               String module, String instance, ServiceRegistryWrapper services) {
+        throw new IllegalStateException(
+                "Unable to handle missing instance, no missing instances should appear at this point, missing: "
+                        + module + ":" + instance);
     }
 
-    private void addRefNames(Services services, Multimap<String, String> providedServices, String module,
-                             String instance, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException {
+    private void addRefNames(ServiceRegistryWrapper services, Multimap<String, String> providedServices, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException {
         for (Entry<String, String> namespaceToService : providedServices.entries()) {
 
             if(services.hasRefName(namespaceToService.getKey(),
@@ -63,13 +53,20 @@ public class ReplaceEditConfigStrategy extends AbstractEditConfigStrategy {
                 continue;
 
             String refName = services.getNewDefaultRefName(namespaceToService.getKey(), namespaceToService.getValue(),
-                    module, instance);
+                    ObjectNameUtil.getFactoryName(on), ObjectNameUtil.getInstanceName(on));
             ta.saveServiceReference(
                     ta.getServiceInterfaceName(namespaceToService.getKey(), namespaceToService.getValue()), refName, on);
         }
     }
+
     @Override
-    void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, Services services) {
+    void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) {
+        try {
+            addRefNames(services, providedServices, ta, on);
+        } catch (InstanceNotFoundException e) {
+            throw new IllegalStateException("Unable to save default ref name for instance " + on, e);
+        }
+
         for (Entry<String, AttributeConfigElement> configAttributeEntry : configuration.entrySet()) {
             try {
                 AttributeConfigElement ace = configAttributeEntry.getValue();
index efe4f7dde9b483bd488e753a90cee2a335b4de05..ea602091a0423ec0957a5c0974f163b89f0fd72a 100644 (file)
@@ -20,12 +20,13 @@ import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorT
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime.InstanceRuntime;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime.ModuleRuntime;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime.Runtime;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.Datastore;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.getconfig.GetConfig;
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
 import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
 import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
@@ -143,14 +144,14 @@ public class Get extends AbstractConfigNetconfOperation {
 
         final Map<String, Map<String, ModuleRuntime>> moduleRuntimes = createModuleRuntimes(configRegistryClient,
                 yangStoreSnapshot.getModuleMXBeanEntryMap());
-        final Map<String, Map<String, ModuleConfig>> moduleConfigs = GetConfig.transform(configRegistryClient,
-                yangStoreSnapshot.getModuleMXBeanEntryMap());
+        final Map<String, Map<String, ModuleConfig>> moduleConfigs = EditConfig.transformMbeToModuleConfigs(
+                configRegistryClient, yangStoreSnapshot.getModuleMXBeanEntryMap());
 
         final Runtime runtime = new Runtime(moduleRuntimes, moduleConfigs);
 
         ObjectName txOn = transactionProvider.getOrCreateTransaction();
         ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(txOn);
-        final Element element = runtime.toXml(runtimeBeans, configBeans, document, ta);
+        final Element element = runtime.toXml(runtimeBeans, configBeans, document, new ServiceRegistryWrapper(ta));
 
         logger.info("{} operation successful", XmlNetconfConstants.GET);
 
index d75cfd5d6f049d9d586ac856fa0ccd7b70b3c00c..16dd5ad80a695aa791ec5b8e86ebacec9dac50ab 100644 (file)
@@ -9,21 +9,18 @@
 package org.opendaylight.controller.netconf.confignetconfconnector.operations.getconfig;
 
 import com.google.common.base.Optional;
-import com.google.common.collect.Maps;
 import org.opendaylight.controller.config.util.ConfigRegistryClient;
 import org.opendaylight.controller.config.util.ConfigTransactionClient;
 import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
-import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Config;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.Datastore;
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
 import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
 import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
@@ -83,14 +80,14 @@ public class GetConfig extends AbstractConfigNetconfOperation {
         final Set<ObjectName> instances = Datastore.getInstanceQueryStrategy(source, this.transactionProvider)
                 .queryInstances(configRegistryClient);
 
-        final Config configMapping = new Config(transform(configRegistryClient,
+        final Config configMapping = new Config(EditConfig.transformMbeToModuleConfigs(configRegistryClient,
                 yangStoreSnapshot.getModuleMXBeanEntryMap()));
 
 
         ObjectName on = transactionProvider.getOrCreateTransaction();
         ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(on);
 
-        Services serviceTracker = new Services(ta);
+        ServiceRegistryWrapper serviceTracker = new ServiceRegistryWrapper(ta);
         dataElement = configMapping.toXml(instances, this.maybeNamespace, document, dataElement, serviceTracker);
 
         logger.info("{} operation successful", GET_CONFIG);
@@ -98,27 +95,6 @@ public class GetConfig extends AbstractConfigNetconfOperation {
         return dataElement;
     }
 
-    // TODO refactor ... duplicate code
-    public static Map<String, Map<String, ModuleConfig>> transform(final ConfigRegistryClient configRegistryClient,
-            Map<String, Map<String, ModuleMXBeanEntry>> mBeanEntries) {
-        return Maps.transformEntries(mBeanEntries,
-                new Maps.EntryTransformer<String, Map<String, ModuleMXBeanEntry>, Map<String, ModuleConfig>>() {
-
-                    @Override
-                    public Map<String, ModuleConfig> transformEntry(String arg0, Map<String, ModuleMXBeanEntry> arg1) {
-                        return Maps.transformEntries(arg1,
-                                new Maps.EntryTransformer<String, ModuleMXBeanEntry, ModuleConfig>() {
-
-                                    @Override
-                                    public ModuleConfig transformEntry(String key, ModuleMXBeanEntry value) {
-                                        return new ModuleConfig(key, new InstanceConfig(configRegistryClient, value
-                                                .getAttributes()), value.getProvidedServices().values());
-                                    }
-                                });
-                    }
-                });
-    }
-
     @Override
     protected String getOperationName() {
         return GET_CONFIG;
index 7463bdd429e4dc9552dfc390d59bcaba32fe5e5b..f838c6f9f5e69160b4c889d799f7e42ed2c7338c 100644 (file)
@@ -127,7 +127,6 @@ public class RuntimeRpc extends AbstractConfigNetconfOperation {
         if (contextInstanceElement.isPresent() == false)
             return HandlingPriority.CANNOT_HANDLE;
 
-        // FIXME update xpath to instance to conform to config-api yang
         final RuntimeRpcElementResolved id = RuntimeRpcElementResolved.fromXpath(contextInstanceElement.get()
                 .getTextContent(), netconfOperationName, netconfOperationNamespace);
 
index 1c806742e9b141c7f836d9565a9f449255406b69..fc8ddc01bdfb2da52ef0aa6cd0bd28f519878377 100644 (file)
@@ -9,13 +9,6 @@
 package org.opendaylight.controller.netconf.confignetconfconnector.util;
 
 import com.google.common.base.Preconditions;
-import org.opendaylight.controller.config.yang.store.api.YangStoreException;
-import org.opendaylight.controller.config.yang.store.api.YangStoreService;
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType;
 
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
@@ -41,15 +34,4 @@ public final class Util {
                 + " should be " + clazz + " of " + value);
     }
 
-    // TODO: add message and proper error types
-    public static YangStoreSnapshot getYangStore(final YangStoreService yangStoreService)
-            throws NetconfDocumentedException {
-        try {
-            return yangStoreService.getYangStoreSnapshot();
-        } catch (final YangStoreException e) {
-            throw new NetconfDocumentedException("TODO", e, ErrorType.application, ErrorTag.bad_attribute,
-                    ErrorSeverity.error);
-        }
-    }
-
 }
index 11cf1aae6a42bc184dda8288dddcafa9ba47f419..9511673ea40781446c4134f02d3b1defbe47353a 100644 (file)
@@ -143,12 +143,19 @@ public class NetconfMappingTest extends AbstractConfigTest {
                 "ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1",
                 "ref_from_code_to_instance-from-code_1");
 
+
         edit("netconfMessages/editConfig_addServiceName.xml");
         config = getConfigCandidate();
         assertCorrectServiceNames(config, 7, "ref_test2", "user_to_instance_from_code", "ref_dep_user",
                 "ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1",
                 "ref_from_code_to_instance-from-code_1", "ref_dep_user_another");
 
+        edit("netconfMessages/editConfig_addServiceNameOnTest.xml");
+        config = getConfigCandidate();
+        assertCorrectServiceNames(config, 7, "ref_test2", "user_to_instance_from_code", "ref_dep_user",
+                "ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1",
+                "ref_from_code_to_instance-from-code_1", "ref_dep_user_another");
+
         commit();
         config = getConfigRunning();
         assertCorrectRefNamesForDependencies(config);
@@ -229,6 +236,7 @@ public class NetconfMappingTest extends AbstractConfigTest {
 
         edit("netconfMessages/editConfig.xml");
         Element configCandidate = getConfigCandidate();
+        System.err.println(XmlUtil.toString(configCandidate));
         checkBinaryLeafEdited(configCandidate);
 
 
index 6e7a225f38452250ca4803c17ac56a2d2999822f..505a91c6cec4ba7f4ce1139059538d322cf8ed69 100644 (file)
@@ -23,7 +23,9 @@ import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfigElementResolved;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementDefinition;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementResolved;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.ValidateTest;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigXmlParser.EditConfigExecution;
@@ -35,7 +37,7 @@ import java.util.Collections;
 import java.util.Map;
 
 import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyMap;
+import static org.mockito.Matchers.anyMapOf;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
@@ -82,8 +84,8 @@ public class EditConfigTest {
                 ValidateTest.NETCONF_SESSION_ID_FOR_REPORTING);
         EditConfigStrategy editStrat = mock(EditConfigStrategy.class);
 
-        doNothing().when(editStrat).executeConfiguration(anyString(), anyString(), anyMap(),
-                any(ConfigTransactionClient.class), any(Services.class));
+        doNothing().when(editStrat).executeConfiguration(anyString(), anyString(), anyMapOf(String.class, AttributeConfigElement.class),
+                any(ConfigTransactionClient.class), any(ServiceRegistryWrapper.class));
 
         EditConfigExecution editConfigExecution = mockExecution(editStrat);
 
@@ -96,20 +98,44 @@ public class EditConfigTest {
         verify(provider).getOrCreateTransaction();
 
         // For every instance execute strat
-        verify(editStrat, times(2/* Test */+ 2/* Set */)).executeConfiguration(anyString(), anyString(), anyMap(),
-                any(ConfigTransactionClient.class), any(Services.class));
+        verify(editStrat, times(2/* Test */+ 2/* Set */ + 2/*Handle missing instance Test*/ + 2 /*Handle missing instance Set*/)).executeConfiguration(anyString(),
+                anyString(), anyMapOf(String.class, AttributeConfigElement.class),
+                any(ConfigTransactionClient.class), any(ServiceRegistryWrapper.class));
     }
 
     private EditConfigExecution mockExecution(EditConfigStrategy editStrat) {
         EditConfigExecution mock = mock(EditConfigExecution.class);
-        doReturn(getMapping(editStrat)).when(mock).getResolvedXmlElements();
+        doReturn(getMapping(editStrat)).when(mock).getResolvedXmlElements(any(ConfigTransactionClient.class));
+        doReturn(getMappingDefinition(editStrat)).when(mock).getModulesDefinition(any(ConfigTransactionClient.class));
         doReturn(EditStrategyType.merge).when(mock).getDefaultStrategy();
         doReturn(true).when(mock).shouldSet();
         doReturn(true).when(mock).shouldTest();
-        doReturn(mockServices()).when(mock).getServices();
+        doReturn(mockServices()).when(mock).getServiceRegistryWrapper(any(ConfigTransactionClient.class));
+        doReturn(new Services()).when(mock).getServices();
         return mock;
     }
 
+    private Object getMappingDefinition(EditConfigStrategy editStrat) {
+        Map<String, Multimap<String, ModuleElementDefinition>> result = Maps.newHashMap();
+
+        Multimap<String, ModuleElementDefinition> innerMultimap = HashMultimap.create();
+        Map<String, AttributeConfigElement> attributes = getSimpleAttributes();
+
+        ModuleElementDefinition mockedDefinition = mock(ModuleElementDefinition.class);
+        doReturn(editStrat).when(mockedDefinition).getEditStrategy();
+        doReturn("i1").when(mockedDefinition).getInstanceName();
+        innerMultimap.put("m1", mockedDefinition);
+
+        ModuleElementDefinition mockedDefinition2 = mock(ModuleElementDefinition.class);
+        doReturn(editStrat).when(mockedDefinition2).getEditStrategy();
+        doReturn("i2").when(mockedDefinition2).getInstanceName();
+        innerMultimap.put("m1", mockedDefinition2);
+
+        result.put("n1", innerMultimap);
+
+        return result;
+    }
+
     private static ServiceReferenceReadableRegistry mockServiceRegistry() {
         ServiceReferenceReadableRegistry mock = mock(ServiceReferenceReadableRegistry.class);
         doReturn(
@@ -120,8 +146,8 @@ public class EditConfigTest {
         return mock;
     }
 
-    static Services mockServices() {
-        return new Services(mockServiceRegistry());
+    static ServiceRegistryWrapper mockServices() {
+        return new ServiceRegistryWrapper(mockServiceRegistry());
     }
 
     private Map<String, Multimap<String, ModuleElementResolved>> getMapping(EditConfigStrategy editStrat) {
index 1c3ac7a455c4f80eb8a1607f1e942bb2c91f3977..b66a1a57c20c9288b60e79cdb54daa1cf53bbec3 100644 (file)
@@ -8,6 +8,7 @@
 
 package org.opendaylight.controller.netconf.persist.impl;
 
+import org.opendaylight.controller.config.persist.api.Persister;
 import org.opendaylight.controller.netconf.api.jmx.CommitJMXNotification;
 import org.opendaylight.controller.netconf.api.jmx.DefaultCommitOperationMXBean;
 import org.opendaylight.controller.netconf.api.jmx.NetconfJMXNotification;
@@ -36,11 +37,11 @@ public class ConfigPersisterNotificationHandler implements NotificationListener,
     private static final Logger logger = LoggerFactory.getLogger(ConfigPersisterNotificationHandler.class);
     private final MBeanServerConnection mBeanServerConnection;
     private final NetconfClient netconfClient;
-    private final PersisterAggregator persisterAggregator;
+    private final Persister persisterAggregator;
     private final Pattern ignoredMissingCapabilityRegex;
 
     public ConfigPersisterNotificationHandler(MBeanServerConnection mBeanServerConnection, NetconfClient netconfClient,
-                                              PersisterAggregator persisterAggregator, Pattern ignoredMissingCapabilityRegex) {
+                                              Persister persisterAggregator, Pattern ignoredMissingCapabilityRegex) {
         this.mBeanServerConnection = mBeanServerConnection;
         this.netconfClient = netconfClient;
         this.persisterAggregator = persisterAggregator;
@@ -72,8 +73,9 @@ public class ConfigPersisterNotificationHandler implements NotificationListener,
         if (notification instanceof CommitJMXNotification) {
             try {
                 handleAfterCommitNotification((CommitJMXNotification) notification);
-            } catch (Exception e) {
-                // TODO: notificationBroadcast support logs only DEBUG
+            } catch (Throwable e) {
+                // log exceptions from notification Handler here since
+                // notificationBroadcastSupport logs only DEBUG level
                 logger.warn("Exception occured during notification handling: ", e);
                 throw e;
             }
index 811ba38c10068d470492a93073a656f6b0c42f79..86a024a240db6b97ba45cb493dba36b8fe1d1d62 100644 (file)
@@ -40,8 +40,6 @@ public final class Util {
         return true;
     }
 
-
-    // TODO: check if closing in correct order
     public static void closeClientAndDispatcher(NetconfClient client) {
         NetconfClientDispatcher dispatcher = client.getNetconfClientDispatcher();
         Exception fromClient = null;
index 15ed5c48fab01635635ea6578c3017d1bcd94a82..2a95cca937ddbee88a7f0723b47f2991d0c64a5f 100644 (file)
@@ -1,10 +1,9 @@
-/**
- * @author Tomas Olvecky
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
  *
- * 11 2013
- *
- * Copyright (c) 2013 by Cisco Systems, Inc.
- * 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.netconf.persist.impl.osgi;
 
index 2ce779a1f54e9ce4f68b9c7f1db478d9de4e0201..8b8c886a1c0328b558a4992c7d67b6b99b71800c 100644 (file)
@@ -71,6 +71,10 @@ public class NetconfClient implements Closeable {
         return new NetconfClient(clientLabelForLogging,address,strat,netconfClientDispatcher);
     }
 
+    public static NetconfClient clientFor(String clientLabelForLogging, InetSocketAddress address, ReconnectStrategy strat, NetconfClientDispatcher netconfClientDispatcher,NetconfClientSessionListener listener) throws InterruptedException {
+        return new NetconfClient(clientLabelForLogging,address,strat,netconfClientDispatcher,listener);
+    }
+
     public NetconfClient(String clientLabelForLogging, InetSocketAddress address, int connectTimeoutMs,
             NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException {
         this(clientLabelForLogging, address,
@@ -83,6 +87,17 @@ public class NetconfClient implements Closeable {
                 DEFAULT_CONNECT_TIMEOUT), netconfClientDispatcher);
     }
 
+    public NetconfClient(String clientLabelForLogging, InetSocketAddress address, ReconnectStrategy strat,
+            NetconfClientDispatcher netconfClientDispatcher, NetconfClientSessionListener listener) throws InterruptedException{
+        this.label = clientLabelForLogging;
+        dispatch = netconfClientDispatcher;
+        sessionListener = listener;
+        Future<NetconfClientSession> clientFuture = dispatch.createClient(address, sessionListener, strat);
+        this.address = address;
+        clientSession = get(clientFuture);
+        this.sessionId = clientSession.getSessionId();
+    }
+
     public NetconfMessage sendMessage(NetconfMessage message) {
         return sendMessage(message, 5, 1000);
     }
@@ -90,6 +105,7 @@ public class NetconfClient implements Closeable {
     public NetconfMessage sendMessage(NetconfMessage message, int attempts, int attemptMsDelay) {
         long startTime = System.currentTimeMillis();
         Preconditions.checkState(clientSession.isUp(), "Session was not up yet");
+        //logger.debug("Sending message: {}",XmlUtil.toString(message.getDocument()));
         clientSession.sendMessage(message);
         try {
             return sessionListener.getLastMessage(attempts, attemptMsDelay);
index 1d2e039b290d9eef4c77e90fa99ef36257c29c5c..8dbdb26bff1934d1f2071be7114363985a16d5f7 100644 (file)
@@ -15,6 +15,8 @@ import org.opendaylight.controller.netconf.impl.mapping.CapabilityProvider;
 import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshot;
 import org.opendaylight.controller.netconf.mapping.api.Capability;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.util.Collections;
 import java.util.Map;
@@ -24,6 +26,8 @@ public class CapabilityProviderImpl implements CapabilityProvider {
     private final NetconfOperationServiceSnapshot netconfOperationServiceSnapshot;
     private final Set<String> capabilityURIs;
 
+    private static final Logger logger = LoggerFactory.getLogger(DefaultCommitNotificationProducer.class);
+
     public CapabilityProviderImpl(NetconfOperationServiceSnapshot netconfOperationServiceSnapshot) {
         this.netconfOperationServiceSnapshot = netconfOperationServiceSnapshot;
         Map<String, Capability> urisToCapabilitiesInternalMap = getCapabilitiesInternal(netconfOperationServiceSnapshot);
@@ -38,7 +42,11 @@ public class CapabilityProviderImpl implements CapabilityProvider {
             final Set<Capability> caps = netconfOperationService.getCapabilities();
 
             for (Capability cap : caps) {
-                // TODO check for duplicates ?
+
+                if(capabilityMap.containsKey(cap.getCapabilityUri())) {
+                    logger.debug("Duplicate capability {} from service {}", cap.getCapabilityUri(), netconfOperationService);
+                }
+
                 capabilityMap.put(cap.getCapabilityUri(), cap);
             }
         }
index 4f60788975fb910f5ae29a4fbac35b8f28d4fe08..7c5bd0cb21dcc25988c3e66c17f7821b3a780d11 100644 (file)
@@ -12,12 +12,13 @@ import io.netty.channel.ChannelFuture;
 import io.netty.channel.EventLoopGroup;
 import io.netty.channel.socket.SocketChannel;
 import io.netty.util.concurrent.Promise;
-import java.net.InetSocketAddress;
 import org.opendaylight.controller.netconf.api.NetconfSession;
 import org.opendaylight.controller.netconf.impl.util.DeserializerExceptionHandler;
 import org.opendaylight.controller.netconf.util.AbstractChannelInitializer;
 import org.opendaylight.protocol.framework.AbstractDispatcher;
 
+import java.net.InetSocketAddress;
+
 public class NetconfServerDispatcher extends AbstractDispatcher<NetconfSession, NetconfServerSessionListener> {
 
     private final ServerChannelInitializer initializer;
@@ -28,7 +29,6 @@ public class NetconfServerDispatcher extends AbstractDispatcher<NetconfSession,
         this.initializer = serverChannelInitializer;
     }
 
-    // TODO test create server with same address twice
     public ChannelFuture createServer(InetSocketAddress address) {
 
         return super.createServer(address, new PipelineInitializer<NetconfSession>() {
index e74723032d247888c65b22c1eed7d9b62a543d71..91734beacbf57f3e164411b6832dcfda1ac93a02 100644 (file)
@@ -8,6 +8,7 @@
 
 package org.opendaylight.controller.netconf.impl;
 
+import com.google.common.base.Preconditions;
 import io.netty.channel.Channel;
 import io.netty.util.Timer;
 import io.netty.util.concurrent.Promise;
@@ -28,9 +29,12 @@ import org.w3c.dom.Node;
 
 import javax.xml.xpath.XPathConstants;
 import javax.xml.xpath.XPathExpression;
+import java.io.InputStream;
 
 public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorFactory {
 
+    public static final String SERVER_HELLO_XML_LOCATION = "/server_hello.xml";
+
     private final Timer timer;
 
     private static final Document helloMessageTemplate = loadHelloMessageTemplate();
@@ -45,8 +49,11 @@ public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorF
     }
 
     private static Document loadHelloMessageTemplate() {
-        return NetconfUtil.createMessage(
-                NetconfServerSessionNegotiatorFactory.class.getResourceAsStream("/server_hello.xml")).getDocument();
+        InputStream resourceAsStream = NetconfServerSessionNegotiatorFactory.class
+                .getResourceAsStream(SERVER_HELLO_XML_LOCATION);
+        Preconditions.checkNotNull(resourceAsStream, "Unable to load server hello message blueprint from %s",
+                SERVER_HELLO_XML_LOCATION);
+        return NetconfUtil.createMessage(resourceAsStream).getDocument();
     }
 
     @Override
index 1b3542595f319132820d6b762d305cff740d7a75..505c74714a71c269ad9721497cdbffaedd4fb706 100644 (file)
@@ -68,6 +68,7 @@ public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, S
     @Override
     public Schemas getSchemas() {
         // FIXME, session ID
+        // capabilities should be split from operations (it will allow to move getSchema operation to monitoring module)
         return transformSchemas(factoriesListener.getSnapshot(0));
     }
 
@@ -78,6 +79,7 @@ public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, S
 
         for (NetconfOperationService netconfOperationService : snapshot.getServices()) {
             // TODO check for duplicates ? move capability merging to snapshot
+            // Split capabilities from operations first and delete this duplicate code
             caps.addAll(netconfOperationService.getCapabilities());
         }
 
@@ -115,8 +117,7 @@ public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, S
         monitoringLocations.add(new Schema.Location(Schema.Location.Enumeration.NETCONF));
 
         for (String location : locations) {
-            // TODO how to create enumerration from string location ?
-            // monitoringLocations.add(new Schema.Location(Schema.Location.Enumeration.valueOf(location)));
+            monitoringLocations.add(new Schema.Location(new Uri(location)));
         }
 
         return monitoringLocations;
index ee474dbba01f4068de6190662c50d25f8339749d..d70a15c18bdf933d56df70d7f7e9be07df6653da 100644 (file)
@@ -185,7 +185,6 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter {
     private NetconfOperationExecution getNetconfOperationWithHighestPriority(
             Document message, NetconfSession session) {
 
-        // TODO test
         TreeMap<HandlingPriority, Set<NetconfOperation>> sortedPriority = getSortedNetconfOperationsWithCanHandle(
                 message, session);
 
index f2c70d61011294d72ba798078bbc3dfc5254ceb2..b70a31a84b0e009052559e7564013f3ae2266de2 100644 (file)
@@ -1,11 +1,6 @@
 package org.opendaylight.controller.netconf.impl.util;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-
+import com.google.common.base.Preconditions;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.slf4j.Logger;
@@ -13,12 +8,18 @@ import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 import org.xml.sax.SAXException;
 
-// TODO purge nulls
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+
 public class NetconfUtil {
 
     private static final Logger logger = LoggerFactory.getLogger(NetconfUtil.class);
 
     public static NetconfMessage createMessage(final File f) {
+        Preconditions.checkNotNull(f, "File parameter was null");
         try {
             return createMessage(new FileInputStream(f));
         } catch (final FileNotFoundException e) {
@@ -28,6 +29,7 @@ public class NetconfUtil {
     }
 
     public static NetconfMessage createMessage(final InputStream is) {
+        Preconditions.checkNotNull(is, "InputStream parameter was null");
         Document doc = null;
         try {
             doc = XmlUtil.readXmlToDocument(is);
index 0140b65c146e4389ecc92e117d23685740ad3f4c..0ecc1cb38324ede5b3443706a071a68a3d21a9dc 100644 (file)
@@ -24,21 +24,14 @@ import java.net.InetSocketAddress;
 public class NetconfDispatcherImplTest {
 
     private EventLoopGroup nettyGroup;
+    private NetconfServerDispatcher dispatch;
+    private DefaultCommitNotificationProducer commitNot;
 
     @Before
     public void setUp() throws Exception {
         nettyGroup = new NioEventLoopGroup();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        nettyGroup.shutdownGracefully();
-    }
 
-    @Test
-    public void test() throws Exception {
-
-        DefaultCommitNotificationProducer commitNot = new DefaultCommitNotificationProducer(
+        commitNot = new DefaultCommitNotificationProducer(
                 ManagementFactory.getPlatformMBeanServer());
         NetconfOperationServiceFactoryListener factoriesListener = new NetconfOperationServiceFactoryListenerImpl();
 
@@ -50,13 +43,20 @@ public class NetconfDispatcherImplTest {
                 factoriesListener, commitNot, idProvider, null);
         NetconfServerDispatcher.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerChannelInitializer(serverNegotiatorFactory, listenerFactory);
 
-
-        NetconfServerDispatcher dispatch = new NetconfServerDispatcher(
+        dispatch = new NetconfServerDispatcher(
                 serverChannelInitializer, nettyGroup, nettyGroup);
+    }
 
+    @After
+    public void tearDown() throws Exception {
+        commitNot.close();
+        nettyGroup.shutdownGracefully();
+    }
+
+    @Test
+    public void test() throws Exception {
         InetSocketAddress addr = new InetSocketAddress("127.0.0.1", 8333);
         ChannelFuture s = dispatch.createServer(addr);
-
-        commitNot.close();
+        s.get();
     }
 }
diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java
new file mode 100644 (file)
index 0000000..14f70d3
--- /dev/null
@@ -0,0 +1,286 @@
+/*
+ * 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.netconf.it;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.util.HashedWheelTimer;
+import org.apache.commons.lang3.StringUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.matchers.JUnitMatchers;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
+import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
+import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
+import org.opendaylight.controller.config.persist.api.Persister;
+import org.opendaylight.controller.config.spi.ModuleFactory;
+import org.opendaylight.controller.config.yang.store.api.YangStoreException;
+import org.opendaylight.controller.config.yang.store.impl.HardcodedYangStoreService;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.netconf.api.jmx.CommitJMXNotification;
+import org.opendaylight.controller.netconf.api.monitoring.NetconfManagementSession;
+import org.opendaylight.controller.netconf.client.NetconfClient;
+import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl;
+import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer;
+import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher;
+import org.opendaylight.controller.netconf.impl.NetconfServerSessionListenerFactory;
+import org.opendaylight.controller.netconf.impl.NetconfServerSessionNegotiatorFactory;
+import org.opendaylight.controller.netconf.impl.SessionIdProvider;
+import org.opendaylight.controller.netconf.impl.osgi.NetconfMonitoringServiceImpl;
+import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListener;
+import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl;
+import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshot;
+import org.opendaylight.controller.netconf.impl.osgi.SessionMonitoringService;
+import org.opendaylight.controller.netconf.mapping.api.Capability;
+import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
+import org.opendaylight.controller.netconf.monitoring.osgi.NetconfMonitoringActivator;
+import org.opendaylight.controller.netconf.monitoring.osgi.NetconfMonitoringOperationService;
+import org.opendaylight.controller.netconf.persist.impl.ConfigPersisterNotificationHandler;
+import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
+import org.opendaylight.controller.netconf.util.xml.XmlUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Element;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.Notification;
+import javax.management.NotificationListener;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetSocketAddress;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Pattern;
+
+import static junit.framework.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+public class NetconfConfigPersisterITTest extends AbstractConfigTest {
+
+    private static final Logger logger =  LoggerFactory.getLogger(NetconfConfigPersisterITTest.class);
+
+    private static final InetSocketAddress tcpAddress = new InetSocketAddress("127.0.0.1", 12023);
+
+    private EventLoopGroup nettyThreadgroup;
+
+    private NetconfClientDispatcher clientDispatcher;
+
+    @Before
+    public void setUp() throws Exception {
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(NetconfITTest.getModuleFactoriesS().toArray(
+                new ModuleFactory[0])));
+
+        NetconfMonitoringServiceImpl monitoringService = new NetconfMonitoringServiceImpl(getFactoriesListener());
+
+        NetconfOperationServiceFactoryListenerImpl factoriesListener = new NetconfOperationServiceFactoryListenerImpl();
+        factoriesListener.onAddNetconfOperationServiceFactory(new NetconfOperationServiceFactoryImpl(getYangStore()));
+        factoriesListener
+                .onAddNetconfOperationServiceFactory(new NetconfMonitoringActivator.NetconfMonitoringOperationServiceFactory(
+                        new NetconfMonitoringOperationService(monitoringService)));
+
+        nettyThreadgroup = new NioEventLoopGroup();
+
+        NetconfServerDispatcher dispatch = createDispatcher(factoriesListener);
+        ChannelFuture s = dispatch.createServer(tcpAddress);
+        s.await();
+
+        clientDispatcher = new NetconfClientDispatcher(nettyThreadgroup, nettyThreadgroup);
+    }
+
+    private HardcodedYangStoreService getYangStore() throws YangStoreException, IOException {
+        final Collection<InputStream> yangDependencies = NetconfITTest.getBasicYangs();
+        return new HardcodedYangStoreService(yangDependencies);
+    }
+
+    private NetconfServerDispatcher createDispatcher(
+                                                     NetconfOperationServiceFactoryListenerImpl factoriesListener) {
+        SessionIdProvider idProvider = new SessionIdProvider();
+        NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
+                new HashedWheelTimer(5000, TimeUnit.MILLISECONDS), factoriesListener, idProvider);
+
+        NetconfServerSessionListenerFactory listenerFactory = new NetconfServerSessionListenerFactory(
+                factoriesListener, new DefaultCommitNotificationProducer(platformMBeanServer), idProvider, mockSessionMonitoringService());
+
+        NetconfServerDispatcher.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerChannelInitializer(
+                serverNegotiatorFactory, listenerFactory);
+        return new NetconfServerDispatcher(serverChannelInitializer, nettyThreadgroup, nettyThreadgroup);
+    }
+
+    private SessionMonitoringService mockSessionMonitoringService() {
+        SessionMonitoringService mockedSessionMonitor = mock(SessionMonitoringService.class);
+        doNothing().when(mockedSessionMonitor).onSessionUp(any(NetconfManagementSession.class));
+        doNothing().when(mockedSessionMonitor).onSessionDown(any(NetconfManagementSession.class));
+        return mockedSessionMonitor;
+    }
+
+    @Test
+    public void testNetconfCommitNotifications() throws Exception {
+
+        VerifyingNotificationListener notificationVerifier = createCommitNotificationListener();
+        VerifyingPersister mockedAggregator = mockAggregator();
+
+        try (NetconfClient persisterClient = new NetconfClient("persister", tcpAddress, 4000, clientDispatcher)) {
+            ConfigPersisterNotificationHandler configPersisterNotificationHandler = new ConfigPersisterNotificationHandler(
+                    platformMBeanServer, persisterClient, mockedAggregator,
+                    Pattern.compile(""));
+            configPersisterNotificationHandler.init();
+
+            try (NetconfClient netconfClient = new NetconfClient("client", tcpAddress, 4000, clientDispatcher)) {
+                NetconfMessage response = netconfClient.sendMessage(loadGetConfigMessage());
+                assertResponse(response, "<modules");
+                assertResponse(response, "<services");
+                response = netconfClient.sendMessage(loadCommitMessage());
+                assertResponse(response, "ok");
+
+                response = netconfClient.sendMessage(loadEditConfigMessage());
+                assertResponse(response, "ok");
+                response = netconfClient.sendMessage(loadCommitMessage());
+                assertResponse(response, "ok");
+            }
+        }
+
+        notificationVerifier.assertNotificationCount(2);
+        notificationVerifier.assertNotificationContent(0, 0, 0, 9);
+        notificationVerifier.assertNotificationContent(1, 4, 4, 9);
+
+        mockedAggregator.assertSnapshotCount(2);
+        // Capabilities are stripped for persister
+        mockedAggregator.assertSnapshotContent(0, 0, 0, 1);
+        mockedAggregator.assertSnapshotContent(1, 4, 4, 3);
+    }
+
+    private VerifyingPersister mockAggregator() throws IOException {
+        return new VerifyingPersister();
+    }
+
+    private VerifyingNotificationListener createCommitNotificationListener() throws InstanceNotFoundException {
+        VerifyingNotificationListener listener = new VerifyingNotificationListener();
+        platformMBeanServer.addNotificationListener(DefaultCommitNotificationProducer.objectName, listener, null, null);
+        return listener;
+    }
+
+    private void assertResponse(NetconfMessage response, String content) {
+        Assert.assertThat(XmlUtil.toString(response.getDocument()), JUnitMatchers.containsString(content));
+    }
+
+    private NetconfMessage loadGetConfigMessage() throws Exception {
+        return XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/getConfig.xml");
+    }
+
+    private NetconfMessage loadEditConfigMessage() throws Exception {
+        return XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/editConfig.xml");
+    }
+
+    private NetconfMessage loadCommitMessage() throws Exception {
+        return XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/commit.xml");
+    }
+
+
+    public NetconfOperationServiceFactoryListener getFactoriesListener() {
+        NetconfOperationServiceFactoryListener factoriesListener = mock(NetconfOperationServiceFactoryListener.class);
+        NetconfOperationServiceSnapshot snap = mock(NetconfOperationServiceSnapshot.class);
+        NetconfOperationService service = mock(NetconfOperationService.class);
+        Set<Capability> caps = Sets.newHashSet();
+        doReturn(caps).when(service).getCapabilities();
+        Set<NetconfOperationService> services = Sets.newHashSet(service);
+        doReturn(services).when(snap).getServices();
+        doReturn(snap).when(factoriesListener).getSnapshot(anyLong());
+
+        return factoriesListener;
+    }
+
+    private static class VerifyingNotificationListener implements NotificationListener {
+        public List<Notification> notifications = Lists.newArrayList();
+
+        @Override
+        public void handleNotification(Notification notification, Object handback) {
+            this.notifications.add(notification);
+        }
+
+        void assertNotificationCount(Object size) {
+            assertEquals(size, notifications.size());
+        }
+
+        void assertNotificationContent(int notificationIndex, int expectedModulesSize, int expectedServicesSize, int expectedCapsSize) {
+            Notification notification = notifications.get(notificationIndex);
+            assertEquals(CommitJMXNotification.class, notification.getClass());
+            int capsSize = ((CommitJMXNotification) notification).getCapabilities().size();
+            assertEquals("Expected capabilities count", expectedCapsSize, capsSize);
+            Element configSnapshot = ((CommitJMXNotification) notification).getConfigSnapshot();
+            int modulesSize = configSnapshot.getElementsByTagName("module").getLength();
+            assertEquals("Expected modules count", expectedModulesSize, modulesSize);
+            int servicesSize = configSnapshot.getElementsByTagName("instance").getLength();
+            assertEquals("Expected services count", expectedServicesSize, servicesSize);
+        }
+    }
+
+    private static class VerifyingPersister implements Persister {
+
+        public List<ConfigSnapshotHolder> snapshots = Lists.newArrayList();
+        private Persister mockedPersister;
+
+        public VerifyingPersister() throws IOException {
+            Persister mockedAggregator = mock(Persister.class);
+
+            doAnswer(new Answer() {
+                @Override
+                public Object answer(InvocationOnMock invocation) throws Throwable {
+                    ConfigSnapshotHolder configSnapshot = (ConfigSnapshotHolder) invocation.getArguments()[0];
+                    snapshots.add(configSnapshot);
+                    return null;
+                }
+            }).when(mockedAggregator).persistConfig(any(ConfigSnapshotHolder.class));
+
+            this.mockedPersister = mockedAggregator;
+        }
+
+        void assertSnapshotCount(Object size) {
+            assertEquals(size, snapshots.size());
+        }
+
+        void assertSnapshotContent(int notificationIndex, int expectedModulesSize, int expectedServicesSize, int expectedCapsSize) {
+            ConfigSnapshotHolder snapshot = snapshots.get(notificationIndex);
+            int capsSize = snapshot.getCapabilities().size();
+            assertEquals("Expected capabilities count", expectedCapsSize, capsSize);
+            String configSnapshot = snapshot.getConfigSnapshot();
+            int modulesSize = StringUtils.countMatches(configSnapshot, "<module>");
+            assertEquals("Expected modules count", expectedModulesSize, modulesSize);
+            int servicesSize = StringUtils.countMatches(configSnapshot, "<instance>");
+            assertEquals("Expected services count", expectedServicesSize, servicesSize);
+        }
+
+        @Override
+        public void persistConfig(ConfigSnapshotHolder configSnapshotHolder) throws IOException {
+            mockedPersister.persistConfig(configSnapshotHolder);
+        }
+
+        @Override
+        public List<ConfigSnapshotHolder> loadLastConfigs() throws IOException {
+            return mockedPersister.loadLastConfigs();
+        }
+
+        @Override
+        public void close() {
+            mockedPersister.close();
+        }
+    }
+}
index 4818b5f0a3c7868be0a02dafd19e8c1657e0d777..36f30dd328f66367cf2582af790dde7b91263134 100644 (file)
@@ -16,19 +16,6 @@ import io.netty.channel.ChannelFuture;
 import io.netty.channel.EventLoopGroup;
 import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.util.HashedWheelTimer;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.management.ManagementFactory;
-import java.net.InetSocketAddress;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-import javax.management.ObjectName;
-import javax.xml.parsers.ParserConfigurationException;
 import junit.framework.Assert;
 import org.junit.After;
 import org.junit.Before;
@@ -74,6 +61,21 @@ import org.w3c.dom.Element;
 import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
 import org.xml.sax.SAXException;
+
+import javax.management.ObjectName;
+import javax.xml.parsers.ParserConfigurationException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.management.ManagementFactory;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
 import static java.util.Collections.emptyList;
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertNotNull;
@@ -215,20 +217,6 @@ public class NetconfITTest extends AbstractConfigTest {
         }
     }
 
-
-    //TODO: test persister actually
-    @Ignore
-    @Test(timeout = 10000)
-    public void testPersister() throws Exception {
-//        Persister persister = mock(Persister.class);
-//        doReturn("mockPersister").when(persister).toString();
-//        doReturn(Collections.emptyList()).when(persister).loadLastConfigs();
-//        ConfigPersisterNotificationHandler h =
-//                new ConfigPersisterNotificationHandler(persister, tcpAddress, ManagementFactory.getPlatformMBeanServer(),
-//                        Pattern.compile(ConfigPersisterActivator.DEFAULT_IGNORED_REGEX));
-//        h.init();
-    }
-
     @Ignore
     @Test
     public void waitingTest() throws Exception {
@@ -432,7 +420,8 @@ public class NetconfITTest extends AbstractConfigTest {
     private void startSSHServer() throws Exception{
         logger.info("Creating SSH server");
         StubUserManager um = new StubUserManager(USERNAME,PASSWORD);
-        AuthProvider ap = new AuthProvider(um);
+        InputStream is = getClass().getResourceAsStream("/RSA.pk");
+        AuthProvider ap = new AuthProvider(um, is);
         Thread sshServerThread = new Thread(NetconfSSHServer.start(10830,tcpAddress,ap));
         sshServerThread.setDaemon(true);
         sshServerThread.start();
index 3a7b7de7a0b2a589b410ddd76996556412e64434..fdea831b47e0dd05d73e1ed70dd1bf4be2b90c84 100644 (file)
@@ -7,27 +7,14 @@
  */
 package org.opendaylight.controller.netconf.it;
 
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
+import com.google.common.base.Charsets;
+import com.google.common.base.Optional;
+import com.google.common.collect.Sets;
 import io.netty.channel.ChannelFuture;
 import io.netty.channel.EventLoopGroup;
 import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.util.HashedWheelTimer;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
 import junit.framework.Assert;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.matchers.JUnitMatchers;
@@ -61,9 +48,20 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 
-import com.google.common.base.Charsets;
-import com.google.common.base.Optional;
-import com.google.common.collect.Sets;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
 
 public class NetconfMonitoringITTest extends AbstractConfigTest {
 
@@ -197,7 +195,7 @@ public class NetconfMonitoringITTest extends AbstractConfigTest {
         return XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/get.xml");
     }
 
-    public NetconfOperationServiceFactoryListener getFactoriesListener() {
+    public static NetconfOperationServiceFactoryListener getFactoriesListener() {
         NetconfOperationServiceFactoryListener factoriesListener = mock(NetconfOperationServiceFactoryListener.class);
         NetconfOperationServiceSnapshot snap = mock(NetconfOperationServiceSnapshot.class);
         NetconfOperationService service = mock(NetconfOperationService.class);
diff --git a/opendaylight/netconf/netconf-it/src/test/resources/RSA.pk b/opendaylight/netconf/netconf-it/src/test/resources/RSA.pk
new file mode 100644 (file)
index 0000000..c0266c7
--- /dev/null
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEAuC9hbEacpewvylI0mwFwjy3Wou2hpr/ncN9BBiFDSaG5yW2k
+3Oy+SCAcFCL+ZKWb6cc6Ch4gUeCwyEHRojZguuhliKtak9YQf6qbvpPLe00842Lx
+iqNAGurMpzizCDsGFq8ChaAkBZQI3TvcHuPoSUWSMJ+K8xHpRyUdVr6g2yEjezKJ
+sTXBtWaeCCh6YUafFujuDJk7fvYcPW7Je5KRBBStIKvxcMW0zB+7eq04deTHwGbJ
+gGjKWilQ72hsDDP3Hbp5CJMAYg1r4GlCmFx3KyHRGztgWgNgaD7nNpKCkTLjtmA6
+b4x7TA+jrzZ6Af2z5TMrI4dv5w1SrxHaZ+ziLQIDAQABAoIBAHTndeGgq/rQf8De
+Do+4CTaHtK0zQSAyu/azbXUzlZ7drKuCEVs8VMY4wzmwwGEnkF+A2YDkgEUX5X0l
+8aYQ97KKoS9u+43MGCrAIhyDeGrpqlT1TzRcy+qJz53v6gq2U/X/3QztiQ+VV078
+mIluxNgE9XYxPaNsYfGLSCTv1+9c8y/hjGVX2kwFK+u4ut0ZZETggNa8UxfaHVDS
+fIJQX9Gm3J3GSUV30fDGMBIUW6ESLc2L8b7u8Mp9TRP39ZeQSuEUjBe8MYKv0Rel
+oEpjZvcnniMTpFbLpndBYn7/AoIiEBvtCN8faVTuRRcvvLcsRm09IctzKQYnMh6M
+6PLKV+ECgYEA8HFRYaKHUzxpzE/fyon82GQbzqFFY0/bbWrfWICMfNbIgshJUie6
+FmH5iUFMfeqaT7v557HFM0GB9FeIeSbvd88YmiBAcRopZ3DfMkDH+DT73yJ+/TKG
+2nrQtdhyuTIs4bwHqeS2BBJYs7PK9R2rratF3l34Tf7mjlvyOgygHdUCgYEAxBo2
+8hEBlAVNcNb1hTYUxe1w1B6675/mFlmw98Xmj9dRYfICXNhahs8tX3/lsBEd+vBu
+fI0oyHaff8m5bPgGzD1ZMybfeROujNrgxaKVk7Ef0FDRRCop4bm18OroFlFAt9l8
+wMp++ToACbdvQvL/mjWMPYlIxhB/YxHswICZZvkCgYAexxKYwdo6sGAGlC7cWT9x
+X5cjowcjyEQZRHXkeUgCbufpvcOM7aLnXJE5nY8yCwbHsBM0MlBA2GDPKylAANjk
+aDEJAZneIHAuWodngl1Wi0m2bU7+ECqs6s2uiU9eH2sZVh1RBQK7kLGkBx6ys6KX
+L3ZZGYRAT6GplWFzRsx0JQKBgCeVlxPD5QqpC1nEumi6YvUVGdpnnZpzL3HBhxxs
+wT612wKnZFyze4qM1X7ahVXGDsQxtkvD/sCAWW/lG13orw6ZL6FIroF1PJ3ILOkY
+CZN3hJF7TtKwpCWhZB2OfWzL2AGEkE8mUP0j/Q/5DCd6f6f0OSvOw3bfq6cm3iB5
+lP2ZAoGAXsRN5TZTX4AQ2xTlrDQ8A5XgcvyWQpJOmEXMTyHV7VaJVzmNWFVAvndK
+5UIq8ALDwB2t7vjmMUW6euvIwqtXiop7G79UOb3e3NhzeyWFGQyBLqCRznGaXQTT
+dlFy73xhukZMhFnj006bjKCYvOPnwuGl3+0fuWil5Rq3jOuY5c8=
+-----END RSA PRIVATE KEY-----
index 5a0688c8d14dd4fd4d2d3de0be37b7ca40c5a802..176cf2d28c02d54dbaeedc39abe23357e27d8324 100644 (file)
@@ -36,8 +36,6 @@ public class HandlingPriority implements Comparable<HandlingPriority> {
         return Optional.of(priority).or(Optional.<Integer> absent());
     }
 
-    // TODO test
-
     @Override
     public int compareTo(HandlingPriority o) {
         if (this == o)
index 3b513790bd128806a7ef1bec2561bd90fee6420a..446c5008960e92a001bf78f332435276dc1aef95 100644 (file)
@@ -8,6 +8,8 @@
 package org.opendaylight.controller.netconf.osgi;
 
 import com.google.common.base.Optional;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.net.InetSocketAddress;
 import org.opendaylight.controller.netconf.ssh.NetconfSSHServer;
 import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider;
@@ -85,7 +87,28 @@ public class NetconfSSHActivator implements BundleActivator{
                 EXCEPTION_MESSAGE, true);
 
         if (sshSocketAddressOptional.isPresent()){
-            AuthProvider authProvider = new AuthProvider(iUserManager);
+            String path = NetconfConfigUtil.getPrivateKeyPath(context);
+            path = path.replace("\\", "/");
+            if (path.equals("")){
+                throw new Exception("Missing netconf.ssh.pk.path key in configuration file.");
+            }
+            FileInputStream fis = null;
+            try {
+                fis = new FileInputStream(path);
+            } catch (FileNotFoundException e){
+                throw new Exception("Missing file described by netconf.ssh.pk.path key in configuration file.");
+            } catch (SecurityException e){
+                throw new Exception("Read access denied to file described by netconf.ssh.pk.path key in configuration file.");
+            }
+            AuthProvider authProvider = null;
+            try {
+                authProvider = new AuthProvider(iUserManager,fis);
+            } catch (Exception e){
+                if (fis!=null){
+                    fis.close();
+                }
+                throw (e);
+            }
             this.server = NetconfSSHServer.start(sshSocketAddressOptional.get().getPort(),tcpSocketAddress,authProvider);
             Thread serverThread = new  Thread(server,"netconf SSH server thread");
             serverThread.setDaemon(true);
index a73dfdfd49eca56129a5ba0e98efb13fba001556..22dda95064c092c286a1046edc90595943485a0d 100644 (file)
@@ -7,8 +7,6 @@
  */
 package org.opendaylight.controller.netconf.ssh.authentication;
 
-import ch.ethz.ssh2.signature.RSAPrivateKey;
-import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.List;
@@ -17,26 +15,30 @@ import org.opendaylight.controller.sal.authorization.AuthResultEnum;
 import org.opendaylight.controller.sal.authorization.UserLevel;
 import org.opendaylight.controller.usermanager.IUserManager;
 import org.opendaylight.controller.usermanager.UserConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class AuthProvider implements AuthProviderInterface {
 
-    private static RSAPrivateKey hostkey = null;
     private static IUserManager um;
-    private static final String DEAFULT_USER = "netconf";
-    private static final String DEAFULT_PASSWORD = "netconf";
+    private static final String DEFAULT_USER = "netconf";
+    private static final String DEFAULT_PASSWORD = "netconf";
+    private static InputStream privateKeyFileInputStream;
 
+    private static final Logger logger =  LoggerFactory.getLogger(AuthProvider.class);
 
-    public AuthProvider(IUserManager ium) throws Exception {
+    public AuthProvider(IUserManager ium,InputStream privateKeyFileInputStream) throws Exception {
 
         this.um = ium;
-
         if (this.um  == null){
             throw new Exception("No usermanager service available.");
         }
 
+        this.privateKeyFileInputStream = privateKeyFileInputStream;
+
         List<String> roles = new ArrayList<String>(1);
         roles.add(UserLevel.SYSTEMADMIN.toString());
-        this.um.addLocalUser(new UserConfig(DEAFULT_USER, DEAFULT_PASSWORD, roles));
+        this.um.addLocalUser(new UserConfig(DEFAULT_USER, DEFAULT_PASSWORD, roles));
     }
     @Override
     public boolean authenticated(String username, String password)  throws Exception {
@@ -51,15 +53,10 @@ public class AuthProvider implements AuthProviderInterface {
     }
 
     @Override
-    public char[] getPEMAsCharArray() {
-
-        InputStream is = getClass().getResourceAsStream("/RSA.pk");
-        try {
-            return IOUtils.toCharArray(is);
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        return null;
+    public char[] getPEMAsCharArray() throws Exception {
+        char [] PEM  = IOUtils.toCharArray(privateKeyFileInputStream);
+        privateKeyFileInputStream.close();
+        return PEM;
     }
 
     @Override
index 71f1cc350fda1d5d829cb101798d208eaf1bc906..8e40578a0e47c001676b8fb28809a9cf306364e2 100644 (file)
@@ -13,7 +13,7 @@ import org.opendaylight.controller.usermanager.IUserManager;
 public interface AuthProviderInterface {
 
     public boolean authenticated(String username, String password) throws Exception;
-    public char[] getPEMAsCharArray();
+    public char[] getPEMAsCharArray() throws Exception;
     public void removeUserManagerService();
     public void addUserManagerService(IUserManager userManagerService);
 }
index e5da03b4cf4c9d97765ce098a8c2761b0eda8e39..32de75ca3969a039bbeb0046fc4c2a7b55d3462d 100644 (file)
@@ -59,8 +59,8 @@ public class SocketThread implements Runnable, ServerAuthenticationCallback, Ser
         conn = new ServerConnection(socket);
         try {
             conn.setPEMHostKey(authProvider.getPEMAsCharArray(),"netconf");
-        } catch (IOException e) {
-            e.printStackTrace();
+        } catch (Exception e) {
+            logger.debug("Server authentication setup failed.");
         }
         conn.setAuthenticationCallback(this);
         conn.setServerConnectionCallback(this);
index 62396ed87ac1f4db3dcaa7942f676012ab35ade8..91783ff755b5e934af8359c47f25b51d9ed5cd23 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.controller.netconf;
 
 import ch.ethz.ssh2.Connection;
+import java.io.InputStream;
 import java.net.InetSocketAddress;
 import junit.framework.Assert;
 import org.junit.Test;
@@ -33,7 +34,8 @@ public class SSHServerTest {
     public void startSSHServer() throws Exception{
         logger.info("Creating SSH server");
         StubUserManager um = new StubUserManager(USER,PASSWORD);
-        AuthProvider ap = new AuthProvider(um);
+        InputStream is = getClass().getResourceAsStream("/RSA.pk");
+        AuthProvider ap = new AuthProvider(um, is);
         NetconfSSHServer server = NetconfSSHServer.start(PORT,tcpAddress,ap);
         sshServerThread = new Thread(server);
         sshServerThread.setDaemon(true);
diff --git a/opendaylight/netconf/netconf-ssh/src/test/resources/RSA.pk b/opendaylight/netconf/netconf-ssh/src/test/resources/RSA.pk
new file mode 100644 (file)
index 0000000..c0266c7
--- /dev/null
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEAuC9hbEacpewvylI0mwFwjy3Wou2hpr/ncN9BBiFDSaG5yW2k
+3Oy+SCAcFCL+ZKWb6cc6Ch4gUeCwyEHRojZguuhliKtak9YQf6qbvpPLe00842Lx
+iqNAGurMpzizCDsGFq8ChaAkBZQI3TvcHuPoSUWSMJ+K8xHpRyUdVr6g2yEjezKJ
+sTXBtWaeCCh6YUafFujuDJk7fvYcPW7Je5KRBBStIKvxcMW0zB+7eq04deTHwGbJ
+gGjKWilQ72hsDDP3Hbp5CJMAYg1r4GlCmFx3KyHRGztgWgNgaD7nNpKCkTLjtmA6
+b4x7TA+jrzZ6Af2z5TMrI4dv5w1SrxHaZ+ziLQIDAQABAoIBAHTndeGgq/rQf8De
+Do+4CTaHtK0zQSAyu/azbXUzlZ7drKuCEVs8VMY4wzmwwGEnkF+A2YDkgEUX5X0l
+8aYQ97KKoS9u+43MGCrAIhyDeGrpqlT1TzRcy+qJz53v6gq2U/X/3QztiQ+VV078
+mIluxNgE9XYxPaNsYfGLSCTv1+9c8y/hjGVX2kwFK+u4ut0ZZETggNa8UxfaHVDS
+fIJQX9Gm3J3GSUV30fDGMBIUW6ESLc2L8b7u8Mp9TRP39ZeQSuEUjBe8MYKv0Rel
+oEpjZvcnniMTpFbLpndBYn7/AoIiEBvtCN8faVTuRRcvvLcsRm09IctzKQYnMh6M
+6PLKV+ECgYEA8HFRYaKHUzxpzE/fyon82GQbzqFFY0/bbWrfWICMfNbIgshJUie6
+FmH5iUFMfeqaT7v557HFM0GB9FeIeSbvd88YmiBAcRopZ3DfMkDH+DT73yJ+/TKG
+2nrQtdhyuTIs4bwHqeS2BBJYs7PK9R2rratF3l34Tf7mjlvyOgygHdUCgYEAxBo2
+8hEBlAVNcNb1hTYUxe1w1B6675/mFlmw98Xmj9dRYfICXNhahs8tX3/lsBEd+vBu
+fI0oyHaff8m5bPgGzD1ZMybfeROujNrgxaKVk7Ef0FDRRCop4bm18OroFlFAt9l8
+wMp++ToACbdvQvL/mjWMPYlIxhB/YxHswICZZvkCgYAexxKYwdo6sGAGlC7cWT9x
+X5cjowcjyEQZRHXkeUgCbufpvcOM7aLnXJE5nY8yCwbHsBM0MlBA2GDPKylAANjk
+aDEJAZneIHAuWodngl1Wi0m2bU7+ECqs6s2uiU9eH2sZVh1RBQK7kLGkBx6ys6KX
+L3ZZGYRAT6GplWFzRsx0JQKBgCeVlxPD5QqpC1nEumi6YvUVGdpnnZpzL3HBhxxs
+wT612wKnZFyze4qM1X7ahVXGDsQxtkvD/sCAWW/lG13orw6ZL6FIroF1PJ3ILOkY
+CZN3hJF7TtKwpCWhZB2OfWzL2AGEkE8mUP0j/Q/5DCd6f6f0OSvOw3bfq6cm3iB5
+lP2ZAoGAXsRN5TZTX4AQ2xTlrDQ8A5XgcvyWQpJOmEXMTyHV7VaJVzmNWFVAvndK
+5UIq8ALDwB2t7vjmMUW6euvIwqtXiop7G79UOb3e3NhzeyWFGQyBLqCRznGaXQTT
+dlFy73xhukZMhFnj006bjKCYvOPnwuGl3+0fuWil5Rq3jOuY5c8=
+-----END RSA PRIVATE KEY-----
index 4fee930eff7db3c3ecfe5beb0bd113c9acfd5366..26ea7ceb79d4b78d98ecf42af34d7be87364ffcb 100644 (file)
@@ -42,7 +42,7 @@ import java.util.concurrent.TimeUnit;
 public abstract class AbstractNetconfSessionNegotiator<P extends NetconfSessionPreferences, S extends NetconfSession>
         extends AbstractSessionNegotiator<NetconfMessage, S> {
 
-    // TODO what time ?
+    // TODO Adjust wait time for negotiation, now is 1 minute ?
     private static final long INITIAL_HOLDTIMER = 1;
 
     private static final Logger logger = LoggerFactory.getLogger(AbstractNetconfSessionNegotiator.class);
index 987708d67ed03db1276a6459ad47c75f7eabf0bf..55ed7e074423968dd7e7626e45a181893cdfd4a1 100644 (file)
@@ -23,6 +23,7 @@ public class NetconfConfigUtil {
     private static final String PORT_SUFFIX_PROP = ".port";
     private static final String ADDRESS_SUFFIX_PROP = ".address";
     private static final String CLIENT_PROP = ".client";
+    private static final String PRIVATE_KEY_PATH_PROP = ".pk.path";
 
     public static InetSocketAddress extractTCPNetconfAddress(BundleContext context, String exceptionMessageIfNotFound, boolean forClient) {
 
@@ -38,6 +39,16 @@ public class NetconfConfigUtil {
         return extractSomeNetconfAddress(context, InfixProp.ssh, exceptionMessage, false);
     }
 
+    public static String getPrivateKeyPath(BundleContext context){
+        return getPropertyValue(context,PREFIX_PROP + InfixProp.ssh +PRIVATE_KEY_PATH_PROP);
+    }
+    private static String getPropertyValue(BundleContext context, String propertyName){
+        String propertyValue = context.getProperty(propertyName);
+        if (propertyValue == null){
+            throw new IllegalStateException("Cannot find initial property with name '"+propertyName+"'");
+        }
+        return propertyValue;
+    }
     /**
      * @param context
      *            from which properties are being read.
diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_addServiceNameOnTest.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_addServiceNameOnTest.xml
new file mode 100644 (file)
index 0000000..6e68326
--- /dev/null
@@ -0,0 +1,38 @@
+<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+    <edit-config>
+        <target>
+            <candidate/>
+        </target>
+        <test-option>
+            test-only
+        </test-option>
+        <default-operation>merge</default-operation>
+        <config>
+            <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+
+                <module>
+                    <name>instance-from-code_dep</name>
+                    <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
+                        test-impl:impl-dep
+                    </type>
+                </module>
+            </modules>
+
+            <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+                <service>
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
+                    <instance>
+                        <name>ref_dep_user_another_test1</name>
+                        <provider>/modules/module[type='impl-dep'][name='instance-from-code_dep']
+                        </provider>
+                    </instance>
+                    <instance>
+                        <name>ref_dep_user_another_test2</name>
+                        <provider>/modules/module[type='impl-dep'][name='instance-from-code_dep']
+                        </provider>
+                    </instance>
+                </service>
+            </services>
+        </config>
+    </edit-config>
+</rpc>
index 7f884dc43c605af7537a95ed7d0bce71e93d577a..36f79a50bcceaaed5649492b69dff79ff08ee157 100644 (file)
@@ -1,19 +1,6 @@
 <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" a="64" id="a" message-id="101" xmlnx="a:b:c:d">
     <data>
-        <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-            <!--<module>
-            <type>impl</type>
-            </module>
-            -->
-            <!--<module>
-            <type>impl-dep</type>
-            </module>
-            -->
-            <!--<module>
-            <type>impl-netconf</type>
-            </module>
-            -->
-        </modules>
+        <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config"/>
         <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config"/>
     </data>
 </rpc-reply>
index a7f1c863910f4b24b421531b82ffb9cb68499452..ade40f6a49c94f2a682b7e55e1ec1a3d79e03ecc 100644 (file)
                     </type>
                 </module>
 
-
                 <module>
                     <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
                         test-impl:impl-netconf
                     </type>
-                    <name>test1</name>
+                    <name>instance-from-code</name>
                     <simple-long-2>44</simple-long-2>
                     <binaryLeaf>8ad1</binaryLeaf>
                     <dto_d>
@@ -72,7 +71,7 @@
                     <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
                         test-impl:impl-netconf
                     </type>
-                    <name>test2</name>
+                    <name>test3</name>
                 </module>
             </modules>
 
index c4b146722004d6792303b0f0a3a423d2d89f91e6..21a1ffe81dab64f9fab54bdf316b03631937ed6c 100644 (file)
@@ -48,7 +48,7 @@
 
     <properties>
         <osgi.version>5.0.0</osgi.version>
-        <maven.bundle.version>2.3.7</maven.bundle.version>
+        <maven.bundle.version>2.4.0</maven.bundle.version>
         <slf4j.version>1.7.2</slf4j.version>
         <netconf.netty.version>4.0.10.Final</netconf.netty.version>
         <ct.exi.version>0.9.2</ct.exi.version>
index 65790ad17ca1383b7e6ae387aa4666dfbd283d3b..0a282b9b28b8c3c68ca31e3419a39b0f607105c2 100644 (file)
@@ -23,7 +23,6 @@ public class CommonsNorthboundExceptionTest extends TestCase {
         try {
             throw new InternalServerErrorException("Internal Server Exception");
         } catch (InternalServerErrorException e) {
-            Assert.assertTrue(e instanceof InternalServerErrorException);
             Assert.assertTrue(e.getResponse().getEntity()
                     .equals("Internal Server Exception"));
         }
@@ -34,7 +33,6 @@ public class CommonsNorthboundExceptionTest extends TestCase {
         try {
             throw new MethodNotAllowedException("Method Not Allowed Exception");
         } catch (MethodNotAllowedException e) {
-            Assert.assertTrue(e instanceof MethodNotAllowedException);
             Assert.assertTrue(e.getResponse().getEntity()
                     .equals("Method Not Allowed Exception"));
         }
@@ -45,7 +43,6 @@ public class CommonsNorthboundExceptionTest extends TestCase {
         try {
             throw new NotAcceptableException("Not Acceptable Exception");
         } catch (NotAcceptableException e) {
-            Assert.assertTrue(e instanceof NotAcceptableException);
             Assert.assertTrue(e.getResponse().getEntity()
                     .equals("Not Acceptable Exception"));
         }
@@ -56,7 +53,6 @@ public class CommonsNorthboundExceptionTest extends TestCase {
         try {
             throw new ResourceConflictException("Resource Conflict Exception");
         } catch (ResourceConflictException e) {
-            Assert.assertTrue(e instanceof ResourceConflictException);
             Assert.assertTrue(e.getResponse().getEntity()
                     .equals("Resource Conflict Exception"));
         }
@@ -67,7 +63,6 @@ public class CommonsNorthboundExceptionTest extends TestCase {
         try {
             throw new ResourceForbiddenException("Resource Forbidden Exception");
         } catch (ResourceForbiddenException e) {
-            Assert.assertTrue(e instanceof ResourceForbiddenException);
             Assert.assertTrue(e.getResponse().getEntity()
                     .equals("Resource Forbidden Exception"));
         }
@@ -78,7 +73,6 @@ public class CommonsNorthboundExceptionTest extends TestCase {
         try {
             throw new ResourceGoneException("Resource Gone Exception");
         } catch (ResourceGoneException e) {
-            Assert.assertTrue(e instanceof ResourceGoneException);
             Assert.assertTrue(e.getResponse().getEntity()
                     .equals("Resource Gone Exception"));
         }
@@ -89,7 +83,6 @@ public class CommonsNorthboundExceptionTest extends TestCase {
         try {
             throw new ResourceNotFoundException("Resource Not Found Exception");
         } catch (ResourceNotFoundException e) {
-            Assert.assertTrue(e instanceof ResourceNotFoundException);
             Assert.assertTrue(e.getResponse().getEntity()
                     .equals("Resource Not Found Exception"));
         }
@@ -101,7 +94,6 @@ public class CommonsNorthboundExceptionTest extends TestCase {
             throw new ServiceUnavailableException(
                     "Service Unavailable Exception");
         } catch (ServiceUnavailableException e) {
-            Assert.assertTrue(e instanceof ServiceUnavailableException);
             Assert.assertTrue(e.getResponse().getEntity()
                     .equals("Service Unavailable Exception"));
         }
@@ -112,7 +104,6 @@ public class CommonsNorthboundExceptionTest extends TestCase {
         try {
             throw new UnauthorizedException("Unauthorized Exception");
         } catch (UnauthorizedException e) {
-            Assert.assertTrue(e instanceof UnauthorizedException);
             Assert.assertTrue(e.getResponse().getEntity()
                     .equals("Unauthorized Exception"));
         }
@@ -124,7 +115,6 @@ public class CommonsNorthboundExceptionTest extends TestCase {
             throw new UnsupportedMediaTypeException(
                     "Unsupported Media Type Exception");
         } catch (UnsupportedMediaTypeException e) {
-            Assert.assertTrue(e instanceof UnsupportedMediaTypeException);
             Assert.assertTrue(e.getResponse().getEntity()
                     .equals("Unsupported Media Type Exception"));
         }
index 9c63f5e5aaaec452653004b04f57d5f6b72ee6b9..cabfb0ee5a1e98e27194cb244f445ca8ba3ca40d 100644 (file)
@@ -62,7 +62,7 @@ public class NorthboundIT {
     private IUserManager userManager = null;
     private IInventoryListener invtoryListener = null;
     private IListenTopoUpdates topoUpdates = null;
-
+    private static final String baseUrlPrefix = "http://127.0.0.1:8080/controller/nb/v2/";
     private final Boolean debugMsg = false;
 
     private String stateToString(int state) {
@@ -267,7 +267,7 @@ public class NorthboundIT {
     @Test
     public void testSubnetsNorthbound() throws JSONException, ConstructionException {
         System.out.println("Starting Subnets JAXB client.");
-        String baseURL = "http://127.0.0.1:8080/controller/nb/v2/subnetservice/";
+        String baseURL = baseUrlPrefix + "subnetservice/";
 
         String name1 = "testSubnet1";
         String subnet1 = "1.1.1.1/24";
@@ -410,7 +410,7 @@ public class NorthboundIT {
     @Test
     public void testStaticRoutingNorthbound() throws JSONException {
         System.out.println("Starting StaticRouting JAXB client.");
-        String baseURL = "http://127.0.0.1:8080/controller/nb/v2/staticroute/";
+        String baseURL = baseUrlPrefix + "staticroute/";
 
         String name1 = "testRoute1";
         String prefix1 = "192.168.1.1/24";
@@ -491,7 +491,7 @@ public class NorthboundIT {
     @Test
     public void testSwitchManager() throws JSONException {
         System.out.println("Starting SwitchManager JAXB client.");
-        String baseURL = "http://127.0.0.1:8080/controller/nb/v2/switchmanager/default/";
+        String baseURL = baseUrlPrefix + "switchmanager/default/";
 
         // define Node/NodeConnector attributes for test
         int nodeId_1 = 51966;
@@ -642,7 +642,7 @@ public class NorthboundIT {
                 "SET_NW_SRC", "SET_NW_DST", "SET_NW_TOS", "SET_TP_SRC", "SET_TP_DST" };
         System.out.println("Starting Statistics JAXB client.");
 
-        String baseURL = "http://127.0.0.1:8080/controller/nb/v2/statistics/default/";
+        String baseURL = baseUrlPrefix + "statistics/default/";
 
         String result = getJsonResult(baseURL + "flow");
         JSONTokener jt = new JSONTokener(result);
@@ -833,7 +833,7 @@ public class NorthboundIT {
     @Test
     public void testFlowProgrammer() throws JSONException {
         System.out.println("Starting FlowProgrammer JAXB client.");
-        String baseURL = "http://127.0.0.1:8080/controller/nb/v2/flowprogrammer/default/";
+        String baseURL = baseUrlPrefix + "flowprogrammer/default/";
         // Attempt to get a flow that doesn't exit. Should return 404
         // status.
         String result = getJsonResult(baseURL + "node/STUB/51966/staticFlow/test1", "GET");
@@ -972,7 +972,7 @@ public class NorthboundIT {
         Integer nodeConnectorId_2 = 34;
         String vlan_2 = "123";
 
-        String baseURL = "http://127.0.0.1:8080/controller/nb/v2/hosttracker/default";
+        String baseURL = baseUrlPrefix + "hosttracker/default";
 
         // test PUT method: addHost()
         JSONObject fc_json = new JSONObject();
@@ -1126,14 +1126,14 @@ public class NorthboundIT {
         } else {
             JSONObject ja = json.getJSONObject("hostConfig");
             String na = ja.getString("networkAddress");
-            return (na.equalsIgnoreCase(hostIp)) ? true : false;
+            return na.equalsIgnoreCase(hostIp);
         }
     }
 
     @Test
     public void testTopology() throws JSONException, ConstructionException {
         System.out.println("Starting Topology JAXB client.");
-        String baseURL = "http://127.0.0.1:8080/controller/nb/v2/topology/default";
+        String baseURL = baseUrlPrefix + "topology/default";
 
         // === test GET method for getTopology()
         short state_1 = State.EDGE_UP, state_2 = State.EDGE_DOWN;
index 45d041c3e1e02533251ff672da2f0908a4da46a9..4fd3f4a32de5964fe7f2b0df20c4125497e71eb6 100644 (file)
@@ -29,7 +29,6 @@ public class LoadBalancerTest extends TestCase {
     public void testRoundRobinPolicy() {\r
         ConfigManager cm = null;\r
         cm = new ConfigManager();\r
-        Assert.assertFalse(cm== null);\r
 \r
         Pool pool = cm.createPool("TestPool","roundrobin");\r
         VIP vip = cm.createVIP("TestVIP","10.0.0.9","TCP",(short)5550,"TestPool");\r
index 1d4211a9267e25a1399f48d99c145cdb6bf5b6fa..ca37f4b7c19658ca14facf9af29d6d83d2cd07cb 100644 (file)
@@ -8,8 +8,10 @@
 
 package org.opendaylight.controller.web;
 
+import java.io.FileInputStream;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Properties;
 import java.util.Set;
 
 import javax.servlet.http.HttpServletRequest;
@@ -28,6 +30,7 @@ import org.opendaylight.controller.sal.utils.StatusCode;
 import org.opendaylight.controller.usermanager.IUserManager;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.ResponseBody;
@@ -52,6 +55,23 @@ public class DaylightWeb {
         return "main";
     }
 
+    /**
+     * Read the version.properties file for the property
+     *
+     * @param request
+     * @return String value configured in the version.properties file
+     */
+    @RequestMapping(value="/versionProperty/{property}", method = RequestMethod.GET)
+    @ResponseBody
+    public String getVersion(HttpServletRequest request, @PathVariable("property") String property) {
+        Properties prop = new Properties();
+        try {
+            prop.load(new FileInputStream("version.properties"));
+            return prop.getProperty(property+".version");
+        } catch (Exception e) {
+            return null;
+        }
+    }
     @RequestMapping(value = "web.json")
     @ResponseBody
     public Map<String, Map<String, Object>> bundles(HttpServletRequest request) {
index 89812af53df5447ef4426dd49ce312aff6f87a43..072f08f581eadb4b6b9290c92e93776f7b560c87 100644 (file)
@@ -46,6 +46,7 @@
              <url-pattern>/images/*</url-pattern>
              <url-pattern>/css/*</url-pattern>
              <url-pattern>/favicon.ico</url-pattern>
+             <url-pattern>/versionProperty/*</url-pattern>
           </web-resource-collection>
         </security-constraint>