Merge "Persist service references as separate MBeans."
authorEd Warnicke <eaw@cisco.com>
Wed, 18 Dec 2013 12:12:43 +0000 (12:12 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Wed, 18 Dec 2013 12:12:43 +0000 (12:12 +0000)
148 files changed:
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dynamicmbean/AbstractDynamicWrapper.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dynamicmbean/AttributeHolder.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dynamicmbean/DynamicWritableWrapper.java
opendaylight/config/yang-test/pom.xml
opendaylight/config/yang-test/src/test/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleTest.java [new file with mode: 0644]
opendaylight/distribution/opendaylight/pom.xml
opendaylight/distribution/opendaylight/src/main/resources/configuration/logback.xml
opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/internal/ForwardingRulesManager.java
opendaylight/md-sal/pom.xml
opendaylight/md-sal/remoterpc-routingtable/implementation/pom.xml [moved from opendaylight/md-sal/zeromq-routingtable/implementation/pom.xml with 98% similarity]
opendaylight/md-sal/remoterpc-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/RouteChangeListener.java [moved from opendaylight/md-sal/zeromq-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/RouteChangeListener.java with 100% similarity]
opendaylight/md-sal/remoterpc-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/RoutingTable.java [moved from opendaylight/md-sal/zeromq-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/RoutingTable.java with 100% similarity]
opendaylight/md-sal/remoterpc-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/RoutingTableException.java [moved from opendaylight/md-sal/zeromq-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/RoutingTableException.java with 100% similarity]
opendaylight/md-sal/remoterpc-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/SystemException.java [moved from opendaylight/md-sal/zeromq-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/SystemException.java with 100% similarity]
opendaylight/md-sal/remoterpc-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/impl/Activator.java [moved from opendaylight/md-sal/zeromq-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/impl/Activator.java with 100% similarity]
opendaylight/md-sal/remoterpc-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/impl/RoutingTableImpl.java [moved from opendaylight/md-sal/zeromq-routingtable/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/impl/RoutingTableImpl.java with 95% similarity]
opendaylight/md-sal/remoterpc-routingtable/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/impl/RoutingTableImplTest.java [moved from opendaylight/md-sal/zeromq-routingtable/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/impl/RoutingTableImplTest.java with 100% similarity]
opendaylight/md-sal/remoterpc-routingtable/integrationtest/pom.xml [moved from opendaylight/md-sal/zeromq-routingtable/integrationtest/pom.xml with 98% similarity]
opendaylight/md-sal/remoterpc-routingtable/integrationtest/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/impl/ZeroMQRoutingTableTestIT.java [moved from opendaylight/md-sal/zeromq-routingtable/integrationtest/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/impl/ZeroMQRoutingTableTestIT.java with 99% similarity]
opendaylight/md-sal/remoterpc-routingtable/integrationtest/src/test/resources/logback.xml [moved from opendaylight/md-sal/zeromq-routingtable/integrationtest/src/test/resources/logback.xml with 100% similarity]
opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/pom.xml [new file with mode: 0644]
opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/src/main/java/org/opendaylight/controller/tests/zmqroutingtable/rest/RouteIdentifierImpl.java [new file with mode: 0644]
opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/src/main/java/org/opendaylight/controller/tests/zmqroutingtable/rest/Router.java [new file with mode: 0644]
opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/src/main/resources/WEB-INF/web.xml [new file with mode: 0644]
opendaylight/md-sal/sal-remoterpc-connector/implementation/pom.xml
opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-nb/pom.xml
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/JsonReader.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestUtil.java [new file with mode: 0644]
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/rest/impl/XmlReader.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/IdentityValuesDTO.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/SimpleNodeWrapper.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonBasicDataTypesTest.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/ToJsonBasicYangTypesTest.java [moved from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonBasicYangTypesTest.java with 87% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonChoiceCaseTest.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/ToJsonIdentityrefTest.java [moved from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonIdentityrefTest.java with 61% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonLeafrefType.java [moved from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonLeafrefType.java with 75% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonWithAugmentTest.java [moved from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonWithAugmentTest.java with 66% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlTest.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 [moved from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/FromJsonToCompositeNodeTest.java with 73% similarity]
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/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/ToJsonBasicDataTypesTest.java [deleted file]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonChoiceCaseTest.java [deleted file]
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/structures/Lf.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/structures/LfLst.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/structures/LstItem.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlToCnSnTest.java [moved from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/FromXmlToCompositeNodeTest.java with 65% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/augmentation/augment-container.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-container.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/augmentation/augment-leaf.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-leaf.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/augmentation/augment-leaflist.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-leaflist.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/augmentation/augment-list.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/augment-list.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/augmentation/xml/data.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/xml/data.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/augmentation/yang.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/augmentation/yang.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/choice/choice.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/choice.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/choice/xml/data_case_defined_without_case.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_case_defined_without_case.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/choice/xml/data_container.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_container.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/choice/xml/data_leaflist.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_leaflist.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/choice/xml/data_list.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_list.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/choice/xml/data_more_choices_same_level.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_more_choices_same_level.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/choice/xml/data_more_choices_same_level_various_paths_err.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_more_choices_same_level_various_paths_err.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/choice/xml/data_no_first_case.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_no_first_case.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/choice/xml/data_random_level.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_random_level.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/choice/xml/data_three_choices_same_level.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_three_choices_same_level.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/choice/xml/data_various_path_err.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/choice/xml/data_various_path_err.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/identityref/identity-module.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/identityref/identity-module.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/identityref/identityref-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/leafref/cont-augment-module.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/leafref/cont-augment-module.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/leafref/main-module.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/leafref/main-module.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/leafref/xml/data_absolut_ref_to_existing_leaf.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/leafref/xml/data_absolut_ref_to_existing_leaf.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/leafref/xml/data_from_leafref_to_leafref.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/leafref/xml/data_from_leafref_to_leafref.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/leafref/xml/data_ref_to_non_existing_leaf.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/leafref/xml/data_ref_to_non_existing_leaf.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/leafref/xml/data_ref_to_not_leaf.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/leafref/xml/data_ref_to_not_leaf.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/leafref/xml/data_relativ_ref_from_leaflist_to_existing_leaf.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/leafref/xml/data_relativ_ref_from_leaflist_to_existing_leaf.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/leafref/xml/data_relativ_ref_to_existing_leaf.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/leafref/xml/data_relativ_ref_to_existing_leaf.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/simple-data-types/simple-data-types.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/simple-data-types/simple-data-types.yang with 90% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/simple-data-types/xml/data.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/simple-data-types/xml/data.xml with 80% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/simple-yang-types/simple-yang-types.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/simple-yang-types/simple-yang-types.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/simple-yang-types/xml/awaited_output_data.json [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/simple-yang-types/xml/awaited_output_data.json with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/simple-yang-types/xml/awaited_output_empty_data.json [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/simple-yang-types/xml/awaited_output_empty_data.json with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/simple-yang-types/xml/data.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/simple-yang-types/xml/data.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/simple-yang-types/xml/empty_data.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/simple-yang-types/xml/empty_data.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/instance_identifier/aug-referenced-elements-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/instance_identifier/eferenced-elements-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/instance_identifier/rinstance-identifier-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/yang/basic-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/yang/referenced-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/array-with-null.json [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-composite-node/array-with-null.json with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/empty-data.json [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-composite-node/empty-data.json with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/empty-data1.json [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-composite-node/empty-data1.json with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/identityref/identity-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/identityref/identityref-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/identityref/json/data.json [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/multiple-items-in-list.json [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-composite-node/multiple-items-in-list.json with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/multiple-leaflist-items.json [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-composite-node/multiple-leaflist-items.json with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-container-yang/simple-container.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-composite-node/simple-container-yang/simple-container.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-container.json [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-composite-node/simple-container.json with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/simple-list1.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-composite-node/simple-list-yang/simple-list1.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list-yang/simple-list2.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-composite-node/simple-list-yang/simple-list2.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/simple-list.json [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-composite-node/simple-list.json with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/wrong-top-level1.json [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-composite-node/wrong-top-level1.json with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/wrong-top-level2.json [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-composite-node/wrong-top-level2.json with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/wrong-top-level3.json [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-composite-node/wrong-top-level3.json with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-container-yang/data-container.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-composite-node/data-container-yang/data-container.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-container.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-composite-node/data-container.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-list-yang/data-container.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-composite-node/data-list-yang/data-container.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-list-yang/data-list.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-composite-node/data-list-yang/data-list.yang with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-list.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-composite-node/data-list.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-nmspc-in-attributes.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/empty-data.xml [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-composite-node/empty-data.xml with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/identity-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/identityref-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-default-nmspc-in-element.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-default-nmspc-in-parrent-element.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-nmspc-in-element.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-nmspc-in-parrent-element.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-no-nmspc-value-with-prefix.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-no-nmspc-value-without-prefix.xml [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/yang-augments/general-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/yang-augments/identity-module.yang [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/yang-augments/identityref-module.yang [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/identityref/identityref-module.yang with 69% similarity]
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceImplTest.java
opendaylight/netconf/netconf-it/pom.xml
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java
opendaylight/netconf/netconf-ssh/pom.xml
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/NetconfSSHServer.java
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java [new file with mode: 0644]
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProviderInterface.java [moved from opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/KeyStoreHandler.java with 52% similarity]
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/RSAKey.java [deleted file]
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/threads/SocketThread.java
opendaylight/netconf/netconf-ssh/src/main/resources/RSA.pk [new file with mode: 0644]
opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/SSHServerTest.java [moved from opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/ssh/SSHServerTest.java with 53% similarity]
opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/StubUserManager.java [new file with mode: 0644]
opendaylight/netconf/pom.xml
opendaylight/northbound/subnets/src/main/resources/WEB-INF/web.xml
opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/SwitchManager.java
opendaylight/usermanager/api/src/main/java/org/opendaylight/controller/usermanager/UserConfig.java
opendaylight/usermanager/api/src/test/java/org/opendaylight/controller/usermanager/AuthorizationUserConfigTest.java
opendaylight/usermanager/implementation/pom.xml
opendaylight/web/flows/src/main/resources/js/page.js

index ba2c1089c2bef93bbcacbbc98019c6ab5045043d..6f0d1b2682a00e17b8935cca72c86599cd2b2b63 100644 (file)
@@ -7,16 +7,14 @@
  */
 package org.opendaylight.controller.config.manager.impl.dynamicmbean;
 
-import static java.lang.String.format;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.api.annotations.Description;
+import org.opendaylight.controller.config.api.annotations.RequireInterface;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.config.manager.impl.util.InterfacesHelper;
+import org.opendaylight.controller.config.spi.Module;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import javax.management.Attribute;
 import javax.management.AttributeList;
@@ -40,15 +38,17 @@ import javax.management.Notification;
 import javax.management.NotificationListener;
 import javax.management.ObjectName;
 import javax.management.ReflectionException;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
-import org.opendaylight.controller.config.api.ModuleIdentifier;
-import org.opendaylight.controller.config.api.annotations.Description;
-import org.opendaylight.controller.config.api.annotations.RequireInterface;
-import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
-import org.opendaylight.controller.config.manager.impl.util.InterfacesHelper;
-import org.opendaylight.controller.config.spi.Module;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import static java.lang.String.format;
 
 /**
  * Contains common code for readable/rw dynamic mbean wrappers. Routes all
@@ -246,6 +246,7 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper {
         } catch (InstanceNotFoundException e) {
             new MBeanException(e);
         }
+
         if (obj instanceof ObjectName) {
             AttributeHolder attributeHolder = attributeHolderMap
                     .get(attributeName);
@@ -254,8 +255,42 @@ abstract class AbstractDynamicWrapper implements DynamicMBeanModuleWrapper {
             }
             return obj;
         }
+
+
+        if(isDependencyListAttr(attributeName, obj)) {
+            obj = fixDependencyListAttribute(obj);
+        }
+
         return obj;
+    }
+
+    private Object fixDependencyListAttribute(Object attribute) {
+        if(attribute.getClass().isArray() == false)
+            throw new IllegalArgumentException("Unexpected attribute type, should be an array, but was " + attribute.getClass());
+
+        for (int i = 0; i < Array.getLength(attribute); i++) {
+
+            Object on = Array.get(attribute, i);
+            if(on instanceof ObjectName == false)
+                throw new IllegalArgumentException("Unexpected attribute type, should be an ObjectName, but was " + on.getClass());
+            on = fixObjectName((ObjectName) on);
+
+            Array.set(attribute, i, on);
+        }
+
+        return attribute;
+    }
+
+    private boolean isDependencyListAttr(String attributeName, Object attribute) {
+        if (attributeHolderMap.containsKey(attributeName) == false)
+            return false;
+
+        AttributeHolder attributeHolder = attributeHolderMap.get(attributeName);
 
+        boolean isDepList = true;
+        isDepList &= attributeHolder.getRequireInterfaceOrNull() != null;
+        isDepList &= attribute instanceof ObjectName[];
+        return isDepList;
     }
 
     protected ObjectName fixObjectName(ObjectName on) {
index 109ab10ac2a086e590ab1023bfa2ffd1442e8ad8..9dd6a2269e259cf4ca5ee4e6b1331d85ef015d81 100644 (file)
@@ -7,18 +7,17 @@
  */
 package org.opendaylight.controller.config.manager.impl.dynamicmbean;
 
-import java.lang.reflect.Method;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import org.opendaylight.controller.config.api.annotations.Description;
+import org.opendaylight.controller.config.api.annotations.RequireInterface;
 
 import javax.annotation.Nullable;
 import javax.annotation.concurrent.Immutable;
 import javax.management.MBeanAttributeInfo;
 import javax.management.ObjectName;
-
-import org.opendaylight.controller.config.api.annotations.Description;
-import org.opendaylight.controller.config.api.annotations.RequireInterface;
+import java.lang.reflect.Method;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
 
 @Immutable
 class AttributeHolder {
@@ -32,6 +31,14 @@ class AttributeHolder {
     private final RequireInterface requireInterfaceAnnotation;
     private final String attributeType;
 
+    public static final Set<Class<?>> PERMITTED_PARAMETER_TYPES_FOR_DEPENDENCY_SETTER = new HashSet<>();
+
+    static {
+        PERMITTED_PARAMETER_TYPES_FOR_DEPENDENCY_SETTER.add(ObjectName.class);
+        PERMITTED_PARAMETER_TYPES_FOR_DEPENDENCY_SETTER.add(ObjectName[].class);
+        PERMITTED_PARAMETER_TYPES_FOR_DEPENDENCY_SETTER.add(List.class);
+    }
+
     public AttributeHolder(String name, Object object, String returnType,
             boolean writable,
             @Nullable RequireInterface requireInterfaceAnnotation,
@@ -114,12 +121,12 @@ class AttributeHolder {
     static RequireInterface findRequireInterfaceAnnotation(final Method setter,
             Set<Class<?>> inspectedInterfaces) {
 
-        // only allow setX(ObjectName y) or setX(ObjectName[] y) to continue
-        if (setter.getParameterTypes().length != 1
-                || (setter.getParameterTypes()[0].equals(ObjectName.class) == false && setter
-                        .getParameterTypes()[0].equals(ObjectName[].class) == false)) {
+        // only allow setX(ObjectName y) or setX(ObjectName[] y) or setX(List<ObjectName> y) to continue
+
+        if (setter.getParameterTypes().length > 1)
+            return null;
+        if(PERMITTED_PARAMETER_TYPES_FOR_DEPENDENCY_SETTER.contains(setter.getParameterTypes()[0]) == false)
             return null;
-        }
 
         List<RequireInterface> foundRequireInterfaces = AnnotationsHelper
                 .findMethodAnnotationInSuperClassesAndIfcs(setter, RequireInterface.class, inspectedInterfaces);
index a1cd6b01339dd7fc82864c3219bc5f32fc7de0ba..2ab04e53e304fa8909543ded413b408941566fcc 100644 (file)
@@ -7,7 +7,13 @@
  */
 package org.opendaylight.controller.config.manager.impl.dynamicmbean;
 
-import java.lang.reflect.Method;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.controller.config.api.ValidationException;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.config.manager.impl.TransactionIdentifier;
+import org.opendaylight.controller.config.spi.Module;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import javax.annotation.concurrent.ThreadSafe;
 import javax.management.Attribute;
@@ -20,14 +26,7 @@ import javax.management.MBeanOperationInfo;
 import javax.management.MBeanServer;
 import javax.management.ObjectName;
 import javax.management.ReflectionException;
-
-import org.opendaylight.controller.config.api.ModuleIdentifier;
-import org.opendaylight.controller.config.api.ValidationException;
-import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
-import org.opendaylight.controller.config.manager.impl.TransactionIdentifier;
-import org.opendaylight.controller.config.spi.Module;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import java.lang.reflect.Method;
 
 /**
  * Wraps {@link org.opendaylight.controller.config.spi.Module} instance in a
@@ -92,16 +91,11 @@ public class DynamicWritableWrapper extends AbstractDynamicWrapper {
 
         try {
             if (attribute.getValue() instanceof ObjectName) {
-                AttributeHolder attributeHolder = attributeHolderMap
-                        .get(attribute.getName());
-                if (attributeHolder.getRequireInterfaceOrNull() != null) {
-                    attribute = new Attribute(attribute.getName(),
-                            fixObjectName((ObjectName) attribute.getValue()));
-                } else {
-                    attribute = new Attribute(attribute.getName(),
-                            attribute.getValue());
-                }
+                attribute = fixDependencyAttribute(attribute);
+            } else if(attribute.getValue() instanceof ObjectName[]) {
+                attribute = fixDependencyListAttribute(attribute);
             }
+
             internalServer.setAttribute(objectNameInternal, attribute);
         } catch (InstanceNotFoundException e) {
             throw new MBeanException(e);
@@ -109,6 +103,39 @@ public class DynamicWritableWrapper extends AbstractDynamicWrapper {
 
     }
 
+    private Attribute fixDependencyListAttribute(Attribute attribute) {
+        AttributeHolder attributeHolder = attributeHolderMap
+                .get(attribute.getName());
+        if (attributeHolder.getRequireInterfaceOrNull() != null) {
+            attribute = new Attribute(attribute.getName(),
+                    fixObjectNames((ObjectName[]) attribute.getValue()));
+        }
+        return attribute;
+    }
+
+    private Attribute fixDependencyAttribute(Attribute attribute) {
+        AttributeHolder attributeHolder = attributeHolderMap
+                .get(attribute.getName());
+        if (attributeHolder.getRequireInterfaceOrNull() != null) {
+            attribute = new Attribute(attribute.getName(),
+                    fixObjectName((ObjectName) attribute.getValue()));
+        } else {
+            attribute = new Attribute(attribute.getName(),
+                    attribute.getValue());
+        }
+        return attribute;
+    }
+
+    private ObjectName[] fixObjectNames(ObjectName[] dependencies) {
+        int i = 0;
+
+        for (ObjectName dependencyOn : dependencies) {
+            dependencies[i++] = fixObjectName(dependencyOn);
+        }
+
+        return dependencies;
+    }
+
     @Override
     public AttributeList setAttributes(AttributeList attributes) {
         AttributeList result = new AttributeList();
index 149348df4b2234e7c54c49f59fd7f7118e9d0c91..b1f7013abef241620ff02d393751133270e78bcb 100644 (file)
             <artifactId>slf4j-api</artifactId>
         </dependency>
         <dependency>
-         <groupId>org.opendaylight.yangtools.model</groupId>
-         <artifactId>ietf-inet-types</artifactId>
+            <groupId>org.opendaylight.yangtools.model</groupId>
+            <artifactId>ietf-inet-types</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.bgpcep</groupId>
+            <artifactId>mockito-configuration</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>config-manager</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>config-manager</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>config-util</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
         </dependency>
     </dependencies>
 
diff --git a/opendaylight/config/yang-test/src/test/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleTest.java b/opendaylight/config/yang-test/src/test/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleTest.java
new file mode 100644 (file)
index 0000000..50e1d4b
--- /dev/null
@@ -0,0 +1,89 @@
+package org.opendaylight.controller.config.yang.test.impl;
+
+import com.google.common.collect.Lists;
+import junit.framework.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.config.api.ConflictingVersionException;
+import org.opendaylight.controller.config.api.ValidationException;
+import org.opendaylight.controller.config.api.jmx.CommitStatus;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
+import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
+import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
+
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.ObjectName;
+import java.util.ArrayList;
+import java.util.List;
+
+public class NetconfTestImplModuleTest  extends AbstractConfigTest {
+
+    public static final String TESTING_DEP_PREFIX = "testing-dep";
+    private NetconfTestImplModuleFactory factory;
+    private final String instanceName = "n1";
+
+    @Before
+    public void setUp() {
+
+        factory = new NetconfTestImplModuleFactory();
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory,
+                new DepTestImplModuleFactory()));
+    }
+
+    @Test
+    public void testDependencyList() throws InstanceAlreadyExistsException, ValidationException,
+            ConflictingVersionException {
+        ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
+
+        ObjectName on = createInstance(transaction, instanceName, 4);
+        transaction.validateConfig();
+        CommitStatus status = transaction.commit();
+
+        assertBeanCount(1, factory.getImplementationName());
+        assertBeanCount(4 + 1, DepTestImplModuleFactory.NAME);
+        assertStatus(status, 1 + 4 + 1, 0, 0);
+
+        transaction = configRegistryClient.createTransaction();
+
+        NetconfTestImplModuleMXBean proxy = transaction.newMXBeanProxy(ObjectNameUtil.withoutTransactionName(on),
+                NetconfTestImplModuleMXBean.class);
+        proxy.getComplexList();
+        List<ObjectName> testingDeps = proxy.getTestingDeps();
+        ObjectName testingDep = proxy.getTestingDep();
+
+        Assert.assertEquals(TESTING_DEP_PREFIX, ObjectNameUtil.getInstanceName(testingDep));
+        assertTestingDeps(testingDeps, 4);
+
+        transaction.abortConfig();
+    }
+
+    private void assertTestingDeps(List<ObjectName> testingDeps, int i) {
+        Assert.assertEquals(i, testingDeps.size());
+
+        int c = 1;
+        for (ObjectName testingDep : testingDeps) {
+            Assert.assertEquals(TESTING_DEP_PREFIX + Integer.toString(c++), ObjectNameUtil.getInstanceName(testingDep));
+        }
+    }
+
+
+    private ObjectName createInstance(ConfigTransactionJMXClient transaction, String instanceName, int depsCount)
+            throws InstanceAlreadyExistsException {
+        ObjectName nameCreated = transaction.createModule(factory.getImplementationName(), instanceName);
+        NetconfTestImplModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated, NetconfTestImplModuleMXBean.class);
+
+        ObjectName dep = transaction.createModule(DepTestImplModuleFactory.NAME, TESTING_DEP_PREFIX);
+        mxBean.setTestingDep(dep);
+
+        ArrayList<ObjectName> testingDeps = Lists.newArrayList();
+        for (int i = 0; i < depsCount; i++) {
+            dep = transaction.createModule(DepTestImplModuleFactory.NAME, TESTING_DEP_PREFIX + Integer.toString(i + 1));
+            testingDeps.add(dep);
+        }
+        mxBean.setTestingDeps(testingDeps);
+
+        return nameCreated;
+    }
+
+}
index 35e160e8274e9fe5ee09bc49ce90f77841218425..b0f7ad89a4b81694c889c52e51f5cc00947c8c4f 100644 (file)
         <dependency>
               <groupId>org.opendaylight.controller</groupId>
               <artifactId>
-                  zeromq-routingtable.implementation
+                  remoterpc-routingtable.implementation
               </artifactId>
               <version>0.4.1-SNAPSHOT</version>
         </dependency>
index 2815422274fad3c61cfa95ba724969eadf30d001..84d1c913c413ef5e1978aded60ff85c200437169 100644 (file)
@@ -61,7 +61,7 @@
   <logger name="org.opendaylight.controller.sal.implementation" level="INFO"/>
   <logger name="org.opendaylight.controller.sal.implementation.internal.Inventory" level="INFO"/>
   <logger name="org.opendaylight.controller.sal.implementation.internal.Topology" level="INFO"/>
-     <!-- zeromq router and zeromq routing table -->
+     <!-- remoterpc router and remoterpc routing table -->
   <logger name="org.opendaylight.controller.sal.connector.remoterpc" level="INFO" />
   <!-- Functional Modules -->
   <logger name="org.opendaylight.controller.arphandler" level="INFO"/>
index 45fb11a83eda110b96b1588dd43b0c8fd6c7b164..3d6a0292ef67225079b11759a3560bdfddf85377 100644 (file)
@@ -2930,8 +2930,16 @@ public class ForwardingRulesManager implements
         }
         if (target != null) {
             // Update Configuration database
-            target.toggleInstallation();
-            target.setStatus(StatusCode.SUCCESS.toString());
+            if (target.getHardTimeout() != null || target.getIdleTimeout() != null) {
+                /*
+                 * No need for checking if actual values: these strings were
+                 * validated at configuration creation. Also, after a switch
+                 * down scenario, no use to reinstall a timed flow. Mark it as
+                 * "do not install". User can manually toggle it.
+                 */
+                target.toggleInstallation();
+            }
+            target.setStatus(StatusCode.GONE.toString());
             staticFlows.put(key, target);
         }
 
index 4f2b255afd50c08005fae6abcf0d683db73dd86f..0d6523bc0bbb38dd059e9c978be147cab7a4b7e8 100644 (file)
@@ -43,7 +43,7 @@
         <module>sal-rest-connector</module>
         <module>sal-netconf-connector</module>
 
-        <module>zeromq-routingtable/implementation</module>
+        <module>remoterpc-routingtable/implementation</module>
         <module>sal-remoterpc-connector/implementation</module>
         <!-- Clustered Data Store -->
         <module>clustered-data-store/implementation</module>
similarity index 98%
rename from opendaylight/md-sal/zeromq-routingtable/implementation/pom.xml
rename to opendaylight/md-sal/remoterpc-routingtable/implementation/pom.xml
index 2926786849f82999903565f3388e49481b4ab637..a788baf4c0642a1ebb26b390ba415a338a45a033 100644 (file)
@@ -15,7 +15,7 @@
         <tag>HEAD</tag>
     </scm>
 
-    <artifactId>zeromq-routingtable.implementation</artifactId>
+    <artifactId>remoterpc-routingtable.implementation</artifactId>
     <version>0.4.1-SNAPSHOT</version>
     <packaging>bundle</packaging>
 
@@ -30,6 +30,7 @@ import javax.transaction.RollbackException;
 import java.util.Collections;
 import java.util.EnumSet;
 import java.util.HashSet;
+import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentMap;
 
@@ -254,6 +255,23 @@ public class RoutingTableImpl<I, R> implements RoutingTable<I, R>, ICacheUpdateA
         return this.routingTableCache;
     }
 
+    /**
+     * This is used from integration test NP rest API to check out the result of the
+     * cache population
+     * <Note> For testing purpose only-- use it wisely</Note>
+     * @return
+     */
+    public String dumpRoutingTableCache(){
+       Set<Map.Entry<I, R>> cacheEntrySet = this.routingTableCache.entrySet();
+       StringBuilder sb = new StringBuilder();
+       for(Map.Entry<I,R> entry:cacheEntrySet){
+           sb.append("Key:").append(entry.getKey()).append("---->Value:")
+                   .append((entry.getValue() != null)?entry.getValue():"null")
+                   .append("\n");
+       }
+       return sb.toString();
+    }
+
     /**
      * Invoked when a new entry is available in the cache, the key is only
      * provided, the value will come as an entryUpdate invocation
similarity index 98%
rename from opendaylight/md-sal/zeromq-routingtable/integrationtest/pom.xml
rename to opendaylight/md-sal/remoterpc-routingtable/integrationtest/pom.xml
index 308d5a9316d621e2b235cd1b356b121475fe311d..bdc4569f31ac6869276e1cc7075ba7ded3844fc6 100644 (file)
     <tag>HEAD</tag>
   </scm>
 
-  <artifactId>zeromq-routingtable.integrationtest</artifactId>
+  <artifactId>remoterpc-routingtable.integrationtest</artifactId>
   <version>0.4.1-SNAPSHOT</version>
 
   <dependencies>
     <dependency>
         <groupId>org.opendaylight.controller</groupId>
-        <artifactId>zeromq-routingtable.implementation</artifactId>
+        <artifactId>remoterpc-routingtable.implementation</artifactId>
         <version>0.4.1-SNAPSHOT</version>
     </dependency>
     <dependency>
@@ -120,7 +120,7 @@ public class
                         .versionAsInProject(),
                 mavenBundle(ODL, "sal-connector-api")
                         .versionAsInProject(),
-                mavenBundle(ODL, "zeromq-routingtable.implementation")
+                mavenBundle(ODL, "remoterpc-routingtable.implementation")
                         .versionAsInProject(),
 
                 mavenBundle("org.jboss.spec.javax.transaction",
diff --git a/opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/pom.xml b/opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/pom.xml
new file mode 100644 (file)
index 0000000..35b2a4b
--- /dev/null
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>sal-remoterpc-connector-test-parent</artifactId>
+    <groupId>org.opendaylight.controller.tests</groupId>
+    <version>1.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>remoterpc-routingtable-nb-it</artifactId>
+  <packaging>bundle</packaging>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <version>${bundle.plugin.version}</version>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Export-Package>
+             org.opendaylight.controller.tests.zmqroutingtable.rest
+            </Export-Package>
+            <Import-Package>
+              com.sun.jersey.spi.container.servlet,
+              org.codehaus.jackson.annotate,
+              javax.ws.rs,
+              javax.ws.rs.core,
+              javax.xml.bind,
+              javax.xml.bind.annotation,
+              org.slf4j,
+              org.apache.catalina.filters,
+              org.codehaus.jackson.jaxrs,
+              org.opendaylight.controller.sal.utils,
+              org.opendaylight.yangtools.yang.common,
+              org.opendaylight.controller.sal.connector.api,
+              org.opendaylight.controller.sal.connector.remoterpc.api,
+              org.opendaylight.controller.sal.connector.remoterpc.impl,
+              org.osgi.framework,
+              com.google.common.base,
+              org.opendaylight.yangtools.yang.data.api,
+              !org.codehaus.enunciate.jaxrs
+
+            </Import-Package>
+            <Web-ContextPath>/controller/nb/v2/zmqnbrt</Web-ContextPath>
+            <Jaxrs-Resources>,${classes;ANNOTATION;javax.ws.rs.Path}</Jaxrs-Resources>
+          </instructions>
+          <manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>containermanager</artifactId>
+      <version>0.5.1-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>commons.northbound</artifactId>
+      <version>0.4.1-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal</artifactId>
+      <version>0.5.1-SNAPSHOT</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <version>5.0.0</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+    </dependency>
+      <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>remoterpc-routingtable.implementation</artifactId>
+          <version>0.4.1-SNAPSHOT</version>
+      </dependency>
+      <dependency>
+          <groupId>com.google.guava</groupId>
+          <artifactId>guava</artifactId>
+      </dependency>
+  </dependencies>
+
+ </project>
diff --git a/opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/src/main/java/org/opendaylight/controller/tests/zmqroutingtable/rest/RouteIdentifierImpl.java b/opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/src/main/java/org/opendaylight/controller/tests/zmqroutingtable/rest/RouteIdentifierImpl.java
new file mode 100644 (file)
index 0000000..6b7ee26
--- /dev/null
@@ -0,0 +1,69 @@
+package org.opendaylight.controller.tests.zmqroutingtable.rest;
+
+import org.opendaylight.controller.sal.connector.api.RpcRouter;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+
+import java.io.Serializable;
+import java.net.URI;
+
+/**
+ * @author: syedbahm
+ * Date: 12/10/13
+ */
+public class RouteIdentifierImpl implements RpcRouter.RouteIdentifier, Serializable {
+
+    private final URI namespace;
+    private final QName QNAME;
+    private final QName instance;
+
+    public RouteIdentifierImpl() {
+        namespace = URI.create("http://cisco.com/example");
+        QNAME = new QName(namespace, "global");
+        instance = new QName(URI.create("127.0.0.1"), "local");
+    }
+
+    public RouteIdentifierImpl(String url,String instanceIP){
+        namespace = URI.create(url);
+        QNAME = new QName(namespace,"global");
+        instance =  new QName(URI.create(instanceIP), "local");
+    }
+
+
+    @Override
+    public QName getContext() {
+        return QNAME;
+    }
+
+    @Override
+    public QName getType() {
+        return QNAME;
+    }
+
+    @Override
+    public org.opendaylight.yangtools.yang.data.api.InstanceIdentifier getRoute() {
+        return InstanceIdentifier.of(instance);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        RouteIdentifierImpl that = (RouteIdentifierImpl) o;
+
+        if (!QNAME.equals(that.QNAME)) return false;
+        if (!instance.equals(that.instance)) return false;
+        if (!namespace.equals(that.namespace)) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = namespace.hashCode();
+        result = 31 * result + QNAME.hashCode();
+        result = 31 * result + instance.hashCode();
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/src/main/java/org/opendaylight/controller/tests/zmqroutingtable/rest/Router.java b/opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/src/main/java/org/opendaylight/controller/tests/zmqroutingtable/rest/Router.java
new file mode 100644 (file)
index 0000000..c426927
--- /dev/null
@@ -0,0 +1,157 @@
+package org.opendaylight.controller.tests.zmqroutingtable.rest;
+
+import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable;
+import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTableException;
+import org.opendaylight.controller.sal.connector.remoterpc.api.SystemException;
+import org.opendaylight.controller.sal.connector.remoterpc.impl.RoutingTableImpl;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleReference;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import java.io.Serializable;
+import java.net.URI;
+
+@Path("router")
+public class Router implements Serializable {
+  private Logger _logger = LoggerFactory.getLogger(Router.class);
+  private final URI namespace = URI.create("http://cisco.com/example");
+  private final QName QNAME = new QName(namespace, "heartbeat");
+
+
+  @GET
+  @Path("/hello")
+  @Produces(MediaType.TEXT_PLAIN)
+  public String hello() {
+    return "Hello";
+  }
+
+
+
+
+    @GET
+    @Path("/rtadd")
+    @Produces(MediaType.TEXT_PLAIN)
+    public String addToRoutingTable(@QueryParam("nsp") String namespace,@QueryParam("inst") String instance,@QueryParam("port") String port) {
+        _logger.info("Invoking adding an entry in routing table");
+
+        BundleContext ctx = getBundleContext();
+        ServiceReference routingTableServiceReference = ctx.getServiceReference(RoutingTable.class);
+        if (routingTableServiceReference == null) {
+            _logger.debug("Could not get routing table impl reference");
+            return "Could not get routingtable referen ";
+        }
+        RoutingTableImpl routingTable = (RoutingTableImpl) ctx.getService(routingTableServiceReference);
+        if (routingTable == null) {
+            _logger.info("Could not get routing table service");
+            return "Could not get routing table service";
+        }
+
+
+        RouteIdentifierImpl rii = new RouteIdentifierImpl(namespace,instance);
+        try {
+            routingTable.addGlobalRoute(rii, instance+":"+ port);
+        } catch (RoutingTableException e) {
+            _logger.error("error in adding routing identifier" + e.getMessage());
+
+        } catch (SystemException e) {
+            _logger.error("error in adding routing identifier" + e.getMessage());
+        }
+
+        StringBuilder stringBuilder = new StringBuilder();
+        stringBuilder.append("Result of adding route:").append("\n")
+                     .append(routingTable.dumpRoutingTableCache());
+        return stringBuilder.toString();
+    }
+
+  @GET
+  @Path("/rtdelete")
+  @Produces(MediaType.TEXT_PLAIN)
+  public String invokeDeleteRoutingTable(@QueryParam("nsp") String namespace,@QueryParam("inst") String instance) {
+    _logger.info("Invoking delete an entry in routing table");
+
+    BundleContext ctx = getBundleContext();
+    ServiceReference routingTableServiceReference = ctx.getServiceReference(RoutingTable.class);
+    if (routingTableServiceReference == null) {
+      _logger.debug("Could not get routing table impl reference");
+      return "Could not get routingtable referen ";
+    }
+    RoutingTableImpl routingTable = (RoutingTableImpl) ctx.getService(routingTableServiceReference);
+    if (routingTable == null) {
+      _logger.info("Could not get routing table service");
+      return "Could not get routing table service";
+    }
+
+
+    RouteIdentifierImpl rii = new RouteIdentifierImpl(namespace,instance);
+    try {
+      routingTable.removeGlobalRoute(rii);
+    } catch (RoutingTableException e) {
+      _logger.error("error in adding routing identifier" + e.getMessage());
+
+    } catch (SystemException e) {
+      _logger.error("error in adding routing identifier" + e.getMessage());
+    }
+
+
+    StringBuilder stringBuilder = new StringBuilder();
+    stringBuilder.append("Result of deleting route:").append("\n")
+              .append(routingTable.dumpRoutingTableCache());
+
+    return stringBuilder.toString();
+  }
+
+    @GET
+    @Path("/routingtable")
+    @Produces(MediaType.TEXT_PLAIN)
+    public String invokeGetRoutingTable() {
+        _logger.info("Invoking getting of routing table");
+
+        BundleContext ctx = getBundleContext();
+        ServiceReference routingTableServiceReference = ctx.getServiceReference(RoutingTable.class);
+        if (routingTableServiceReference == null) {
+            _logger.debug("Could not get routing table impl reference");
+            return "Could not get routingtable referen ";
+        }
+        RoutingTableImpl routingTable = (RoutingTableImpl) ctx.getService(routingTableServiceReference);
+        if (routingTable == null) {
+            _logger.info("Could not get routing table service");
+            return "Could not get routing table service";
+        }
+
+
+        StringBuilder stringBuilder = new StringBuilder();
+        stringBuilder.append("Result of getting routetable:").append("\n")
+                .append(routingTable.dumpRoutingTableCache());
+
+        return stringBuilder.toString();
+    }
+
+
+
+  private BundleContext getBundleContext() {
+    ClassLoader tlcl = Thread.currentThread().getContextClassLoader();
+    Bundle bundle = null;
+
+    if (tlcl instanceof BundleReference) {
+      bundle = ((BundleReference) tlcl).getBundle();
+    } else {
+      _logger.info("Unable to determine the bundle context based on " +
+          "thread context classloader.");
+      bundle = FrameworkUtil.getBundle(this.getClass());
+    }
+    return (bundle == null ? null : bundle.getBundleContext());
+  }
+
+
+
+}
diff --git a/opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/src/main/resources/WEB-INF/web.xml b/opendaylight/md-sal/remoterpc-routingtable/integrationtest/test-nb/src/main/resources/WEB-INF/web.xml
new file mode 100644 (file)
index 0000000..2a0f3f3
--- /dev/null
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+        version="3.0">
+  <servlet>
+    <servlet-name>JAXRSZmqRT</servlet-name>
+    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
+    <init-param>
+      <param-name>javax.ws.rs.Application</param-name>
+      <param-value>org.opendaylight.controller.northbound.commons.NorthboundApplication</param-value>
+    </init-param>
+    <load-on-startup>1</load-on-startup>
+  </servlet>
+
+  <servlet-mapping>
+    <servlet-name>JAXRSZmqRT</servlet-name>
+    <url-pattern>/*</url-pattern>
+  </servlet-mapping>
+
+
+
+        <security-constraint>
+          <web-resource-collection>
+            <web-resource-name>NB api</web-resource-name>
+            <url-pattern>/*</url-pattern>
+            <http-method>POST</http-method>
+            <http-method>GET</http-method>
+            <http-method>PUT</http-method>
+            <http-method>PATCH</http-method>
+            <http-method>DELETE</http-method>
+            <http-method>HEAD</http-method>
+          </web-resource-collection>
+          <auth-constraint>
+            <role-name>System-Admin</role-name>
+            <role-name>Network-Admin</role-name>
+            <role-name>Network-Operator</role-name>
+            <role-name>Container-User</role-name>
+          </auth-constraint>
+        </security-constraint>
+
+        <security-role>
+                <role-name>System-Admin</role-name>
+        </security-role>
+        <security-role>
+                <role-name>Network-Admin</role-name>
+        </security-role>
+        <security-role>
+                <role-name>Network-Operator</role-name>
+        </security-role>
+        <security-role>
+                <role-name>Container-User</role-name>
+        </security-role>
+
+        <login-config>
+                <auth-method>BASIC</auth-method>
+                <realm-name>opendaylight</realm-name>
+        </login-config>
+</web-app>
index b8e0938a5f0901c9d7b73de541543aa472fca217..c973498e8549888e4b076d7e102c388c6222b9e8 100644 (file)
@@ -37,7 +37,7 @@
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
-      <artifactId>zeromq-routingtable.implementation</artifactId>
+      <artifactId>remoterpc-routingtable.implementation</artifactId>
       <!-- TODO: fix the version. Why is it not MD Sal project version?-->
       <version>0.4.1-SNAPSHOT</version>
     </dependency>
index dd7e36cfb4f8647656a6a0492731dfd730a4f458..dc2fdbf9a05382d19307d6cccb20c918c6c1aafc 100644 (file)
@@ -97,7 +97,7 @@
     </dependency>
       <dependency>
           <groupId>org.opendaylight.controller</groupId>
-          <artifactId>zeromq-routingtable.implementation</artifactId>
+          <artifactId>remoterpc-routingtable.implementation</artifactId>
           <version>0.4.1-SNAPSHOT</version>
       </dependency>
       <dependency>
index a42c468c2af27ea5f2cb84887757ed8057a4466f..fb7872f8bcd4e1efdf27be0183fd20176651ac33 100644 (file)
@@ -3,15 +3,38 @@ package org.opendaylight.controller.sal.rest.impl;
 import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.io.IOException;
-import java.util.*;
+import java.net.URI;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
 
 import javax.activation.UnsupportedDataTypeException;
 
 import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
+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.*;
-import org.opendaylight.yangtools.yang.model.api.*;
-import org.opendaylight.yangtools.yang.model.api.type.*;
+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.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.type.BooleanTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Preconditions;
 import com.google.gson.stream.JsonWriter;
@@ -20,6 +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); 
 
     public void write(JsonWriter writer, CompositeNode data, DataNodeContainer schema) throws IOException {
         Preconditions.checkNotNull(writer);
@@ -158,117 +182,42 @@ class JsonMapper {
     private void writeValueOfNodeByType(JsonWriter writer, SimpleNode<?> node, TypeDefinition<?> type,
             DataSchemaNode schema) throws IOException {
 
-        String value = String.valueOf(node.getValue());
-        TypeDefinition<?> baseType = resolveBaseTypeFrom(type);
+        TypeDefinition<?> baseType = RestUtil.resolveBaseTypeFrom(type);
 
-        // TODO check InstanceIdentifierTypeDefinition,
-        // IdentityrefTypeDefinition
+        // TODO check InstanceIdentifierTypeDefinition
         if (baseType instanceof IdentityrefTypeDefinition) {
             if (node.getValue() instanceof QName) {
-                QName qName = (QName) node.getValue();
-
-                ControllerContext contContext = ControllerContext.getInstance();
-                String moduleName = contContext.findModuleByNamespace(qName.getNamespace());
-
-                writer.value(moduleName + ":" + qName.getLocalName());
-            }
-
-        } else if (baseType instanceof LeafrefTypeDefinition) {
-            ControllerContext contContext = ControllerContext.getInstance();
-            LeafSchemaNode lfSchemaNode = contContext.resolveTypeFromLeafref((LeafrefTypeDefinition) baseType, schema);
-            if (lfSchemaNode != null) {
-                writeValueOfNodeByType(writer, node, lfSchemaNode.getType(), lfSchemaNode);
+                IdentityValuesDTO valueDTO = (IdentityValuesDTO) RestCodec.from(baseType).serialize(node.getValue());
+                IdentityValue valueFromDTO = valueDTO.getValuesWithNamespaces().get(0);
+                String moduleName = ControllerContext.getInstance().findModuleByNamespace(URI.create(valueFromDTO.getNamespace()));
+                writer.value(moduleName + ":" + valueFromDTO.getValue());
             } else {
-                writer.value(value);
+                logger.debug("Value of " + baseType.getQName().getNamespace() + ":"
+                        + baseType.getQName().getLocalName() + " is not instance of " + QName.class + " but is " + node.getValue().getClass());
+                writer.value(String.valueOf(node.getValue()));
             }
-        } else if (baseType instanceof InstanceIdentifierTypeDefinition) {
-            writer.value(((InstanceIdentifierTypeDefinition) baseType).getPathStatement().toString());
-        } else if (baseType instanceof UnionTypeDefinition) {
-            processTypeIsUnionType(writer, (UnionTypeDefinition) baseType, value);
         } else if (baseType instanceof DecimalTypeDefinition || baseType instanceof IntegerTypeDefinition
                 || baseType instanceof UnsignedIntegerTypeDefinition) {
-            writer.value(new NumberForJsonWriter(value));
+            writer.value(new NumberForJsonWriter((String) RestCodec.from(baseType).serialize(node.getValue())));
         } else if (baseType instanceof BooleanTypeDefinition) {
-            writer.value(Boolean.parseBoolean(value));
+            writer.value(Boolean.parseBoolean((String) RestCodec.from(baseType).serialize(node.getValue())));
         } else if (baseType instanceof EmptyTypeDefinition) {
             writeEmptyDataTypeToJson(writer);
         } else {
+            String value = String.valueOf(RestCodec.from(baseType).serialize(node.getValue()));
+            if (value == null) {
+                value = String.valueOf(node.getValue());
+            }
             writer.value(value.equals("null") ? "" : value);
         }
     }
 
-    private void processTypeIsUnionType(JsonWriter writer, UnionTypeDefinition unionType, String value)
-            throws IOException {
-        if (value == null) {
-            writeEmptyDataTypeToJson(writer);
-        } else if ((isNumber(value))
-                && containsType(unionType, UnsignedIntegerTypeDefinition.class, IntegerTypeDefinition.class,
-                        DecimalTypeDefinition.class)) {
-            writer.value(new NumberForJsonWriter(value));
-        } else if (isBoolean(value) && containsType(unionType, BooleanTypeDefinition.class)) {
-            writer.value(Boolean.parseBoolean(value));
-        } else {
-            writer.value(value);
-        }
-    }
-
-    private boolean isBoolean(String value) {
-        if (value.equals("true") || value.equals("false")) {
-            return true;
-        }
-        return false;
-    }
-
     private void writeEmptyDataTypeToJson(JsonWriter writer) throws IOException {
         writer.beginArray();
         writer.nullValue();
         writer.endArray();
     }
 
-    private boolean isNumber(String value) {
-        try {
-            Double.valueOf(value);
-        } catch (NumberFormatException e) {
-            return false;
-        }
-        return true;
-    }
-
-    private boolean containsType(UnionTypeDefinition unionType, Class<?>... searchedTypes) {
-        List<TypeDefinition<?>> allUnionSubtypes = resolveAllUnionSubtypesFrom(unionType);
-
-        for (TypeDefinition<?> unionSubtype : allUnionSubtypes) {
-            for (Class<?> searchedType : searchedTypes) {
-                if (searchedType.isInstance(unionSubtype)) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    private List<TypeDefinition<?>> resolveAllUnionSubtypesFrom(UnionTypeDefinition inputType) {
-        List<TypeDefinition<?>> result = new ArrayList<>();
-        for (TypeDefinition<?> subtype : inputType.getTypes()) {
-            TypeDefinition<?> resolvedSubtype = subtype;
-
-            resolvedSubtype = resolveBaseTypeFrom(subtype);
-
-            if (resolvedSubtype instanceof UnionTypeDefinition) {
-                List<TypeDefinition<?>> subtypesFromRecursion = resolveAllUnionSubtypesFrom((UnionTypeDefinition) resolvedSubtype);
-                result.addAll(subtypesFromRecursion);
-            } else {
-                result.add(resolvedSubtype);
-            }
-        }
-
-        return result;
-    }
-
-    private TypeDefinition<?> resolveBaseTypeFrom(TypeDefinition<?> type) {
-        return type.getBaseType() != null ? resolveBaseTypeFrom(type.getBaseType()) : type;
-    }
-
     private void writeName(Node<?> node, DataSchemaNode schema, JsonWriter writer) throws IOException {
         String nameForOutput = node.getNodeType().getLocalName();
         if (schema.isAugmenting()) {
index 83e2d20d0e74334a8b138846e7fcd3396902c23f..f4c5034776ec1e83fa5022c7a68223d139d3060a 100644 (file)
@@ -9,6 +9,7 @@ import java.util.Set;
 import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
 import org.opendaylight.controller.sal.restconf.impl.EmptyNodeWrapper;
 import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO;
 
 import com.google.common.collect.Lists;
 import com.google.gson.JsonElement;
@@ -52,8 +53,8 @@ class JsonReader {
     }
 
     private CompositeNodeWrapper createStructureWithRoot(String rootObjectName, JsonObject rootObject) {
-        CompositeNodeWrapper firstNode = new CompositeNodeWrapper(getNamespaceFrom(rootObjectName),
-                getLocalNameFrom(rootObjectName));
+        CompositeNodeWrapper firstNode = new CompositeNodeWrapper(getNamespaceFor(rootObjectName),
+                getLocalNameFor(rootObjectName));
         for (Entry<String, JsonElement> childOfFirstNode : rootObject.entrySet()) {
             addChildToParent(childOfFirstNode.getKey(), childOfFirstNode.getValue(), firstNode);
         }
@@ -62,15 +63,15 @@ class JsonReader {
 
     private void addChildToParent(String childName, JsonElement childType, CompositeNodeWrapper parent) {
         if (childType.isJsonObject()) {
-            CompositeNodeWrapper child = new CompositeNodeWrapper(getNamespaceFrom(childName),
-                    getLocalNameFrom(childName));
+            CompositeNodeWrapper child = new CompositeNodeWrapper(getNamespaceFor(childName),
+                    getLocalNameFor(childName));
             parent.addValue(child);
             for (Entry<String, JsonElement> childOfChild : childType.getAsJsonObject().entrySet()) {
                 addChildToParent(childOfChild.getKey(), childOfChild.getValue(), child);
             }
         } else if (childType.isJsonArray()) {
             if (childType.getAsJsonArray().size() == 1 && childType.getAsJsonArray().get(0).isJsonNull()) {
-                parent.addValue(new EmptyNodeWrapper(getNamespaceFrom(childName), getLocalNameFrom(childName)));
+                parent.addValue(new EmptyNodeWrapper(getNamespaceFor(childName), getLocalNameFor(childName)));
 
             } else {
                 for (JsonElement childOfChildType : childType.getAsJsonArray()) {
@@ -80,24 +81,36 @@ class JsonReader {
         } else if (childType.isJsonPrimitive()) {
             JsonPrimitive childPrimitive = childType.getAsJsonPrimitive();
             String value = childPrimitive.getAsString();
-            parent.addValue(new SimpleNodeWrapper(getNamespaceFrom(childName), getLocalNameFrom(childName), value));
+            parent.addValue(new SimpleNodeWrapper(getNamespaceFor(childName), getLocalNameFor(childName),
+                    resolveValueOfElement(value)));
         }
     }
 
-    private URI getNamespaceFrom(String jsonElementName) {
-        int indexOfDelimeter = jsonElementName.lastIndexOf(':');
-        if (indexOfDelimeter == -1) {
+    private URI getNamespaceFor(String jsonElementName) {
+        String[] moduleNameAndLocalName = jsonElementName.split(":");
+        if (moduleNameAndLocalName.length != 2) { // it is not "moduleName:localName"
             return null;
         }
-        return URI.create(jsonElementName.substring(0, indexOfDelimeter));
+        return URI.create(moduleNameAndLocalName[0]);
     }
 
-    private String getLocalNameFrom(String jsonElementName) {
-        int indexOfDelimeter = jsonElementName.lastIndexOf(':');
-        if (indexOfDelimeter == -1) {
+    private String getLocalNameFor(String jsonElementName) {
+        String[] moduleNameAndLocalName = jsonElementName.split(":");
+        if (moduleNameAndLocalName.length != 2) { // it is not "moduleName:localName"
             return jsonElementName;
         }
-        return jsonElementName.substring(indexOfDelimeter + 1, jsonElementName.length());
+        return moduleNameAndLocalName[1];
+    }
+
+    /**
+     * @param value
+     *            value of json element
+     * @return if value is "moduleName:localName" then {@link IdentityValuesDTO} else
+     *         the same string as parameter "value"
+     */
+    private Object resolveValueOfElement(String value) {
+        URI namespace = getNamespaceFor(value);
+        return namespace == null ? value : new IdentityValuesDTO(namespace.toString(), getLocalNameFor(value), null);
     }
 
 }
diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestUtil.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestUtil.java
new file mode 100644 (file)
index 0000000..6e70b9b
--- /dev/null
@@ -0,0 +1,15 @@
+package org.opendaylight.controller.sal.rest.impl;
+
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+
+public final class RestUtil {
+
+    public final static TypeDefinition<?> resolveBaseTypeFrom(TypeDefinition<?> type) {
+        TypeDefinition<?> superType = type;
+        while (superType.getBaseType() != null) {
+            superType = superType.getBaseType();
+        }
+        return superType;
+    }
+
+}
index 53b401e4a2c55856dc215c4fc5b62987ebaa71f0..242f18d240122597bea4d1dac29a4f1a31ea9e31 100644 (file)
@@ -20,7 +20,7 @@ import org.osgi.util.tracker.ServiceTrackerCustomizer;
 
 public class RestconfProvider implements BundleActivator, Provider, ServiceTrackerCustomizer<Broker, Broker> {
 
-    public final static String NOT_INITALIZED_MSG = "Restcof is not initialized yet. Please try again later";
+    public final static String NOT_INITALIZED_MSG = "Restconf is not initialized yet. Please try again later";
     
     private ListenerRegistration<SchemaServiceListener> listenerRegistration;
     private ServiceTracker<Broker, Broker> brokerServiceTrancker;
index 4a077e663f187f6d23e05a771d4ec988290c8c90..a3d658e7bfec43bca4dc743a460cab8bd6cea9de 100644 (file)
@@ -7,6 +7,9 @@ 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;
@@ -61,9 +64,9 @@ public class XmlMapper {
         Element itemEl = doc.createElementNS(dataType.getNamespace().toString(), dataType.getLocalName());
         if (data instanceof SimpleNode<?>) {
             if (schema instanceof LeafListSchemaNode) {
-                writeValueOfNodeByType(itemEl, (SimpleNode<?>) data, ((LeafListSchemaNode) schema).getType());
+                writeValueOfNodeByType(itemEl, (SimpleNode<?>) data, ((LeafListSchemaNode) schema).getType(), (DataSchemaNode) schema);
             } else if (schema instanceof LeafSchemaNode) {
-                writeValueOfNodeByType(itemEl, (SimpleNode<?>) data, ((LeafSchemaNode) schema).getType());
+                writeValueOfNodeByType(itemEl, (SimpleNode<?>) data, ((LeafSchemaNode) schema).getType(), (DataSchemaNode) schema);
             } else {
                 Object value = data.getValue();
                 if (value != null) {
@@ -88,18 +91,32 @@ public class XmlMapper {
         return itemEl;
     }
 
-    private void writeValueOfNodeByType(Element element, SimpleNode<?> node, TypeDefinition<?> type) {
+    private void writeValueOfNodeByType(Element element, SimpleNode<?> node, TypeDefinition<?> type, DataSchemaNode schema) {
 
-        TypeDefinition<?> baseType = resolveBaseTypeFrom(type);
+        TypeDefinition<?> baseType = RestUtil.resolveBaseTypeFrom(type);
 
-        if (baseType instanceof IdentityrefTypeDefinition && node.getValue() instanceof QName) {
-            QName value = (QName) node.getValue();
-            element.setAttribute("xmlns:x", value.getNamespace().toString());
-            element.setTextContent("x:" + value.getLocalName());
+        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();
+                }
+                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 {
-            Object value = node.getValue();
-            if (value != null) {
-                element.setTextContent(String.valueOf(value));
+            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);
             }
         }
     }
@@ -122,8 +139,4 @@ public class XmlMapper {
         return null;
     }
 
-    private TypeDefinition<?> resolveBaseTypeFrom(TypeDefinition<?> type) {
-        return type.getBaseType() != null ? resolveBaseTypeFrom(type.getBaseType()) : type;
-    }
-
 }
index a53281492f23f28bd3e912c51cb8ae1ba1a752fa..014e839f2665c7e9aa7c89c5a9f344aaef377b7b 100644 (file)
@@ -14,6 +14,7 @@ import javax.xml.stream.events.StartElement;
 import javax.xml.stream.events.XMLEvent;
 
 import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO;
 import org.opendaylight.controller.sal.restconf.impl.EmptyNodeWrapper;
 import org.opendaylight.controller.sal.restconf.impl.NodeWrapper;
 import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
@@ -123,11 +124,24 @@ public class XmlReader {
         return false;
     }
 
+    private CompositeNodeWrapper resolveCompositeNodeFromStartElement(final StartElement startElement) {
+        checkArgument(startElement != null, "Start Element cannot be NULL!");
+        return new CompositeNodeWrapper(getNamespaceFor(startElement), getLocalNameFor(startElement));
+    }
+
     private NodeWrapper<? extends Node<?>> resolveSimpleNodeFromStartElement(final StartElement startElement)
             throws XMLStreamException {
         checkArgument(startElement != null, "Start Element cannot be NULL!");
-        String data = null;
+        String data = getValueOf(startElement);
+        if (data == null) {
+            return new EmptyNodeWrapper(getNamespaceFor(startElement), getLocalNameFor(startElement));
+        }
+        return new SimpleNodeWrapper(getNamespaceFor(startElement), getLocalNameFor(startElement),
+                resolveValueOfElement(data, startElement));
+    }
 
+    private String getValueOf(StartElement startElement) throws XMLStreamException {
+        String data = null;
         if (eventReader.hasNext()) {
             final XMLEvent innerEvent = eventReader.peek();
             if (innerEvent.isCharacters()) {
@@ -143,24 +157,36 @@ public class XmlReader {
                 }
             }
         }
-        if(data == null) {
-            return new EmptyNodeWrapper(getNamespaceFrom(startElement), getLocalNameFrom(startElement));
-        }
-        return new SimpleNodeWrapper(getNamespaceFrom(startElement), getLocalNameFrom(startElement), data);
+        return data;
     }
 
-    private CompositeNodeWrapper resolveCompositeNodeFromStartElement(final StartElement startElement) {
-        checkArgument(startElement != null, "Start Element cannot be NULL!");
-        return new CompositeNodeWrapper(getNamespaceFrom(startElement), getLocalNameFrom(startElement));
-    }
-
-    private String getLocalNameFrom(StartElement startElement) {
+    private String getLocalNameFor(StartElement startElement) {
         return startElement.getName().getLocalPart();
     }
 
-    private URI getNamespaceFrom(StartElement startElement) {
+    private URI getNamespaceFor(StartElement startElement) {
         String namespaceURI = startElement.getName().getNamespaceURI();
         return namespaceURI.isEmpty() ? null : URI.create(namespaceURI);
     }
 
+    /**
+     * @param value
+     *            value of startElement
+     * @param startElement
+     *            element containing value
+     * @return if value is "prefix:value" then {@link IdentityValuesDTO} else the same
+     *         string as parameter "value"
+     */
+    private Object resolveValueOfElement(String value, StartElement startElement) {
+        String[] namespaceAndValue = value.split(":");
+        if (namespaceAndValue.length != 2) { // it is not "prefix:value"
+            return value;
+        }
+        String namespace = startElement.getNamespaceContext().getNamespaceURI(namespaceAndValue[0]);
+        if (namespace != null && !namespace.isEmpty()) {
+            return new IdentityValuesDTO(namespace, namespaceAndValue[1], namespaceAndValue[0]);
+        }
+        return value;
+    }
+
 }
index 930aa663bb4cc91b013d42dec40b5775921e95c2..eec2d452a178c15da2f0c70befa8c1367aae31eb 100644 (file)
@@ -1,6 +1,7 @@
 package org.opendaylight.controller.sal.restconf.impl
 
 import com.google.common.collect.BiMap
+import com.google.common.collect.FluentIterable
 import com.google.common.collect.HashBiMap
 import java.net.URI
 import java.net.URLDecoder
@@ -11,6 +12,7 @@ import java.util.Map
 import java.util.concurrent.ConcurrentHashMap
 import javax.ws.rs.core.Response
 import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener
+import org.opendaylight.controller.sal.rest.impl.RestUtil
 import org.opendaylight.controller.sal.rest.impl.RestconfProvider
 import org.opendaylight.yangtools.yang.common.QName
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
@@ -18,6 +20,7 @@ import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.InstanceIdent
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument
+import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec
 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode
 import org.opendaylight.yangtools.yang.model.api.ChoiceNode
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
@@ -27,15 +30,10 @@ import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
 import org.opendaylight.yangtools.yang.model.api.RpcDefinition
 import org.opendaylight.yangtools.yang.model.api.SchemaContext
-import org.opendaylight.yangtools.yang.model.api.SchemaNode
-import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition
-import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil
-
-import static com.google.common.base.Preconditions.*
-import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec
 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition
 import org.slf4j.LoggerFactory
-import com.google.common.collect.FluentIterable
+
+import static com.google.common.base.Preconditions.*
 
 class ControllerContext implements SchemaServiceListener {
     val static LOG = LoggerFactory.getLogger(ControllerContext)
@@ -96,7 +94,7 @@ class ControllerContext implements SchemaServiceListener {
         return getLatestModule(startModule)
     }
 
-    private def getLatestModule(String moduleName) {
+    def getLatestModule(String moduleName) {
         checkPreconditions
         checkArgument(moduleName !== null && !moduleName.empty)
         val modules = schemas.modules.filter[m|m.name == moduleName]
@@ -142,20 +140,37 @@ class ControllerContext implements SchemaServiceListener {
         var module = uriToModuleName.get(namespace)
         if (module === null) {
             val moduleSchemas = schemas.findModuleByNamespace(namespace);
-            if(moduleSchemas === null) throw new IllegalArgumentException()
+            if(moduleSchemas === null) return null
             var latestModule = moduleSchemas.head
             for (m : moduleSchemas) {
                 if (m.revision.after(latestModule.revision)) {
                     latestModule = m
                 }
             }
-            if(latestModule === null) throw new IllegalArgumentException()
+            if(latestModule === null) return null
             uriToModuleName.put(namespace, latestModule.name)
             module = latestModule.name;
         }
         return module
     }
 
+    def findNamespaceByModule(String module) {
+        var namespace = moduleNameToUri.get(module)
+        if (namespace === null) {
+            val moduleSchemas = schemas.modules.filter[it|it.name.equals(module)]
+            var latestModule = moduleSchemas.head
+            for (m : moduleSchemas) {
+                if (m.revision.after(latestModule.revision)) {
+                    latestModule = m
+                }
+            }
+            if(latestModule === null) return null
+            namespace = latestModule.namespace
+            uriToModuleName.put(namespace, latestModule.name)
+        }
+        return namespace
+    }
+
     def CharSequence toRestconfIdentifier(QName qname) {
         checkPreconditions
         var module = uriToModuleName.get(qname.namespace)
@@ -295,11 +310,8 @@ class ControllerContext implements SchemaServiceListener {
         val typedef = (node as LeafSchemaNode).type;
         
         var decoded = TypeDefinitionAwareCodec.from(typedef)?.deserialize(urlDecoded)
-        if(decoded == null) {
-            var baseType = typedef
-            while (baseType.baseType != null) {
-                baseType = baseType.baseType;
-            }
+        if(decoded === null) {
+            var baseType = RestUtil.resolveBaseTypeFrom(typedef)
             if(baseType instanceof IdentityrefTypeDefinition) {
                 decoded = toQName(urlDecoded)
             }
@@ -349,35 +361,4 @@ class ControllerContext implements SchemaServiceListener {
         }
     }
 
-    /**
-     * Resolve target type from leafref type.
-     * 
-     * According to RFC 6020 referenced element has to be leaf (chapter 9.9).
-     * Therefore if other element is referenced then null value is returned.
-     * 
-     * Currently only cases without path-predicate are supported.
-     * 
-     * @param leafRef
-     * @param schemaNode
-     *            data schema node which contains reference
-     * @return type if leaf is referenced and it is possible to find referenced
-     *         node in schema context. In other cases null value is returned
-     */
-    def LeafSchemaNode resolveTypeFromLeafref(LeafrefTypeDefinition leafRef, DataSchemaNode schemaNode) {
-        val xPath = leafRef.getPathStatement();
-        val module = SchemaContextUtil.findParentModule(schemas, schemaNode);
-
-        var SchemaNode foundSchemaNode
-        if (xPath.isAbsolute()) {
-            foundSchemaNode = SchemaContextUtil.findDataSchemaNode(schemas, module, xPath);
-        } else {
-            foundSchemaNode = SchemaContextUtil.findDataSchemaNodeForRelativeXPath(schemas, module, schemaNode, xPath);
-        }
-
-        if (foundSchemaNode instanceof LeafSchemaNode) {
-            return foundSchemaNode as LeafSchemaNode;
-        }
-
-        return null;
-    }
 }
diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/IdentityValuesDTO.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/IdentityValuesDTO.java
new file mode 100644 (file)
index 0000000..6924fb6
--- /dev/null
@@ -0,0 +1,60 @@
+package org.opendaylight.controller.sal.restconf.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public final class IdentityValuesDTO {
+
+    private final List<IdentityValue> elementData = new ArrayList<>();
+
+    public IdentityValuesDTO(String namespace, String value, String prefix) {
+        elementData.add(new IdentityValue(namespace, value, prefix));
+    }
+
+    public void add(String namespace, String value, String prefix) {
+        elementData.add(new IdentityValue(namespace, value, prefix));
+    }
+
+    public List<IdentityValue> getValuesWithNamespaces() {
+        return Collections.unmodifiableList(elementData);
+    }
+
+    public static final class IdentityValue {
+
+        private String namespace;
+        private String value;
+        private String prefix;
+
+        public IdentityValue(String namespace, String value, String prefix) {
+            this.namespace = namespace;
+            this.value = value;
+            this.prefix = prefix;
+        }
+
+        public String getNamespace() {
+            return namespace;
+        }
+
+        public void setNamespace(String namespace) {
+            this.namespace = namespace;
+        }
+
+        public String getValue() {
+            return value;
+        }
+
+        public void setValue(String value) {
+            this.value = value;
+        }
+
+        public String getPrefix() {
+            return prefix;
+        }
+
+        public void setPrefix(String prefix) {
+            this.prefix = prefix;
+        }
+
+    }
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java
new file mode 100644 (file)
index 0000000..450ba02
--- /dev/null
@@ -0,0 +1,123 @@
+package org.opendaylight.controller.sal.restconf.impl;
+
+import java.net.URI;
+
+import org.opendaylight.controller.sal.rest.impl.RestUtil;
+import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO.IdentityValue;
+import org.opendaylight.yangtools.concepts.Codec;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.codec.IdentityrefCodec;
+import org.opendaylight.yangtools.yang.data.api.codec.LeafrefCodec;
+import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+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();
+
+        private TypeDefinition<?> type;
+
+        private ObjectCodec(TypeDefinition<?> typeDefinition) {
+            type = RestUtil.resolveBaseTypeFrom(typeDefinition);
+        }
+        
+        @SuppressWarnings("unchecked")
+        @Override
+        public Object deserialize(Object input) {
+            try {
+                if (type instanceof IdentityrefTypeDefinition) {
+                    return IDENTITYREF_DEFAULT_CODEC.deserialize(input);
+                } else if (type instanceof LeafrefTypeDefinition) {
+                    return LEAFREF_DEFAULT_CODEC.deserialize(input);
+                } else {
+                    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.");
+                        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);
+                return input;
+            }
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        public Object serialize(Object input) {
+            try {
+                if (type instanceof IdentityrefTypeDefinition) {
+                    return IDENTITYREF_DEFAULT_CODEC.serialize(input);
+                } else if (type instanceof LeafrefTypeDefinition) {
+                    return LEAFREF_DEFAULT_CODEC.serialize(input);
+                } else {
+                    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.");
+                        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);
+                return input;
+            }
+        }
+        
+    }
+    
+    public static class IdentityrefCodecImpl implements IdentityrefCodec<IdentityValuesDTO> {
+
+        @Override
+        public IdentityValuesDTO serialize(QName data) {
+            return new IdentityValuesDTO(data.getNamespace().toString(), data.getLocalName(), data.getPrefix());
+        }
+
+        @Override
+        public QName deserialize(IdentityValuesDTO data) {
+            IdentityValue valueWithNamespace = data.getValuesWithNamespaces().get(0);
+            String namespace = valueWithNamespace.getNamespace();
+            URI validNamespace = ControllerContext.getInstance().findNamespaceByModule(namespace);
+            if (validNamespace == null) {
+                validNamespace = URI.create(namespace);
+            }
+            return QName.create(validNamespace, null, valueWithNamespace.getValue());
+        }
+
+    }
+    
+    public static class LeafrefCodecImpl implements LeafrefCodec<String> {
+
+        @Override
+        public String serialize(Object data) {
+            return String.valueOf(data);
+        }
+
+        @Override
+        public Object deserialize(String data) {
+            return data;
+        }
+        
+    }
+    
+}
index 94a7756da65cefd02adbe3a00eecb69efe9a8dab..4645a411c17c88baa7d55d94c21fcb944faf4d2f 100644 (file)
@@ -6,18 +6,20 @@ import java.util.Set
 import javax.ws.rs.core.Response
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus
 import org.opendaylight.controller.sal.rest.api.RestconfService
+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.impl.NodeFactory
 import org.opendaylight.yangtools.yang.model.api.ChoiceNode
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
-import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode
-import org.opendaylight.yangtools.yang.common.QName
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
+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.type.IdentityrefTypeDefinition
+
 import static javax.ws.rs.core.Response.Status.*
 
 class RestconfImpl implements RestconfService {
@@ -148,7 +150,7 @@ class RestconfImpl implements RestconfService {
         }
         val moduleName = controllerContext.findModuleByNamespace(validQName.namespace);
         if (nodeBuilder.namespace === null || nodeBuilder.namespace == validQName.namespace ||
-            nodeBuilder.namespace.path == moduleName) {
+            nodeBuilder.namespace.toString == moduleName) {
             nodeBuilder.qname = validQName
         } else {
             throw new ResponseException(BAD_REQUEST,
@@ -164,12 +166,34 @@ class RestconfImpl implements RestconfService {
                     findFirstSchemaByLocalName(child.localName, (schema as DataNodeContainer).childNodes),
                     currentAugment)
             }
+            if(schema instanceof ListSchemaNode) {
+                val listKeys = (schema as ListSchemaNode).keyDefinition
+                for (listKey : listKeys) {
+                    var foundKey = false
+                    for (child : children) {
+                        if (child.unwrap.nodeType.localName == listKey.localName) {
+                            foundKey = true;
+                        }
+                    }
+                    if (!foundKey) {
+                        throw new ResponseException(BAD_REQUEST,
+                            "Missing key \"" + listKey.localName + "\" of list \"" + schema.QName.localName + "\"")
+                    }
+                }
+            }
         } else if (nodeBuilder instanceof SimpleNodeWrapper) {
             val simpleNode = (nodeBuilder as SimpleNodeWrapper)
-            val stringValue = simpleNode.value as String;
-
-            val objectValue = TypeDefinitionAwareCodec.from(schema.typeDefinition)?.deserialize(stringValue);
-            simpleNode.setValue(objectValue)
+            val value = simpleNode.value
+            var inputValue = value;
+            
+            if (schema.typeDefinition instanceof IdentityrefTypeDefinition) {
+                if (value instanceof String) {
+                    inputValue = new IdentityValuesDTO(validQName.namespace.toString, value as String, null)
+                } // else value is instance of ValuesDTO
+            }
+            
+            val outputValue = RestCodec.from(schema.typeDefinition)?.deserialize(inputValue);
+            simpleNode.setValue(outputValue)
         } else if (nodeBuilder instanceof EmptyNodeWrapper) {
             val emptyNodeBuilder = nodeBuilder as EmptyNodeWrapper
             if (schema instanceof LeafSchemaNode) {
@@ -183,11 +207,19 @@ class RestconfImpl implements RestconfService {
     }
 
     private def dispatch TypeDefinition<?> typeDefinition(LeafSchemaNode node) {
-        node.type
+        var baseType = node.type
+        while (baseType.baseType !== null) {
+            baseType = baseType.baseType;
+        }
+        baseType
     }
 
     private def dispatch TypeDefinition<?> typeDefinition(LeafListSchemaNode node) {
-        node.type
+        var TypeDefinition<?> baseType = node.type
+        while (baseType.baseType !== null) {
+            baseType = baseType.baseType;
+        }
+        baseType
     }
 
     private def DataSchemaNode findFirstSchemaByLocalName(String localName, Set<DataSchemaNode> schemas) {
index 9f3c6e51e95b1c9d53a231b62b63d4072c6374cc..97f8102127c2b71f69aaf729aeeeed598043aed0 100644 (file)
@@ -13,7 +13,7 @@ import com.google.common.base.Preconditions;
 
 public final class SimpleNodeWrapper implements NodeWrapper<SimpleNode<?>>, SimpleNode<Object> {
     
-    private SimpleNode<?> simpleNode;
+    private SimpleNode<Object> simpleNode;
     
     private String localName;
     private Object value;
@@ -25,7 +25,7 @@ public final class SimpleNodeWrapper implements NodeWrapper<SimpleNode<?>>, Simp
         this.value = value;
     }
     
-    public SimpleNodeWrapper(URI namespace, String localName, String value) {
+    public SimpleNodeWrapper(URI namespace, String localName, Object value) {
         this(localName, value);
         this.namespace = namespace;
     }
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonBasicDataTypesTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonBasicDataTypesTest.java
new file mode 100644 (file)
index 0000000..73d0c82
--- /dev/null
@@ -0,0 +1,349 @@
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.math.BigDecimal;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.*;
+
+import javax.ws.rs.WebApplicationException;
+import javax.xml.bind.DatatypeConverter;
+
+import org.junit.Test;
+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 com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+
+public class ToJsonBasicDataTypesTest {
+
+    @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);
+
+        TestUtils.normalizeCompositeNode(compositeNode, modules, dataSchemaNode, "simple-data-types:cont");
+
+        try {
+            jsonOutput = TestUtils.writeCompNodeWithSchemaContextToJson(compositeNode, modules, dataSchemaNode);
+        } catch (WebApplicationException | IOException e) {
+            assertTrue(false); // shouldn't get here
+        }
+
+        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);
+
+        String exception = null;
+        try {
+            jsonReadCont(jReader);
+        } catch (IOException e) {
+            exception = e.getMessage();
+        }
+
+        assertNull("Error during reading Json output: " + exception, exception);
+    }
+
+    private void jsonReadCont(JsonReader jReader) throws IOException {
+        jReader.beginObject();
+        assertNotNull("cont1 is missing.", jReader.hasNext());
+
+        // Cont dataFromJson = new Cont(jReader.nextName());
+        jReader.nextName();
+        jsonReadContElements(jReader);
+
+        assertFalse("cont shouldn't have other element.", jReader.hasNext());
+        jReader.endObject();
+        // return dataFromJson;
+    }
+
+    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;
+        boolean lfdecimal4Checked = false;
+        boolean lfdecimal3Checked = false;
+        boolean lfdecimal2Checked = false;
+        boolean lfdecimal1Checked = false;
+        boolean lfbool1Checked = false;
+        boolean lfbool2Checked = false;
+        boolean lfstrChecked = false;
+        boolean lfbinaryChecked = false;
+        // boolean lfref1Checked = false;
+        boolean lfemptyChecked = false;
+        boolean lfstr1Checked = false;
+        boolean lfidentityrefChecked = false;
+
+        while (jReader.hasNext()) {
+            String keyName = jReader.nextName();
+            JsonToken peek = null;
+            try {
+                peek = jReader.peek();
+            } catch (IOException e) {
+                if (keyName.equals("lfdecimal5")) {
+                    exceptForDecimal5Raised = true;
+                } else {
+                    assertTrue("Key " + keyName + " has incorrect value for specifed type", false);
+                }
+            }
+
+            if (keyName.startsWith("lfnint") || keyName.startsWith("lfnuint")) {
+                assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
+                try {
+                    jReader.nextLong();
+                } catch (NumberFormatException e) {
+                    assertTrue("Key " + keyName + " has incorrect value - " + e.getMessage(), false);
+                }
+                loadedLfs.add(keyName.substring(3));
+            } else if (keyName.equals("identityref1")) {
+                assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+                assertEquals("simple-data-types:iden", jReader.nextString());
+                lfidentityrefChecked = true;
+            } else if (keyName.equals("lfstr")) {
+                assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+                assertEquals("lfstr", jReader.nextString());
+                lfstrChecked = true;
+            } else if (keyName.equals("lfstr1")) {
+                assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+                assertEquals("", jReader.nextString());
+                lfstr1Checked = true;
+            } else if (keyName.equals("lfbool1")) {
+                assertEquals("Key " + keyName + " has incorrect type", JsonToken.BOOLEAN, peek);
+                assertEquals(true, jReader.nextBoolean());
+                lfbool1Checked = true;
+            } else if (keyName.equals("lfbool2")) {
+                assertEquals("Key " + keyName + " has incorrect type", JsonToken.BOOLEAN, peek);
+                assertEquals(false, jReader.nextBoolean());
+                lfbool2Checked = true;
+            } else if (keyName.equals("lfbool3")) {
+                assertEquals("Key " + keyName + " has incorrect type", JsonToken.BOOLEAN, peek);
+                assertEquals(false, jReader.nextBoolean());
+            } else if (keyName.equals("lfdecimal1")) {
+                assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
+                assertEquals(new Double(43.32), (Double) jReader.nextDouble());
+                lfdecimal1Checked = true;
+            } else if (keyName.equals("lfdecimal2")) {
+                assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
+                assertEquals(new Double(-0.43), (Double) jReader.nextDouble());
+                lfdecimal2Checked = true;
+            } else if (keyName.equals("lfdecimal3")) {
+                assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
+                assertEquals(new Double(43), (Double) jReader.nextDouble());
+                lfdecimal3Checked = true;
+            } else if (keyName.equals("lfdecimal4")) {
+                assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
+                assertEquals(new Double(43E3), (Double) jReader.nextDouble());
+                lfdecimal4Checked = true;
+            } else if (keyName.equals("lfdecimal6")) {
+                assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
+                assertEquals(new Double(33.12345), (Double) jReader.nextDouble());
+                lfdecimal6Checked = true;
+            } else if (keyName.equals("lfenum")) {
+                assertEquals("enum3", jReader.nextString());
+                enumChecked = true;
+            } else if (keyName.equals("lfbits")) {
+                assertEquals("bit3 bit2", jReader.nextString());
+                bitsChecked = true;
+            } else if (keyName.equals("lfbinary")) {
+                assertEquals("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", jReader.nextString());
+                lfbinaryChecked = true;
+            } else if (keyName.equals("lfempty")) {
+                jReader.beginArray();
+                jReader.nextNull();
+                jReader.endArray();
+                lfemptyChecked = true;
+            } else if (keyName.startsWith("lfunion")) {
+                checkLfUnion(jReader, keyName, peek);
+            } else {
+                assertTrue("Key " + keyName + " doesn't exists in yang file.", false);
+            }
+
+        }
+        Collections.sort(loadedLfs);
+        String expectedLfsStr = "[int16Max, int16Min, int32Max, int32Min, int64Max, int64Min, int8Max, int8Min, uint16Max, uint32Max, uint8Max]";
+        String actualLfsStr = loadedLfs.toString();
+        assertEquals("Some leaves are missing", expectedLfsStr, actualLfsStr);
+        assertTrue("Enum wasn't checked", enumChecked);
+        assertTrue("Bits wasn't checked", bitsChecked);
+        assertTrue("Decimal1 wasn't checked", lfdecimal1Checked);
+        assertTrue("Decimal2 wasn't checked", lfdecimal2Checked);
+        assertTrue("Decimal3 wasn't checked", lfdecimal3Checked);
+        assertTrue("Decimal4 wasn't checked", lfdecimal4Checked);
+        assertTrue("Decimal5 wasn't checked", lfdecimal6Checked);
+        assertTrue("lfbool1 wasn't checked", lfbool1Checked);
+        assertTrue("lfbool2 wasn't checked", lfbool2Checked);
+        assertTrue("lfstr wasn't checked", lfstrChecked);
+        assertTrue("lfstr1 wasn't checked", lfstr1Checked);
+        assertTrue("lfbinary wasn't checked", lfbinaryChecked);
+        assertTrue("lfempty wasn't checked", lfemptyChecked);
+        assertTrue("lfidentityref wasn't checked", lfidentityrefChecked);
+        jReader.endObject();
+    }
+
+    private void checkLfUnion(JsonReader jReader, String keyName, JsonToken peek) throws IOException {
+        if (keyName.equals("lfunion1")) {
+            assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+            assertEquals("324", jReader.nextString());
+        } else if (keyName.equals("lfunion2")) {
+            assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+            assertEquals("33.3", jReader.nextString());
+        } else if (keyName.equals("lfunion3")) {
+            assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+            assertEquals("55", jReader.nextString());
+        } else if (keyName.equals("lfunion4")) {
+            assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+            assertEquals("true", jReader.nextString());
+        } else if (keyName.equals("lfunion5")) {
+            assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+            assertEquals("true", jReader.nextString());
+        } else if (keyName.equals("lfunion6")) {
+            assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+            assertEquals("false", jReader.nextString());
+        } else if (keyName.equals("lfunion7")) {
+            assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+            assertEquals("", jReader.nextString());
+        } else if (keyName.equals("lfunion8")) {
+            assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+            assertEquals("", jReader.nextString());
+        } else if (keyName.equals("lfunion9")) {
+            assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+            assertEquals("", jReader.nextString());
+        } else if (keyName.equals("lfunion10")) {
+            assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+            assertEquals("bt1", jReader.nextString());
+        } else if (keyName.equals("lfunion11")) {
+            assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+            assertEquals("33", jReader.nextString());
+        } else if (keyName.equals("lfunion12")) {
+            assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+            assertEquals("false", jReader.nextString());
+        } else if (keyName.equals("lfunion13")) {
+            assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+            assertEquals("44", jReader.nextString());
+        } else if (keyName.equals("lfunion14")) {
+            assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
+            assertEquals("21", jReader.nextString());
+        }
+    }
+}
@@ -1,20 +1,20 @@
-package org.opendaylight.controller.sal.restconf.impl.test;
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
 
-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 static org.junit.Assert.*;
 
-import java.io.*;
-import java.util.*;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.Map;
+import java.util.Set;
 
 import org.junit.Test;
+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.yangtools.yang.data.impl.NodeFactory;
 
-import com.google.gson.stream.*;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
 
 public class ToJsonBasicYangTypesTest {
 
@@ -25,7 +25,7 @@ public class ToJsonBasicYangTypesTest {
     @Test
     public void compositeNodeAndYangWithJsonReaderEmptyDataTest() {
         String jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson(prepareCompositeNodeWithEmpties(),
-                "/yang-to-json-conversion/simple-yang-types", "/yang-to-json-conversion/simple-yang-types/xml");
+                "/cnsn-to-json/simple-yang-types", "/cnsn-to-json/simple-yang-types/xml", "simple-yang-types", "cont1");
         verifyJsonOutputForEmpty(jsonOutput);
     }
 
@@ -36,8 +36,8 @@ public class ToJsonBasicYangTypesTest {
     @Test
     public void xmlAndYangTypesWithJsonReaderTest() {
         String jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson(
-                TestUtils.loadCompositeNode("/yang-to-json-conversion/simple-yang-types/xml/data.xml"),
-                "/yang-to-json-conversion/simple-yang-types", "/yang-to-json-conversion/simple-yang-types/xml");
+                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");
         verifyJsonOutput(jsonOutput);
     }
 
@@ -204,10 +204,12 @@ public class ToJsonBasicYangTypesTest {
         return lstItem;
     }
 
-    private String nextValue(JsonReader jReader) throws IOException {
+    private Object nextValue(JsonReader jReader) throws IOException {
         if (jReader.peek().equals(JsonToken.NULL)) {
             jReader.nextNull();
             return null;
+        } else if (jReader.peek().equals(JsonToken.NUMBER)) {
+            return jReader.nextInt();
         } else {
             return jReader.nextString();
         }
@@ -289,11 +291,11 @@ public class ToJsonBasicYangTypesTest {
         LstItem lst11_2 = null;
         LstItem lst11_3 = null;
         for (LstItem lstItem : lstItems) {
-            if (lstItem.getLfs().get("lf111").getValue().equals("1")) {
+            if (lstItem.getLfs().get("lf111").getValue().equals(1)) {
                 lst11_1 = lstItem;
-            } else if (lstItem.getLfs().get("lf111").getValue().equals("2")) {
+            } else if (lstItem.getLfs().get("lf111").getValue().equals(2)) {
                 lst11_2 = lstItem;
-            } else if (lstItem.getLfs().get("lf111").getValue().equals("3")) {
+            } else if (lstItem.getLfs().get("lf111").getValue().equals(3)) {
                 lst11_3 = lstItem;
             }
         }
@@ -307,8 +309,11 @@ public class ToJsonBasicYangTypesTest {
         assertEquals(1, lst11_1.getLfs().size());
         assertEquals(1, lst11_1.getConts().size());
         assertEquals(1, lst11_1.getLsts().size());
-        assertEquals(lst11_1.getLsts().get("lst111"), new Lst("lst111").addLstItem(new LstItem().addLf("lf1111", "35"))
-                .addLstItem(new LstItem().addLf("lf1111", "34")).addLstItem(new LstItem()).addLstItem(new LstItem()));
+        assertEquals(
+                lst11_1.getLsts().get("lst111"),
+                new Lst("lst111").addLstItem(new LstItem().addLf("lf1111", (int) 35))
+                        .addLstItem(new LstItem().addLf("lf1111", (int) 34)).addLstItem(new LstItem())
+                        .addLstItem(new LstItem()));
         assertEquals(lst11_1.getConts().get("cont111"), new Cont("cont111"));
         // : lst11_1
 
@@ -327,9 +332,10 @@ public class ToJsonBasicYangTypesTest {
         assertEquals(1, lst11_2_cont111.getLsts().size());
         assertTrue(lst11_2_cont111.getConts().isEmpty());
 
-        assertEquals(new LfLst("lflst1111").addLf("1024").addLf("4096"), lst11_2_cont111.getLfLsts().get("lflst1111"));
+        assertEquals(new LfLst("lflst1111").addLf((int) 1024).addLf((int) 4096),
+                lst11_2_cont111.getLfLsts().get("lflst1111"));
         assertEquals(
-                new Lst("lst1111").addLstItem(new LstItem().addLf("lf1111B", "4")).addLstItem(
+                new Lst("lst1111").addLstItem(new LstItem().addLf("lf1111B", (int) 4)).addLstItem(
                         new LstItem().addLf("lf1111A", "lf1111A str12")), lst11_2_cont111.getLsts().get("lst1111"));
         // :-cont111
         assertEquals(lst11_2.getLsts().get("lst112"), new Lst("lst112").addLstItem(new LstItem()));
@@ -369,9 +375,9 @@ public class ToJsonBasicYangTypesTest {
         assertNotNull(lflst12);
 
         assertEquals(3, lflst11.getLfs().size());
-        assertTrue(lflst11.getLfs().contains(new Lf("55")));
-        assertTrue(lflst11.getLfs().contains(new Lf("56")));
-        assertTrue(lflst11.getLfs().contains(new Lf("57")));
+        assertTrue(lflst11.getLfs().contains(new Lf(55)));
+        assertTrue(lflst11.getLfs().contains(new Lf(56)));
+        assertTrue(lflst11.getLfs().contains(new Lf(57)));
 
         assertEquals(3, lflst12.getLfs().size());
         assertTrue(lflst12.getLfs().contains(new Lf("lflst12 str1")));
@@ -387,9 +393,9 @@ public class ToJsonBasicYangTypesTest {
         LstItem lst11_2 = null;
         for (LstItem lstItem : lst11.getLstItems()) {
             Lf lf = lstItem.getLfs().get("lf111");
-            if (lf != null && lf.getValue().equals("140")) {
+            if (lf != null && lf.getValue().equals(140)) {
                 lst11_1 = lstItem;
-            } else if (lf != null && lf.getValue().equals("141")) {
+            } else if (lf != null && lf.getValue().equals(141)) {
                 lst11_2 = lstItem;
             }
         }
@@ -414,15 +420,15 @@ public class ToJsonBasicYangTypesTest {
 
         // cont111 check
         assertEquals(new Lf("lf1111", "lf1111 str2"), lst11_2_cont.getLfs().get("lf1111"));
-        assertEquals(new LfLst("lflst1111").addLf(new Lf("2049")).addLf(new Lf("1025")).addLf(new Lf("4097")),
-                lst11_2_cont.getLfLsts().get("lflst1111"));
+        assertEquals(new LfLst("lflst1111").addLf(new Lf(2049)).addLf(new Lf(1025)).addLf(new Lf(4097)), lst11_2_cont
+                .getLfLsts().get("lflst1111"));
 
         assertNotNull(lst11_2_cont.getLsts().get("lst1111"));
         checkLst1111(lst11_2_cont.getLsts().get("lst1111").getLstItems(), new Lf("lf1111A", "lf1111A str21"), new Lf(
-                "lf1111B", "5"), new Lf("lf1111A", "lf1111A str22"), new Lf("lf1111B", "8"));
+                "lf1111B", 5), new Lf("lf1111A", "lf1111A str22"), new Lf("lf1111B", 8));
 
-        checkLst11x(lst11_2.getLsts().get("lst111"), new LstItem().addLf(new Lf("lf1111", "55")),
-                new LstItem().addLf(new Lf("lf1111", "56")));
+        checkLst11x(lst11_2.getLsts().get("lst111"), new LstItem().addLf(new Lf("lf1111", 55)),
+                new LstItem().addLf(new Lf("lf1111", 56)));
         checkLst11x(lst11_2.getLsts().get("lst112"), new LstItem().addLf(new Lf("lf1121", "lf1121 str22")),
                 new LstItem().addLf(new Lf("lf1121", "lf1121 str21")));
     }
@@ -444,14 +450,14 @@ public class ToJsonBasicYangTypesTest {
 
         // cont111 check
         assertEquals(new Lf("lf1111", "lf1111 str"), lst11_1_cont.getLfs().get("lf1111"));
-        assertEquals(new LfLst("lflst1111").addLf(new Lf("2048")).addLf(new Lf("1024")).addLf(new Lf("4096")),
-                lst11_1_cont.getLfLsts().get("lflst1111"));
+        assertEquals(new LfLst("lflst1111").addLf(new Lf(2048)).addLf(new Lf(1024)).addLf(new Lf(4096)), lst11_1_cont
+                .getLfLsts().get("lflst1111"));
 
         assertNotNull(lst11_1_cont.getLsts().get("lst1111"));
         checkLst1111(lst11_1_cont.getLsts().get("lst1111").getLstItems(), new Lf("lf1111A", "lf1111A str11"), new Lf(
-                "lf1111B", "4"), new Lf("lf1111A", "lf1111A str12"), new Lf("lf1111B", "7"));
+                "lf1111B", 4), new Lf("lf1111A", "lf1111A str12"), new Lf("lf1111B", 7));
 
-        checkLst11x(lst11_1.getLsts().get("lst111"), new LstItem().addLf(new Lf("lf1111", "65")));
+        checkLst11x(lst11_1.getLsts().get("lst111"), new LstItem().addLf(new Lf("lf1111", 65)));
         checkLst11x(lst11_1.getLsts().get("lst112"), new LstItem().addLf(new Lf("lf1121", "lf1121 str11")));
     }
 
@@ -491,8 +497,8 @@ public class ToJsonBasicYangTypesTest {
                 null, ModifyAction.CREATE, null);
         cont1.getChildren().add(lst11_1);
 
-        MutableSimpleNode<?> lf111_1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111"), lst11_1, "1",
-                ModifyAction.CREATE, null);
+        MutableSimpleNode<?> lf111_1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111"), lst11_1,
+                (short) 1, ModifyAction.CREATE, null);
         lst11_1.getChildren().add(lf111_1);
 
         // lst111_1_1
@@ -500,7 +506,7 @@ public class ToJsonBasicYangTypesTest {
                 lst11_1, null, ModifyAction.CREATE, null);
         lst11_1.getChildren().add(lst111_1_1);
         MutableSimpleNode<?> lf1111_1_1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111"),
-                lst111_1_1, "34", ModifyAction.CREATE, null);
+                lst111_1_1, (int) 34, ModifyAction.CREATE, null);
         lst111_1_1.getChildren().add(lf1111_1_1);
         lst111_1_1.init();
         // :lst111_1_1
@@ -510,7 +516,7 @@ public class ToJsonBasicYangTypesTest {
                 lst11_1, null, ModifyAction.CREATE, null);
         lst11_1.getChildren().add(lst111_1_2);
         MutableSimpleNode<?> lf1111_1_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111"),
-                lst111_1_2, "35", ModifyAction.CREATE, null);
+                lst111_1_2, (int) 35, ModifyAction.CREATE, null);
         lst111_1_2.getChildren().add(lf1111_1_2);
         lst111_1_2.init();
         // :lst111_1_2
@@ -541,8 +547,8 @@ public class ToJsonBasicYangTypesTest {
                 null, ModifyAction.CREATE, null);
         cont1.getChildren().add(lst11_2);
 
-        MutableSimpleNode<?> lf111_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111"), lst11_2, "2",
-                ModifyAction.CREATE, null);
+        MutableSimpleNode<?> lf111_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111"), lst11_2,
+                (short) 2, ModifyAction.CREATE, null);
         lst11_2.getChildren().add(lf111_2);
 
         // cont111_2
@@ -551,10 +557,10 @@ public class ToJsonBasicYangTypesTest {
         lst11_2.getChildren().add(cont111_2);
 
         MutableSimpleNode<?> lflst1111_2_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lflst1111"),
-                cont111_2, "1024", ModifyAction.CREATE, null);
+                cont111_2, (int) 1024, ModifyAction.CREATE, null);
         cont111_2.getChildren().add(lflst1111_2_2);
         MutableSimpleNode<?> lflst1111_2_3 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lflst1111"),
-                cont111_2, "4096", ModifyAction.CREATE, null);
+                cont111_2, (int) 4096, ModifyAction.CREATE, null);
         cont111_2.getChildren().add(lflst1111_2_3);
 
         // lst1111_2
@@ -562,16 +568,16 @@ public class ToJsonBasicYangTypesTest {
                 cont111_2, null, ModifyAction.CREATE, null);
         cont111_2.getChildren().add(lst1111_2_1);
         MutableSimpleNode<?> lf1111B_2_1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111B"),
-                lst1111_2_1, "4", ModifyAction.CREATE, null);
+                lst1111_2_1, (short) 4, ModifyAction.CREATE, null);
         lst1111_2_1.getChildren().add(lf1111B_2_1);
         lst1111_2_1.init();
 
         MutableCompositeNode lst1111_2_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst1111"),
                 cont111_2, null, ModifyAction.CREATE, null);
         cont111_2.getChildren().add(lst1111_2_2);
-        MutableSimpleNode<?> lf1111B_2_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111A"),
+        MutableSimpleNode<?> lf1111A_2_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111A"),
                 lst1111_2_2, "lf1111A str12", ModifyAction.CREATE, null);
-        lst1111_2_2.getChildren().add(lf1111B_2_2);
+        lst1111_2_2.getChildren().add(lf1111A_2_2);
         lst1111_2_2.init();
         // :lst1111_2
 
@@ -591,8 +597,8 @@ public class ToJsonBasicYangTypesTest {
                 null, ModifyAction.CREATE, null);
         cont1.getChildren().add(lst11_3);
 
-        MutableSimpleNode<?> lf111_3 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111"), lst11_3, "3",
-                ModifyAction.CREATE, null);
+        MutableSimpleNode<?> lf111_3 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111"), lst11_3,
+                (short) 3, ModifyAction.CREATE, null);
         lst11_3.getChildren().add(lf111_3);
 
         // cont111_3
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonChoiceCaseTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/ToJsonChoiceCaseTest.java
new file mode 100644 (file)
index 0000000..b745411
--- /dev/null
@@ -0,0 +1,123 @@
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.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.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 {
+
+    @BeforeClass
+    public static void initialization() {
+        dataLoad("/cnsn-to-json/choice");
+    }
+
+    /**
+     * Test when some data are in one case node and other in another. This isn't
+     * correct. Next Json validator should return error because nodes has to be
+     * from one case below concrete choice.
+     * 
+     */
+    @Test
+    public void nodeSchemasOnVariousChoiceCasePathTest() {
+        testWrapper("/cnsn-to-json/choice/xml/data_various_path_err.xml", "choice-case-test:cont");
+    }
+
+    /**
+     * Test when some data are in one case node and other in another.
+     * Additionally data are loadef from various choices. This isn't correct.
+     * Next Json validator should return error because nodes has to be from one
+     * case below concrete choice.
+     * 
+     */
+    @Test
+    public void nodeSchemasOnVariousChoiceCasePathAndMultipleChoicesTest() {
+        testWrapper("/cnsn-to-json/choice/xml/data_more_choices_same_level_various_paths_err.xml",
+                "choice-case-test:cont");
+    }
+
+    /**
+     * Test when second level data are red first, then first and at the end
+     * third level. Level represents pass through couple choice-case
+     */
+
+    @Test
+    public void nodeSchemasWithRandomOrderAccordingLevel() {
+        testWrapper("/cnsn-to-json/choice/xml/data_random_level.xml", "choice-case-test:cont");
+    }
+
+    /**
+     * Test when element from no first case is used
+     */
+    @Test
+    public void nodeSchemasNotInFirstCase() {
+        testWrapper("/cnsn-to-json/choice/xml/data_no_first_case.xml", "choice-case-test:cont");
+    }
+
+    /**
+     * Test when element in case is list
+     */
+    @Test
+    public void nodeSchemaAsList() {
+        testWrapper("/cnsn-to-json/choice/xml/data_list.xml", "choice-case-test:cont");
+    }
+
+    /**
+     * Test when element in case is container
+     */
+    @Test
+    public void nodeSchemaAsContainer() {
+        testWrapper("/cnsn-to-json/choice/xml/data_container.xml", "choice-case-test:cont");
+    }
+
+    /**
+     * Test when element in case is leaflist
+     */
+    @Test
+    public void nodeSchemaAsLeafList() {
+        testWrapper("/cnsn-to-json/choice/xml/data_leaflist.xml", "choice-case-test:cont");
+    }
+
+    /**
+     * 
+     */
+    @Test
+    public void nodeSchemasInMultipleChoicesTest() {
+        testWrapper("/cnsn-to-json/choice/xml/data_more_choices_same_level.xml", "choice-case-test:cont");
+    }
+
+    /**
+     * Test whether is possible to find data schema for node which is specified
+     * as dirrect subnode of choice (case without CASE key word)
+     */
+    @Test
+    public void nodeSchemasInCaseNotDefinedWithCaseKeyword() {
+        testWrapper("/cnsn-to-json/choice/xml/data_case_defined_without_case.xml", "choice-case-test:cont");
+    }
+
+    /**
+     * Test of multiple use of choices
+     */
+    @Test
+    public void nodeSchemasInThreeChoicesAtSameLevel() {
+        testWrapper("/cnsn-to-json/choice/xml/data_three_choices_same_level.xml", "choice-case-test:cont");
+    }
+
+    private void testWrapper(String xmlPath, String pathToSchemaNode) {
+        CompositeNode compNode = TestUtils.loadCompositeNode(xmlPath);
+        TestUtils.normalizeCompositeNode(compNode, modules, dataSchemaNode, pathToSchemaNode);
+        try {
+            TestUtils.writeCompNodeWithSchemaContextToJson(compNode, modules, dataSchemaNode);
+        } catch (WebApplicationException | IOException e) {
+            // shouldn't end here
+            assertTrue(false);
+        }
+    }
+}
@@ -1,14 +1,18 @@
-package org.opendaylight.controller.sal.restconf.impl.test;
+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.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import javax.ws.rs.WebApplicationException;
 
-import org.junit.*;
+import org.junit.BeforeClass;
+import org.junit.Test;
+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;
 
@@ -16,15 +20,14 @@ public class ToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader {
 
     @BeforeClass
     public static void initialization() {
-        dataLoad("/yang-to-json-conversion/identityref", 2, "identityref-module", "cont");
+        dataLoad("/cnsn-to-json/identityref", 2, "identityref-module", "cont");
     }
 
     @Test
     public void identityrefToJsonTest() {
         String json = null;
         try {
-            json = TestUtils
-                    .writeCompNodeWithSchemaContextToJson(prepareCompositeNode(), null, modules, dataSchemaNode);
+            json = TestUtils.writeCompNodeWithSchemaContextToJson(prepareCompositeNode(), modules, dataSchemaNode);
         } catch (WebApplicationException | IOException e) {
             // shouldn't end here
             assertTrue(false);
@@ -40,9 +43,14 @@ public class ToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader {
     private CompositeNode prepareCompositeNode() {
         MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null,
                 ModifyAction.CREATE, null);
-        MutableSimpleNode<?> lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1"), cont,
+        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);
-        cont.getChildren().add(lf1);
+        cont1.getChildren().add(lf1);
+        cont1.init();
         cont.init();
 
         return cont;
@@ -1,4 +1,4 @@
-package org.opendaylight.controller.sal.restconf.impl.test;
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.json.test;
 
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
@@ -9,21 +9,30 @@ 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("/yang-to-json-conversion/leafref", 2, "main-module", "cont");
+        dataLoad("/cnsn-to-json/leafref", 2, "main-module", "cont");
     }
 
+    @Ignore
     @Test
     public void leafrefAbsolutePathToExistingLeafTest() {
         String json = null;
         try {
-            json = TestUtils.writeCompNodeWithSchemaContextToJson(TestUtils
-                    .loadCompositeNode("/yang-to-json-conversion/leafref/xml/data_absolut_ref_to_existing_leaf.xml"),
-                    "/yang-to-json-conversion/leafref/xml", modules, dataSchemaNode);
+            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);
@@ -35,13 +44,14 @@ public class ToJsonLeafrefType extends YangAndXmlAndDataSchemaLoader {
         assertTrue(mtch.matches());
     }
 
+    @Ignore
     @Test
     public void leafrefRelativePathToExistingLeafTest() {
         String json = null;
         try {
-            json = TestUtils.writeCompNodeWithSchemaContextToJson(TestUtils
-                    .loadCompositeNode("/yang-to-json-conversion/leafref/xml/data_relativ_ref_to_existing_leaf.xml"),
-                    "/yang-to-json-conversion/leafref/xml", modules, dataSchemaNode);
+            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);
@@ -57,13 +67,14 @@ public class ToJsonLeafrefType extends YangAndXmlAndDataSchemaLoader {
      * 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("/yang-to-json-conversion/leafref/xml/data_ref_to_non_existing_leaf.xml"),
-                    "/yang-to-json-conversion/leafref/xml", modules, dataSchemaNode);
+            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);
@@ -79,13 +90,14 @@ public class ToJsonLeafrefType extends YangAndXmlAndDataSchemaLoader {
      * 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("/yang-to-json-conversion/leafref/xml/data_ref_to_not_leaf.xml"),
-                    "/yang-to-json-conversion/leafref/xml", modules, dataSchemaNode);
+                    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);
@@ -101,6 +113,7 @@ public class ToJsonLeafrefType extends YangAndXmlAndDataSchemaLoader {
     /**
      * Tests case when leaflist element is refers to leaf.
      */
+    @Ignore
     @Test
     public void leafrefFromLeafListToLeafTest() {
         String json = null;
@@ -108,8 +121,8 @@ public class ToJsonLeafrefType extends YangAndXmlAndDataSchemaLoader {
             json = TestUtils
                     .writeCompNodeWithSchemaContextToJson(
                             TestUtils
-                                    .loadCompositeNode("/yang-to-json-conversion/leafref/xml/data_relativ_ref_from_leaflist_to_existing_leaf.xml"),
-                            "/yang-to-json-conversion/leafref/xml", modules, dataSchemaNode);
+                                    .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);
@@ -126,13 +139,14 @@ public class ToJsonLeafrefType extends YangAndXmlAndDataSchemaLoader {
     /**
      * Tests case when leaflist element is refers to leaf.
      */
+    @Ignore
     @Test
     public void leafrefFromLeafrefToLeafrefTest() {
         String json = null;
         try {
-            json = TestUtils.writeCompNodeWithSchemaContextToJson(TestUtils
-                    .loadCompositeNode("/yang-to-json-conversion/leafref/xml/data_from_leafref_to_leafref.xml"),
-                    "/yang-to-json-conversion/leafref/xml", modules, dataSchemaNode);
+            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);
@@ -1,8 +1,10 @@
-package org.opendaylight.controller.sal.restconf.impl.test;
+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 {
 
@@ -12,9 +14,10 @@ public class ToJsonWithAugmentTest {
      */
     @Test
     public void augmentedElementsToJson() {
-        String jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson(
-                TestUtils.loadCompositeNode("/yang-to-json-conversion/augmentation/xml/data.xml"),
-                "/yang-to-json-conversion/augmentation", "/yang-to-json-conversion/augmentation/xml", "yang", "cont");
+
+        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\": {"));
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlTest.java
new file mode 100644 (file)
index 0000000..d043378
--- /dev/null
@@ -0,0 +1,247 @@
+package org.opendaylight.controller.sal.restconf.impl.cnsn.to.xml.test;
+
+import static org.junit.Assert.*;
+
+import java.io.StringWriter;
+import java.util.Set;
+
+import javax.activation.UnsupportedDataTypeException;
+import javax.xml.transform.*;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.XmlMapper;
+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.data.impl.codec.TypeDefinitionAwareCodec;
+import org.opendaylight.yangtools.yang.model.api.*;
+import org.w3c.dom.Document;
+
+/**
+ * 
+ * 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 CnSnToXmlTest {
+
+    private static Set<Module> modules;
+    private static DataSchemaNode dataSchemaNode;
+
+    @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);
+
+    }
+
+    @Test
+    public void snAsYangIdentityrefToXMLTest() {
+        serializeToXml(prepareIdentityrefData(), "<lf11 xmlns:x=\"referenced:module\">x:iden</lf11>");
+    }
+
+    @Test
+    public void snAsYangStringToXmlTest() {
+        serializeToXml(
+                prepareCnStructForYangData(TypeDefinitionAwareCodec.STRING_DEFAULT_CODEC.deserialize("lfStr value"),
+                        "lfStr"), "<lfStr>lfStr value</lfStr>");
+    }
+
+    @Test
+    public void snAsYangInt8ToXmlTest() {
+        String elName = "lfInt8";
+        serializeToXml(
+                prepareCnStructForYangData(TypeDefinitionAwareCodec.INT8_DEFAULT_CODEC.deserialize("14"), elName), "<"
+                        + elName + ">14</" + elName + ">");
+    }
+
+    @Test
+    public void snAsYangInt16ToXmlTest() {
+        String elName = "lfInt16";
+        serializeToXml(
+                prepareCnStructForYangData(TypeDefinitionAwareCodec.INT16_DEFAULT_CODEC.deserialize("3000"), elName),
+                "<" + elName + ">3000</" + elName + ">");
+    }
+
+    @Test
+    public void snAsYangInt32ToXmlTest() {
+        String elName = "lfInt32";
+        serializeToXml(
+                prepareCnStructForYangData(TypeDefinitionAwareCodec.INT32_DEFAULT_CODEC.deserialize("201234"), elName),
+                "<" + elName + ">201234</" + elName + ">");
+    }
+
+    @Test
+    public void snAsYangInt64ToXmlTest() {
+        String elName = "lfInt64";
+        serializeToXml(
+                prepareCnStructForYangData(TypeDefinitionAwareCodec.INT64_DEFAULT_CODEC.deserialize("5123456789"),
+                        elName), "<" + elName + ">5123456789</" + elName + ">");
+    }
+
+    @Test
+    public void snAsYangUint8ToXmlTest() {
+        String elName = "lfUint8";
+        serializeToXml(
+                prepareCnStructForYangData(TypeDefinitionAwareCodec.UINT8_DEFAULT_CODEC.deserialize("200"), elName),
+                "<" + elName + ">200</" + elName + ">");
+    }
+
+    @Test
+    public void snAsYangUint16ToXmlTest() {
+        String elName = "lfUint16";
+        serializeToXml(
+                prepareCnStructForYangData(TypeDefinitionAwareCodec.UINT16_DEFAULT_CODEC.deserialize("4000"), elName),
+                "<" + elName + ">4000</" + elName + ">");
+    }
+
+    @Test
+    public void snAsYangUint32ToXmlTest() {
+        String elName = "lfUint32";
+        serializeToXml(
+                prepareCnStructForYangData(TypeDefinitionAwareCodec.UINT32_DEFAULT_CODEC.deserialize("4123456789"),
+                        elName), "<" + elName + ">4123456789</" + elName + ">");
+    }
+
+    @Test
+    public void snAsYangUint64ToXmlTest() {
+        String elName = "lfUint64";
+        serializeToXml(
+                prepareCnStructForYangData(TypeDefinitionAwareCodec.UINT64_DEFAULT_CODEC.deserialize("5123456789"),
+                        elName), "<" + elName + ">5123456789</" + elName + ">");
+    }
+
+    @Test
+    public void snAsYangBinaryToXmlTest() {
+        String elName = "lfBinary";
+        serializeToXml(
+                prepareCnStructForYangData(
+                        TypeDefinitionAwareCodec.BINARY_DEFAULT_CODEC
+                                .deserialize("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567"),
+                        elName), "<" + elName + ">ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567</"
+                        + elName + ">");
+    }
+
+    @Test
+    public void snAsYangBitsToXmlTest() {
+        String elName = "lfBits";
+        serializeToXml(
+                prepareCnStructForYangData(TypeDefinitionAwareCodec.BITS_DEFAULT_CODEC.deserialize("one two"), elName),
+                "<" + elName + ">one two</" + elName + ">", "<" + elName + ">two one</" + elName + ">");
+    }
+
+    @Test
+    public void snAsYangEnumerationToXmlTest() {
+        String elName = "lfEnumeration";
+        serializeToXml(
+                prepareCnStructForYangData(TypeDefinitionAwareCodec.ENUMERATION_DEFAULT_CODEC.deserialize("enum2"),
+                        elName), "<" + elName + ">enum2</" + elName + ">");
+    }
+
+    @Test
+    public void snAsYangEmptyToXmlTest() {
+        String elName = "lfEmpty";
+        serializeToXml(
+                prepareCnStructForYangData(TypeDefinitionAwareCodec.EMPTY_DEFAULT_CODEC.deserialize(null), elName), "<"
+                        + elName + "/>");
+    }
+
+    @Test
+    public void snAsYangBooleanToXmlTest() {
+        String elName = "lfBoolean";
+        serializeToXml(
+                prepareCnStructForYangData(TypeDefinitionAwareCodec.BOOLEAN_DEFAULT_CODEC.deserialize("str"), elName),
+                "<" + elName + ">false</" + elName + ">");
+        serializeToXml(
+                prepareCnStructForYangData(TypeDefinitionAwareCodec.BOOLEAN_DEFAULT_CODEC.deserialize("true"), elName),
+                "<" + elName + ">true</" + elName + ">");
+    }
+
+    @Test
+    public void snAsYangUnionToXmlTest() {
+        String elName = "lfUnion";
+        String int8 = "15";
+        serializeToXml(
+                prepareCnStructForYangData(TypeDefinitionAwareCodec.UNION_DEFAULT_CODEC.deserialize(int8), elName), "<"
+                        + elName + ">15</" + elName + ">");
+
+        String bits = "first second";
+        serializeToXml(
+                prepareCnStructForYangData(TypeDefinitionAwareCodec.UNION_DEFAULT_CODEC.deserialize(bits), elName), "<"
+                        + elName + ">first second</" + elName + ">");
+
+        String bool = "str";
+        serializeToXml(
+                prepareCnStructForYangData(TypeDefinitionAwareCodec.UNION_DEFAULT_CODEC.deserialize(bool), elName), "<"
+                        + elName + ">str</" + elName + ">");
+    }
+
+    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) {
+            }
+        }
+        assertNotNull(xmlMapper);
+        boolean containSearchedStr = false;
+        String strRepresentation = "";
+        for (String searchedStr : xmlRepresentation) {
+            if (xmlString.contains(searchedStr)) {
+                containSearchedStr = true;
+                break;
+            }
+            strRepresentation = strRepresentation + "[" + searchedStr + "]";
+        }
+        assertTrue("At least one of specified strings " + strRepresentation + " wasn't found.", containSearchedStr);
+
+    }
+
+    private CompositeNode prepareIdentityrefData() {
+        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);
+
+        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);
+        cont1.getChildren().add(lf11);
+        cont1.init();
+        cont.init();
+
+        return cont;
+    }
+
+    private CompositeNode prepareCnStructForYangData(Object data, String leafName) {
+        MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null,
+                ModifyAction.CREATE, null);
+
+        MutableSimpleNode<Object> lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName(leafName), cont, data,
+                ModifyAction.CREATE, null);
+        cont.getChildren().add(lf1);
+        cont.init();
+
+        return cont;
+    }
+
+}
@@ -1,43 +1,41 @@
-package org.opendaylight.controller.sal.restconf.impl.test;
+package org.opendaylight.controller.sal.restconf.impl.json.to.cnsn.test;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
 
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
+import java.io.*;
 import java.net.URISyntaxException;
 import java.util.List;
+import java.util.Set;
 
 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.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.Node;
-import org.opendaylight.yangtools.yang.data.api.SimpleNode;
+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.model.api.Module;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.gson.JsonSyntaxException;
 
-public class FromJsonToCompositeNodeTest {
+public class JsonToCnSnTest {
 
-    private static final Logger LOG = LoggerFactory.getLogger(FromJsonToCompositeNodeTest.class);
+    private static final Logger LOG = LoggerFactory.getLogger(JsonToCnSnTest.class);
 
     @Test
     public void simpleListTest() {
-        simpleTest("/json-to-composite-node/simple-list.json", "/json-to-composite-node/simple-list-yang", "lst",
-                "simple:list:yang1", "simple-list-yang1");
+        simpleTest("/json-to-cnsn/simple-list.json", "/json-to-cnsn/simple-list-yang", "lst", "simple:list:yang1",
+                "simple-list-yang1");
     }
 
     @Test
     public void simpleContainerTest() {
-        simpleTest("/json-to-composite-node/simple-container.json", "/json-to-composite-node/simple-container-yang",
-                "cont", "simple:container:yang", "simple-container-yang");
+        simpleTest("/json-to-cnsn/simple-container.json", "/json-to-cnsn/simple-container-yang", "cont",
+                "simple:container:yang", "simple-container-yang");
     }
 
     /**
@@ -45,8 +43,7 @@ public class FromJsonToCompositeNodeTest {
      */
     @Test
     public void multipleItemsInLeafList() {
-        CompositeNode compositeNode = compositeContainerFromJson(
-                "/json-to-composite-node/multiple-leaflist-items.json", true);
+        CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/multiple-leaflist-items.json", true);
         assertNotNull(compositeNode);
         assertEquals(3, compositeNode.getChildren().size());
 
@@ -79,8 +76,7 @@ public class FromJsonToCompositeNodeTest {
      */
     @Test
     public void multipleItemsInListTest() {
-        CompositeNode compositeNode = compositeContainerFromJson("/json-to-composite-node/multiple-items-in-list.json",
-                true);
+        CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/multiple-items-in-list.json", true);
         assertNotNull(compositeNode);
 
         assertEquals("lst", compositeNode.getNodeType().getLocalName());
@@ -90,7 +86,7 @@ public class FromJsonToCompositeNodeTest {
 
     @Test
     public void nullArrayToSimpleNodeWithNullValueTest() {
-        CompositeNode compositeNode = compositeContainerFromJson("/json-to-composite-node/array-with-null.json", true);
+        CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/array-with-null.json", true);
         assertNotNull(compositeNode);
         assertEquals("cont", compositeNode.getNodeType().getLocalName());
 
@@ -107,7 +103,7 @@ public class FromJsonToCompositeNodeTest {
     public void incorrectTopLevelElementsTest() {
         Throwable cause1 = null;
         try {
-            compositeContainerFromJson("/json-to-composite-node/wrong-top-level1.json", true);
+            compositeContainerFromJson("/json-to-cnsn/wrong-top-level1.json", true);
         } catch (WebApplicationException e) {
             cause1 = e;
         }
@@ -121,7 +117,7 @@ public class FromJsonToCompositeNodeTest {
 
         Throwable cause2 = null;
         try {
-            compositeContainerFromJson("/json-to-composite-node/wrong-top-level2.json", true);
+            compositeContainerFromJson("/json-to-cnsn/wrong-top-level2.json", true);
         } catch (WebApplicationException e) {
             cause2 = e;
         }
@@ -130,7 +126,7 @@ public class FromJsonToCompositeNodeTest {
 
         Throwable cause3 = null;
         try {
-            compositeContainerFromJson("/json-to-composite-node/wrong-top-level3.json", true);
+            compositeContainerFromJson("/json-to-cnsn/wrong-top-level3.json", true);
         } catch (WebApplicationException e) {
             cause3 = e;
         }
@@ -149,7 +145,7 @@ public class FromJsonToCompositeNodeTest {
      */
     @Test
     public void emptyDataReadTest() {
-        CompositeNode compositeNode = compositeContainerFromJson("/json-to-composite-node/empty-data.json", true);
+        CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/empty-data.json", true);
 
         assertNotNull(compositeNode);
 
@@ -162,7 +158,7 @@ public class FromJsonToCompositeNodeTest {
 
         String reason = null;
         try {
-            compositeContainerFromJson("/json-to-composite-node/empty-data1.json", true);
+            compositeContainerFromJson("/json-to-cnsn/empty-data1.json", true);
         } catch (JsonSyntaxException e) {
             reason = e.getMessage();
         }
@@ -180,16 +176,14 @@ public class FromJsonToCompositeNodeTest {
     @Test
     public void notSupplyNamespaceIfAlreadySupplied() {
 
-        CompositeNode compositeNode = compositeContainerFromJson("/json-to-composite-node/simple-list.json");
+        CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/simple-list.json");
         assertNotNull(compositeNode);
 
         DataSchemaNode dataSchemaNode1 = null;
         DataSchemaNode dataSchemaNode2 = null;
         try {
-            dataSchemaNode1 = TestUtils.obtainSchemaFromYang("/json-to-composite-node/simple-list-yang",
-                    "simple-list-yang1");
-            dataSchemaNode2 = TestUtils.obtainSchemaFromYang("/json-to-composite-node/simple-list-yang",
-                    "simple-list-yang2");
+            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);
@@ -214,6 +208,64 @@ public class FromJsonToCompositeNodeTest {
 
     }
 
+    @Test
+    public void jsonIdentityrefToCompositeNode() {
+        CompositeNode compositeNode = compositeContainerFromJson("/json-to-cnsn/identityref/json/data.json");
+        assertNotNull(compositeNode);
+
+        Set<Module> modules = TestUtils.resolveModules("/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");
+
+        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());
+    }
+
     private void simpleTest(String jsonPath, String yangPath, String topLevelElementName, String namespace,
             String moduleName) {
         CompositeNode compositeNode = compositeContainerFromJson(jsonPath);
@@ -325,7 +377,7 @@ public class FromJsonToCompositeNodeTest {
             throws WebApplicationException {
 
         JsonToCompositeNodeProvider jsonToCompositeNodeProvider = JsonToCompositeNodeProvider.INSTANCE;
-        InputStream jsonStream = FromJsonToCompositeNodeTest.class.getResourceAsStream(jsonPath);
+        InputStream jsonStream = JsonToCnSnTest.class.getResourceAsStream(jsonPath);
         try {
             CompositeNode compositeNode = jsonToCompositeNodeProvider
                     .readFrom(null, null, null, null, null, jsonStream);
index bc77430aea88f8eccf84d39bdd808de3b4d21c41..cac77eb368d1423fa91c33a304e0695d208c4e2a 100644 (file)
@@ -6,17 +6,14 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import java.io.FileNotFoundException;
-import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
 import java.net.URI;
 import java.net.URLEncoder;
 import java.util.List;
 import java.util.Set;
-import java.util.concurrent.Future;
 import java.util.logging.Level;
 import java.util.logging.LogRecord;
 
-import javax.ws.rs.client.Entity;
 import javax.ws.rs.core.Application;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
@@ -27,13 +24,11 @@ import org.glassfish.jersey.test.TestProperties;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
 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.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.model.api.Module;
@@ -74,8 +69,7 @@ public class ReadConfAndOperDataTest extends JerseyTest {
 
         String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/eth0");
 
-        InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
-        CompositeNode loadedCompositeNode = TestUtils.loadCompositeNode(xmlStream);
+        CompositeNode loadedCompositeNode = TestUtils.loadCompositeNodeWithXmlTreeBuilder("/parts/ietf-interfaces_interfaces.xml");
         when(brokerFacade.readConfigurationData(any(InstanceIdentifier.class))).thenReturn(loadedCompositeNode);
 
         Response response = target(uri).request(MEDIA_TYPE_DRAFT02).get();
@@ -92,8 +86,7 @@ public class ReadConfAndOperDataTest extends JerseyTest {
     public void testReadOperationalData() throws UnsupportedEncodingException, FileNotFoundException {
         String uri = createUri("/operational/", "ietf-interfaces:interfaces/interface/eth0");
 
-        InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
-        CompositeNode loadedCompositeNode = TestUtils.loadCompositeNode(xmlStream);
+        CompositeNode loadedCompositeNode = TestUtils.loadCompositeNodeWithXmlTreeBuilder("/parts/ietf-interfaces_interfaces.xml");
         when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(loadedCompositeNode);
 
         Response response = target(uri).request(MEDIA_TYPE_DRAFT02).get();
index c36de6e4eabc9abc11c10d20cb3eab353e73d096..41cc0ddb5130f0fc49e4b76f51e9d423f25fd47a 100644 (file)
@@ -1,7 +1,9 @@
 package org.opendaylight.controller.sal.restconf.impl.test;
 
-import static org.mockito.Mockito.*;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 import java.io.FileNotFoundException;
 import java.io.InputStream;
@@ -9,9 +11,7 @@ import java.util.Set;
 
 import org.junit.BeforeClass;
 import org.junit.Test;
-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.*;
 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,7 +23,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.loadModules(RestconfImplTest.class.getResource("/full-versions/yangs")
+                .getPath());
         SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules);
         ControllerContext controllerContext = ControllerContext.getInstance();
         controllerContext.setSchemas(schemaContext);
@@ -33,7 +34,7 @@ public class RestconfImplTest {
     @Test
     public void testExample() throws FileNotFoundException {
         InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
-        CompositeNode loadedCompositeNode = TestUtils.loadCompositeNode(xmlStream);
+        CompositeNode loadedCompositeNode = TestUtils.loadCompositeNodeWithXmlTreeBuilder(xmlStream);
         BrokerFacade brokerFacade = mock(BrokerFacade.class);
         when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(loadedCompositeNode);
         assertEquals(loadedCompositeNode, brokerFacade.readOperationalData(null));
index 20dfb31dab3362261fb1496dd1da9246fbc8052a..366d99dbcb88a3dcb18f55c826b0b1c2dcc09b93 100644 (file)
@@ -1,13 +1,13 @@
 package org.opendaylight.controller.sal.restconf.impl.test;
 
-import static org.junit.Assert.assertFalse;
 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.*;
-import java.net.*;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.sql.Date;
 import java.util.*;
 import java.util.concurrent.Future;
@@ -20,21 +20,23 @@ 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.StructuredDataToJsonProvider;
+import org.opendaylight.controller.sal.rest.impl.*;
 import org.opendaylight.controller.sal.restconf.impl.*;
-import org.opendaylight.yangtools.yang.common.*;
+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.model.parser.api.YangModelParser;
 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
-import org.slf4j.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 import org.xml.sax.SAXException;
 
 import com.google.common.base.Preconditions;
 
-final class TestUtils {
+public final class TestUtils {
 
     private static final Logger logger = LoggerFactory.getLogger(TestUtils.class);
 
@@ -75,27 +77,7 @@ final class TestUtils {
         return result;
     }
 
-    public static CompositeNode loadCompositeNode(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 Document loadDocumentFrom(InputStream inputStream) {
         try {
@@ -131,18 +113,17 @@ final class TestUtils {
 
     }
 
-    static String convertCompositeNodeDataAndYangToJson(CompositeNode compositeNode, String yangPath, String outputPath) {
-        return convertCompositeNodeDataAndYangToJson(compositeNode, yangPath, outputPath, null, null);
-    }
-
-    static String convertCompositeNodeDataAndYangToJson(CompositeNode compositeNode, String yangPath,
+    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, outputPath, modules, dataSchemaNode);
+            return writeCompNodeWithSchemaContextToJson(compositeNode, modules, dataSchemaNode);
         } catch (WebApplicationException | IOException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
@@ -151,7 +132,16 @@ final class TestUtils {
 
     }
 
-    static Module resolveModule(String searchedModuleName, Set<Module> modules) {
+    public static void normalizeCompositeNode(CompositeNode compositeNode, Set<Module> modules,
+            DataSchemaNode dataSchemaNode, String schemaNodePath) {
+        RestconfImpl restconf = RestconfImpl.getInstance();
+        ControllerContext.getInstance().setSchemas(TestUtils.loadSchemaContext(modules));
+
+        TestUtils.prepareMockForRestconfBeforeNormalization(modules, dataSchemaNode, restconf);
+        restconf.createConfigurationData(schemaNodePath, compositeNode);
+    }
+
+    public static Module resolveModule(String searchedModuleName, Set<Module> modules) {
         assertNotNull("modules can't be null.", modules);
         Module module = null;
         if (searchedModuleName != null) {
@@ -167,11 +157,11 @@ final class TestUtils {
         return module;
     }
 
-    static Set<Module> resolveModules(String yangPath) {
+    public static Set<Module> resolveModules(String yangPath) {
         Set<Module> modules = null;
 
         try {
-            modules = TestUtils.loadModules(ToJsonBasicDataTypesTest.class.getResource(yangPath).getPath());
+            modules = TestUtils.loadModules(TestUtils.class.getResource(yangPath).getPath());
         } catch (FileNotFoundException e) {
             e.printStackTrace();
         }
@@ -179,7 +169,7 @@ final class TestUtils {
         return modules;
     }
 
-    static DataSchemaNode resolveDataSchemaNode(Module module, String searchedDataSchemaName) {
+    public static DataSchemaNode resolveDataSchemaNode(Module module, String searchedDataSchemaName) {
         assertNotNull("Module is missing", module);
 
         DataSchemaNode dataSchemaNode = null;
@@ -195,39 +185,33 @@ final class TestUtils {
         return dataSchemaNode;
     }
 
-    static String writeCompNodeWithSchemaContextToJson(CompositeNode compositeNode, String outputPath,
-            Set<Module> modules, DataSchemaNode dataSchemaNode) throws IOException, WebApplicationException {
+    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 contContext = ControllerContext.getInstance();
-        contContext.setSchemas(loadSchemaContext(modules));
+        ControllerContext.getInstance().setSchemas(loadSchemaContext(modules));
 
         StructuredDataToJsonProvider structuredDataToJsonProvider = StructuredDataToJsonProvider.INSTANCE;
         structuredDataToJsonProvider.writeTo(new StructuredData(compositeNode, dataSchemaNode), null, null, null, null,
                 null, byteArrayOS);
 
         jsonResult = byteArrayOS.toString();
-        if (outputPath != null) {
-            try {
-                outputToFile(byteArrayOS, outputPath);
-            } catch (IOException e) {
-                System.out.println("Output file wasn't cloased sucessfuly.");
-            }
-        }
 
         return jsonResult;
     }
 
-    static CompositeNode loadCompositeNode(String xmlDataPath) {
-        InputStream xmlStream = ToJsonBasicDataTypesTest.class.getResourceAsStream(xmlDataPath);
+    public static CompositeNode loadCompositeNode(String xmlDataPath) {
+        InputStream xmlStream = TestUtils.class.getResourceAsStream(xmlDataPath);
         CompositeNode compositeNode = null;
         try {
-            compositeNode = TestUtils.loadCompositeNode(xmlStream);
-        } catch (FileNotFoundException e) {
+            XmlReader xmlReader = new XmlReader();
+            compositeNode = xmlReader.read(xmlStream);
+
+        } catch (UnsupportedFormatException | XMLStreamException e) {
             e.printStackTrace();
         }
         return compositeNode;
@@ -236,7 +220,7 @@ final class TestUtils {
     static void outputToFile(ByteArrayOutputStream outputStream, String outputDir) throws IOException {
         FileOutputStream fileOS = null;
         try {
-            String path = ToJsonBasicDataTypesTest.class.getResource(outputDir).getPath();
+            String path = TestUtils.class.getResource(outputDir).getPath();
             File outFile = new File(path + "/data.json");
             fileOS = new FileOutputStream(outFile);
             try {
@@ -285,7 +269,7 @@ final class TestUtils {
     }
 
     private static FileReader getFileReader(String path) {
-        String fullPath = ToJsonBasicDataTypesTest.class.getResource(path).getPath();
+        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);
@@ -317,7 +301,7 @@ final class TestUtils {
         return strBuilder.toString();
     }
 
-    static QName buildQName(String name, String uri, String date) {
+    public static QName buildQName(String name, String uri, String date) {
         try {
             URI u = new URI(uri);
             Date dt = null;
@@ -330,11 +314,11 @@ final class TestUtils {
         }
     }
 
-    static QName buildQName(String name) {
+    public static QName buildQName(String name) {
         return buildQName(name, "", null);
     }
 
-    static void supplementNamespace(DataSchemaNode dataSchemaNode, CompositeNode compositeNode) {
+    public static void supplementNamespace(DataSchemaNode dataSchemaNode, CompositeNode compositeNode) {
         RestconfImpl restconf = RestconfImpl.getInstance();
 
         InstanceIdWithSchemaNode instIdAndSchema = new InstanceIdWithSchemaNode(mock(InstanceIdentifier.class),
@@ -358,13 +342,14 @@ final class TestUtils {
         restconf.createConfigurationData("something", compositeNode);
     }
 
-    static DataSchemaNode obtainSchemaFromYang(String yangFolder) throws FileNotFoundException {
+    public static DataSchemaNode obtainSchemaFromYang(String yangFolder) throws FileNotFoundException {
         return obtainSchemaFromYang(yangFolder, null);
     }
 
-    static DataSchemaNode obtainSchemaFromYang(String yangFolder, String moduleName) throws FileNotFoundException {
+    public static DataSchemaNode obtainSchemaFromYang(String yangFolder, String moduleName)
+            throws FileNotFoundException {
         Set<Module> modules = null;
-        modules = TestUtils.loadModules(ToJsonBasicDataTypesTest.class.getResource(yangFolder).getPath());
+        modules = TestUtils.loadModules(TestUtils.class.getResource(yangFolder).getPath());
 
         if (modules == null) {
             return null;
@@ -403,7 +388,7 @@ final class TestUtils {
 
     }
 
-    static void addDummyNamespaceToAllNodes(NodeWrapper<?> wrappedNode) throws URISyntaxException {
+    public static void addDummyNamespaceToAllNodes(NodeWrapper<?> wrappedNode) throws URISyntaxException {
         wrappedNode.setNamespace(new URI(""));
         if (wrappedNode instanceof CompositeNodeWrapper) {
             for (NodeWrapper<?> childNodeWrapper : ((CompositeNodeWrapper) wrappedNode).getValues()) {
@@ -412,4 +397,56 @@ 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());
+
+        BrokerFacade mockedBrokerFacade = mock(BrokerFacade.class);
+        when(mockedBrokerFacade.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class)))
+                .thenReturn(
+                        new DummyFuture.Builder().rpcResult(
+                                new DummyRpcResult.Builder<TransactionStatus>().result(TransactionStatus.COMMITED)
+                                        .build()).build());
+        restconf.setBroker(mockedBrokerFacade);
+    }
+    
+    static CompositeNode loadCompositeNodeWithXmlTreeBuilder(String xmlDataPath) {
+        InputStream xmlStream = TestUtils.class.getResourceAsStream(xmlDataPath);
+        CompositeNode compositeNode = null;
+        try {
+            compositeNode = TestUtils.loadCompositeNodeWithXmlTreeBuilder(xmlStream);
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        }
+        return compositeNode;
+        
+        
+        
+    }
+    
+    
+    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;
+    }        
+
 }
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonBasicDataTypesTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonBasicDataTypesTest.java
deleted file mode 100644 (file)
index 69de9f8..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-package org.opendaylight.controller.sal.restconf.impl.test;
-
-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.*;
-import java.util.*;
-
-import org.junit.Test;
-
-import com.google.gson.stream.*;
-
-public class ToJsonBasicDataTypesTest {
-
-    @Test
-    public void simpleYangDataTest() {
-        String jsonOutput;
-        jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson(
-                TestUtils.loadCompositeNode("/yang-to-json-conversion/simple-data-types/xml/data.xml"),
-                "/yang-to-json-conversion/simple-data-types", "/yang-to-json-conversion/simple-data-types/xml");
-        verifyJsonOutput(jsonOutput);
-    }
-
-    private void verifyJsonOutput(String jsonOutput) {
-        StringReader strReader = new StringReader(jsonOutput);
-        JsonReader jReader = new JsonReader(strReader);
-
-        String exception = null;
-        try {
-            jsonReadCont(jReader);
-        } catch (IOException e) {
-            exception = e.getMessage();
-        }
-
-        assertNull("Error during reading Json output: " + exception, exception);
-    }
-
-    private void jsonReadCont(JsonReader jReader) throws IOException {
-        jReader.beginObject();
-        assertNotNull("cont1 is missing.", jReader.hasNext());
-
-        // Cont dataFromJson = new Cont(jReader.nextName());
-        jReader.nextName();
-        jsonReadContElements(jReader);
-
-        assertFalse("cont shouldn't have other element.", jReader.hasNext());
-        jReader.endObject();
-        // return dataFromJson;
-    }
-
-    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;
-        boolean lfdecimal4Checked = false;
-        boolean lfdecimal3Checked = false;
-        boolean lfdecimal2Checked = false;
-        boolean lfdecimal1Checked = false;
-        boolean lfbool1Checked = false;
-        boolean lfbool2Checked = false;
-        boolean lfstrChecked = false;
-        boolean lfbinaryChecked = false;
-        // boolean lfref1Checked = false;
-        boolean lfemptyChecked = false;
-        boolean lfstr1Checked = false;
-
-        while (jReader.hasNext()) {
-            String keyName = jReader.nextName();
-            JsonToken peek = null;
-            try {
-                peek = jReader.peek();
-            } catch (IOException e) {
-                if (keyName.equals("lfdecimal5")) {
-                    exceptForDecimal5Raised = true;
-                } else {
-                    assertTrue("Key " + keyName + " has incorrect value for specifed type", false);
-                }
-            }
-
-            if (keyName.startsWith("lfnint") || keyName.startsWith("lfnuint")) {
-                assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
-                try {
-                    jReader.nextLong();
-                } catch (NumberFormatException e) {
-                    assertTrue("Key " + keyName + " has incorrect value - " + e.getMessage(), false);
-                }
-                loadedLfs.add(keyName.substring(3));
-            } else if (keyName.equals("lfstr")) {
-                assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
-                assertEquals("lfstr", jReader.nextString());
-                lfstrChecked = true;
-            } else if (keyName.equals("lfstr1")) {
-                assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
-                assertEquals("", jReader.nextString());
-                lfstr1Checked = true;
-            } else if (keyName.equals("lfbool1")) {
-                assertEquals("Key " + keyName + " has incorrect type", JsonToken.BOOLEAN, peek);
-                assertEquals(true, jReader.nextBoolean());
-                lfbool1Checked = true;
-            } else if (keyName.equals("lfbool2")) {
-                assertEquals("Key " + keyName + " has incorrect type", JsonToken.BOOLEAN, peek);
-                assertEquals(false, jReader.nextBoolean());
-                lfbool2Checked = true;
-            } else if (keyName.equals("lfbool3")) {
-                assertEquals("Key " + keyName + " has incorrect type", JsonToken.BOOLEAN, peek);
-                assertEquals(false, jReader.nextBoolean());
-            } else if (keyName.equals("lfdecimal1")) {
-                assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
-                assertEquals(new Double(43.32), (Double) jReader.nextDouble());
-                lfdecimal1Checked = true;
-            } else if (keyName.equals("lfdecimal2")) {
-                assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
-                assertEquals(new Double(-0.43), (Double) jReader.nextDouble());
-                lfdecimal2Checked = true;
-            } else if (keyName.equals("lfdecimal3")) {
-                assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
-                assertEquals(new Double(43), (Double) jReader.nextDouble());
-                lfdecimal3Checked = true;
-            } else if (keyName.equals("lfdecimal4")) {
-                assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
-                assertEquals(new Double(43E3), (Double) jReader.nextDouble());
-                lfdecimal4Checked = true;
-            } else if (keyName.equals("lfdecimal6")) {
-                assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
-                assertEquals(new Double(33.12345), (Double) jReader.nextDouble());
-                lfdecimal6Checked = true;
-            } else if (keyName.equals("lfenum")) {
-                assertEquals("enum3", jReader.nextString());
-                enumChecked = true;
-            } else if (keyName.equals("lfbits")) {
-                assertEquals("bit3", jReader.nextString());
-                bitsChecked = true;
-            } else if (keyName.equals("lfbinary")) {
-                assertEquals("AAaacdabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ%%-#^", jReader.nextString());
-                lfbinaryChecked = true;
-            } else if (keyName.equals("lfempty")) {
-                jReader.beginArray();
-                jReader.nextNull();
-                jReader.endArray();
-                lfemptyChecked = true;
-            } else if (keyName.startsWith("lfunion")) {
-                checkLfUnion(jReader, keyName, peek);
-            } else {
-                assertTrue("Key " + keyName + " doesn't exists in yang file.", false);
-            }
-
-        }
-        Collections.sort(loadedLfs);
-        String expectedLfsStr = "[int16Max, int16Min, int32Max, int32Min, int64Max, int64Min, int8Max, int8Min, uint16Max, uint32Max, uint8Max]";
-        String actualLfsStr = loadedLfs.toString();
-        assertEquals("Some leaves are missing", expectedLfsStr, actualLfsStr);
-        // assertTrue("For lfdecimal5 wasn't catch error",exceptForDecimal5Raised);
-        assertTrue("Enum wasn't checked", enumChecked);
-        assertTrue("Bits wasn't checked", bitsChecked);
-        assertTrue("Decimal1 wasn't checked", lfdecimal1Checked);
-        assertTrue("Decimal2 wasn't checked", lfdecimal2Checked);
-        assertTrue("Decimal3 wasn't checked", lfdecimal3Checked);
-        assertTrue("Decimal4 wasn't checked", lfdecimal4Checked);
-        assertTrue("Decimal5 wasn't checked", lfdecimal6Checked);
-        assertTrue("lfbool1 wasn't checked", lfbool1Checked);
-        assertTrue("lfbool2 wasn't checked", lfbool2Checked);
-        assertTrue("lfstr wasn't checked", lfstrChecked);
-        assertTrue("lfstr1 wasn't checked", lfstr1Checked);
-        assertTrue("lfbinary wasn't checked", lfbinaryChecked);
-        assertTrue("lfempty wasn't checked", lfemptyChecked);
-        // assertTrue("lfref1 wasn't checked", lfref1Checked);
-
-        jReader.endObject();
-
-    }
-
-    private void checkLfUnion(JsonReader jReader, String keyName, JsonToken peek) throws IOException {
-        if (keyName.equals("lfunion1")) {
-            assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
-            jReader.nextString();
-        } else if (keyName.equals("lfunion2")) {
-            assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
-            jReader.nextString();
-        } else if (keyName.equals("lfunion3")) {
-            assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
-            jReader.nextInt();
-        } else if (keyName.equals("lfunion4")) {
-            assertEquals("Key " + keyName + " has incorrect type", JsonToken.BOOLEAN, peek);
-            jReader.nextBoolean();
-        } else if (keyName.equals("lfunion5")) {
-            assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
-            jReader.nextString();
-        } else if (keyName.equals("lfunion6")) {
-            assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
-            jReader.nextString();
-        } else if (keyName.equals("lfunion7")) {
-            assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
-            jReader.nextString();
-        } else if (keyName.equals("lfunion8")) {
-            assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
-            jReader.nextString();
-        } else if (keyName.equals("lfunion9")) {
-            assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
-            jReader.nextString();
-        } else if (keyName.equals("lfunion10")) {
-            assertEquals("Key " + keyName + " has incorrect type", JsonToken.STRING, peek);
-            jReader.nextString();
-        } else if (keyName.equals("lfunion11")) {
-            assertEquals("Key " + keyName + " has incorrect type", JsonToken.NUMBER, peek);
-            jReader.nextString();
-        } else if (keyName.equals("lfunion12")) {
-            assertEquals("Key " + keyName + " has incorrect type", JsonToken.BOOLEAN, peek);
-            jReader.nextBoolean();
-        }
-    }
-}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonChoiceCaseTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonChoiceCaseTest.java
deleted file mode 100644 (file)
index c5682cb..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-package org.opendaylight.controller.sal.restconf.impl.test;
-
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-
-import javax.ws.rs.WebApplicationException;
-
-import org.junit.*;
-
-public class ToJsonChoiceCaseTest extends YangAndXmlAndDataSchemaLoader {
-
-    @BeforeClass
-    public static void initialization() {
-        dataLoad("/yang-to-json-conversion/choice");
-    }
-
-    /**
-     * Test when some data are in one case node and other in another. This isn't
-     * correct. Next Json validator should return error because nodes has to be
-     * from one case below concrete choice.
-     * 
-     */
-    @Test
-    public void nodeSchemasOnVariousChoiceCasePathTest() {
-        try {
-            TestUtils.writeCompNodeWithSchemaContextToJson(
-                    TestUtils.loadCompositeNode("/yang-to-json-conversion/choice/xml/data_various_path_err.xml"),
-                    "/yang-to-json-conversion/choice/xml", modules, dataSchemaNode);
-        } catch (WebApplicationException | IOException e) {
-            // shouldn't end here
-            assertTrue(false);
-        }
-    }
-
-    /**
-     * Test when some data are in one case node and other in another.
-     * Additionally data are loadef from various choices. This isn't correct.
-     * Next Json validator should return error because nodes has to be from one
-     * case below concrete choice.
-     * 
-     */
-    @Test
-    public void nodeSchemasOnVariousChoiceCasePathAndMultipleChoicesTest() {
-        try {
-            TestUtils
-                    .writeCompNodeWithSchemaContextToJson(
-                            TestUtils
-                                    .loadCompositeNode("/yang-to-json-conversion/choice/xml/data_more_choices_same_level_various_paths_err.xml"),
-                            "/yang-to-json-conversion/choice/xml", modules, dataSchemaNode);
-        } catch (WebApplicationException | IOException e) {
-            // shouldn't end here
-            assertTrue(false);
-        }
-    }
-
-    /**
-     * Test when second level data are red first, then first and at the end
-     * third level. Level represents pass through couple choice-case
-     */
-
-    @Test
-    public void nodeSchemasWithRandomOrderAccordingLevel() {
-        try {
-            TestUtils.writeCompNodeWithSchemaContextToJson(
-                    TestUtils.loadCompositeNode("/yang-to-json-conversion/choice/xml/data_random_level.xml"),
-                    "/yang-to-json-conversion/choice/xml", modules, dataSchemaNode);
-
-        } catch (WebApplicationException | IOException e) {
-            // shouldn't end here
-            assertTrue(false);
-        }
-    }
-
-    /**
-     * Test when element from no first case is used
-     */
-    @Test
-    public void nodeSchemasNotInFirstCase() {
-        try {
-            TestUtils.writeCompNodeWithSchemaContextToJson(
-                    TestUtils.loadCompositeNode("/yang-to-json-conversion/choice/xml/data_no_first_case.xml"),
-                    "/yang-to-json-conversion/choice/xml", modules, dataSchemaNode);
-        } catch (WebApplicationException | IOException e) {
-            // shouldn't end here
-            assertTrue(false);
-        }
-    }
-
-    /**
-     * Test when element in case is list
-     */
-    @Test
-    public void nodeSchemaAsList() {
-        try {
-            TestUtils.writeCompNodeWithSchemaContextToJson(
-                    TestUtils.loadCompositeNode("/yang-to-json-conversion/choice/xml/data_list.xml"),
-                    "/yang-to-json-conversion/choice/xml", modules, dataSchemaNode);
-        } catch (WebApplicationException | IOException e) {
-            // shouldn't end here
-            assertTrue(false);
-        }
-    }
-
-    /**
-     * Test when element in case is container
-     */
-    @Test
-    public void nodeSchemaAsContainer() {
-        try {
-            TestUtils.writeCompNodeWithSchemaContextToJson(
-                    TestUtils.loadCompositeNode("/yang-to-json-conversion/choice/xml/data_container.xml"),
-                    "/yang-to-json-conversion/choice/xml", modules, dataSchemaNode);
-        } catch (WebApplicationException | IOException e) {
-            // shouldn't end here
-            assertTrue(false);
-        }
-    }
-
-    /**
-     * Test when element in case is leaflist
-     */
-    @Test
-    public void nodeSchemaAsLeafList() {
-        try {
-            TestUtils.writeCompNodeWithSchemaContextToJson(
-                    TestUtils.loadCompositeNode("/yang-to-json-conversion/choice/xml/data_leaflist.xml"),
-                    "/yang-to-json-conversion/choice/xml", modules, dataSchemaNode);
-        } catch (WebApplicationException | IOException e) {
-            // shouldn't end here
-            assertTrue(false);
-        }
-    }
-
-    /**
-     * 
-     */
-    @Test
-    public void nodeSchemasInMultipleChoicesTest() {
-        try {
-            TestUtils
-                    .writeCompNodeWithSchemaContextToJson(TestUtils
-                            .loadCompositeNode("/yang-to-json-conversion/choice/xml/data_more_choices_same_level.xml"),
-                            "/yang-to-json-conversion/choice/xml", modules, dataSchemaNode);
-        } catch (WebApplicationException | IOException e) {
-            // shouldn't end here
-            assertTrue(false);
-        }
-    }
-
-    /**
-     * Test whether is possible to find data schema for node which is specified
-     * as dirrect subnode of choice (case without CASE key word)
-     */
-    @Test
-    public void nodeSchemasInCaseNotDefinedWithCaseKeyword() {
-        try {
-            TestUtils.writeCompNodeWithSchemaContextToJson(TestUtils
-                    .loadCompositeNode("/yang-to-json-conversion/choice/xml/data_case_defined_without_case.xml"),
-                    "/yang-to-json-conversion/choice/xml", modules, dataSchemaNode);
-        } catch (WebApplicationException | IOException e) {
-            // shouldn't end here
-            assertTrue(false);
-        }
-    }
-
-    /**
-     * Test of multiple use of choices
-     */
-    @Test
-    public void nodeSchemasInThreeChoicesAtSameLevel() {
-        try {
-            TestUtils.writeCompNodeWithSchemaContextToJson(TestUtils
-                    .loadCompositeNode("/yang-to-json-conversion/choice/xml/data_three_choices_same_level.xml"),
-                    "/yang-to-json-conversion/choice/xml", modules, dataSchemaNode);
-        } catch (WebApplicationException | IOException e) {
-            // shouldn't end here
-            assertTrue(false);
-        }
-    }
-}
index ec7dba67b9a35392845e93588862411f45362b49..4cea120d4d1896f498394e176184d1b63e3b262c 100644 (file)
@@ -11,8 +11,7 @@ import java.io.UnsupportedEncodingException;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URLEncoder;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
 import java.util.concurrent.Future;
 import java.util.logging.Level;
 import java.util.logging.LogRecord;
@@ -33,12 +32,10 @@ import org.opendaylight.controller.sal.rest.api.Draft01;
 import org.opendaylight.controller.sal.rest.api.RestconfService;
 import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
 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.controller.sal.restconf.impl.*;
 import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.*;
+import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
@@ -77,14 +74,31 @@ public class XmlProvidersTest extends JerseyTest {
     public void testStructuredDataToXmlProvider() throws FileNotFoundException, UnsupportedEncodingException {
         String uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0");
 
-        InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
-        CompositeNode loadedCompositeNode = TestUtils.loadCompositeNode(xmlStream);
+        CompositeNode loadedCompositeNode = prepareCompositeNodeWithIetfInterfacesInterfacesData();
         when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(loadedCompositeNode);
 
         Response response = target(uri).request(MEDIA_TYPE).get();
         assertEquals(200, response.getStatus());
     }
 
+    private CompositeNode prepareCompositeNodeWithIetfInterfacesInterfacesData() {
+        CompositeNode intface;
+        try {
+            intface = new CompositeNodeWrapper(new URI("interface"), "interface");
+            List<Node<?>> childs = new ArrayList<>();
+
+            childs.add(new SimpleNodeWrapper(new URI("name"), "name", "eth0"));
+            childs.add(new SimpleNodeWrapper(new URI("type"), "type", "ethernetCsmacd"));
+            childs.add(new SimpleNodeWrapper(new URI("enabled"), "enabled", Boolean.FALSE));
+            childs.add(new SimpleNodeWrapper(new URI("description"), "description", "some interface"));
+            intface.setValue(childs);
+            return intface;
+        } catch (URISyntaxException e) {
+        }
+
+        return null;
+    }
+
     @Test
     public void testBadFormatXmlToCompositeNodeProvider() throws UnsupportedEncodingException, URISyntaxException {
         String uri = createUri("/operations/", "ietf-interfaces:interfaces/interface/eth0");
index a1e06c3cabfa1d1cbeb207c676da1583cb4643d2..afd40d1c2ba6aee49ed4124380e1cddd14b98585 100644 (file)
@@ -1,21 +1,20 @@
 package org.opendaylight.controller.sal.restconf.impl.test.structures;
 
 public class Lf extends YangElement {
-    private String value;
+    private Object value;
     private int numOfEqualItems = 0;
 
-
-    public Lf(String name, String value) {
+    public Lf(String name, Object value) {
         super(name);
         this.value = value;
     }
 
-    public Lf(String value) {
+    public Lf(Object value) {
         super("");
         this.value = value;
     }
 
-    public String getValue() {
+    public Object getValue() {
         return value;
     }
 
@@ -43,11 +42,10 @@ public class Lf extends YangElement {
         }
         return true;
     }
-    
+
     public void incNumOfEqualItems() {
         this.numOfEqualItems++;
     }
-    
 
     @Override
     public int hashCode() {
index 87fed95f6ff15b4a2a3800a0adaa25c1aaf62ba0..dda590944ace0f6bd5cf6c1462a1e352af016358 100644 (file)
@@ -1,6 +1,7 @@
 package org.opendaylight.controller.sal.restconf.impl.test.structures;
 
-import java.util.*;
+import java.util.HashSet;
+import java.util.Set;
 
 public class LfLst extends YangElement {
     Set<Lf> lfs;
@@ -10,11 +11,10 @@ public class LfLst extends YangElement {
         lfs = new HashSet<>();
     }
 
-    public LfLst addLf(String value) {
+    public LfLst addLf(Object value) {
         return addLf(new Lf(value));
     }
 
-    
     public LfLst addLf(Lf lf) {
         while (this.lfs.contains(lf)) {
             lf.incNumOfEqualItems();
index 9eb58b5344186690484658ffa489fc376df811cd..10582de08374e4302765437da257c44af7b7ce01 100644 (file)
@@ -1,6 +1,7 @@
 package org.opendaylight.controller.sal.restconf.impl.test.structures;
 
-import java.util.*;
+import java.util.HashMap;
+import java.util.Map;
 
 public class LstItem {
     String lstName;
@@ -42,7 +43,7 @@ public class LstItem {
         return this;
     }
 
-    public LstItem addLf(String name, String value) {
+    public LstItem addLf(String name, Object value) {
         lfs.put(name, new Lf(name, value));
         return this;
     }
@@ -1,23 +1,27 @@
-package org.opendaylight.controller.sal.restconf.impl.test;
+package org.opendaylight.controller.sal.restconf.impl.xml.to.cnsn.test;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+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.*;
+import org.junit.Test;
 import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
-import org.opendaylight.controller.sal.restconf.impl.*;
+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.yangtools.yang.data.api.*;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.slf4j.*;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-public class FromXmlToCompositeNodeTest {
-    private static final Logger LOG = LoggerFactory.getLogger(FromXmlToCompositeNodeTest.class);
+public class XmlToCnSnTest {
+    private static final Logger LOG = LoggerFactory.getLogger(XmlToCnSnTest.class);
 
     /**
      * top level element represents container. second level element is list with
@@ -25,11 +29,11 @@ public class FromXmlToCompositeNodeTest {
      */
     @Test
     public void testXmlDataContainer() {
-        CompositeNode compNode = compositeContainerFromXml("/xml-to-composite-node/data-container.xml", false);
+        CompositeNode compNode = compositeNodeFromXml("/xml-to-cnsn/data-container.xml", false);
         assertNotNull(compNode);
         DataSchemaNode dataSchemaNode = null;
         try {
-            dataSchemaNode = TestUtils.obtainSchemaFromYang("/xml-to-composite-node/data-container-yang");
+            dataSchemaNode = TestUtils.obtainSchemaFromYang("/xml-to-cnsn/data-container-yang");
         } catch (FileNotFoundException e) {
             LOG.error(e.getMessage());
             assertTrue(false);
@@ -73,13 +77,12 @@ public class FromXmlToCompositeNodeTest {
 
     @Test
     public void testXmlDataList() {
-        CompositeNode compNode = compositeContainerFromXml("/xml-to-composite-node/data-list.xml", false);
+        CompositeNode compNode = compositeNodeFromXml("/xml-to-cnsn/data-list.xml", false);
         assertNotNull(compNode);
 
         DataSchemaNode dataSchemaNode = null;
         try {
-            dataSchemaNode = TestUtils.obtainSchemaFromYang("/xml-to-composite-node/data-list-yang",
-                    "data-container-yang");
+            dataSchemaNode = TestUtils.obtainSchemaFromYang("/xml-to-cnsn/data-list-yang", "data-container-yang");
         } catch (FileNotFoundException e) {
             LOG.error(e.getMessage());
         }
@@ -145,7 +148,7 @@ public class FromXmlToCompositeNodeTest {
 
     @Test
     public void testXmlEmptyData() {
-        CompositeNode compNode = compositeContainerFromXml("/xml-to-composite-node/empty-data.xml", true);
+        CompositeNode compNode = compositeNodeFromXml("/xml-to-cnsn/empty-data.xml", true);
         assertEquals("cont", compNode.getNodeType().getLocalName());
         SimpleNode<?> lf1 = null;
         SimpleNode<?> lflst1_1 = null;
@@ -189,6 +192,72 @@ public class FromXmlToCompositeNodeTest {
 
     }
 
+    /**
+     * 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;
@@ -254,10 +323,10 @@ public class FromXmlToCompositeNodeTest {
         assertEquals((short) 100, cont1_lf11.getValue());
     }
 
-    private CompositeNode compositeContainerFromXml(String xmlPath, boolean dummyNamespaces) {
+    private CompositeNode compositeNodeFromXml(String xmlPath, boolean dummyNamespaces) {
         XmlToCompositeNodeProvider xmlToCompositeNodeProvider = XmlToCompositeNodeProvider.INSTANCE;
         try {
-            InputStream xmlStream = FromXmlToCompositeNodeTest.class.getResourceAsStream(xmlPath);
+            InputStream xmlStream = XmlToCnSnTest.class.getResourceAsStream(xmlPath);
             CompositeNode compositeNode = xmlToCompositeNodeProvider.readFrom(null, null, null, null, null, xmlStream);
             if (dummyNamespaces) {
                 try {
@@ -277,4 +346,47 @@ public class FromXmlToCompositeNodeTest {
         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;
+    }
+
 }
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/identityref/identityref-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/identityref/identityref-module.yang
new file mode 100644 (file)
index 0000000..20f91b2
--- /dev/null
@@ -0,0 +1,21 @@
+module identityref-module {
+  namespace "identityref:module";  
+
+  prefix "iderefmod";
+  
+  import identity-module {prefix idemo; revision-date 2013-12-2;}
+   
+  revision 2013-12-2 {    
+  }
+  
+       container cont {
+          container cont1 {
+               leaf lf1 {
+                       type identityref {
+                               base "idemo:iden";
+                       }
+               }
+               }
+       }
+         
+}
\ No newline at end of file
@@ -5,6 +5,9 @@ module simple-data-types {
   revision 2013-11-12 {    
   }
   
+  identity iden {
+  }
+  
   typedef tpdfempty {
        type empty;
   }
@@ -245,6 +248,26 @@ module simple-data-types {
     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;
+        }
+    }
          
          
   }
similarity index 80%
rename from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/simple-data-types/xml/data.xml
rename to opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-json/simple-data-types/xml/data.xml
index 0d31e9037a763b3732274da5eddc2512a8c8ecb4..56872a337d0124be4789789ef8f58427ab378278 100644 (file)
@@ -21,9 +21,9 @@
        <lfdecimal4>43E3</lfdecimal4>
        <lfdecimal6>33.12345</lfdecimal6>
        <lfenum>enum3</lfenum>
-       <lfbits>bit3</lfbits>   
-       <lfbinary>AAaacdabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ%%-#^</lfbinary>
-       <lfempty></lfempty>
+       <lfbits>bit3 bit2</lfbits>      
+       <lfbinary>ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz</lfbinary>
+       <lfempty />
        <lfunion1>324</lfunion1>
        <lfunion2>33.3</lfunion2>
        <lfunion3>55</lfunion3>
@@ -36,4 +36,8 @@
        <lfunion10>bt1</lfunion10>
        <lfunion11>33</lfunion11>
        <lfunion12>false</lfunion12>
+       <lfunion13>44</lfunion13>
+       <lfunion14>21</lfunion14>
+       <lfempty />
+       <identityref1 xmlns:x="simple:data:types">x:iden</identityref1>
 </cont>
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/instance_identifier/aug-referenced-elements-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/instance_identifier/aug-referenced-elements-module.yang
new file mode 100644 (file)
index 0000000..1b861f5
--- /dev/null
@@ -0,0 +1,18 @@
+module aug-referenced-elements-module {
+  namespace "aug:referenced:elements:module";  
+
+  prefix "augrefelmo";
+  
+  import referenced-elements-module {prefix refelmo; revision-date 2013-12-3;}
+   
+  revision 2013-12-3 {    
+  }
+  
+  augment "/refelmo:cont" {
+    leaf lf2 {
+        type boolean;
+    }
+  }
+  
+         
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/instance_identifier/eferenced-elements-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/instance_identifier/eferenced-elements-module.yang
new file mode 100644 (file)
index 0000000..fd6e0fb
--- /dev/null
@@ -0,0 +1,20 @@
+module referenced-elements-module {
+  namespace "referenced:elements:module";  
+
+  prefix "refelmo";
+   
+  revision 2013-12-3 {    
+  }
+  
+       container cont {
+               leaf lf1 {
+                       type string;                            
+                       }
+               }
+               leaf-list lflst1 {
+                       type uint32;
+               }
+               
+       }
+         
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/instance_identifier/rinstance-identifier-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/instance_identifier/rinstance-identifier-module.yang
new file mode 100644 (file)
index 0000000..61ce822
--- /dev/null
@@ -0,0 +1,16 @@
+module instance-identifier-module {
+  namespace "instance:identifier:module";  
+
+  prefix "inidmod";
+   
+  revision 2013-12-3 {    
+  }
+  
+       container cont {
+               leaf lf1 {
+                       type instance-identifier {                              
+                       }
+               }
+       }
+         
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/yang/basic-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/yang/basic-module.yang
new file mode 100644 (file)
index 0000000..7023c94
--- /dev/null
@@ -0,0 +1,96 @@
+module basic-module {
+  namespace "basic:module";  
+
+  prefix "basmod";
+  
+  import referenced-module {prefix refmo; revision-date 2013-12-2;}
+   
+  revision 2013-12-2 {    
+  }
+  
+       container cont {
+          container cont1 {
+               leaf lf11 {
+                       type identityref {
+                               base "refmo:iden";
+                       }
+               }
+               }
+               leaf lfStr {
+                 type string;
+               }
+               leaf lfInt8 {
+                 type int8;
+               }
+               
+               leaf lfInt16 {
+                 type int16;
+               }
+               
+               leaf lfInt32 {
+                 type int32;
+               }
+               
+               leaf lfInt64 {
+                 type int64;
+               }
+               
+               leaf lfUint8 {
+                 type uint8;
+               }
+               
+               leaf lfUint16 {
+                 type uint16;
+               }
+               
+               leaf lfUint32 {
+                 type uint32;
+               }
+               
+               leaf lfUint64 {
+                 type uint64;
+               }
+               
+               leaf lfBinary {
+                 type binary;
+               }
+               
+               leaf lfBits {
+                 type bits {
+                     bit one;
+                     bit two;
+                     bit three;
+                 }
+               }
+               
+               leaf lfEnumeration {
+                 type enumeration {
+                     enum enum1;
+                     enum enum2;
+                     enum enum3;
+                 }
+               }
+               
+               leaf lfEmpty {
+                 type empty;
+               }
+               
+               leaf lfBoolean {
+                 type boolean;
+               }
+               
+               leaf lfUnion {
+                 type union {
+                     type int8;
+                     type string;
+                     type bits {
+                         bit first;
+                         bit second;
+                     }
+                     type boolean;
+                 }
+               }
+               
+       }
+         
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/yang/referenced-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/cnsn-to-xml/yang/referenced-module.yang
new file mode 100644 (file)
index 0000000..9821b1e
--- /dev/null
@@ -0,0 +1,10 @@
+module referenced-module {
+  namespace "referenced:module";  
+
+  prefix "refmod";
+  revision 2013-12-2 {    
+  }
+  
+       identity iden {         
+       }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/identityref/identity-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/identityref/identity-module.yang
new file mode 100644 (file)
index 0000000..30890bf
--- /dev/null
@@ -0,0 +1,10 @@
+module identity-module {
+  namespace "identity:module";  
+
+  prefix "idemod";
+  revision 2013-12-2 {    
+  }
+  
+       identity iden {         
+       }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/identityref/identityref-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/identityref/identityref-module.yang
new file mode 100644 (file)
index 0000000..b90b533
--- /dev/null
@@ -0,0 +1,39 @@
+module identityref-module {
+  namespace "identityref:module";  
+
+  prefix "iderefmod";
+  
+  import identity-module {prefix idemo; revision-date 2013-12-2;}
+   
+  revision 2013-12-2 {    
+  }
+  
+  identity iden_local {
+  }
+  
+       container cont {
+          container cont1 {
+               leaf lf11 {
+                       type identityref {
+                               base "idemo:iden";
+                       }
+               }
+               leaf lf12 {
+                       type identityref {
+                               base "iden_local";
+                       }
+               }
+               leaf lf13 {
+                       type identityref {
+                               base "iden_local";
+                       }
+               }
+               leaf lf14 {
+                       type identityref {
+                               base "iden_local";
+                       }
+               }
+               }
+       }
+         
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/identityref/json/data.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/json-to-cnsn/identityref/json/data.json
new file mode 100644 (file)
index 0000000..320ee05
--- /dev/null
@@ -0,0 +1,10 @@
+{
+    "cont":{
+        "cont1":{
+            "lf11":"identity-module:iden",
+            "lf12":"iden_local",              
+            "identityref-module:lf13":"iden_local",
+            "identityref-module:lf14":"identity-module:iden_local"  
+        }
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-nmspc-in-attributes.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/data-nmspc-in-attributes.xml
new file mode 100644 (file)
index 0000000..848c020
--- /dev/null
@@ -0,0 +1,5 @@
+<cont xmlns:x="x:namespace" xmlns:y="y:namespace">
+    <cont1 xmlns:z="z:namespace" xmlns:a="a:namespace" xmlns:b="b:namespace">
+        <lf11 xmlns:c="identity:module">c:iden</lf11>
+    </cont1>
+</cont>
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/identity-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/identity-module.yang
new file mode 100644 (file)
index 0000000..30890bf
--- /dev/null
@@ -0,0 +1,10 @@
+module identity-module {
+  namespace "identity:module";  
+
+  prefix "idemod";
+  revision 2013-12-2 {    
+  }
+  
+       identity iden {         
+       }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/identityref-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/identityref-module.yang
new file mode 100644 (file)
index 0000000..a43d439
--- /dev/null
@@ -0,0 +1,21 @@
+module identityref-module {
+  namespace "identityref:module";  
+
+  prefix "iderefmod";
+  
+  import identity-module {prefix idemo; revision-date 2013-12-2;}
+   
+  revision 2013-12-2 {    
+  }
+  
+       container cont {
+          container cont1 {
+               leaf lf11 {
+                       type identityref {
+                               base "idemo:iden";
+                       }
+               }
+               }
+       }
+         
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-default-nmspc-in-element.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-default-nmspc-in-element.xml
new file mode 100644 (file)
index 0000000..aae2af3
--- /dev/null
@@ -0,0 +1,5 @@
+<cont xmlns="general:module" xmlns:x="x:namespace" xmlns:y="y:namespace">
+    <cont1 xmlns:z="z:namespace" xmlns:a="a:namespace" xmlns:b="b:namespace">        
+        <lf11 xmlns="identityref:module" xmlns:c="c:namespace">iden</lf11>  
+    </cont1>
+</cont>
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-default-nmspc-in-parrent-element.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-default-nmspc-in-parrent-element.xml
new file mode 100644 (file)
index 0000000..621d2bc
--- /dev/null
@@ -0,0 +1,5 @@
+<cont xmlns:x="x:namespace" xmlns:y="y:namespace">
+    <cont1 xmlns="identityref:module" xmlns:z="z:namespace" xmlns:a="a:namespace" xmlns:b="b:namespace">        
+        <lf11 xmlns:c="c:namespace">iden</lf11>  
+    </cont1>
+</cont>
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-nmspc-in-element.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-nmspc-in-element.xml
new file mode 100644 (file)
index 0000000..76de72d
--- /dev/null
@@ -0,0 +1,5 @@
+<cont xmlns="identityref:module" xmlns:x="x:namespace" xmlns:y="y:namespace">
+    <cont1 xmlns:z="z:namespace" xmlns:a="a:namespace" xmlns:b="b:namespace">
+        <lf11 xmlns:c="identity:module">c:iden</lf11>
+    </cont1>
+</cont>
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-nmspc-in-parrent-element.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-nmspc-in-parrent-element.xml
new file mode 100644 (file)
index 0000000..497c35f
--- /dev/null
@@ -0,0 +1,5 @@
+<cont xmlns="identityref:module" xmlns:x="x:namespace" xmlns:y="y:namespace">
+    <cont1 xmlns:c="identity:module" xmlns:z="z:namespace" xmlns:a="a:namespace" xmlns:b="b:namespace">        
+        <lf11>z:iden</lf11>  
+    </cont1>
+</cont>
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-no-nmspc-value-with-prefix.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-no-nmspc-value-with-prefix.xml
new file mode 100644 (file)
index 0000000..925442f
--- /dev/null
@@ -0,0 +1,5 @@
+<cont>
+    <cont1>   
+        <lf11>x:iden</lf11>  
+    </cont1>
+</cont>
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-no-nmspc-value-without-prefix.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/xml/data-no-nmspc-value-without-prefix.xml
new file mode 100644 (file)
index 0000000..5a86eb0
--- /dev/null
@@ -0,0 +1,5 @@
+<cont>
+    <cont1>
+        <lf11>iden</lf11>  
+    </cont1>
+</cont>
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/yang-augments/general-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/yang-augments/general-module.yang
new file mode 100644 (file)
index 0000000..f1a1ea6
--- /dev/null
@@ -0,0 +1,14 @@
+module general-module {
+  namespace "general:module";  
+
+  prefix "genmod";
+  revision 2013-12-12 {    
+  }
+
+    container cont {
+       container cont1 {
+        }
+    }
+
+  
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/yang-augments/identity-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/xml-to-cnsn/identityref/yang-augments/identity-module.yang
new file mode 100644 (file)
index 0000000..30890bf
--- /dev/null
@@ -0,0 +1,10 @@
+module identity-module {
+  namespace "identity:module";  
+
+  prefix "idemod";
+  revision 2013-12-2 {    
+  }
+  
+       identity iden {         
+       }
+}
\ No newline at end of file
@@ -4,12 +4,13 @@ module identityref-module {
   prefix "iderefmod";
   
   import identity-module {prefix idemo; revision-date 2013-12-2;}
+  import general-module {prefix gmo; revision-date 2013-12-12;}
    
   revision 2013-12-2 {    
   }
   
-       container cont {
-               leaf lf1 {
+       augment "/gmo:cont/gmo:cont1" {
+               leaf lf11 {
                        type identityref {
                                base "idemo:iden";
                        }
index 0d459cfb865904fee47d19f0831aa62b8f795fa0..53e14ba5fbe8e1d0d945ac957b98c9e45ba65ad8 100644 (file)
@@ -19,16 +19,27 @@ import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
 import org.opendaylight.yangtools.yang.common.QName;
 
 import java.net.URI;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.Map;
 import java.util.Set;
 
+import static org.junit.Assert.fail;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 
 public class NetconfOperationServiceImplTest {
 
-    private Date date = new Date(0);
+    private static final Date date1970_01_01;
+
+    static {
+        try {
+            date1970_01_01 = new SimpleDateFormat("yyyy-MM-dd").parse("1970-01-01");
+        } catch (ParseException e) {
+            throw new IllegalStateException(e);
+        }
+    }
 
     @Test
     public void testCheckConsistencyBetweenYangStoreAndConfig_ok() throws Exception {
@@ -51,22 +62,22 @@ public class NetconfOperationServiceImplTest {
                 mockYangStoreSnapshot());
     }
 
-    @Test(expected = IllegalStateException.class)
+    @Test
     public void testCheckConsistencyBetweenYangStoreAndConfig_yangStoreMore() throws Exception {
         try {
             NetconfOperationServiceImpl.checkConsistencyBetweenYangStoreAndConfig(mockJmxClient("qname1"),
                     mockYangStoreSnapshot("qname2", "qname1"));
+            fail("An exception of type " + IllegalArgumentException.class + " was expected");
         } catch (IllegalStateException e) {
             String message = e.getMessage();
             Assert.assertThat(
                     message,
                     JUnitMatchers
-                            .containsString(" missing from config subsystem but present in yangstore: [(namespace?revision=1970-01-01)qname2]"));
+                            .containsString("missing from config subsystem but present in yangstore: [(namespace?revision=1970-01-01)qname2]"));
             Assert.assertThat(
                     message,
                     JUnitMatchers
                             .containsString("All modules present in config: [(namespace?revision=1970-01-01)qname1]"));
-            throw e;
         }
     }
 
@@ -97,7 +108,7 @@ public class NetconfOperationServiceImplTest {
     }
 
     private QName getQName(String qname) {
-        return new QName(URI.create("namespace"), date, qname);
+        return new QName(URI.create("namespace"), date1970_01_01, qname);
     }
 
     private LookupRegistry mockJmxClient(String... visibleQNames) {
index f2de91ef46d2be313b7626262076463fa8cc687d..31248137e8fef8f741d9473b71322b777b00f3e5 100644 (file)
             <artifactId>netconf-ssh</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>netconf-ssh</artifactId>
+            <scope>test</scope>
+            <type>test-jar</type>
+        </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>netconf-util</artifactId>
index c61dab7f643ebd119544cb12d76c0b420435d6af..4818b5f0a3c7868be0a02dafd19e8c1657e0d777 100644 (file)
@@ -8,18 +8,14 @@
 
 package org.opendaylight.controller.netconf.it;
 
-import static java.util.Collections.emptyList;
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertTrue;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
+import ch.ethz.ssh2.Connection;
+import ch.ethz.ssh2.Session;
+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 java.io.IOException;
 import java.io.InputStream;
 import java.lang.management.ManagementFactory;
@@ -31,12 +27,9 @@ 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;
 import org.junit.Ignore;
@@ -51,6 +44,7 @@ import org.opendaylight.controller.config.yang.test.impl.DepTestImplModuleFactor
 import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleFactory;
 import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleMXBean;
 import org.opendaylight.controller.config.yang.test.impl.TestImplModuleFactory;
+import org.opendaylight.controller.netconf.StubUserManager;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.client.NetconfClient;
 import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
@@ -68,6 +62,7 @@ import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFact
 import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshot;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
 import org.opendaylight.controller.netconf.ssh.NetconfSSHServer;
+import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider;
 import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
 import org.opendaylight.controller.netconf.util.xml.ExiParameters;
 import org.opendaylight.controller.netconf.util.xml.XmlElement;
@@ -79,12 +74,13 @@ import org.w3c.dom.Element;
 import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
 import org.xml.sax.SAXException;
-
-import ch.ethz.ssh2.Connection;
-import ch.ethz.ssh2.Session;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
+import static java.util.Collections.emptyList;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertTrue;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
 
 public class NetconfITTest extends AbstractConfigTest {
 
@@ -435,7 +431,9 @@ public class NetconfITTest extends AbstractConfigTest {
 
     private void startSSHServer() throws Exception{
         logger.info("Creating SSH server");
-        Thread sshServerThread = new Thread(NetconfSSHServer.start(10830,tcpAddress));
+        StubUserManager um = new StubUserManager(USERNAME,PASSWORD);
+        AuthProvider ap = new AuthProvider(um);
+        Thread sshServerThread = new Thread(NetconfSSHServer.start(10830,tcpAddress,ap));
         sshServerThread.setDaemon(true);
         sshServerThread.start();
         logger.info("SSH server on");
index f60b4b02f5edb571c15313139ce32895fb4843a8..5dde0448bd03ac6b16b49aee77f5589969ea77d1 100644 (file)
             <groupId>commons-io</groupId>
             <artifactId>commons-io</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>usermanager</artifactId>
+            <version>0.4.1-SNAPSHOT</version>
+        </dependency>
     </dependencies>
 
     <build>
         <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <version>2.4</version>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>test-jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
             <plugin>
                 <groupId>org.apache.felix</groupId>
                 <artifactId>maven-bundle-plugin</artifactId>
                             org.apache.commons.io,
                             org.opendaylight.controller.netconf.util,
                             org.opendaylight.controller.netconf.util.osgi,
+                            org.opendaylight.controller.usermanager,
+                            org.opendaylight.controller.sal.authorization,
+                            org.opendaylight.controller.sal.utils,
                             org.opendaylight.protocol.framework,
                             org.osgi.framework,
-                            org.slf4j
+                            org.osgi.util.tracker,
+                            org.slf4j,
                         </Import-Package>
                     </instructions>
                 </configuration>
index b91824866a107ffef75290f3a52af53318dca7a5..3b513790bd128806a7ef1bec2561bd90fee6420a 100644 (file)
@@ -10,9 +10,14 @@ package org.opendaylight.controller.netconf.osgi;
 import com.google.common.base.Optional;
 import java.net.InetSocketAddress;
 import org.opendaylight.controller.netconf.ssh.NetconfSSHServer;
+import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider;
 import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil;
+import org.opendaylight.controller.usermanager.IUserManager;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -31,18 +36,57 @@ public class NetconfSSHActivator implements BundleActivator{
     private NetconfSSHServer server;
     private static final Logger logger =  LoggerFactory.getLogger(NetconfSSHActivator.class);
     private static final String EXCEPTION_MESSAGE = "Netconf ssh bridge is not available.";
+    private IUserManager iUserManager;
+    private BundleContext context = null;
+
+    ServiceTrackerCustomizer<IUserManager, IUserManager> customizer = new ServiceTrackerCustomizer<IUserManager, IUserManager>(){
+        @Override
+        public IUserManager addingService(ServiceReference<IUserManager> reference) {
+            logger.info("Service IUserManager added, let there be SSH bridge.");
+            iUserManager =  context.getService(reference);
+            try {
+                onUserManagerFound(iUserManager);
+            } catch (Exception e) {
+                logger.trace("Can't start SSH server due to {}",e);
+            }
+            return iUserManager;
+        }
+        @Override
+        public void modifiedService(ServiceReference<IUserManager> reference, IUserManager service) {
+            logger.info("Replacing modified service IUserManager in netconf SSH.");
+            server.addUserManagerService(service);
+        }
+        @Override
+        public void removedService(ServiceReference<IUserManager> reference, IUserManager service) {
+            logger.info("Removing service IUserManager from netconf SSH. " +
+                    "SSH won't authenticate users until IUserManeger service will be started.");
+            removeUserManagerService();
+        }
+    };
+
 
     @Override
     public void start(BundleContext context) throws Exception {
+        this.context = context;
+        listenForManagerService();
+    }
 
+    @Override
+    public void stop(BundleContext context) throws Exception {
+        if (server != null){
+            server.stop();
+            logger.trace("Netconf SSH bridge is down ...");
+        }
+    }
+    private void startSSHServer() throws Exception {
         logger.trace("Starting netconf SSH  bridge.");
-
-        Optional<InetSocketAddress> sshSocketAddressOptional = NetconfConfigUtil.extractSSHNetconfAddress(context,EXCEPTION_MESSAGE);
+        Optional<InetSocketAddress> sshSocketAddressOptional = NetconfConfigUtil.extractSSHNetconfAddress(context, EXCEPTION_MESSAGE);
         InetSocketAddress tcpSocketAddress = NetconfConfigUtil.extractTCPNetconfAddress(context,
                 EXCEPTION_MESSAGE, true);
 
         if (sshSocketAddressOptional.isPresent()){
-            server = NetconfSSHServer.start(sshSocketAddressOptional.get().getPort(),tcpSocketAddress);
+            AuthProvider authProvider = new AuthProvider(iUserManager);
+            this.server = NetconfSSHServer.start(sshSocketAddressOptional.get().getPort(),tcpSocketAddress,authProvider);
             Thread serverThread = new  Thread(server,"netconf SSH server thread");
             serverThread.setDaemon(true);
             serverThread.start();
@@ -52,13 +96,18 @@ public class NetconfSSHActivator implements BundleActivator{
             throw new Exception("No valid connection configuration for SSH bridge found.");
         }
     }
-
-    @Override
-    public void stop(BundleContext context) throws Exception {
-        if (server != null){
-            logger.trace("Netconf SSH bridge going down ...");
-            server.stop();
-            logger.trace("Netconf SSH bridge is down ...");
+    private void onUserManagerFound(IUserManager userManager) throws Exception{
+        if (server!=null && server.isUp()){
+           server.addUserManagerService(userManager);
+        } else {
+           startSSHServer();
         }
     }
+    private void removeUserManagerService(){
+        this.server.removeUserManagerService();
+    }
+    private void listenForManagerService(){
+        ServiceTracker<IUserManager, IUserManager> listenerTracker = new ServiceTracker<>(context, IUserManager.class,customizer);
+        listenerTracker.open();
+    }
 }
index 72135cc7dcdd39acddfd8d69d826f2683ee9b921..45807a83334f8e655b268c00bcb9c9e163ccf88f 100644 (file)
@@ -12,20 +12,23 @@ import java.net.InetSocketAddress;
 import java.net.ServerSocket;
 import java.util.concurrent.atomic.AtomicLong;
 import javax.annotation.concurrent.ThreadSafe;
+import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider;
 import org.opendaylight.controller.netconf.ssh.threads.SocketThread;
+import org.opendaylight.controller.usermanager.IUserManager;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @ThreadSafe
 public class NetconfSSHServer implements Runnable {
 
-    private static boolean acceptMore = true;
     private ServerSocket ss = null;
     private static final Logger logger =  LoggerFactory.getLogger(NetconfSSHServer.class);
     private static final AtomicLong sesssionId = new AtomicLong();
     private final InetSocketAddress clientAddress;
+    private final AuthProvider authProvider;
+    private boolean up = false;
 
-    private NetconfSSHServer(int serverPort,InetSocketAddress clientAddress) throws Exception{
+    private NetconfSSHServer(int serverPort,InetSocketAddress clientAddress, AuthProvider authProvider) throws Exception{
 
         logger.trace("Creating SSH server socket on port {}",serverPort);
         this.ss = new ServerSocket(serverPort);
@@ -34,27 +37,37 @@ public class NetconfSSHServer implements Runnable {
         }
         logger.trace("Server socket created.");
         this.clientAddress = clientAddress;
-
+        this.authProvider = authProvider;
+        this.up = true;
     }
 
-
-    public static NetconfSSHServer start(int serverPort, InetSocketAddress clientAddress) throws Exception {
-        return new NetconfSSHServer(serverPort, clientAddress);
+    public static NetconfSSHServer start(int serverPort, InetSocketAddress clientAddress,AuthProvider authProvider) throws Exception {
+        return new NetconfSSHServer(serverPort, clientAddress,authProvider);
     }
 
     public void stop() throws Exception {
-        acceptMore = false;
+        up = false;
         logger.trace("Closing SSH server socket.");
         ss.close();
         logger.trace("SSH server socket closed.");
     }
 
+    public void removeUserManagerService(){
+        this.authProvider.removeUserManagerService();
+    }
+
+    public void addUserManagerService(IUserManager userManagerService){
+        this.authProvider.addUserManagerService(userManagerService);
+    }
+    public boolean isUp(){
+        return this.up;
+    }
     @Override
     public void run() {
-        while (acceptMore) {
+        while (up) {
             logger.trace("Starting new socket thread.");
             try {
-               SocketThread.start(ss.accept(), clientAddress, sesssionId.incrementAndGet());
+               SocketThread.start(ss.accept(), clientAddress, sesssionId.incrementAndGet(),authProvider);
             } catch (IOException e) {
                 e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
             }
diff --git a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java
new file mode 100644 (file)
index 0000000..a73dfdf
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * 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.ssh.authentication;
+
+import ch.ethz.ssh2.signature.RSAPrivateKey;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.io.IOUtils;
+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;
+
+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";
+
+
+    public AuthProvider(IUserManager ium) throws Exception {
+
+        this.um = ium;
+
+        if (this.um  == null){
+            throw new Exception("No usermanager service available.");
+        }
+
+        List<String> roles = new ArrayList<String>(1);
+        roles.add(UserLevel.SYSTEMADMIN.toString());
+        this.um.addLocalUser(new UserConfig(DEAFULT_USER, DEAFULT_PASSWORD, roles));
+    }
+    @Override
+    public boolean authenticated(String username, String password)  throws Exception {
+        if (this.um  == null){
+            throw new Exception("No usermanager service available.");
+        }
+        AuthResultEnum authResult = this.um.authenticate(username,password);
+        if (authResult.equals(AuthResultEnum.AUTH_ACCEPT) || authResult.equals(AuthResultEnum.AUTH_ACCEPT_LOC)){
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public char[] getPEMAsCharArray() {
+
+        InputStream is = getClass().getResourceAsStream("/RSA.pk");
+        try {
+            return IOUtils.toCharArray(is);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    @Override
+    public void removeUserManagerService() {
+        this.um = null;
+    }
+
+    @Override
+    public void addUserManagerService(IUserManager userManagerService) {
+        this.um = userManagerService;
+    }
+
+
+}
@@ -1,3 +1,4 @@
+
 /*
  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
  *
@@ -7,8 +8,12 @@
  */
 package org.opendaylight.controller.netconf.ssh.authentication;
 
-import ch.ethz.ssh2.signature.RSAPrivateKey;
+import org.opendaylight.controller.usermanager.IUserManager;
+
+public interface AuthProviderInterface {
 
-public interface KeyStoreHandler {
-    public RSAPrivateKey getPrivateKey();
+    public boolean authenticated(String username, String password) throws Exception;
+    public char[] getPEMAsCharArray();
+    public void removeUserManagerService();
+    public void addUserManagerService(IUserManager userManagerService);
 }
diff --git a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/RSAKey.java b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/RSAKey.java
deleted file mode 100644 (file)
index b420b33..0000000
+++ /dev/null
@@ -1,36 +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.ssh.authentication;
-
-import ch.ethz.ssh2.signature.RSAPrivateKey;
-
-import java.math.BigInteger;
-
-public class RSAKey implements KeyStoreHandler {
-
-    private static RSAPrivateKey hostkey = null;
-    private static String user = "netconf";
-    private static String password = "netconf";
-    static {
-
-        BigInteger p = new BigInteger("2967886344240998436887630478678331145236162666668503940430852241825039192450179076148979094256007292741704260675085192441025058193581327559331546948442042987131728039318861235625879376246169858586459472691398815098207618446039");    //.BigInteger.probablePrime(N / 2, rnd);
-        BigInteger q = new BigInteger("4311534819291430017572425052029278681302539382618633848168923130451247487970187151403375389974616614405320169278870943605377518341666894603659873284783174749122655429409273983428000534304828056597676444751611433784228298909767"); //BigInteger.probablePrime(N / 2, rnd);
-        BigInteger phi = (p.subtract(BigInteger.ONE)).multiply(q.subtract(BigInteger.ONE));
-
-        BigInteger n = p.multiply(q);
-        BigInteger e = new BigInteger("65537");
-        BigInteger d = e.modInverse(phi);
-
-        hostkey = new RSAPrivateKey(d, e, n);
-    }
-
-    @Override
-    public RSAPrivateKey getPrivateKey() {
-        return hostkey;
-    }
-}
index 15d99a44ee4db4a7b31bd0ee2fd6abd25476079c..e5da03b4cf4c9d97765ce098a8c2761b0eda8e39 100644 (file)
@@ -13,7 +13,7 @@ import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.net.Socket;
 import javax.annotation.concurrent.ThreadSafe;
-import org.opendaylight.controller.netconf.ssh.authentication.RSAKey;
+import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -30,27 +30,38 @@ public class SocketThread implements Runnable, ServerAuthenticationCallback, Ser
     private long sessionId;
     private String currentUser;
     private final String remoteAddressWithPort;
+    private final AuthProvider authProvider;
 
 
-    public static void start(Socket socket, InetSocketAddress clientAddress, long sessionId) throws IOException{
-        Thread netconf_ssh_socket_thread = new Thread(new SocketThread(socket,clientAddress,sessionId));
+    public static void start(Socket socket,
+                             InetSocketAddress clientAddress,
+                             long sessionId,
+                             AuthProvider authProvider) throws IOException{
+        Thread netconf_ssh_socket_thread = new Thread(new SocketThread(socket,clientAddress,sessionId,authProvider));
         netconf_ssh_socket_thread.setDaemon(true);
         netconf_ssh_socket_thread.start();
     }
-    private SocketThread(Socket socket, InetSocketAddress clientAddress, long sessionId) throws IOException {
+    private SocketThread(Socket socket,
+                         InetSocketAddress clientAddress,
+                         long sessionId,
+                         AuthProvider authProvider) throws IOException {
 
         this.socket = socket;
         this.clientAddress = clientAddress;
         this.sessionId = sessionId;
         this.remoteAddressWithPort = socket.getRemoteSocketAddress().toString().replaceFirst("/","");
+        this.authProvider = authProvider;
 
     }
 
     @Override
     public void run() {
         conn = new ServerConnection(socket);
-        RSAKey keyStore = new RSAKey();
-        conn.setRsaHostKey(keyStore.getPrivateKey());
+        try {
+            conn.setPEMHostKey(authProvider.getPEMAsCharArray(),"netconf");
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
         conn.setAuthenticationCallback(this);
         conn.setServerConnectionCallback(this);
         try {
@@ -90,7 +101,7 @@ public class SocketThread implements Runnable, ServerAuthenticationCallback, Ser
                                 netconf_ssh_output.start();
 
                             } catch (Throwable t){
-                                logger.error(t.getMessage(),t);
+                                logger.error("SSH bridge couldn't create echo socket",t.getMessage(),t);
 
                                 try {
                                     if (netconf_ssh_input!=null){
@@ -166,13 +177,16 @@ public class SocketThread implements Runnable, ServerAuthenticationCallback, Ser
 
     public AuthenticationResult authenticateWithPassword(ServerConnection sc, String username, String password)
     {
-        if (USER.equals(username) && PASSWORD.equals(password)){
-            currentUser = username;
-            logger.trace("user {}@{} authenticated",currentUser,remoteAddressWithPort);
-            return AuthenticationResult.SUCCESS;
-        }
-
 
+        try {
+            if (authProvider.authenticated(username,password)){
+                currentUser = username;
+                logger.trace("user {}@{} authenticated",currentUser,remoteAddressWithPort);
+                return AuthenticationResult.SUCCESS;
+            }
+        } catch (Exception e){
+            logger.info("Authentication failed due to :" + e.getLocalizedMessage());
+        }
         return AuthenticationResult.FAILURE;
     }
 
diff --git a/opendaylight/netconf/netconf-ssh/src/main/resources/RSA.pk b/opendaylight/netconf/netconf-ssh/src/main/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-----
similarity index 53%
rename from opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/ssh/SSHServerTest.java
rename to opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/SSHServerTest.java
index 54bc7bc4b686771279e5542bb7c29e4dabc0d8d2..62396ed87ac1f4db3dcaa7942f676012ab35ade8 100644 (file)
@@ -5,15 +5,14 @@
  * 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.ssh;
+package org.opendaylight.controller.netconf;
 
 import ch.ethz.ssh2.Connection;
-import ch.ethz.ssh2.Session;
-import java.io.IOException;
 import java.net.InetSocketAddress;
 import junit.framework.Assert;
-import org.apache.commons.io.IOUtils;
 import org.junit.Test;
+import org.opendaylight.controller.netconf.ssh.NetconfSSHServer;
+import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -26,36 +25,37 @@ public class SSHServerTest {
     private static final int PORT = 1830;
     private static final InetSocketAddress tcpAddress = new InetSocketAddress("127.0.0.1", 8383);
     private static final Logger logger =  LoggerFactory.getLogger(SSHServerTest.class);
+    private Thread sshServerThread;
+
+
+
 
-//    @Before
     public void startSSHServer() throws Exception{
-            logger.info("Creating SSH server");
-            NetconfSSHServer server = NetconfSSHServer.start(PORT,tcpAddress);
-            Thread sshServerThread = new Thread(server);
-            sshServerThread.setDaemon(true);
-            sshServerThread.start();
-            logger.info("SSH server on");
+        logger.info("Creating SSH server");
+        StubUserManager um = new StubUserManager(USER,PASSWORD);
+        AuthProvider ap = new AuthProvider(um);
+        NetconfSSHServer server = NetconfSSHServer.start(PORT,tcpAddress,ap);
+        sshServerThread = new Thread(server);
+        sshServerThread.setDaemon(true);
+        sshServerThread.start();
+        logger.info("SSH server on");
     }
 
     @Test
     public void connect(){
-        Connection conn = new Connection(HOST,PORT);
-        Assert.assertNotNull(conn);
         try {
+            this.startSSHServer();
+            Connection conn = new Connection(HOST,PORT);
+            Assert.assertNotNull(conn);
             logger.info("connecting to SSH server");
             conn.connect();
             logger.info("authenticating ...");
             boolean isAuthenticated = conn.authenticateWithPassword(USER,PASSWORD);
             Assert.assertTrue(isAuthenticated);
-            logger.info("opening session");
-            Session sess = conn.openSession();
-            logger.info("subsystem netconf");
-            sess.startSubSystem("netconf");
-            sess.getStdin().write("<?xml version=\"1.0\" encoding=\"UTF-8\"?><hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><capabilities><capability>urn:ietf:params:netconf:base:1.1</capability></capabilities></hello>]]>]]>".getBytes());
-            IOUtils.copy(sess.getStdout(), System.out);
-        } catch (IOException e) {
-            e.printStackTrace();
+        } catch (Exception e) {
+            logger.error("Error while starting SSH server.", e);
         }
+
     }
 
 }
diff --git a/opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/StubUserManager.java b/opendaylight/netconf/netconf-ssh/src/test/java/org/opendaylight/controller/netconf/StubUserManager.java
new file mode 100644 (file)
index 0000000..4a3a650
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * 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;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.opendaylight.controller.sal.authorization.AuthResultEnum;
+import org.opendaylight.controller.sal.authorization.UserLevel;
+import org.opendaylight.controller.sal.utils.Status;
+import org.opendaylight.controller.sal.utils.StatusCode;
+import org.opendaylight.controller.usermanager.AuthorizationConfig;
+import org.opendaylight.controller.usermanager.ISessionManager;
+import org.opendaylight.controller.usermanager.IUserManager;
+import org.opendaylight.controller.usermanager.ServerConfig;
+import org.opendaylight.controller.usermanager.UserConfig;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.security.web.context.SecurityContextRepository;
+
+public class StubUserManager implements IUserManager{
+
+
+    private static String user;
+    private static String password;
+
+    public StubUserManager(String user, String password){
+        this.user = user;
+        this.password = password;
+    }
+    @Override
+    public List<String> getUserRoles(String userName) {
+        return null;
+    }
+
+    @Override
+    public AuthResultEnum authenticate(String username, String password) {
+        if (this.user.equals(username) && this.password.equals(password)){
+            return AuthResultEnum.AUTH_ACCEPT_LOC;
+        }
+        return AuthResultEnum.AUTH_REJECT_LOC;
+    }
+
+    @Override
+    public Status addAAAServer(ServerConfig configObject) {
+        return null;
+    }
+
+    @Override
+    public Status removeAAAServer(ServerConfig configObject) {
+        return null;
+    }
+
+    @Override
+    public Status addLocalUser(UserConfig configObject) {
+        return new Status(StatusCode.SUCCESS);
+    }
+
+    @Override
+    public Status modifyLocalUser(UserConfig configObject) {
+        return null;
+    }
+
+    @Override
+    public Status removeLocalUser(UserConfig configObject) {
+        return null;
+    }
+
+    @Override
+    public Status removeLocalUser(String userName) {
+        return null;
+    }
+
+    @Override
+    public Status addAuthInfo(AuthorizationConfig AAAconf) {
+        return null;
+    }
+
+    @Override
+    public Status removeAuthInfo(AuthorizationConfig AAAconf) {
+        return null;
+    }
+
+    @Override
+    public List<AuthorizationConfig> getAuthorizationList() {
+        return null;
+    }
+
+    @Override
+    public Set<String> getAAAProviderNames() {
+        return null;
+    }
+
+    @Override
+    public Status changeLocalUserPassword(String user, String curPassword, String newPassword) {
+        return null;
+    }
+
+    @Override
+    public List<ServerConfig> getAAAServerList() {
+        return null;
+    }
+
+    @Override
+    public List<UserConfig> getLocalUserList() {
+        return null;
+    }
+
+    @Override
+    public Status saveLocalUserList() {
+        return null;
+    }
+
+    @Override
+    public Status saveAAAServerList() {
+        return null;
+    }
+
+    @Override
+    public Status saveAuthorizationList() {
+        return null;
+    }
+
+    @Override
+    public void userLogout(String username) {
+
+    }
+
+    @Override
+    public void userTimedOut(String username) {
+
+    }
+
+    @Override
+    public Map<String, List<String>> getUserLoggedIn() {
+        return null;
+    }
+
+    @Override
+    public String getAccessDate(String user) {
+        return null;
+    }
+
+    @Override
+    public UserLevel getUserLevel(String userName) {
+        return null;
+    }
+
+    @Override
+    public List<UserLevel> getUserLevels(String userName) {
+        return null;
+    }
+
+    @Override
+    public SecurityContextRepository getSecurityContextRepo() {
+        return null;
+    }
+
+    @Override
+    public ISessionManager getSessionManager() {
+        return null;
+    }
+
+    @Override
+    public boolean isRoleInUse(String role) {
+        return false;
+    }
+
+    @Override
+    public String getPassword(String username) {
+        return null;
+    }
+
+    @Override
+    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
+        return null;
+    }
+
+}
index e70df1b9493634806c701b5ebd861bac36ab4b6d..c4b146722004d6792303b0f0a3a423d2d89f91e6 100644 (file)
                 <artifactId>netconf-ssh</artifactId>
                 <version>${netconf.version}</version>
             </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>netconf-ssh</artifactId>
+                <version>${netconf.version}</version>
+                <type>test-jar</type>
+            </dependency>
             <dependency>
                 <groupId>${project.groupId}</groupId>
                 <artifactId>netconf-mapping-api</artifactId>
index 2300b8da400d6f15f46812f868c3e262b30b32df..7e0d465256fa63b5af631ce76e4fb078ef257c28 100644 (file)
@@ -25,7 +25,7 @@
           </init-param>
           <init-param>
             <param-name>cors.allowed.methods</param-name>
-            <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
+            <param-value>GET,POST,HEAD,OPTIONS,PUT,DELETE</param-value>
           </init-param>
           <init-param>
             <param-name>cors.allowed.headers</param-name>
index f895ca0c85bd4583405453d65fcd4195dcb8b5ce..b5d0a48c28709e575f13646971e00ab1ddbc3ea0 100644 (file)
@@ -319,7 +319,7 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
     @Override
     public SubnetConfig getSubnetConfig(String subnet) {
         // if there are no subnets, return the default subnet
-        if(subnetsConfigList.size() == 0 && subnet == DEFAULT_SUBNET_NAME){
+        if(subnetsConfigList.isEmpty() && subnet.equalsIgnoreCase(DEFAULT_SUBNET_NAME)){
             return DEFAULT_SUBNETCONFIG;
         }else{
             return subnetsConfigList.get(subnet);
@@ -428,11 +428,11 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
     }
 
     private Status semanticCheck(SubnetConfig conf) {
-        Subnet newSubnet = new Subnet(conf);
         Set<InetAddress> IPs = subnets.keySet();
         if (IPs == null) {
             return new Status(StatusCode.SUCCESS);
         }
+        Subnet newSubnet = new Subnet(conf);
         for (InetAddress i : IPs) {
             Subnet existingSubnet = subnets.get(i);
             if ((existingSubnet != null) && !existingSubnet.isMutualExclusive(newSubnet)) {
@@ -462,7 +462,7 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
                 return status;
             }
         } else {
-            if (conf.getName().equals(DEFAULT_SUBNET_NAME)) {
+            if (conf.getName().equalsIgnoreCase(DEFAULT_SUBNET_NAME)) {
                 return new Status(StatusCode.NOTALLOWED, "The specified subnet gateway cannot be removed");
             }
         }
@@ -506,7 +506,7 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
 
     @Override
     public Status removeSubnet(String name) {
-        if (name.equals(DEFAULT_SUBNET_NAME)) {
+        if (name.equalsIgnoreCase(DEFAULT_SUBNET_NAME)) {
             return new Status(StatusCode.NOTALLOWED, "The specified subnet gateway cannot be removed");
         }
         SubnetConfig conf = subnetsConfigList.get(name);
index 0c14dea38a4a9ff69993d1e6a88503ceb5db0792..83532a1012f6a9431cd4f75a3f1b201e653ec395 100644 (file)
@@ -9,10 +9,11 @@
 package org.opendaylight.controller.usermanager;
 
 import java.io.Serializable;
-import java.nio.charset.Charset;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.regex.Matcher;
@@ -24,6 +25,7 @@ import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 
 import org.opendaylight.controller.sal.authorization.AuthResultEnum;
+import org.opendaylight.controller.sal.packet.BitBufferHelper;
 import org.opendaylight.controller.sal.utils.HexEncode;
 import org.opendaylight.controller.sal.utils.Status;
 import org.opendaylight.controller.sal.utils.StatusCode;
@@ -46,6 +48,7 @@ public class UserConfig implements Serializable {
     protected static final String PASSWORD_REGEX = "(?=.*[^a-zA-Z0-9])(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{8,256}$";
     private static final Pattern INVALID_USERNAME_CHARACTERS = Pattern.compile("([/\\s\\.\\?#%;\\\\]+)");
     private static MessageDigest oneWayFunction;
+    private static SecureRandom randomGenerator;
 
     static {
         try {
@@ -54,6 +57,7 @@ public class UserConfig implements Serializable {
             log.error(String.format("Implementation of %s digest algorithm not found: %s", DIGEST_ALGORITHM,
                     e.getMessage()));
         }
+        UserConfig.randomGenerator = new SecureRandom(BitBufferHelper.toByteArray(System.currentTimeMillis()));
     }
 
     /**
@@ -81,6 +85,8 @@ public class UserConfig implements Serializable {
     @XmlElement
     private String password;
 
+    private byte[] salt;
+
 
 
     public UserConfig() {
@@ -102,11 +108,19 @@ public class UserConfig implements Serializable {
         /*
          * Password validation to be done on clear text password. If fails, mark
          * the password with a well known label, so that object validation can
-         * report the proper error. Only if password is a valid one, hash it.
+         * report the proper error. Only if password is a valid one, generate
+         * salt, concatenate it with clear text password and hash the
+         * resulting string. Hash result is going to be our stored password.
          */
-        this.password = (validatePassword(password).isSuccess()) ? hash(password) : BAD_PASSWORD;
+        if (validateClearTextPassword(password).isSuccess()) {
+            this.salt = BitBufferHelper.toByteArray(randomGenerator.nextLong());
+            this.password = hash(salt, password);
+        } else {
+            this.salt = null;
+            this.password = BAD_PASSWORD;
+        }
 
-        this.roles = (roles == null) ? new ArrayList<String>() : new ArrayList<String>(roles);
+        this.roles = (roles == null) ? Collections.<String>emptyList() : new ArrayList<String>(roles);
     }
 
     public String getUser() {
@@ -176,6 +190,7 @@ public class UserConfig implements Serializable {
     public Status validate() {
         Status validCheck = validateUsername();
         if (validCheck.isSuccess()) {
+            // Password validation was run at object construction time
             validCheck = (!password.equals(BAD_PASSWORD)) ? new Status(StatusCode.SUCCESS) : new Status(
                     StatusCode.BADREQUEST,
                     "Password should be 8 to 256 characters long, contain both upper and lower case letters, "
@@ -203,7 +218,7 @@ public class UserConfig implements Serializable {
         return new Status(StatusCode.SUCCESS);
     }
 
-    private Status validatePassword(String password) {
+    private Status validateClearTextPassword(String password) {
         if (password == null || password.isEmpty()) {
             return new Status(StatusCode.BADREQUEST, "Password cannot be empty");
         }
@@ -227,14 +242,14 @@ public class UserConfig implements Serializable {
 
         // To make any changes to a user configured profile, current password
         // must always be provided
-        if (!this.password.equals(hash(currentPassword))) {
+        if (!this.password.equals(hash(this.salt, currentPassword))) {
             return new Status(StatusCode.BADREQUEST, "Current password is incorrect");
         }
 
         // Create a new object with the proposed modifications
         UserConfig proposed = new UserConfig();
         proposed.user = this.user;
-        proposed.password = (newPassword == null)? this.password : hash(newPassword);
+        proposed.password = (newPassword == null)? this.password : hash(this.salt, newPassword);
         proposed.roles = (newRoles == null)? this.roles : newRoles;
 
         // Validate it
@@ -251,9 +266,9 @@ public class UserConfig implements Serializable {
         return status;
     }
 
-    public AuthResponse authenticate(String clearTextPass) {
+    public AuthResponse authenticate(String clearTextPassword) {
         AuthResponse locResponse = new AuthResponse();
-        if (password.equals(hash(clearTextPass))) {
+        if (password.equals(hash(this.salt, clearTextPassword))) {
             locResponse.setStatus(AuthResultEnum.AUTH_ACCEPT_LOC);
             locResponse.addData(getRolesString());
         } else {
@@ -275,12 +290,32 @@ public class UserConfig implements Serializable {
         return buffer.toString();
     }
 
-    public static String hash(String message) {
+    private static byte[] concatenate(byte[] salt, String password) {
+        byte[] messageArray = password.getBytes();
+        byte[] concatenation = new byte[salt.length + password.length()];
+        System.arraycopy(salt, 0, concatenation, 0, salt.length);
+        System.arraycopy(messageArray, 0, concatenation, salt.length, messageArray.length);
+        return concatenation;
+    }
+
+    private static String hash(byte[] salt, String message) {
         if (message == null) {
+            log.warn("Password hash requested but empty or no password provided");
             return message;
         }
+        if (salt == null || salt.length == 0) {
+            log.warn("Password hash requested but empty or no salt provided");
+            return message;
+        }
+
+        // Concatenate salt and password
+        byte[] messageArray = message.getBytes();
+        byte[] concatenation = new byte[salt.length + message.length()];
+        System.arraycopy(salt, 0, concatenation, 0, salt.length);
+        System.arraycopy(messageArray, 0, concatenation, salt.length, messageArray.length);
+
         UserConfig.oneWayFunction.reset();
-        return HexEncode.bytesToHexString(UserConfig.oneWayFunction.digest(message.getBytes(Charset.defaultCharset())));
+        return HexEncode.bytesToHexString(UserConfig.oneWayFunction.digest(concatenate(salt, message)));
     }
 
     /**
@@ -299,7 +334,8 @@ public class UserConfig implements Serializable {
     public static UserConfig getUncheckedUserConfig(String userName, String password, List<String> roles) {
         UserConfig config = new UserConfig();
         config.user = userName;
-        config.password = hash(password);
+        config.salt = BitBufferHelper.toByteArray(randomGenerator.nextLong());
+        config.password = hash(config.salt, password);
         config.roles = roles;
         return config;
     }
index d225e5c76014bfc2e647ceeb0fbff756de4065ba..8fc7f07df1db2fc3283057c1f55caed85799d604 100644 (file)
@@ -7,7 +7,6 @@
  */
 package org.opendaylight.controller.usermanager;
 
-import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
@@ -71,12 +70,12 @@ public class AuthorizationUserConfigTest {
                 .isSuccess());
 
         // New Password = null, No change in password
-        assertTrue(userConfig.getPassword().equals(UserConfig.hash("ciscocisco")));
+        assertTrue(userConfig.authenticate("ciscocisco").getStatus().equals(AuthResultEnum.AUTH_ACCEPT_LOC));
 
         // Password changed successfully, no change in user role
         assertTrue(userConfig.update("ciscocisco", "cisco123", roles)
                 .isSuccess());
-        assertTrue(userConfig.getPassword().equals(UserConfig.hash("cisco123")));
+        assertTrue(userConfig.authenticate("cisco123").getStatus().equals(AuthResultEnum.AUTH_ACCEPT_LOC));
         assertTrue(userConfig.getRoles().get(0).equals(
                 UserLevel.NETWORKOPERATOR.toString()));
 
@@ -85,14 +84,14 @@ public class AuthorizationUserConfigTest {
         roles.add(UserLevel.SYSTEMADMIN.toString());
         assertTrue(userConfig.update("cisco123", "cisco123", roles)
                 .isSuccess());
-        assertTrue(userConfig.getPassword().equals(UserConfig.hash("cisco123")));
+        assertTrue(userConfig.authenticate("cisco123").getStatus().equals(AuthResultEnum.AUTH_ACCEPT_LOC));
         assertTrue(userConfig.getRoles().get(0)
                 .equals(UserLevel.SYSTEMADMIN.toString()));
 
         // Password and role changed successfully
         assertTrue(userConfig.update("cisco123", "ciscocisco", roles)
                 .isSuccess());
-        assertTrue(userConfig.getPassword().equals(UserConfig.hash("ciscocisco")));
+        assertTrue(userConfig.authenticate("ciscocisco").getStatus().equals(AuthResultEnum.AUTH_ACCEPT_LOC));
         assertTrue(userConfig.getRoles().get(0)
                 .equals(UserLevel.SYSTEMADMIN.toString()));
 
@@ -104,14 +103,6 @@ public class AuthorizationUserConfigTest {
         assertTrue(authresp.getStatus().equals(AuthResultEnum.AUTH_ACCEPT_LOC));
         authresp = userConfig.authenticate("wrongPassword");
         assertTrue(authresp.getStatus().equals(AuthResultEnum.AUTH_REJECT_LOC));
-
-        // test equals()
-        roles.clear();
-        roles.add(UserLevel.NETWORKOPERATOR.toString());
-        userConfig = new UserConfig("uname", "ciscocisco", roles);
-        assertEquals(userConfig, userConfig);
-        UserConfig userConfig2 = new UserConfig("uname", "ciscocisco", roles);
-        assertEquals(userConfig, userConfig2);
     }
 
     @Test
index 4eedf7eda99f42bb70d011dd7daba2d81d2d4ae0..dcdc2f6d50447e942fe868c22bc69bc732bfe248 100644 (file)
               org.opendaylight.controller.usermanager
             </Import-Package>
             <Export-Package>
-<!--
+               <!--
               org.opendaylight.controller.usermanager,
               org.opendaylight.controller.usermanager.internal
- -->
             -->
              </Export-Package>
             <Bundle-Activator>
               org.opendaylight.controller.usermanager.internal.Activator
index 094562fac07252b182e601774e79209d0a473e20..6b4cfa00253ef4f36026a51f639fba6af02ed4b6 100644 (file)
@@ -390,8 +390,8 @@ one.f.flows = {
                     $tr = $(tr);
                     $span = $("td span", $tr);
                     var flowstatus = $span.data("flowstatus");
-                    if($span.data("installinhw") != null) {
-                        var installInHw = $span.data("installinhw").toString();
+                    if($span.data("installInHw") != null) {
+                        var installInHw = $span.data("installInHw").toString();
                         if(installInHw == "true" && flowstatus == "Success") {
                             $tr.addClass("success");
                         } else {