Add Honeynode emulator for device221 95/82195/5
authorGilles Thouenon <gilles.thouenon@orange.com>
Tue, 21 May 2019 15:41:50 +0000 (17:41 +0200)
committerguillaume.lambert <guillaume.lambert@orange.com>
Wed, 29 May 2019 13:00:04 +0000 (15:00 +0200)
- new version of honeynode emulator for managing org-openroadm-device
2.2.1 and org-openroadm-pm 2.2.1
- new simple configuration files for XPDR and ROADM (with bidirectionnal
ports)

Change-Id: I5c470514fdb5ffe5c33d2ebc3933b10007b6944e
JIRA: TRNSPRTPCE-101
Signed-off-by: Gilles Thouenon <gilles.thouenon@orange.com>
Co-authored-by: Christophe Betoule <christophe.betoule@orange.com>
210 files changed:
tests/buildHoneynode221.sh [new file with mode: 0755]
tests/honeynode221/README [new file with mode: 0644]
tests/honeynode221/fd_io_honeycomb_settings.xml [new file with mode: 0644]
tests/honeynode221/honeynode-common/asciidoc/Readme.adoc [new file with mode: 0644]
tests/honeynode221/honeynode-common/pom.xml [new file with mode: 0644]
tests/honeynode221/honeynode-common/src/main/java/io/fd/honeycomb/transportpce/binding/converter/AbstractDataObjectConverter.java [new file with mode: 0644]
tests/honeynode221/honeynode-common/src/main/java/io/fd/honeycomb/transportpce/binding/converter/JSONDataObjectConverter.java [new file with mode: 0644]
tests/honeynode221/honeynode-common/src/main/java/io/fd/honeycomb/transportpce/binding/converter/XMLDataObjectConverter.java [new file with mode: 0644]
tests/honeynode221/honeynode-common/src/main/java/io/fd/honeycomb/transportpce/binding/converter/api/DataObjectConverter.java [new file with mode: 0644]
tests/honeynode221/honeynode-common/src/main/java/io/fd/honeycomb/transportpce/test/common/DataStoreContext.java [new file with mode: 0644]
tests/honeynode221/honeynode-common/src/main/java/io/fd/honeycomb/transportpce/test/common/DataStoreContextImpl.java [new file with mode: 0644]
tests/honeynode221/honeynode-distribution/asciidoc/Readme.adoc [new file with mode: 0644]
tests/honeynode221/honeynode-distribution/pom.xml [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-api/asciidoc/Readme.adoc [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-api/pom.xml [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-api/src/main/java/org/opendaylight/yang/gen/v1/http/org/openroadm/pm/types/rev171215/PmDataTypeBuilder.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-api/src/main/java/org/opendaylight/yang/gen/v1/http/org/openroadm/syslog/rev171215/syslog/selector/log/selector/selector/facility/log/facility/LogFacilityFacilityBuilder.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-api/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev130715/HostBuilder.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-api/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev130715/IpAddressBuilder.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-api/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev130715/IpAddressNoZoneBuilder.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-api/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev130715/IpPrefixBuilder.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-api/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/monitoring/rev101004/netconf/state/schemas/SchemaLocationBuilder.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-api/src/main/yang/common/iana-afn-safi@2013-07-04.yang [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-api/src/main/yang/common/ietf-inet-types@2013-07-15.yang [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-api/src/main/yang/common/ietf-netconf-monitoring-extension@2013-12-10.yang [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-api/src/main/yang/common/ietf-netconf-monitoring@2010-10-04.yang [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-api/src/main/yang/common/ietf-netconf-notifications@2012-02-06.yang [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-api/src/main/yang/common/ietf-netconf@2011-06-01.yang [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-api/src/main/yang/common/ietf-network-topology@2015-06-08.yang [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-api/src/main/yang/common/ietf-network@2015-06-08.yang [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-api/src/main/yang/common/ietf-yang-types@2013-07-15.yang [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-api/src/main/yang/common/notifications@2008-07-14.yang [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-api/src/main/yang/common/org-openroadm-common-types@2018-10-19.yang [new file with mode: 0755]
tests/honeynode221/honeynode-plugin-api/src/main/yang/common/org-openroadm-equipment-states-types@2017-12-15.yang [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-api/src/main/yang/common/org-openroadm-otn-common-types@2017-12-15.yang [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-api/src/main/yang/common/org-openroadm-pm-types@2017-12-15.yang [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-api/src/main/yang/common/org-openroadm-pm@2018-10-19.yang [new file with mode: 0755]
tests/honeynode221/honeynode-plugin-api/src/main/yang/common/org-openroadm-port-types@2018-10-19.yang [new file with mode: 0755]
tests/honeynode221/honeynode-plugin-api/src/main/yang/common/org-openroadm-resource-types@2018-10-19.yang [new file with mode: 0755]
tests/honeynode221/honeynode-plugin-api/src/main/yang/common/org-openroadm-resource@2018-10-19.yang [new file with mode: 0755]
tests/honeynode221/honeynode-plugin-api/src/main/yang/common/org-openroadm-switching-pool-types@2017-12-15.yang [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-api/src/main/yang/common/org-openroadm-user-mgmt@2017-12-15.yang [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-device@2018-10-19.yang [new file with mode: 0755]
tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-ethernet-interfaces@2018-10-19.yang [new file with mode: 0755]
tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-interfaces@2017-06-26.yang [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-lldp@2018-10-19.yang [new file with mode: 0755]
tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-maintenance-loopback@2017-12-15.yang [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-maintenance-testsignal@2017-12-15.yang [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-media-channel-interfaces@2018-10-19.yang [new file with mode: 0755]
tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-network-media-channel-interfaces@2018-10-19.yang [new file with mode: 0755]
tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-optical-channel-interfaces@2018-10-19.yang [new file with mode: 0755]
tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-optical-transport-interfaces@2018-10-19.yang [new file with mode: 0755]
tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-otn-common@2017-06-26.yang [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-otn-odu-interfaces@2018-10-19.yang [new file with mode: 0755]
tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-otn-otu-interfaces@2018-10-19.yang [new file with mode: 0755]
tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-physical-types@2018-10-19.yang [new file with mode: 0755]
tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-swdl@2018-10-19.yang [new file with mode: 0755]
tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-syslog@2017-12-15.yang [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/asciidoc/Readme.adoc [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/pom.xml [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/DeviceBindingDataBrokerProvider.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/DeviceModule.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/DeviceNotificationModule.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/DeviceReaderModule.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/DeviceRpcModule.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/DeviceWriterModule.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/configuration/DeviceConfiguration.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/configuration/DeviceConfigurationModule.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/configuration/NetconfConfiguration.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/configuration/NetconfConfigurationModule.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/configuration/PmConfiguration.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/configuration/PmConfigurationModule.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/notifications/DeviceNotificationProducer.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/read/DeviceReaderFactory.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/read/DummyMonitoringService.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/read/PmReaderFactory.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/rpcs/ConnectionPortTrailService.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/tools/DefaultDeviceFactory.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/tools/DefaultNetconfFactory.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/tools/DefaultPmListFactory.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/write/DeviceChangeListener.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/write/DeviceWriterFactory.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/src/main/resources/honeycomb-minimal-resources/config/device/NamespaceTrimmer.xslt [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/src/main/resources/honeycomb-minimal-resources/config/device/OperToConfig.xsl [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/src/main/resources/honeycomb-minimal-resources/config/device/config.xsl [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/src/test/java/io/fd/honeycomb/transportpce/device/test/CreateDeviceFromXMLFileTest.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/src/test/java/io/fd/honeycomb/transportpce/device/test/CreatePmListFromXMLFileTest.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/src/test/java/io/fd/honeycomb/transportpce/device/test/DeviceOperToConfig.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/src/test/java/io/fd/honeycomb/transportpce/device/test/DirectoryWatchTest.java [new file with mode: 0644]
tests/honeynode221/honeynode-plugin-impl/src/test/java/io/fd/honeycomb/transportpce/device/test/RestAPICallsTest.java [new file with mode: 0644]
tests/honeynode221/log/honeycomb/honeycomb.log [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/asciidoc/Readme.adoc [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/pom.xml [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/InitializationException.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/activation/ActivationConfig.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/activation/ActivationModule.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/activation/ActiveModuleProvider.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/activation/ActiveModules.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/cfgattrs/CfgAttrsModule.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/cfgattrs/HoneycombConfiguration.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/BindingDataBrokerProvider.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/ConfigAndOperationalPipelineModule.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/DOMNotificationServiceProvider.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/DataStoreProvider.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/DataTreeProvider.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/HoneycombBindingDataBrokerProvider.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/HoneycombDOMBrokerProvider.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/HoneycombDOMDataBrokerProvider.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/HoneycombDOMRpcServiceProvider.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/HoneycombNotificationManagerProvider.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/InmemoryDOMDataBrokerProvider.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/ModifiableDTDelegProvider.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/PersistedConfigInitializerProvider.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/PersistingDataTreeProvider.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/RpcRegistryBuilderProvider.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/RpcRegistryProvider.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/config/WriterRegistryProvider.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/context/ContextPipelineModule.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/context/HoneycombContextDOMDataBrokerProvider.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/context/ModifiableDTMgrProvider.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/context/PersistedContextInitializerProvider.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/context/RealtimeMappingContextProvider.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/oper/ReadableDTDelegProvider.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/oper/ReaderRegistryProvider.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/initializer/DeviceChangeListener.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/initializer/InitializerPipelineModule.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/initializer/InitializerRegistryAdapter.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/initializer/InitializerRegistryAdapterProvider.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/initializer/ModifiableDTDelegInitProvider.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/schema/ModuleInfoBackedCtxProvider.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/schema/ResourceLoader.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/schema/SchemaModule.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/schema/SchemaServiceProvider.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/schema/SerializerProvider.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/schema/YangBindingProviderModule.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/schema/YangModuleMappingIndex.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/schema/YangModulesProvider.java [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/resources/honeycomb-minimal-resources/cert/honeycomb-keystore [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/resources/honeycomb-minimal-resources/config/WEB-INF/web.xml [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/resources/honeycomb-minimal-resources/config/activation.json [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/resources/honeycomb-minimal-resources/config/honeycomb.json [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/resources/honeycomb-minimal-resources/config/logback.xml [new file with mode: 0644]
tests/honeynode221/minimal-distribution-core/src/main/resources/honeycomb-minimal-resources/honeycomb-tpce [new file with mode: 0755]
tests/honeynode221/minimal-distribution/asciidoc/Readme.adoc [new file with mode: 0644]
tests/honeynode221/minimal-distribution/pom.xml [new file with mode: 0644]
tests/honeynode221/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/Main.java [new file with mode: 0644]
tests/honeynode221/netconf-netty-util/.gitignore [new file with mode: 0644]
tests/honeynode221/netconf-netty-util/pom.xml [new file with mode: 0644]
tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/AbstractChannelInitializer.java [new file with mode: 0644]
tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/AbstractNetconfSession.java [new file with mode: 0644]
tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/AbstractNetconfSessionNegotiator.java [new file with mode: 0644]
tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/BufferedWriter.java [new file with mode: 0644]
tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/ChunkedFramingMechanismEncoder.java [new file with mode: 0644]
tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/EOMFramingMechanismEncoder.java [new file with mode: 0644]
tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/FramingMechanismHandlerFactory.java [new file with mode: 0644]
tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/NetconfChunkAggregator.java [new file with mode: 0644]
tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/NetconfEOMAggregator.java [new file with mode: 0644]
tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/NetconfEXICodec.java [new file with mode: 0644]
tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/NetconfEXIToMessageDecoder.java [new file with mode: 0644]
tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/NetconfHelloMessageToXMLEncoder.java [new file with mode: 0644]
tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/NetconfMessageToEXIEncoder.java [new file with mode: 0644]
tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/NetconfMessageToXMLEncoder.java [new file with mode: 0644]
tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/NetconfXMLToHelloMessageDecoder.java [new file with mode: 0644]
tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/NetconfXMLToMessageDecoder.java [new file with mode: 0644]
tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/ThreadLocalTransformers.java [new file with mode: 0644]
tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/exi/EXIParameters.java [new file with mode: 0644]
tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/exi/NetconfStartExiMessage.java [new file with mode: 0644]
tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/ssh/authentication/AuthenticationHandler.java [new file with mode: 0644]
tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/ssh/authentication/LoginPassword.java [new file with mode: 0644]
tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/ssh/authentication/PublicKeyAuth.java [new file with mode: 0644]
tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/ssh/client/AsyncSshHandler.java [new file with mode: 0644]
tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/ssh/client/AsyncSshHandlerReader.java [new file with mode: 0644]
tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/ssh/client/AsyncSshHandlerWriter.java [new file with mode: 0644]
tests/honeynode221/netconf/asciidoc/Readme.adoc [new file with mode: 0644]
tests/honeynode221/netconf/pom.xml [new file with mode: 0644]
tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/HoneycombNotification2NetconfProvider.java [new file with mode: 0644]
tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfBindingBrokerProvider.java [new file with mode: 0644]
tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfConfigurationModule.java [new file with mode: 0644]
tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfMdsalMapperProvider.java [new file with mode: 0644]
tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfModule.java [new file with mode: 0644]
tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfMonitoringMapperProvider.java [new file with mode: 0644]
tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfMonitoringReaderFactoryProvider.java [new file with mode: 0644]
tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfMonitoringServiceProvider.java [new file with mode: 0644]
tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfNotificationMapperProvider.java [new file with mode: 0644]
tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfNotificationsReaderFactoryProvider.java [new file with mode: 0644]
tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfReadersModule.java [new file with mode: 0644]
tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfServerDispatcherProvider.java [new file with mode: 0644]
tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfSshServerProvider.java [new file with mode: 0644]
tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfTcpServerProvider.java [new file with mode: 0644]
tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NettyThreadGroupProvider.java [new file with mode: 0644]
tests/honeynode221/netconf/src/main/resources/honeycomb-minimal-resources/config/netconf-whitelist.xml [new file with mode: 0644]
tests/honeynode221/netconf/src/main/resources/honeycomb-minimal-resources/config/netconf.json [new file with mode: 0644]
tests/honeynode221/pom.xml [new file with mode: 0644]
tests/honeynode221/restconf/asciidoc/Readme.adoc [new file with mode: 0644]
tests/honeynode221/restconf/pom.xml [new file with mode: 0644]
tests/honeynode221/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/HttpConnectorProvider.java [new file with mode: 0644]
tests/honeynode221/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/HttpsConnectorProvider.java [new file with mode: 0644]
tests/honeynode221/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/JettyServerProvider.java [new file with mode: 0644]
tests/honeynode221/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/JettyServerStarter.java [new file with mode: 0644]
tests/honeynode221/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/RestconfConfiguration.java [new file with mode: 0644]
tests/honeynode221/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/RestconfConfigurationModule.java [new file with mode: 0644]
tests/honeynode221/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/RestconfModule.java [new file with mode: 0644]
tests/honeynode221/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/RestconfProvider.java [new file with mode: 0644]
tests/honeynode221/restconf/src/main/resources/honeycomb-minimal-resources/config/restconf-whitelist.xml [new file with mode: 0644]
tests/honeynode221/restconf/src/main/resources/honeycomb-minimal-resources/config/restconf.json [new file with mode: 0644]
tests/sample_configs/openroadm/2.2.1/oper-ROADMA.xml [new file with mode: 0644]
tests/sample_configs/openroadm/2.2.1/oper-ROADMB.xml [new file with mode: 0644]
tests/sample_configs/openroadm/2.2.1/oper-ROADMC.xml [new file with mode: 0644]
tests/sample_configs/openroadm/2.2.1/oper-XPDRA.xml [new file with mode: 0644]
tests/sample_configs/openroadm/2.2.1/oper-XPDRC.xml [new file with mode: 0644]

diff --git a/tests/buildHoneynode221.sh b/tests/buildHoneynode221.sh
new file mode 100755 (executable)
index 0000000..4f2e3ba
--- /dev/null
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+set -e
+
+rm -rf honeynode221/honeynode-plugin-impl/src/main/resources/honeycomb-minimal-resources/config/yang
+mkdir -p honeynode221/honeynode-plugin-impl/src/main/resources/honeycomb-minimal-resources/config/yang
+cp honeynode221/honeynode-plugin-api/src/main/yang/common/* honeynode221/honeynode-plugin-impl/src/main/resources/honeycomb-minimal-resources/config/yang
+cp honeynode221/honeynode-plugin-api/src/main/yang/device221/* honeynode221/honeynode-plugin-impl/src/main/resources/honeycomb-minimal-resources/config/yang
+(cd honeynode221 && mvn clean install -DskipTests -Dcheckstyle.skip -s fd_io_honeycomb_settings.xml)
+chmod +x ./honeynode221/honeynode-distribution/target/honeynode-distribution-1.18.01-hc/honeynode-distribution-1.18.01/honeycomb-tpce
+
+exit $?
diff --git a/tests/honeynode221/README b/tests/honeynode221/README
new file mode 100644 (file)
index 0000000..f7158d9
--- /dev/null
@@ -0,0 +1,30 @@
+= This is a Honeycomb distribution
+
+Built from: io.fd.honeycomb.transportpce/honeynode-distribution
+Version: 1.18.01
+
+https://wiki.fd.io/view/Honeycomb
+
+== Structure
+(under folder honeynode-distribution/target/honeynode-distribution-1.18.0.1-hc/honeynode-distribution-1.18.0.1)
+
+Structure of the distribution:
+
+=== Config
+Folder config contains any configuration that's exposed by Honeycomb and its plugins
+
+=== Cert
+Keystore/Truststore for Restconf's HTTPS endpoint
+
+=== Modules
+Folder modules contains text files with list of modules to be installed into Honeycomb.
+Those modules bring up Honeycomb's infrastructure as well as modules.
+
+=== Shell scripts
+honeycomb - Start Honeycomb
+honeycomb-debug - Start Honeycomb with JVM remote debug capabilities
+honeycomb-start - Start Honeycomb in background
+honeycomb-kill - Kill all running Honeycomb instances
+honeycomb-tpce - Start Honeycomb with port and initial config files options
+Eg : honeycomb-tpce 17830 sample-config-ROADM.xml
+
diff --git a/tests/honeynode221/fd_io_honeycomb_settings.xml b/tests/honeynode221/fd_io_honeycomb_settings.xml
new file mode 100644 (file)
index 0000000..2fd709f
--- /dev/null
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=2 tabstop=2: -->
+<!-- retrived from FD.io wiki https://wiki.fd.io/view/Honeycomb/Releases/1609/Setting_Up_Your_Dev_Environment#Setup_settings.xml -->
+<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
+
+  <profiles>
+    <profile>
+      <id>fd.io-release</id>
+      <repositories>
+        <repository>
+          <id>fd.io-mirror</id>
+          <name>fd.io-mirror</name>
+          <url>https://nexus.fd.io/content/groups/public/</url>
+          <releases>
+            <enabled>true</enabled>
+            <updatePolicy>never</updatePolicy>
+          </releases>
+          <snapshots>
+            <enabled>false</enabled>
+          </snapshots>
+        </repository>
+      </repositories>
+      <pluginRepositories>
+        <pluginRepository>
+          <id>fd.io-mirror</id>
+          <name>fd.io-mirror</name>
+          <url>https://nexus.fd.io/content/repositories/public/</url>
+          <releases>
+            <enabled>true</enabled>
+            <updatePolicy>never</updatePolicy>
+          </releases>
+          <snapshots>
+            <enabled>false</enabled>
+          </snapshots>
+        </pluginRepository>
+      </pluginRepositories>
+    </profile>
+
+    <profile>
+      <id>fd.io-snapshots</id>
+      <repositories>
+        <repository>
+          <id>fd.io-snapshot</id>
+          <name>fd.io-snapshot</name>
+          <url>https://nexus.fd.io/content/repositories/fd.io.snapshot/</url>
+          <releases>
+            <enabled>false</enabled>
+          </releases>
+          <snapshots>
+            <enabled>true</enabled>
+          </snapshots>
+        </repository>
+      </repositories>
+      <pluginRepositories>
+        <pluginRepository>
+          <id>fd.io-snapshot</id>
+          <name>fd.io-snapshot</name>
+          <url>https://nexus.fd.io/content/repositories/fd.io.snapshot/</url>
+          <releases>
+            <enabled>false</enabled>
+          </releases>
+          <snapshots>
+            <enabled>true</enabled>
+          </snapshots>
+        </pluginRepository>
+      </pluginRepositories>
+    </profile>
+    <profile>
+      <id>opendaylight-snapshots</id>
+      <repositories>
+        <repository>
+          <id>opendaylight-snapshot</id>
+          <name>opendaylight-snapshot</name>
+          <url>https://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/</url>
+          <releases>
+            <enabled>false</enabled>
+          </releases>
+          <snapshots>
+            <enabled>true</enabled>
+          </snapshots>
+        </repository>
+      </repositories>
+      <pluginRepositories>
+        <pluginRepository>
+          <id>opendaylight-shapshot</id>
+          <name>opendaylight-snapshot</name>
+          <url>https://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/</url>
+          <releases>
+            <enabled>false</enabled>
+          </releases>
+          <snapshots>
+            <enabled>true</enabled>
+          </snapshots>
+        </pluginRepository>
+      </pluginRepositories>
+    </profile>
+    <profile>
+      <id>opendaylight-release</id>
+      <repositories>
+        <repository>
+          <id>opendaylight-mirror</id>
+          <name>opendaylight-mirror</name>
+          <url>https://nexus.opendaylight.org/content/repositories/public/</url>
+          <releases>
+            <enabled>true</enabled>
+            <updatePolicy>never</updatePolicy>
+          </releases>
+          <snapshots>
+            <enabled>false</enabled>
+          </snapshots>
+        </repository>
+      </repositories>
+      <pluginRepositories>
+        <pluginRepository>
+          <id>opendaylight-mirror</id>
+          <name>opendaylight-mirror</name>
+          <url>https://nexus.opendaylight.org/content/repositories/public/</url>
+          <releases>
+            <enabled>true</enabled>
+            <updatePolicy>never</updatePolicy>
+          </releases>
+          <snapshots>
+            <enabled>false</enabled>
+          </snapshots>
+        </pluginRepository>
+      </pluginRepositories>
+    </profile>
+  </profiles>
+
+  <activeProfiles>
+    <activeProfile>fd.io-release</activeProfile>
+    <activeProfile>fd.io-snapshots</activeProfile>
+    <activeProfile>opendaylight-snapshots</activeProfile>
+    <activeProfile>opendaylight-release</activeProfile>
+  </activeProfiles>
+
+</settings>
diff --git a/tests/honeynode221/honeynode-common/asciidoc/Readme.adoc b/tests/honeynode221/honeynode-common/asciidoc/Readme.adoc
new file mode 100644 (file)
index 0000000..f8b7862
--- /dev/null
@@ -0,0 +1,3 @@
+= honeynode-common
+
+Overview of honeynode-common
\ No newline at end of file
diff --git a/tests/honeynode221/honeynode-common/pom.xml b/tests/honeynode221/honeynode-common/pom.xml
new file mode 100644 (file)
index 0000000..78ed932
--- /dev/null
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2018 Orange and others.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+You may not use this file except in compliance with the License.
+You may obtain a copy of the License at:http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<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>
+        <groupId>io.fd.honeycomb.common</groupId>
+        <artifactId>impl-parent</artifactId>
+        <version>1.18.01</version>
+    </parent>
+
+    <groupId>io.fd.honeycomb.transportpce</groupId>
+    <artifactId>honeynode-common</artifactId>
+    <version>1.18.01</version>
+    <packaging>bundle</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-binding-broker-impl</artifactId>
+            <version>1.6.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-binding-api</artifactId>
+            <version>1.6.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-data-codec-xml</artifactId>
+            <version>1.2.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-data-codec-gson</artifactId>
+            <version>1.2.0</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/tests/honeynode221/honeynode-common/src/main/java/io/fd/honeycomb/transportpce/binding/converter/AbstractDataObjectConverter.java b/tests/honeynode221/honeynode-common/src/main/java/io/fd/honeycomb/transportpce/binding/converter/AbstractDataObjectConverter.java
new file mode 100644 (file)
index 0000000..6b021ea
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2018 AT&T and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.transportpce.binding.converter;
+
+import com.google.common.base.Preconditions;
+
+import io.fd.honeycomb.transportpce.binding.converter.api.DataObjectConverter;
+
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Optional;
+
+import javax.annotation.Nonnull;
+
+import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.Notification;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Converts XML and {@link DataObject} vice versa.
+ *
+ */
+public abstract class AbstractDataObjectConverter implements DataObjectConverter {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractDataObjectConverter.class);
+
+    private final SchemaContext schemaContext;
+    private final BindingNormalizedNodeSerializer codecRegistry;
+
+    /**
+     * This is the default constructor, which should be used.
+     *
+     * @param schemaContext schema context for converter
+     * @param codecRegistry codec registry used for converting
+     *
+     */
+    protected AbstractDataObjectConverter(SchemaContext schemaContext, BindingNormalizedNodeSerializer codecRegistry) {
+        this.schemaContext = schemaContext;
+        this.codecRegistry = codecRegistry;
+    }
+
+    public SchemaContext getSchemaContext() {
+        return schemaContext;
+    }
+
+    public BindingNormalizedNodeSerializer getCodecRegistry() {
+        return codecRegistry;
+    }
+
+    /**
+     * Transforms the given input {@link NormalizedNode} into the given
+     * {@link DataObject}.
+     *
+     * @param normalizedNode normalized node you want to convert
+     * @param rootNode {@link QName} of converted normalized node root
+     *
+     * <p>
+     * The input object should be {@link ContainerNode}
+     * </p>
+     */
+    @Override
+    @SuppressWarnings("unchecked")
+    public <T extends DataObject> Optional<T> getDataObject(
+            @Nonnull NormalizedNode<?, ?> normalizedNode,
+            @Nonnull QName rootNode) {
+        Preconditions.checkNotNull(normalizedNode);
+        if (normalizedNode instanceof ContainerNode) {
+            YangInstanceIdentifier.PathArgument directChildIdentifier =
+                    YangInstanceIdentifier.of(rootNode).getLastPathArgument();
+            Optional<NormalizedNode<?, ?>> directChild =
+                    NormalizedNodes.getDirectChild(normalizedNode, directChildIdentifier).toJavaUtil();
+            if (!directChild.isPresent()) {
+                throw new IllegalStateException(String.format("Could not get the direct child of %s", rootNode));
+            }
+            normalizedNode = directChild.get();
+        }
+        YangInstanceIdentifier rootNodeYangInstanceIdentifier = YangInstanceIdentifier.of(rootNode);
+
+        Map.Entry<?, ?> bindingNodeEntry =
+                codecRegistry.fromNormalizedNode(rootNodeYangInstanceIdentifier, normalizedNode);
+        if (bindingNodeEntry == null) {
+            return Optional.empty();
+        }
+        return Optional.ofNullable((T) bindingNodeEntry.getValue());
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <T extends DataObject> Optional<T> getDataObjectFromRpc(
+            @Nonnull NormalizedNode<?, ?> normalizedNode,
+            @Nonnull SchemaPath rpcSchemaPath) {
+
+        if (! (normalizedNode instanceof ContainerNode)) {
+            LOG.error("converting normalized node is not ContainerNode. It's actual type is {}",
+                    normalizedNode.getClass().getSimpleName());
+            return Optional.empty();
+        }
+        T rpcDataObject = (T) codecRegistry.fromNormalizedNodeRpcData(rpcSchemaPath, (ContainerNode) normalizedNode);
+        return Optional.ofNullable(rpcDataObject);
+    }
+
+    @Override
+    public <T extends DataObject> Optional<NormalizedNode<?, ?>> toNormalizedNodes(@Nonnull T object,
+            Class<T> dataObjectClass) {
+        Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedNode =
+                codecRegistry.toNormalizedNode(InstanceIdentifier.create(dataObjectClass), object);
+        return Optional.ofNullable(normalizedNode.getValue());
+    }
+
+    @Override
+    public <T extends DataObject> ConvertType<T> dataContainer() {
+        return (object, objectClass) -> {
+            NormalizedNode<?, ?> value =
+                    getCodecRegistry().toNormalizedNode(InstanceIdentifier.create(objectClass), object).getValue();
+            return Optional.ofNullable(value);
+        };
+    }
+
+    @Override
+    public <T extends DataContainer> ConvertType<T> rpcData() {
+        return (object, objectClass) -> {
+            ContainerNode normalizedNodeRpcData = getCodecRegistry().toNormalizedNodeRpcData(object);
+            return Optional.ofNullable(normalizedNodeRpcData);
+        };
+    }
+
+    @Override
+    public <T extends Notification> ConvertType<T> notification() {
+        return (object, objectClass) -> {
+            ContainerNode normalizedNodeNotification = getCodecRegistry().toNormalizedNodeNotification(object);
+            return Optional.ofNullable(normalizedNodeNotification);
+        };
+    }
+}
diff --git a/tests/honeynode221/honeynode-common/src/main/java/io/fd/honeycomb/transportpce/binding/converter/JSONDataObjectConverter.java b/tests/honeynode221/honeynode-common/src/main/java/io/fd/honeycomb/transportpce/binding/converter/JSONDataObjectConverter.java
new file mode 100644 (file)
index 0000000..657672c
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2018 AT&T and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.transportpce.binding.converter;
+
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+
+import io.fd.honeycomb.transportpce.binding.converter.api.DataObjectConverter;
+import io.fd.honeycomb.transportpce.test.common.DataStoreContext;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.Optional;
+
+import javax.annotation.Nonnull;
+
+import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
+import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactory;
+import org.opendaylight.yangtools.yang.data.codec.gson.JSONNormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.codec.gson.JsonParserStream;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class JSONDataObjectConverter extends AbstractDataObjectConverter {
+
+    private static final Logger LOG = LoggerFactory.getLogger(JSONDataObjectConverter.class);
+
+    private JSONDataObjectConverter(SchemaContext schemaContext, BindingNormalizedNodeCodecRegistry codecRegistry) {
+        super(schemaContext, codecRegistry);
+    }
+
+    /**
+     * extracts codec and schema context (?).
+     *
+     * @param dataStoreContextUtil datastore context util used to extract codec and schema context
+     * @return {@link AbstractDataObjectConverter}
+     */
+    public static DataObjectConverter createWithDataStoreUtil(@Nonnull DataStoreContext dataStoreContextUtil) {
+        return new JSONDataObjectConverter(dataStoreContextUtil.getSchemaContext(),
+                dataStoreContextUtil.getBindingToNormalizedNodeCodec());
+    }
+
+    /**
+     * extracts codec and schema context (?).
+     *
+     * @param schemaContext schema context for converter
+     * @param codecRegistry codec registry used for converting
+     * @return converter
+     */
+    public static DataObjectConverter createWithSchemaContext(@Nonnull SchemaContext schemaContext,
+            @Nonnull BindingNormalizedNodeCodecRegistry codecRegistry) {
+        return new JSONDataObjectConverter(schemaContext, codecRegistry);
+    }
+
+    /**
+     * Transforms the JSON input stream into normalized nodes.
+     *
+     * @param inputStream of the given JSON
+     * @return {@link Optional} instance of {@link NormalizedNode}.
+     */
+    @Override
+    public Optional<NormalizedNode<? extends YangInstanceIdentifier.PathArgument, ?>> transformIntoNormalizedNode(
+            @Nonnull InputStream inputStream) {
+        try {
+            JsonReader reader = new JsonReader(new InputStreamReader(inputStream, "UTF-8"));
+            return parseInputJSON(reader);
+        } catch (IOException e) {
+            LOG.warn(e.getMessage(), e);
+            return Optional.empty();
+        }
+    }
+
+    @Override
+    public Optional<NormalizedNode<? extends YangInstanceIdentifier.PathArgument, ?>> transformIntoNormalizedNode(
+            @Nonnull Reader inputReader, SchemaNode parentSchema) {
+        throw new UnsupportedOperationException("Not Implemented yet");
+    }
+
+    @Override
+    public Optional<NormalizedNode<? extends YangInstanceIdentifier.PathArgument, ?>> transformIntoNormalizedNode(
+            @Nonnull Reader inputReader) {
+        JsonReader reader = new JsonReader(inputReader);
+        return parseInputJSON(reader);
+    }
+
+    @Override
+    public <T extends DataObject> Writer writerFromDataObject(@Nonnull DataObject object, Class<T> dataObjectClass,
+            ConvertType<T> convertType) {
+        Writer writer = new StringWriter();
+        JsonWriter jsonWriter = new JsonWriter(writer);
+        JSONCodecFactory jsonCodecFactory = JSONCodecFactory.createLazy(getSchemaContext());
+        NormalizedNodeStreamWriter create =
+                JSONNormalizedNodeStreamWriter.createExclusiveWriter(jsonCodecFactory, null, null, jsonWriter);
+
+        try (NormalizedNodeWriter normalizedNodeWriter = NormalizedNodeWriter.forStreamWriter(create);) {
+            normalizedNodeWriter
+                    .write(convertType.toNormalizedNodes(dataObjectClass.cast(object), dataObjectClass).get());
+        } catch (IOException ioe) {
+            throw new IllegalStateException(ioe);
+        }
+        return writer;
+    }
+
+    @Override
+    public <T extends DataObject> Writer writerFromRpcDataObject(@Nonnull DataObject object, Class<T> dataObjectClass,
+            ConvertType<T> convertType, QName rpcOutputQName, String rpcName) {
+        return null;
+    }
+
+    /**
+     * Parses the input json with concrete implementation of {@link JsonParserStream}.
+     *
+     * @param reader of the given JSON
+     *
+     */
+    private Optional<NormalizedNode<? extends YangInstanceIdentifier.PathArgument, ?>> parseInputJSON(
+            JsonReader reader) {
+        NormalizedNodeResult result = new NormalizedNodeResult();
+        try (NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
+            JsonParserStream jsonParser = JsonParserStream.create(streamWriter, getSchemaContext(),
+            getSchemaContext())) {
+            jsonParser.parse(reader);
+        } catch (IOException e) {
+            LOG.warn("An error {} occured during parsing Json input stream", e.getMessage(), e);
+            return Optional.empty();
+        }
+        return Optional.ofNullable(result.getResult());
+    }
+
+}
diff --git a/tests/honeynode221/honeynode-common/src/main/java/io/fd/honeycomb/transportpce/binding/converter/XMLDataObjectConverter.java b/tests/honeynode221/honeynode-common/src/main/java/io/fd/honeycomb/transportpce/binding/converter/XMLDataObjectConverter.java
new file mode 100644 (file)
index 0000000..8b50035
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2018 AT&T and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.transportpce.binding.converter;
+
+import io.fd.honeycomb.transportpce.test.common.DataStoreContext;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.net.URISyntaxException;
+import java.util.Optional;
+
+import javax.annotation.Nonnull;
+import javax.xml.XMLConstants;
+import javax.xml.parsers.FactoryConfigurationError;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
+import org.opendaylight.yangtools.yang.data.codec.xml.XMLStreamNormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.SAXException;
+
+public class XMLDataObjectConverter extends AbstractDataObjectConverter {
+
+    private static final Logger LOG = LoggerFactory.getLogger(XMLDataObjectConverter.class);
+
+    private final XMLInputFactory xmlInputFactory;
+
+    /**
+     * This is the default constructor, which should be used.
+     *
+     * @param schemaContext schema context for converter
+     * @param codecRegistry codec registry used for converting
+     *
+     */
+    private XMLDataObjectConverter(SchemaContext schemaContext, BindingNormalizedNodeSerializer codecRegistry) {
+        super(schemaContext, codecRegistry);
+        this.xmlInputFactory = XMLInputFactory.newInstance();
+    }
+
+    /**
+     * Extract codec and schema context (?).
+     *
+     * @param dataStoreContextUtil datastore context util used to extract codec and schema context
+     * @return {@link AbstractDataObjectConverter}
+     */
+    public static XMLDataObjectConverter createWithDataStoreUtil(@Nonnull DataStoreContext dataStoreContextUtil) {
+        BindingNormalizedNodeSerializer bindingToNormalizedNodeCodec =
+                dataStoreContextUtil.getBindingToNormalizedNodeCodec();
+        return new XMLDataObjectConverter(dataStoreContextUtil.getSchemaContext(), bindingToNormalizedNodeCodec);
+    }
+
+    /**
+     * Extract codec and schema context (?).
+     *
+     * @param schemaContext schema context for converter
+     * @param codecRegistry codec registry used for converting
+     * @return new {@link XMLDataObjectConverter}
+     */
+    public static XMLDataObjectConverter createWithSchemaContext(@Nonnull SchemaContext schemaContext,
+            @Nonnull BindingNormalizedNodeSerializer codecRegistry) {
+        return new XMLDataObjectConverter(schemaContext, codecRegistry);
+    }
+
+    /**
+     * Transforms the XML input stream into normalized nodes.
+     *
+     * @param inputStream of the given XML
+     * @return {@link Optional} instance of {@link NormalizedNode}.
+     */
+    @Override
+    public Optional<NormalizedNode<? extends YangInstanceIdentifier.PathArgument, ?>> transformIntoNormalizedNode(
+            @Nonnull InputStream inputStream) {
+        try {
+            XMLStreamReader reader = this.xmlInputFactory.createXMLStreamReader(inputStream);
+            return parseInputXML(reader);
+        } catch (XMLStreamException e) {
+            LOG.warn(e.getMessage(), e);
+            return Optional.empty();
+        }
+    }
+
+    @Override
+    public Optional<NormalizedNode<? extends YangInstanceIdentifier.PathArgument, ?>> transformIntoNormalizedNode(
+            @Nonnull Reader inputReader, SchemaNode parentSchema) {
+        try {
+            XMLStreamReader reader = this.xmlInputFactory.createXMLStreamReader(inputReader);
+            return parseInputXML(reader, parentSchema);
+        } catch (XMLStreamException e) {
+            LOG.warn(e.getMessage(), e);
+            return Optional.empty();
+        }
+    }
+
+    /**
+     * Transforms the XML input stream into normalized nodes.
+     *
+     * @param inputReader of the given XML
+     * @return {@link Optional} instance of {@link NormalizedNode}.
+     */
+    @Override
+    public Optional<NormalizedNode<? extends YangInstanceIdentifier.PathArgument, ?>> transformIntoNormalizedNode(
+            @Nonnull Reader inputReader) {
+        try {
+            XMLStreamReader reader = this.xmlInputFactory.createXMLStreamReader(inputReader);
+            return parseInputXML(reader);
+        } catch (XMLStreamException e) {
+            LOG.warn(e.getMessage(), e);
+            return Optional.empty();
+        }
+    }
+
+    @Override
+    public <T extends DataObject> Writer writerFromRpcDataObject(@Nonnull DataObject object, Class<T> dataObjectClass,
+            ConvertType<T> convertType, QName rpcOutputQName, String rpcName) {
+        Writer writer = new StringWriter();
+        XMLStreamWriter xmlStreamWriter = createXmlStreamWriter(writer);
+        SchemaPath rpcOutputSchemaPath = SchemaPath.create(true, QName.create(rpcOutputQName.getModule(), rpcName),
+                rpcOutputQName);
+        try (NormalizedNodeWriter normalizedNodeWriter = createWriterBackedNormalizedNodeWriter(xmlStreamWriter,
+                rpcOutputSchemaPath)) {
+            xmlStreamWriter.writeStartElement(XMLConstants.DEFAULT_NS_PREFIX,
+                    rpcOutputQName.getLocalName(), rpcOutputQName.getNamespace().toString());
+            xmlStreamWriter.writeDefaultNamespace(rpcOutputQName.getNamespace().toString());
+            NormalizedNode<?, ?> rpcOutputNormalizedNode = convertType.toNormalizedNodes(dataObjectClass.cast(object),
+                    dataObjectClass).get();
+            for (final NormalizedNode<?, ?> child : ((ContainerNode)rpcOutputNormalizedNode).getValue()) {
+                normalizedNodeWriter.write(child);
+            }
+            normalizedNodeWriter.flush();
+            xmlStreamWriter.writeEndElement();
+            xmlStreamWriter.flush();
+        } catch (IOException | XMLStreamException ioe) {
+            throw new IllegalStateException(ioe);
+        }
+        return writer;
+    }
+
+    /**
+     * Returns a {@link Writer}.
+     *
+     * @param convertType converter used of converting into normalized node
+     * @param dataObjectClass class of converting object
+     * @param object object you want to convert
+     *
+     */
+    @Override
+    public <T extends DataObject> Writer writerFromDataObject(@Nonnull DataObject object, Class<T> dataObjectClass,
+            ConvertType<T> convertType) {
+        Writer writer = new StringWriter();
+
+        try (NormalizedNodeWriter normalizedNodeWriter = createWriterBackedNormalizedNodeWriter(writer, null)) {
+            normalizedNodeWriter
+                    .write(convertType.toNormalizedNodes(dataObjectClass.cast(object), dataObjectClass).get());
+            normalizedNodeWriter.flush();
+        } catch (IOException ioe) {
+            throw new IllegalStateException(ioe);
+        }
+        return writer;
+    }
+
+    private Optional<NormalizedNode<? extends YangInstanceIdentifier.PathArgument, ?>> parseInputXML(
+            XMLStreamReader reader) {
+        return parseInputXML(reader, getSchemaContext());
+    }
+
+    private Optional<NormalizedNode<? extends YangInstanceIdentifier.PathArgument, ?>> parseInputXML(
+            XMLStreamReader reader, SchemaNode parentSchemaNode) {
+        NormalizedNodeResult result = new NormalizedNodeResult();
+        try (NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
+             XmlParserStream xmlParser = XmlParserStream.create(streamWriter, getSchemaContext(), parentSchemaNode)) {
+            xmlParser.parse(reader);
+        } catch (XMLStreamException | URISyntaxException | IOException | ParserConfigurationException
+                | SAXException e) {
+            LOG.warn("An error {} occured during parsing XML input stream", e.getMessage(), e);
+            return Optional.empty();
+        }
+        return Optional.ofNullable(result.getResult());
+    }
+
+    private NormalizedNodeWriter createWriterBackedNormalizedNodeWriter(Writer backingWriter, SchemaPath pathToParent) {
+        XMLStreamWriter createXMLStreamWriter = createXmlStreamWriter(backingWriter);
+        NormalizedNodeStreamWriter streamWriter;
+        if (pathToParent == null) {
+            streamWriter = XMLStreamNormalizedNodeStreamWriter.create(createXMLStreamWriter,
+                    getSchemaContext());
+        } else {
+            streamWriter = XMLStreamNormalizedNodeStreamWriter.create(createXMLStreamWriter,
+                    getSchemaContext(), pathToParent);
+        }
+        return NormalizedNodeWriter.forStreamWriter(streamWriter);
+    }
+
+    private NormalizedNodeWriter createWriterBackedNormalizedNodeWriter(XMLStreamWriter backingWriter,
+            SchemaPath pathToParent) {
+        NormalizedNodeStreamWriter streamWriter;
+        if (pathToParent == null) {
+            streamWriter = XMLStreamNormalizedNodeStreamWriter.create(backingWriter,
+                    getSchemaContext());
+        } else {
+            streamWriter = XMLStreamNormalizedNodeStreamWriter.create(backingWriter,
+                    getSchemaContext(), pathToParent);
+        }
+        return NormalizedNodeWriter.forStreamWriter(streamWriter);
+    }
+
+    private static XMLStreamWriter createXmlStreamWriter(Writer backingWriter) {
+        XMLStreamWriter xmlStreamWriter;
+        try {
+            XMLOutputFactory factory = XMLOutputFactory.newFactory();
+            factory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, true);
+            xmlStreamWriter = factory.createXMLStreamWriter(backingWriter);
+        } catch (XMLStreamException | FactoryConfigurationError e) {
+            LOG.error("Error [{}] while creating XML writer", e.getMessage(), e);
+            throw new IllegalStateException(e);
+        }
+        return xmlStreamWriter;
+    }
+}
diff --git a/tests/honeynode221/honeynode-common/src/main/java/io/fd/honeycomb/transportpce/binding/converter/api/DataObjectConverter.java b/tests/honeynode221/honeynode-common/src/main/java/io/fd/honeycomb/transportpce/binding/converter/api/DataObjectConverter.java
new file mode 100644 (file)
index 0000000..4dcc17b
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2018 AT&T and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.transportpce.binding.converter.api;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.Optional;
+
+import javax.annotation.Nonnull;
+
+import org.opendaylight.yangtools.yang.binding.DataContainer;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.Notification;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+public interface DataObjectConverter {
+
+    <T extends DataObject> Optional<T> getDataObject(
+            @Nonnull NormalizedNode<? extends YangInstanceIdentifier.PathArgument, ?> normalizedNode,
+            @Nonnull QName rootNode);
+
+    <T extends DataObject> Optional<T> getDataObjectFromRpc(
+            @Nonnull NormalizedNode<? extends YangInstanceIdentifier.PathArgument, ?> normalizedNode,
+            @Nonnull SchemaPath rpcSchemaPath);
+
+    Optional<NormalizedNode<? extends YangInstanceIdentifier.PathArgument, ?>> transformIntoNormalizedNode(
+            @Nonnull InputStream inputStream);
+
+    Optional<NormalizedNode<? extends YangInstanceIdentifier.PathArgument, ?>> transformIntoNormalizedNode(
+            @Nonnull Reader inputReader, SchemaNode parentSchema);
+
+    Optional<NormalizedNode<? extends YangInstanceIdentifier.PathArgument, ?>> transformIntoNormalizedNode(
+            @Nonnull Reader inputReader);
+
+    <T extends DataObject> Writer writerFromDataObject(@Nonnull DataObject object, Class<T> dataObjectClass,
+            ConvertType<T> convertType);
+
+    <T extends DataObject> Writer writerFromRpcDataObject(@Nonnull DataObject object, Class<T> dataObjectClass,
+            ConvertType<T> convertType, QName rpcOutputQName, String rpcName);
+
+    <T extends DataObject> Optional<NormalizedNode<?, ?>> toNormalizedNodes(@Nonnull T object,
+            Class<T> dataObjectClass);
+
+    public interface ConvertType<T> {
+        Optional<NormalizedNode<?, ?>> toNormalizedNodes(T object, Class<T> clazz);
+    }
+
+    /**
+     * Returns a converter for {@link DataObject} container type.
+     *
+     * @return {@link ConvertType} converter for {@link DataContainer}
+     */
+    <T extends DataObject> ConvertType<T> dataContainer();
+
+    /**
+     * Returns converter for {@link DataContainer} rpc type.
+     *
+     * @return {@link ConvertType} converter for {@link DataContainer}
+     * representing rpc data
+     */
+    <T extends DataContainer> ConvertType<T> rpcData();
+
+    /**
+     * Return converter for {@link Notification}.
+     *
+     * @return {@link ConvertType} converter for {@link Notification}
+     */
+    <T extends Notification> ConvertType<T> notification();
+
+}
diff --git a/tests/honeynode221/honeynode-common/src/main/java/io/fd/honeycomb/transportpce/test/common/DataStoreContext.java b/tests/honeynode221/honeynode-common/src/main/java/io/fd/honeycomb/transportpce/test/common/DataStoreContext.java
new file mode 100644 (file)
index 0000000..9af16fa
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018 AT&T and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.transportpce.test.common;
+
+import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public interface DataStoreContext {
+
+//    DataBroker getDataBroker();
+//
+//    DOMDataBroker getDOMDataBroker();
+//
+//    NotificationService createNotificationService();
+//
+//    NotificationPublishService createNotificationPublishService();
+
+    SchemaContext getSchemaContext();
+
+    BindingNormalizedNodeCodecRegistry getBindingToNormalizedNodeCodec();
+
+//    NotificationService getNotificationService();
+//
+//    NotificationPublishService getNotificationPublishService();
+
+}
diff --git a/tests/honeynode221/honeynode-common/src/main/java/io/fd/honeycomb/transportpce/test/common/DataStoreContextImpl.java b/tests/honeynode221/honeynode-common/src/main/java/io/fd/honeycomb/transportpce/test/common/DataStoreContextImpl.java
new file mode 100644 (file)
index 0000000..c7ebc08
--- /dev/null
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2018 AT&T and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.transportpce.test.common;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Optional;
+import java.util.ServiceLoader;
+
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.mdsal.binding.generator.impl.GeneratedClassLoadingStrategy;
+import org.opendaylight.mdsal.binding.generator.impl.ModuleInfoBackedContext;
+import org.opendaylight.mdsal.binding.generator.util.BindingRuntimeContext;
+import org.opendaylight.mdsal.binding.generator.util.JavassistUtils;
+import org.opendaylight.mdsal.dom.api.DOMSchemaService;
+import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator;
+import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.util.ListenerRegistry;
+import org.opendaylight.yangtools.yang.binding.YangModelBindingProvider;
+import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javassist.ClassPool;
+
+public class DataStoreContextImpl implements DataStoreContext {
+
+    private static final Logger LOG = LoggerFactory.getLogger(DataStoreContextImpl.class);
+
+//    private final Map<LogicalDatastoreType, DOMStore> datastores;
+    private final SchemaContextHolder mockedSchemaContext;
+//    private final DOMNotificationRouter domNotificationRouter;
+//    private final DOMDataBroker domDataBroker;
+//    private final DataBroker dataBroker;
+//    private final NotificationService notificationService;
+//    private final NotificationPublishService notificationPublishService;
+
+    public DataStoreContextImpl() {
+        this(false);
+    }
+
+    public DataStoreContextImpl(boolean fromClasspath) {
+        this.mockedSchemaContext = new SchemaContextHolder(fromClasspath);
+//        this.datastores = createDatastores();
+//        this.domNotificationRouter = DOMNotificationRouter.create(16);
+//        this.domDataBroker = createDOMDataBroker();
+//        this.dataBroker = createDataBroker();
+//        this.notificationService = createNotificationService();
+//        this.notificationPublishService = createNotificationPublishService();
+//        for (ListenerRegistration<SchemaContextListener> listener : this.mockedSchemaContext.listeners) {
+//            listener.getInstance().onGlobalContextUpdated(this.mockedSchemaContext.schemaContext);
+//        }
+    }
+
+//    @Override
+//    public DataBroker getDataBroker() {
+//        return this.dataBroker;
+//    }
+//
+//    @Override
+//    public DOMDataBroker getDOMDataBroker() {
+//        return this.domDataBroker;
+//    }
+//
+//    @Override
+//    public NotificationService createNotificationService() {
+//        return new BindingDOMNotificationServiceAdapter(this.mockedSchemaContext.bindingStreamCodecs,
+//                this.domNotificationRouter);
+//    }
+//
+//    @Override
+//    public NotificationPublishService createNotificationPublishService() {
+//        return new BindingDOMNotificationPublishServiceAdapter(this.mockedSchemaContext.bindingToNormalized,
+//                this.domNotificationRouter);
+//    }
+
+    @Override
+    public SchemaContext getSchemaContext() {
+        return this.mockedSchemaContext.schemaContext;
+    }
+
+    @Override
+    public BindingNormalizedNodeCodecRegistry getBindingToNormalizedNodeCodec() {
+        return this.mockedSchemaContext.bindingStreamCodecs;
+    }
+
+//    @Override
+//    public NotificationService getNotificationService() {
+//        return this.notificationService;
+//    }
+//
+//    @Override
+//    public NotificationPublishService getNotificationPublishService() {
+//        return this.notificationPublishService;
+//    }
+//
+//    private DOMDataBroker createDOMDataBroker() {
+//        return new SerializedDOMDataBroker(this.datastores,
+//                MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor()));
+//    }
+//
+//    private ListeningExecutorService getDataTreeChangeListenerExecutor() {
+//        return MoreExecutors.newDirectExecutorService();
+//    }
+//
+//    private DataBroker createDataBroker() {
+//        return new BindingDOMDataBrokerAdapter(getDOMDataBroker(), this.mockedSchemaContext.bindingToNormalized);
+//    }
+//
+//    private Map<LogicalDatastoreType, DOMStore> createDatastores() {
+//        return ImmutableMap.<LogicalDatastoreType, DOMStore>builder()
+//                .put(LogicalDatastoreType.OPERATIONAL, createOperationalDatastore())
+//                .put(LogicalDatastoreType.CONFIGURATION, createConfigurationDatastore()).build();
+//    }
+//
+//    private DOMStore createConfigurationDatastore() {
+//        final InMemoryDOMDataStore store = new InMemoryDOMDataStore("CFG", getDataTreeChangeListenerExecutor());
+//        this.mockedSchemaContext.registerSchemaContextListener(store);
+//        return store;
+//    }
+//
+//    private DOMStore createOperationalDatastore() {
+//        final InMemoryDOMDataStore store = new InMemoryDOMDataStore("OPER", getDataTreeChangeListenerExecutor());
+//        this.mockedSchemaContext.registerSchemaContextListener(store);
+//        return store;
+//    }
+
+    private class SchemaContextHolder implements DOMSchemaService, SchemaContextProvider {
+
+        private final SchemaContext schemaContext;
+        private final ListenerRegistry<SchemaContextListener> listeners;
+        private final BindingNormalizedNodeCodecRegistry bindingStreamCodecs;
+        private final BindingToNormalizedNodeCodec bindingToNormalized;
+        private final ModuleInfoBackedContext moduleInfoBackedCntxt;
+
+        private SchemaContextHolder(boolean fromClasspath) {
+            List<YangModuleInfo> moduleInfos = loadModuleInfos();
+            this.moduleInfoBackedCntxt = ModuleInfoBackedContext.create();
+            this.schemaContext = getSchemaContext(moduleInfos);
+            this.listeners = ListenerRegistry.create();
+            this.bindingStreamCodecs = createBindingRegistry();
+            GeneratedClassLoadingStrategy loading = GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy();
+            this.bindingToNormalized = new BindingToNormalizedNodeCodec(loading, this.bindingStreamCodecs);
+            registerSchemaContextListener(this.bindingToNormalized);
+        }
+
+        @Override
+        public SchemaContext getSchemaContext() {
+            return this.schemaContext;
+        }
+
+        /**
+         * Get the schemacontext from loaded modules on classpath.
+         *
+         * @param moduleInfos a list of Yang module Infos
+         * @return SchemaContext a schema context
+         */
+        private SchemaContext getSchemaContext(List<YangModuleInfo> moduleInfos) {
+            this.moduleInfoBackedCntxt.addModuleInfos(moduleInfos);
+            Optional<SchemaContext> tryToCreateSchemaContext =
+                    this.moduleInfoBackedCntxt.tryToCreateSchemaContext().toJavaUtil();
+            if (!tryToCreateSchemaContext.isPresent()) {
+                LOG.error("Could not create the initial schema context. Schema context is empty");
+                throw new IllegalStateException();
+            }
+            return tryToCreateSchemaContext.get();
+        }
+
+        @Override
+        public SchemaContext getGlobalContext() {
+            return this.schemaContext;
+        }
+
+        @Override
+        public SchemaContext getSessionContext() {
+            return this.schemaContext;
+        }
+
+        @Override
+        public ListenerRegistration<SchemaContextListener> registerSchemaContextListener(
+                SchemaContextListener listener) {
+            return this.listeners.register(listener);
+        }
+
+        /**
+         * Loads all {@link YangModelBindingProvider} on the classpath.
+         *
+         * @return list of known {@link YangModuleInfo}
+         */
+        private List<YangModuleInfo> loadModuleInfos() {
+            List<YangModuleInfo> moduleInfos = new LinkedList<>();
+            ServiceLoader<YangModelBindingProvider> yangProviderLoader =
+                    ServiceLoader.load(YangModelBindingProvider.class);
+            for (YangModelBindingProvider yangModelBindingProvider : yangProviderLoader) {
+                moduleInfos.add(yangModelBindingProvider.getModuleInfo());
+                LOG.debug("Adding [{}] module into known modules", yangModelBindingProvider.getModuleInfo());
+            }
+            return moduleInfos;
+        }
+
+        /**
+         * Creates binding registry.
+         *
+         * @return BindingNormalizedNodeCodecRegistry the resulting binding registry
+         */
+        private BindingNormalizedNodeCodecRegistry createBindingRegistry() {
+            BindingRuntimeContext bindingContext = BindingRuntimeContext.create(this.moduleInfoBackedCntxt, this.schemaContext);
+            BindingNormalizedNodeCodecRegistry bindingNormalizedNodeCodecRegistry =
+                    new BindingNormalizedNodeCodecRegistry(
+                            StreamWriterGenerator.create(JavassistUtils.forClassPool(ClassPool.getDefault())));
+            bindingNormalizedNodeCodecRegistry.onBindingRuntimeContextUpdated(bindingContext);
+            return bindingNormalizedNodeCodecRegistry;
+        }
+    }
+}
diff --git a/tests/honeynode221/honeynode-distribution/asciidoc/Readme.adoc b/tests/honeynode221/honeynode-distribution/asciidoc/Readme.adoc
new file mode 100644 (file)
index 0000000..608fb53
--- /dev/null
@@ -0,0 +1,3 @@
+= honeynode-distribution
+
+Overview of honeynode-distribution
\ No newline at end of file
diff --git a/tests/honeynode221/honeynode-distribution/pom.xml b/tests/honeynode221/honeynode-distribution/pom.xml
new file mode 100644 (file)
index 0000000..6521e3b
--- /dev/null
@@ -0,0 +1,76 @@
+<?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">
+
+  <parent>
+    <groupId>io.fd.honeycomb.common</groupId>
+    <artifactId>minimal-distribution-parent</artifactId>
+    <version>1.18.01</version>
+  </parent>
+
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>io.fd.honeycomb.transportpce</groupId>
+  <artifactId>honeynode-distribution</artifactId>
+  <version>1.18.01</version>
+
+  <properties>
+    <exec.parameters>-Xms128m -Xmx128m</exec.parameters>
+    <main.class>io.fd.honeycomb.infra.distro.Main</main.class>
+    <interfaces.mapping.version>1.18.01</interfaces.mapping.version>
+    <honeycomb.min.distro.version>1.18.01</honeycomb.min.distro.version>
+    <!--
+       Defines list of specific modules provided by the distribution
+       (adds them to base modules like NetconfModule and RestconfModule).
+
+       Module configuration is placed in 'modules' subdir of the target distro folder.
+       Modules can be disabled by commenting them out in the pom.xml
+       or modules configuration file.
+     -->
+    <distribution.modules>
+        io.fd.honeycomb.transportpce.device.DeviceModule,
+        io.fd.honeycomb.transportpce.device.DeviceWriterModule,
+        io.fd.honeycomb.transportpce.device.DeviceReaderModule,
+        io.fd.honeycomb.transportpce.device.DeviceRpcModule,
+        io.fd.honeycomb.transportpce.device.DeviceNotificationModule,
+    </distribution.modules>
+  </properties>
+
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.gmaven</groupId>
+        <artifactId>groovy-maven-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <artifactId>maven-assembly-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <!-- Dependency on honeynode plugin -->
+    <dependency>
+      <groupId>io.fd.honeycomb.transportpce</groupId>
+      <artifactId>honeynode-plugin-impl</artifactId>
+      <version>${interfaces.mapping.version}</version>
+    </dependency>
+    <!-- Dependency on TPCE distribution base -->
+    <dependency>
+      <groupId>io.fd.honeycomb.transportpce</groupId>
+      <artifactId>minimal-distribution</artifactId>
+      <version>${honeycomb.min.distro.version}</version>
+    </dependency>
+
+  </dependencies>
+</project>
+
diff --git a/tests/honeynode221/honeynode-plugin-api/asciidoc/Readme.adoc b/tests/honeynode221/honeynode-plugin-api/asciidoc/Readme.adoc
new file mode 100644 (file)
index 0000000..ebe40ce
--- /dev/null
@@ -0,0 +1,3 @@
+= honeynode-plugin-api
+
+Overview of honeynode-plugin-api
\ No newline at end of file
diff --git a/tests/honeynode221/honeynode-plugin-api/pom.xml b/tests/honeynode221/honeynode-plugin-api/pom.xml
new file mode 100644 (file)
index 0000000..33665ae
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2015 Cisco and/or its affiliates.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at:
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+--><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">
+  <parent>
+    <groupId>io.fd.honeycomb.common</groupId>
+    <artifactId>api-parent</artifactId>
+    <version>1.18.01</version>
+  </parent>
+
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>io.fd.honeycomb.transportpce</groupId>
+  <artifactId>honeynode-plugin-api</artifactId>
+  <name>honeynode-plugin-api</name>
+  <version>1.18.01</version>
+  <packaging>bundle</packaging>
+</project>
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/java/org/opendaylight/yang/gen/v1/http/org/openroadm/pm/types/rev171215/PmDataTypeBuilder.java b/tests/honeynode221/honeynode-plugin-api/src/main/java/org/opendaylight/yang/gen/v1/http/org/openroadm/pm/types/rev171215/PmDataTypeBuilder.java
new file mode 100644 (file)
index 0000000..2435ab8
--- /dev/null
@@ -0,0 +1,18 @@
+package org.opendaylight.yang.gen.v1.http.org.openroadm.pm.types.rev171215;
+
+/**
+ * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation.
+ * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32).
+ *
+ * The reason behind putting it under src/main/java is:
+ * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent
+ * loss of user code.
+ *
+ */
+public class PmDataTypeBuilder {
+
+    public static PmDataType getDefaultInstance(java.lang.String defaultValue) {
+        throw new java.lang.UnsupportedOperationException("Not yet implemented");
+    }
+
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/java/org/opendaylight/yang/gen/v1/http/org/openroadm/syslog/rev171215/syslog/selector/log/selector/selector/facility/log/facility/LogFacilityFacilityBuilder.java b/tests/honeynode221/honeynode-plugin-api/src/main/java/org/opendaylight/yang/gen/v1/http/org/openroadm/syslog/rev171215/syslog/selector/log/selector/selector/facility/log/facility/LogFacilityFacilityBuilder.java
new file mode 100644 (file)
index 0000000..85bfccc
--- /dev/null
@@ -0,0 +1,19 @@
+package org.opendaylight.yang.gen.v1.http.org.openroadm.syslog.rev171215.syslog.selector.log.selector.selector.facility.log.facility;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.syslog.rev171215.syslog.selector.log.selector.selector.facility.log.facility.LogFacility.Facility;
+
+/**
+ * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation.
+ * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32).
+ *
+ * The reason behind putting it under src/main/java is:
+ * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent
+ * loss of user code.
+ *
+ */
+public class LogFacilityFacilityBuilder {
+
+    public static Facility getDefaultInstance(java.lang.String defaultValue) {
+        throw new java.lang.UnsupportedOperationException("Not yet implemented");
+    }
+
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev130715/HostBuilder.java b/tests/honeynode221/honeynode-plugin-api/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev130715/HostBuilder.java
new file mode 100644 (file)
index 0000000..03e21de
--- /dev/null
@@ -0,0 +1,18 @@
+package org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715;
+
+/**
+ * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation.
+ * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32).
+ *
+ * The reason behind putting it under src/main/java is:
+ * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent
+ * loss of user code.
+ *
+ */
+public class HostBuilder {
+
+    public static Host getDefaultInstance(java.lang.String defaultValue) {
+        throw new java.lang.UnsupportedOperationException("Not yet implemented");
+    }
+
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev130715/IpAddressBuilder.java b/tests/honeynode221/honeynode-plugin-api/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev130715/IpAddressBuilder.java
new file mode 100644 (file)
index 0000000..148b59c
--- /dev/null
@@ -0,0 +1,18 @@
+package org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715;
+
+/**
+ * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation.
+ * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32).
+ *
+ * The reason behind putting it under src/main/java is:
+ * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent
+ * loss of user code.
+ *
+ */
+public class IpAddressBuilder {
+
+    public static IpAddress getDefaultInstance(java.lang.String defaultValue) {
+        throw new java.lang.UnsupportedOperationException("Not yet implemented");
+    }
+
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev130715/IpAddressNoZoneBuilder.java b/tests/honeynode221/honeynode-plugin-api/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev130715/IpAddressNoZoneBuilder.java
new file mode 100644 (file)
index 0000000..d017bc5
--- /dev/null
@@ -0,0 +1,18 @@
+package org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715;
+
+/**
+ * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation.
+ * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32).
+ *
+ * The reason behind putting it under src/main/java is:
+ * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent
+ * loss of user code.
+ *
+ */
+public class IpAddressNoZoneBuilder {
+
+    public static IpAddressNoZone getDefaultInstance(java.lang.String defaultValue) {
+        throw new java.lang.UnsupportedOperationException("Not yet implemented");
+    }
+
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev130715/IpPrefixBuilder.java b/tests/honeynode221/honeynode-plugin-api/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev130715/IpPrefixBuilder.java
new file mode 100644 (file)
index 0000000..89fcee0
--- /dev/null
@@ -0,0 +1,18 @@
+package org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715;
+
+/**
+ * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation.
+ * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32).
+ *
+ * The reason behind putting it under src/main/java is:
+ * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent
+ * loss of user code.
+ *
+ */
+public class IpPrefixBuilder {
+
+    public static IpPrefix getDefaultInstance(java.lang.String defaultValue) {
+        throw new java.lang.UnsupportedOperationException("Not yet implemented");
+    }
+
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/monitoring/rev101004/netconf/state/schemas/SchemaLocationBuilder.java b/tests/honeynode221/honeynode-plugin-api/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/monitoring/rev101004/netconf/state/schemas/SchemaLocationBuilder.java
new file mode 100644 (file)
index 0000000..7f7249f
--- /dev/null
@@ -0,0 +1,19 @@
+package org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.Schema.Location;
+
+/**
+ * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation.
+ * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32).
+ *
+ * The reason behind putting it under src/main/java is:
+ * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent
+ * loss of user code.
+ *
+ */
+public class SchemaLocationBuilder {
+
+    public static Location getDefaultInstance(java.lang.String defaultValue) {
+        throw new java.lang.UnsupportedOperationException("Not yet implemented");
+    }
+
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/iana-afn-safi@2013-07-04.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/iana-afn-safi@2013-07-04.yang
new file mode 100644 (file)
index 0000000..c076260
--- /dev/null
@@ -0,0 +1,526 @@
+module iana-afn-safi {
+  namespace "urn:ietf:params:xml:ns:yang:iana-afn-safi";
+  prefix "ianaaf";
+
+  organization
+    "IANA";
+  contact
+    "        Internet Assigned Numbers Authority
+
+     Postal: ICANN
+             4676 Admiralty Way, Suite 330
+             Marina del Rey, CA 90292
+
+     Tel:    +1 310 823 9358
+     E-Mail: iana&iana.org";
+  description
+    "This YANG module provides two typedefs containing YANG
+     definitions for the following IANA-registered enumerations:
+
+     - Address Family Numbers (AFN)
+
+     - Subsequent Address Family Identifiers (SAFI)
+
+     The latest revision of this YANG module can be obtained from the
+     IANA web site.
+
+     Copyright (c) 2012 IETF Trust and the persons identified as
+     authors of the code. All rights reserved.
+
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject to
+     the license terms contained in, the Simplified BSD License set
+     forth in Section 4.c of the IETF Trust's Legal Provisions
+     Relating to IETF Documents
+     (http://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC XXXX; see the
+     RFC itself for full legal notices.";
+  // RFC Ed.: replace XXXX with actual RFC number and remove this
+  // note.
+
+  // RFC Ed.: update the date below with the date of RFC publication
+  // and remove this note.
+  revision 2013-07-04 {
+    description
+      "Initial revision.";
+    reference
+      "RFC XXXX: IANA Address Family Numbers and
+                 Subsequent Address Family Identifiers YANG Module";
+  }
+
+  typedef address-family {
+    type enumeration {
+      // value 0 is reserved by IANA
+      enum ipV4 {
+        value "1";
+        description
+          "IP version 4";
+      }
+      enum ipV6 {
+        value "2";
+        description
+          "IP version 6";
+      }
+      enum nsap {
+        value "3";
+        description
+          "NSAP";
+      }
+      enum hdlc {
+        value "4";
+        description
+          "HDLC (8-bit multidrop)";
+      }
+      enum bbn1822 {
+        value "5";
+        description
+          "BBN 1822";
+      }
+      enum all802 {
+        value "6";
+        description
+          "802 (includes all 802 media plus Ethernet 'canonical
+           format')";
+      }
+      enum e163 {
+        value "7";
+        description
+          "E.163";
+      }
+      enum e164 {
+        value "8";
+        description
+          "E.164 (SMDS, FrameRelay, ATM)";
+      }
+      enum f69 {
+        value "9";
+        description
+          "F.69 (Telex)";
+      }
+      enum x121 {
+        value "10";
+        description
+          "X.121 (X.25, Frame Relay)";
+      }
+      enum ipx {
+        value "11";
+        description
+          "IPX (Internetwork Packet Exchange)";
+      }
+      enum appletalk {
+        value "12";
+        description
+          "Appletalk";
+      }
+      enum decnetIV {
+        value "13";
+        description
+          "DECnet IV";
+      }
+      enum banyanVines {
+        value "14";
+        description
+          "Banyan Vines";
+      }
+      enum e164withNsap {
+        value "15";
+        description
+          "E.164 with NSAP format subaddress";
+        reference
+          "ATM Forum UNI 3.1";
+      }
+      enum dns {
+        value "16";
+        description
+          "DNS (Domain Name System)";
+      }
+      enum distinguishedName {
+        value "17";
+        description
+          "Distinguished Name (per X.500)";
+      }
+      enum asNumber {
+        value "18";
+        description
+          "Autonomous System Number";
+      }
+      enum xtpOverIpv4 {
+        value "19";
+        description
+          "XTP over IP version 4";
+      }
+      enum xtpOverIpv6 {
+        value "20";
+        description
+          "XTP over IP version 6";
+      }
+      enum xtpNativeModeXTP {
+        value "21";
+        description
+          "XTP native mode XTP";
+      }
+      enum fibreChannelWWPN {
+        value "22";
+        description
+          "Fibre Channel World-Wide Port Name";
+      }
+      enum fibreChannelWWNN {
+        value "23";
+        description
+          "Fibre Channel World-Wide Node Name";
+      }
+      enum gwid {
+        value "24";
+        description
+          "Gateway Identifier";
+      }
+      // FIXME: This one is actually called "afi" in the MIB, but
+      // that must be a mistake.
+      enum l2vpn {
+        value "25";
+        description
+          "AFI for L2VPN information";
+        reference
+          "RFC 4761: Virtual Private LAN Service (VPLS): Using BGP
+           for Auto-Discovery and Signaling
+
+           RFC 6074: Provisioning, Auto-Discovery, and Signaling in
+           Layer 2 Virtual Private Networks (L2VPNs)";
+      }
+      enum mplsTpSectionEndpointIdentifier {
+        value "26";
+        description
+          "MPLS-TP Section Endpoint Identifier";
+        reference
+          "draft-ietf-mpls-gach-adv";
+      }
+      enum mplsTpLspEndpointIdentifier {
+        value "27";
+        description
+          "MPLS-TP LSP Endpoint Identifier";
+        reference
+          "draft-ietf-mpls-gach-adv";
+      }
+      enum mplsTpPseudowireEndpointIdentifier {
+        value "28";
+        description
+          "MPLS-TP Pseudowire Endpoint Identifier";
+        reference
+          "draft-ietf-mpls-gach-adv";
+      }
+      enum eigrpCommonServiceFamily {
+        value "16384";
+        description
+          "EIGRP Common Service Family";
+      }
+      enum eigrpIpv4ServiceFamily {
+        value "16385";
+        description
+          "EIGRP IPv4 Service Family";
+      }
+      enum eigrpIpv6ServiceFamily {
+        value "16386";
+        description
+          "EIGRP IPv6 Service Family";
+      }
+      enum lispCanonicalAddressFormat {
+        value "16387";
+        description
+          "LISP Canonical Address Format (LCAF)";
+      }
+      enum bgpLs {
+        value "16388";
+        description
+          "BGP-LS";
+        reference
+          "draft-ietf-idr-ls-distribution";
+      }
+      enum 48BitMac {
+        value "16389";
+        description
+          "48-bit MAC";
+        reference
+          "draft-eastlake-rfc5342bis";
+      }
+      enum 64BitMac {
+        value "16390";
+        description
+          "64-bit MAC";
+        reference
+          "draft-eastlake-rfc5342bis";
+      }
+      // value 65535 is reserved by IANA
+    }
+    description
+      "This typedef is a YANG enumeration of IANA-registered address
+       family numbers (AFN).";
+    reference
+      "IANA Address Family Numbers registry.
+       <http://www.iana.org/assignments/address-family-numbers>";
+  }
+
+  typedef subsequent-address-family {
+    type enumeration {
+      // value 0 is reserved by IANA
+      enum nlriUnicast {
+        value "1";
+        description
+          "Network Layer Reachability Information used for unicast
+           forwarding";
+        reference
+          "RFC 4760: Multiprotocol Extensions for BGP-4";
+      }
+      enum nlriMulticast {
+        value "2";
+        description
+          "Network Layer Reachability Information used for multicast
+           forwarding";
+        reference
+          "RFC 4760: Multiprotocol Extensions for BGP-4";
+      }
+      // value 3 is reserved by IANA
+      enum nlriMpls {
+        value "4";
+        description
+          "Network Layer Reachability Information (NLRI) with MPLS
+           Labels";
+        reference
+          "RFC 3107: Carrying Label Information in BGP-4";
+      }
+      enum mcastVpn {
+        value "5";
+        description
+          "MCAST-VPN";
+        reference
+          "RFC 6514: BGP Encodings and Procedures for Multicast in
+           MPLS/BGP IP VPNs";
+      }
+      enum nlriDynamicMsPw {
+        value "6";
+        status "obsolete";
+        description
+          "Network Layer Reachability Information used for Dynamic
+           Placement of Multi-Segment Pseudowires (TEMPORARY -
+           Expires 2008-08-23)";
+        reference
+          "draft-ietf-pwe3-dynamic-ms-pw: Dynamic Placement of Multi
+           Segment Pseudowires";
+      }
+      enum encapsulation {
+        value "7";
+        description
+          "Encapsulation SAFI";
+        reference
+          "RFC 5512: The BGP Encapsulation Subsequent Address Family
+           Identifier (SAFI) and the BGP Tunnel Encapsulation
+           Attribute";
+      }
+      enum tunnel {
+        value "64";
+        status "obsolete";
+        description
+          "Tunnel SAFI";
+        reference
+          "draft-nalawade-kapoor-tunnel-safi: BGP Tunnel SAFI";
+      }
+      enum vpls {
+        value "65";
+        description
+          "Virtual Private LAN Service (VPLS)";
+        reference
+          "RFC 4761: Virtual Private LAN Service (VPLS): Using BGP
+           for Auto-Discovery and Signaling
+
+           RFC 6074: Provisioning, Auto-Discovery, and Signaling in
+           Layer 2 Virtual Private Networks (L2VPNs)";
+      }
+      enum bgpMdt {
+        value "66";
+        description
+          "BGP MDT SAFI";
+        reference
+          "RFC 6037: Cisco Systems' Solution for Multicast in
+           BGP/MPLS IP VPNs";
+      }
+      enum bgp4over6 {
+        value "67";
+        description
+          "BGP 4over6 SAFI";
+        reference
+          "RFC 5747: 4over6 Transit Solution Using IP Encapsulation
+           and MP-BGP Extensions";
+      }
+      enum bgp6over4 {
+        value "68";
+        description
+          "BGP 6over4 SAFI";
+      }
+      enum l1VpnAutoDiscovery {
+        value "69";
+        description
+          "Layer-1 VPN auto-discovery information";
+        reference
+          "RFC 5195: BGP-Based Auto-Discovery for Layer-1 VPNs";
+      }
+      enum mplsVpn {
+        value "128";
+        description
+          "MPLS-labeled VPN address";
+        reference
+          "RFC 4364: BGP/MPLS IP Virtual Private Networks (VPNs)";
+      }
+      enum multicastBgpMplsVpn {
+        value "129";
+        description
+          "Multicast for BGP/MPLS IP Virtual Private Networks
+           (VPNs)";
+        reference
+          "RFC 6513: Multicast in MPLS/BGP IP VPNs
+
+           RFC 6514: BGP Encodings and Procedures for Multicast in
+           MPLS/BGP IP VPNs";
+      }
+      // values 130-131 are reserved by IANA
+      enum routeTargetConstraints {
+        value "132";
+        description
+          "Route Target constraints";
+        reference
+          "RFC 4684: Constrained Route Distribution for Border
+           Gateway Protocol/MultiProtocol Label Switching (BGP/MPLS)
+           Internet Protocol (IP) Virtual Private Networks (VPNs)";
+      }
+      enum ipv4DissFlow {
+        value "133";
+        description
+          "IPv4 dissemination of flow specification rules";
+        reference
+          "RFC 5575: Dissemination of Flow Specification Rules";
+      }
+      enum vpnv4DissFlow {
+        value "134";
+        description
+          "VPNv4 dissemination of flow specification rules";
+        reference
+          "RFC 5575: Dissemination of Flow Specification Rules";
+      }
+      // values 135-139 are reserved by IANA
+      enum vpnAutoDiscovery {
+        value "140";
+        status "obsolete";
+        description
+          "VPN auto-discovery";
+        reference
+          "draft-ietf-l3vpn-bgpvpn-auto: Using BGP as an
+           Auto-Discovery Mechanism for VR-based Layer-3 VPNs";
+      }
+      // values 141-240 are reserved by IANA
+      enum private241 {
+        value "241";
+        description
+          "Reserved for Private Use";
+        reference
+          "RFC 4760: Multiprotocol Extensions for BGP-4";
+      }
+      enum private242 {
+        value "242";
+        description
+          "Reserved for Private Use";
+        reference
+          "RFC 4760: Multiprotocol Extensions for BGP-4";
+      }
+      enum private243 {
+        value "243";
+        description
+          "Reserved for Private Use";
+        reference
+          "RFC 4760: Multiprotocol Extensions for BGP-4";
+      }
+      enum private244 {
+        value "244";
+        description
+          "Reserved for Private Use";
+        reference
+          "RFC 4760: Multiprotocol Extensions for BGP-4";
+      }
+      enum private245 {
+        value "245";
+        description
+          "Reserved for Private Use";
+        reference
+          "RFC 4760: Multiprotocol Extensions for BGP-4";
+      }
+      enum private246 {
+        value "246";
+        description
+          "Reserved for Private Use";
+        reference
+          "RFC 4760: Multiprotocol Extensions for BGP-4";
+      }
+      enum private247 {
+        value "247";
+        description
+          "Reserved for Private Use";
+        reference
+          "RFC 4760: Multiprotocol Extensions for BGP-4";
+      }
+      enum private248 {
+        value "248";
+        description
+          "Reserved for Private Use";
+        reference
+          "RFC 4760: Multiprotocol Extensions for BGP-4";
+      }
+      enum private249 {
+        value "249";
+        description
+          "Reserved for Private Use";
+        reference
+          "RFC 4760: Multiprotocol Extensions for BGP-4";
+      }
+      enum private250 {
+        value "250";
+        description
+          "Reserved for Private Use";
+        reference
+          "RFC 4760: Multiprotocol Extensions for BGP-4";
+      }
+      enum private251 {
+        value "251";
+        description
+          "Reserved for Private Use";
+        reference
+          "RFC 4760: Multiprotocol Extensions for BGP-4";
+      }
+      enum private252 {
+        value "252";
+        description
+          "Reserved for Private Use";
+        reference
+          "RFC 4760: Multiprotocol Extensions for BGP-4";
+      }
+      enum private253 {
+        value "253";
+        description
+          "Reserved for Private Use";
+        reference
+          "RFC 4760: Multiprotocol Extensions for BGP-4";
+      }
+      enum private254 {
+        value "254";
+        description
+          "Reserved for Private Use";
+        reference
+          "RFC 4760: Multiprotocol Extensions for BGP-4";
+      }
+      // value 255 is reserved by IANA
+    }
+    description
+      "This typedef is a YANG enumeration of IANA-registered
+       subsequent address family identifiers (SAFI).";
+    reference
+      "IANA SAFI Values registry.
+       <http://www.iana.org/assignments/safi-namespace>";
+  }
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/ietf-inet-types@2013-07-15.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/ietf-inet-types@2013-07-15.yang
new file mode 100644 (file)
index 0000000..5c6f139
--- /dev/null
@@ -0,0 +1,457 @@
+module ietf-inet-types {
+
+  namespace "urn:ietf:params:xml:ns:yang:ietf-inet-types";
+  prefix "inet";
+
+  organization
+   "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
+
+  contact
+   "WG Web:   <http://tools.ietf.org/wg/netmod/>
+    WG List:  <mailto:netmod@ietf.org>
+
+    WG Chair: David Kessens
+              <mailto:david.kessens@nsn.com>
+
+    WG Chair: Juergen Schoenwaelder
+              <mailto:j.schoenwaelder@jacobs-university.de>
+
+    Editor:   Juergen Schoenwaelder
+              <mailto:j.schoenwaelder@jacobs-university.de>";
+
+  description
+   "This module contains a collection of generally useful derived
+    YANG data types for Internet addresses and related things.
+
+    Copyright (c) 2013 IETF Trust and the persons identified as
+    authors of the code.  All rights reserved.
+
+    Redistribution and use in source and binary forms, with or
+    without modification, is permitted pursuant to, and subject
+    to the license terms contained in, the Simplified BSD License
+    set forth in Section 4.c of the IETF Trust's Legal Provisions
+    Relating to IETF Documents
+    (http://trustee.ietf.org/license-info).
+
+    This version of this YANG module is part of RFC 6991; see
+    the RFC itself for full legal notices.";
+
+  revision 2013-07-15 {
+    description
+     "This revision adds the following new data types:
+      - ip-address-no-zone
+      - ipv4-address-no-zone
+      - ipv6-address-no-zone";
+    reference
+     "RFC 6991: Common YANG Data Types";
+  }
+
+  revision 2010-09-24 {
+    description
+     "Initial revision.";
+    reference
+     "RFC 6021: Common YANG Data Types";
+  }
+
+  /*** collection of types related to protocol fields ***/
+
+  typedef ip-version {
+    type enumeration {
+      enum unknown {
+        value "0";
+        description
+         "An unknown or unspecified version of the Internet
+          protocol.";
+      }
+      enum ipv4 {
+        value "1";
+        description
+         "The IPv4 protocol as defined in RFC 791.";
+      }
+      enum ipv6 {
+        value "2";
+        description
+         "The IPv6 protocol as defined in RFC 2460.";
+      }
+    }
+    description
+     "This value represents the version of the IP protocol.
+
+      In the value set and its semantics, this type is equivalent
+      to the InetVersion textual convention of the SMIv2.";
+    reference
+     "RFC  791: Internet Protocol
+      RFC 2460: Internet Protocol, Version 6 (IPv6) Specification
+      RFC 4001: Textual Conventions for Internet Network Addresses";
+  }
+
+  typedef dscp {
+    type uint8 {
+      range "0..63";
+    }
+    description
+     "The dscp type represents a Differentiated Services Code Point
+      that may be used for marking packets in a traffic stream.
+      In the value set and its semantics, this type is equivalent
+      to the Dscp textual convention of the SMIv2.";
+    reference
+     "RFC 3289: Management Information Base for the Differentiated
+                Services Architecture
+      RFC 2474: Definition of the Differentiated Services Field
+                (DS Field) in the IPv4 and IPv6 Headers
+      RFC 2780: IANA Allocation Guidelines For Values In
+                the Internet Protocol and Related Headers";
+  }
+
+  typedef ipv6-flow-label {
+    type uint32 {
+      range "0..1048575";
+    }
+    description
+     "The ipv6-flow-label type represents the flow identifier or Flow
+      Label in an IPv6 packet header that may be used to
+      discriminate traffic flows.
+
+      In the value set and its semantics, this type is equivalent
+      to the IPv6FlowLabel textual convention of the SMIv2.";
+    reference
+     "RFC 3595: Textual Conventions for IPv6 Flow Label
+      RFC 2460: Internet Protocol, Version 6 (IPv6) Specification";
+  }
+
+  typedef port-number {
+    type uint16 {
+      range "0..65535";
+    }
+    description
+     "The port-number type represents a 16-bit port number of an
+      Internet transport-layer protocol such as UDP, TCP, DCCP, or
+      SCTP.  Port numbers are assigned by IANA.  A current list of
+      all assignments is available from <http://www.iana.org/>.
+
+      Note that the port number value zero is reserved by IANA.  In
+      situations where the value zero does not make sense, it can
+      be excluded by subtyping the port-number type.
+      In the value set and its semantics, this type is equivalent
+      to the InetPortNumber textual convention of the SMIv2.";
+    reference
+     "RFC  768: User Datagram Protocol
+      RFC  793: Transmission Control Protocol
+      RFC 4960: Stream Control Transmission Protocol
+      RFC 4340: Datagram Congestion Control Protocol (DCCP)
+      RFC 4001: Textual Conventions for Internet Network Addresses";
+  }
+
+  /*** collection of types related to autonomous systems ***/
+
+  typedef as-number {
+    type uint32;
+    description
+     "The as-number type represents autonomous system numbers
+      which identify an Autonomous System (AS).  An AS is a set
+      of routers under a single technical administration, using
+      an interior gateway protocol and common metrics to route
+      packets within the AS, and using an exterior gateway
+      protocol to route packets to other ASes.  IANA maintains
+      the AS number space and has delegated large parts to the
+      regional registries.
+
+      Autonomous system numbers were originally limited to 16
+      bits.  BGP extensions have enlarged the autonomous system
+      number space to 32 bits.  This type therefore uses an uint32
+      base type without a range restriction in order to support
+      a larger autonomous system number space.
+
+      In the value set and its semantics, this type is equivalent
+      to the InetAutonomousSystemNumber textual convention of
+      the SMIv2.";
+    reference
+     "RFC 1930: Guidelines for creation, selection, and registration
+                of an Autonomous System (AS)
+      RFC 4271: A Border Gateway Protocol 4 (BGP-4)
+      RFC 4001: Textual Conventions for Internet Network Addresses
+      RFC 6793: BGP Support for Four-Octet Autonomous System (AS)
+                Number Space";
+  }
+
+  /*** collection of types related to IP addresses and hostnames ***/
+
+  typedef ip-address {
+    type union {
+      type inet:ipv4-address;
+      type inet:ipv6-address;
+    }
+    description
+     "The ip-address type represents an IP address and is IP
+      version neutral.  The format of the textual representation
+      implies the IP version.  This type supports scoped addresses
+      by allowing zone identifiers in the address format.";
+    reference
+     "RFC 4007: IPv6 Scoped Address Architecture";
+  }
+
+  typedef ipv4-address {
+    type string {
+      pattern
+        '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+      +  '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+      + '(%[\p{N}\p{L}]+)?';
+    }
+    description
+      "The ipv4-address type represents an IPv4 address in
+       dotted-quad notation.  The IPv4 address may include a zone
+       index, separated by a % sign.
+
+       The zone index is used to disambiguate identical address
+       values.  For link-local addresses, the zone index will
+       typically be the interface index number or the name of an
+       interface.  If the zone index is not present, the default
+       zone of the device will be used.
+
+       The canonical format for the zone index is the numerical
+       format";
+  }
+
+  typedef ipv6-address {
+    type string {
+      pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+            + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+            + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+            + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+            + '(%[\p{N}\p{L}]+)?';
+      pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+            + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+            + '(%.+)?';
+    }
+    description
+     "The ipv6-address type represents an IPv6 address in full,
+      mixed, shortened, and shortened-mixed notation.  The IPv6
+      address may include a zone index, separated by a % sign.
+
+      The zone index is used to disambiguate identical address
+      values.  For link-local addresses, the zone index will
+      typically be the interface index number or the name of an
+      interface.  If the zone index is not present, the default
+      zone of the device will be used.
+
+      The canonical format of IPv6 addresses uses the textual
+      representation defined in Section 4 of RFC 5952.  The
+      canonical format for the zone index is the numerical
+      format as described in Section 11.2 of RFC 4007.";
+    reference
+     "RFC 4291: IP Version 6 Addressing Architecture
+      RFC 4007: IPv6 Scoped Address Architecture
+      RFC 5952: A Recommendation for IPv6 Address Text
+                Representation";
+  }
+
+  typedef ip-address-no-zone {
+    type union {
+      type inet:ipv4-address-no-zone;
+      type inet:ipv6-address-no-zone;
+    }
+    description
+     "The ip-address-no-zone type represents an IP address and is
+      IP version neutral.  The format of the textual representation
+      implies the IP version.  This type does not support scoped
+      addresses since it does not allow zone identifiers in the
+      address format.";
+    reference
+     "RFC 4007: IPv6 Scoped Address Architecture";
+  }
+
+  typedef ipv4-address-no-zone {
+    type inet:ipv4-address {
+      pattern '[0-9\.]*';
+    }
+    description
+      "An IPv4 address without a zone index.  This type, derived from
+       ipv4-address, may be used in situations where the zone is
+       known from the context and hence no zone index is needed.";
+  }
+
+  typedef ipv6-address-no-zone {
+    type inet:ipv6-address {
+      pattern '[0-9a-fA-F:\.]*';
+    }
+    description
+      "An IPv6 address without a zone index.  This type, derived from
+       ipv6-address, may be used in situations where the zone is
+       known from the context and hence no zone index is needed.";
+    reference
+     "RFC 4291: IP Version 6 Addressing Architecture
+      RFC 4007: IPv6 Scoped Address Architecture
+      RFC 5952: A Recommendation for IPv6 Address Text
+                Representation";
+  }
+
+  typedef ip-prefix {
+    type union {
+      type inet:ipv4-prefix;
+      type inet:ipv6-prefix;
+    }
+    description
+     "The ip-prefix type represents an IP prefix and is IP
+      version neutral.  The format of the textual representations
+      implies the IP version.";
+  }
+
+  typedef ipv4-prefix {
+    type string {
+      pattern
+         '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+       +  '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+       + '/(([0-9])|([1-2][0-9])|(3[0-2]))';
+    }
+    description
+     "The ipv4-prefix type represents an IPv4 address prefix.
+      The prefix length is given by the number following the
+      slash character and must be less than or equal to 32.
+
+      A prefix length value of n corresponds to an IP address
+      mask that has n contiguous 1-bits from the most
+      significant bit (MSB) and all other bits set to 0.
+
+      The canonical format of an IPv4 prefix has all bits of
+      the IPv4 address set to zero that are not part of the
+      IPv4 prefix.";
+  }
+
+  typedef ipv6-prefix {
+    type string {
+      pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+            + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+            + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+            + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+            + '(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))';
+      pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+            + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+            + '(/.+)';
+    }
+    description
+     "The ipv6-prefix type represents an IPv6 address prefix.
+      The prefix length is given by the number following the
+      slash character and must be less than or equal to 128.
+
+      A prefix length value of n corresponds to an IP address
+      mask that has n contiguous 1-bits from the most
+      significant bit (MSB) and all other bits set to 0.
+
+      The IPv6 address should have all bits that do not belong
+      to the prefix set to zero.
+
+      The canonical format of an IPv6 prefix has all bits of
+      the IPv6 address set to zero that are not part of the
+      IPv6 prefix.  Furthermore, the IPv6 address is represented
+      as defined in Section 4 of RFC 5952.";
+    reference
+     "RFC 5952: A Recommendation for IPv6 Address Text
+                Representation";
+  }
+
+  /*** collection of domain name and URI types ***/
+
+  typedef domain-name {
+    type string {
+      pattern
+        '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*'
+      + '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)'
+      + '|\.';
+      length "1..253";
+    }
+    description
+     "The domain-name type represents a DNS domain name.  The
+      name SHOULD be fully qualified whenever possible.
+
+      Internet domain names are only loosely specified.  Section
+      3.5 of RFC 1034 recommends a syntax (modified in Section
+      2.1 of RFC 1123).  The pattern above is intended to allow
+      for current practice in domain name use, and some possible
+      future expansion.  It is designed to hold various types of
+      domain names, including names used for A or AAAA records
+      (host names) and other records, such as SRV records.  Note
+      that Internet host names have a stricter syntax (described
+      in RFC 952) than the DNS recommendations in RFCs 1034 and
+      1123, and that systems that want to store host names in
+      schema nodes using the domain-name type are recommended to
+      adhere to this stricter standard to ensure interoperability.
+
+      The encoding of DNS names in the DNS protocol is limited
+      to 255 characters.  Since the encoding consists of labels
+      prefixed by a length bytes and there is a trailing NULL
+      byte, only 253 characters can appear in the textual dotted
+      notation.
+
+      The description clause of schema nodes using the domain-name
+      type MUST describe when and how these names are resolved to
+      IP addresses.  Note that the resolution of a domain-name value
+      may require to query multiple DNS records (e.g., A for IPv4
+      and AAAA for IPv6).  The order of the resolution process and
+      which DNS record takes precedence can either be defined
+      explicitly or may depend on the configuration of the
+      resolver.
+
+      Domain-name values use the US-ASCII encoding.  Their canonical
+      format uses lowercase US-ASCII characters.  Internationalized
+      domain names MUST be A-labels as per RFC 5890.";
+    reference
+     "RFC  952: DoD Internet Host Table Specification
+      RFC 1034: Domain Names - Concepts and Facilities
+      RFC 1123: Requirements for Internet Hosts -- Application
+                and Support
+      RFC 2782: A DNS RR for specifying the location of services
+                (DNS SRV)
+      RFC 5890: Internationalized Domain Names in Applications
+                (IDNA): Definitions and Document Framework";
+  }
+
+  typedef host {
+    type union {
+      type inet:ip-address;
+      type inet:domain-name;
+    }
+    description
+     "The host type represents either an IP address or a DNS
+      domain name.";
+  }
+
+  typedef uri {
+    type string;
+    description
+     "The uri type represents a Uniform Resource Identifier
+      (URI) as defined by STD 66.
+
+      Objects using the uri type MUST be in US-ASCII encoding,
+      and MUST be normalized as described by RFC 3986 Sections
+      6.2.1, 6.2.2.1, and 6.2.2.2.  All unnecessary
+      percent-encoding is removed, and all case-insensitive
+      characters are set to lowercase except for hexadecimal
+      digits, which are normalized to uppercase as described in
+      Section 6.2.2.1.
+
+      The purpose of this normalization is to help provide
+      unique URIs.  Note that this normalization is not
+      sufficient to provide uniqueness.  Two URIs that are
+      textually distinct after this normalization may still be
+      equivalent.
+
+      Objects using the uri type may restrict the schemes that
+      they permit.  For example, 'data:' and 'urn:' schemes
+      might not be appropriate.
+
+      A zero-length URI is not a valid URI.  This can be used to
+      express 'URI absent' where required.
+
+      In the value set and its semantics, this type is equivalent
+      to the Uri SMIv2 textual convention defined in RFC 5017.";
+    reference
+     "RFC 3986: Uniform Resource Identifier (URI): Generic Syntax
+      RFC 3305: Report from the Joint W3C/IETF URI Planning Interest
+                Group: Uniform Resource Identifiers (URIs), URLs,
+                and Uniform Resource Names (URNs): Clarifications
+                and Recommendations
+      RFC 5017: MIB Textual Conventions for Uniform Resource
+                Identifiers (URIs)";
+  }
+
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/ietf-netconf-monitoring-extension@2013-12-10.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/ietf-netconf-monitoring-extension@2013-12-10.yang
new file mode 100644 (file)
index 0000000..e8f2ec3
--- /dev/null
@@ -0,0 +1,31 @@
+module ietf-netconf-monitoring-extension {
+
+    yang-version 1;
+
+    namespace
+      "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring-extension";
+
+    prefix ncme;
+
+    import ietf-netconf-monitoring {
+      prefix ncm;
+    }
+
+    revision "2013-12-10" {
+      description "Initial revision.";
+
+    }
+
+    identity netconf-tcp {
+      base ncm:transport;
+      description
+        "NETCONF over TCP.";
+    }
+
+    augment "/ncm:netconf-state/ncm:sessions/ncm:session" {
+      leaf session-identifier {
+        type string;
+      }
+    }
+
+}
\ No newline at end of file
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/ietf-netconf-monitoring@2010-10-04.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/ietf-netconf-monitoring@2010-10-04.yang
new file mode 100644 (file)
index 0000000..730a416
--- /dev/null
@@ -0,0 +1,596 @@
+module ietf-netconf-monitoring {
+
+    yang-version 1;
+
+    namespace
+      "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring";
+
+    prefix ncm;
+
+    import ietf-yang-types {
+      prefix yang;
+      revision-date "2013-07-15";
+    }
+
+    import ietf-inet-types {
+      prefix inet;
+      revision-date "2013-07-15";
+    }
+
+    organization
+      "IETF NETCONF (Network Configuration) Working Group";
+
+    contact
+      "WG Web:   <http://tools.ietf.org/wg/netconf/>
+     WG List:  <mailto:netconf@ietf.org>
+
+     WG Chair: Mehmet Ersue
+               <mailto:mehmet.ersue@nsn.com>
+
+     WG Chair: Bert Wijnen
+               <mailto:bertietf@bwijnen.net>
+
+     Editor:   Mark Scott
+               <mailto:mark.scott@ericsson.com>
+
+     Editor:   Martin Bjorklund
+               <mailto:mbj@tail-f.com>";
+
+    description
+      "NETCONF Monitoring Module.
+     All elements in this module are read-only.
+
+     Copyright (c) 2010 IETF Trust and the persons identified as
+     authors of the code. All rights reserved.
+
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject
+     to the license terms contained in, the Simplified BSD
+     License set forth in Section 4.c of the IETF Trust's
+     Legal Provisions Relating to IETF Documents
+     (http://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC 6022; see
+     the RFC itself for full legal notices.";
+
+    revision "2010-10-04" {
+      description "Initial revision.";
+      reference
+        "RFC 6022: YANG Module for NETCONF Monitoring";
+
+    }
+
+
+    typedef netconf-datastore-type {
+      type enumeration {
+        enum "running" {
+          value 0;
+        }
+        enum "candidate" {
+          value 1;
+        }
+        enum "startup" {
+          value 2;
+        }
+      }
+      description
+        "Enumeration of possible NETCONF datastore types.";
+      reference
+        "RFC 4741: NETCONF Configuration Protocol";
+
+    }
+
+    identity transport {
+      description
+        "Base identity for NETCONF transport types.";
+    }
+
+    identity netconf-ssh {
+      base transport;
+      description
+        "NETCONF over Secure Shell (SSH).";
+      reference
+        "RFC 4742: Using the NETCONF Configuration Protocol
+              over Secure SHell (SSH)";
+
+    }
+
+    identity netconf-soap-over-beep {
+      base transport;
+      description
+        "NETCONF over Simple Object Access Protocol (SOAP) over
+       Blocks Extensible Exchange Protocol (BEEP).";
+      reference
+        "RFC 4743: Using NETCONF over the Simple Object
+              Access Protocol (SOAP)";
+
+    }
+
+    identity netconf-soap-over-https {
+      base transport;
+      description
+        "NETCONF over Simple Object Access Protocol (SOAP)
+      over Hypertext Transfer Protocol Secure (HTTPS).";
+      reference
+        "RFC 4743: Using NETCONF over the Simple Object
+              Access Protocol (SOAP)";
+
+    }
+
+    identity netconf-beep {
+      base transport;
+      description
+        "NETCONF over Blocks Extensible Exchange Protocol (BEEP).";
+      reference
+        "RFC 4744: Using the NETCONF Protocol over the
+              Blocks Extensible Exchange Protocol (BEEP)";
+
+    }
+
+    identity netconf-tls {
+      base transport;
+      description
+        "NETCONF over Transport Layer Security (TLS).";
+      reference
+        "RFC 5539: NETCONF over Transport Layer Security (TLS)";
+
+    }
+
+    identity schema-format {
+      description
+        "Base identity for data model schema languages.";
+    }
+
+    identity xsd {
+      base schema-format;
+      description
+        "W3C XML Schema Definition.";
+      reference
+        "W3C REC REC-xmlschema-1-20041028:
+          XML Schema Part 1: Structures";
+
+    }
+
+    identity yang {
+      base schema-format;
+      description
+        "The YANG data modeling language for NETCONF.";
+      reference
+        "RFC 6020:  YANG - A Data Modeling Language for the
+               Network Configuration Protocol (NETCONF)";
+
+    }
+
+    identity yin {
+      base schema-format;
+      description "The YIN syntax for YANG.";
+      reference
+        "RFC 6020:  YANG - A Data Modeling Language for the
+               Network Configuration Protocol (NETCONF)";
+
+    }
+
+    identity rng {
+      base schema-format;
+      description
+        "Regular Language for XML Next Generation (RELAX NG).";
+      reference
+        "ISO/IEC 19757-2:2008: RELAX NG";
+
+    }
+
+    identity rnc {
+      base schema-format;
+      description "Relax NG Compact Syntax";
+      reference
+        "ISO/IEC 19757-2:2008: RELAX NG";
+
+    }
+
+    grouping common-counters {
+      description
+        "Counters that exist both per session, and also globally,
+       accumulated from all sessions.";
+      leaf in-rpcs {
+        type yang:zero-based-counter32;
+        description
+          "Number of correct <rpc> messages received.";
+      }
+
+      leaf in-bad-rpcs {
+        type yang:zero-based-counter32;
+        description
+          "Number of messages received when an <rpc> message was expected,
+         that were not correct <rpc> messages.  This includes XML parse
+         errors and errors on the rpc layer.";
+      }
+
+      leaf out-rpc-errors {
+        type yang:zero-based-counter32;
+        description
+          "Number of <rpc-reply> messages sent that contained an
+         <rpc-error> element.";
+      }
+
+      leaf out-notifications {
+        type yang:zero-based-counter32;
+        description
+          "Number of <notification> messages sent.";
+      }
+    }  // grouping common-counters
+
+    container netconf-state {
+      config false;
+      description
+        "The netconf-state container is the root of the monitoring
+       data model.";
+      container capabilities {
+        description
+          "Contains the list of NETCONF capabilities supported by the
+         server.";
+        leaf-list capability {
+          type inet:uri;
+          description
+            "List of NETCONF capabilities supported by the server.";
+        }
+      }  // container capabilities
+
+      container datastores {
+        description
+          "Contains the list of NETCONF configuration datastores.";
+        list datastore {
+          key "name";
+          description
+            "List of NETCONF configuration datastores supported by
+           the NETCONF server and related information.";
+          leaf name {
+            type netconf-datastore-type;
+            description
+              "Name of the datastore associated with this list entry.";
+          }
+
+          container locks {
+            presence
+              "This container is present only if the datastore
+             is locked.";
+            description
+              "The NETCONF <lock> and <partial-lock> operations allow
+             a client to lock specific resources in a datastore.  The
+             NETCONF server will prevent changes to the locked
+             resources by all sessions except the one that acquired
+             the lock(s).
+
+             Monitoring information is provided for each datastore
+             entry including details such as the session that acquired
+             the lock, the type of lock (global or partial) and the
+             list of locked resources.  Multiple locks per datastore
+             are supported.";
+            grouping lock-info {
+              description
+                "Lock related parameters, common to both global and
+               partial locks.";
+              leaf locked-by-session {
+                type uint32;
+                mandatory true;
+                description
+                  "The session ID of the session that has locked
+                 this resource.  Both a global lock and a partial
+                 lock MUST contain the NETCONF session-id.
+
+                 If the lock is held by a session that is not managed
+                 by the NETCONF server (e.g., a CLI session), a session
+                 id of 0 (zero) is reported.";
+                reference
+                  "RFC 4741: NETCONF Configuration Protocol";
+
+              }
+
+              leaf locked-time {
+                type yang:date-and-time;
+                mandatory true;
+                description
+                  "The date and time of when the resource was
+                 locked.";
+              }
+            }  // grouping lock-info
+            choice lock-type {
+              description
+                "Indicates if a global lock or a set of partial locks
+               are set.";
+              container global-lock {
+                description
+                  "Present if the global lock is set.";
+                uses lock-info;
+              }  // container global-lock
+              list partial-lock {
+                key "lock-id";
+                description
+                  "List of partial locks.";
+                reference
+                  "RFC 5717: Partial Lock Remote Procedure Call (RPC) for
+                      NETCONF";
+
+                leaf lock-id {
+                  type uint32;
+                  description
+                    "This is the lock id returned in the <partial-lock>
+                   response.";
+                }
+
+                uses lock-info;
+
+                leaf-list select {
+                  type yang:xpath1.0;
+                  min-elements 1;
+                  description
+                    "The xpath expression that was used to request
+                   the lock.  The select expression indicates the
+                   original intended scope of the lock.";
+                }
+
+                leaf-list locked-node {
+                  type instance-identifier;
+                  description
+                    "The list of instance-identifiers (i.e., the
+                   locked nodes).
+
+                   The scope of the partial lock is defined by the list
+                   of locked nodes.";
+                }
+              }  // list partial-lock
+            }  // choice lock-type
+          }  // container locks
+        }  // list datastore
+      }  // container datastores
+
+      container schemas {
+        description
+          "Contains the list of data model schemas supported by the
+         server.";
+        list schema {
+          key "identifier version format";
+          description
+            "List of data model schemas supported by the server.";
+          leaf identifier {
+            type string;
+            description
+              "Identifier to uniquely reference the schema.  The
+             identifier is used in the <get-schema> operation and may
+             be used for other purposes such as file retrieval.
+
+             For modeling languages that support or require a data
+             model name (e.g., YANG module name) the identifier MUST
+             match that name.  For YANG data models, the identifier is
+             the name of the module or submodule.  In other cases, an
+             identifier such as a filename MAY be used instead.";
+          }
+
+          leaf version {
+            type string;
+            description
+              "Version of the schema supported.  Multiple versions MAY be
+             supported simultaneously by a NETCONF server.  Each
+             version MUST be reported individually in the schema list,
+             i.e., with same identifier, possibly different location,
+             but different version.
+
+             For YANG data models, version is the value of the most
+             recent YANG 'revision' statement in the module or
+             submodule, or the empty string if no 'revision' statement
+             is present.";
+          }
+
+          leaf format {
+            type identityref {
+              base schema-format;
+            }
+            description
+              "The data modeling language the schema is written
+             in (currently xsd, yang, yin, rng, or rnc).
+             For YANG data models, 'yang' format MUST be supported and
+             'yin' format MAY also be provided.";
+          }
+
+          leaf namespace {
+            type inet:uri;
+            mandatory true;
+            description
+              "The XML namespace defined by the data model.
+
+             For YANG data models, this is the module's namespace.
+             If the list entry describes a submodule, this field
+             contains the namespace of the module to which the
+             submodule belongs.";
+          }
+
+          leaf-list location {
+            type union {
+              type enumeration {
+                enum "NETCONF" {
+                  value 0;
+                }
+              }
+              type inet:uri;
+            }
+            description
+              "One or more locations from which the schema can be
+             retrieved.  This list SHOULD contain at least one
+             entry per schema.
+
+             A schema entry may be located on a remote file system
+             (e.g., reference to file system for ftp retrieval) or
+             retrieved directly from a server supporting the
+             <get-schema> operation (denoted by the value 'NETCONF').";
+          }
+        }  // list schema
+      }  // container schemas
+
+      container sessions {
+        description
+          "The sessions container includes session-specific data for
+         NETCONF management sessions.  The session list MUST include
+         all currently active NETCONF sessions.";
+        list session {
+          key "session-id";
+          description
+            "All NETCONF sessions managed by the NETCONF server
+           MUST be reported in this list.";
+          leaf session-id {
+            type uint32 {
+              range "1..max";
+            }
+            description
+              "Unique identifier for the session.  This value is the
+             NETCONF session identifier, as defined in RFC 4741.";
+            reference
+              "RFC 4741: NETCONF Configuration Protocol";
+
+          }
+
+          leaf transport {
+            type identityref {
+              base transport;
+            }
+            mandatory true;
+            description
+              "Identifies the transport for each session, e.g.,
+            'netconf-ssh', 'netconf-soap', etc.";
+          }
+
+          leaf username {
+            type string;
+            mandatory true;
+            description
+              "The username is the client identity that was authenticated
+            by the NETCONF transport protocol.  The algorithm used to
+            derive the username is NETCONF transport protocol specific
+            and in addition specific to the authentication mechanism
+            used by the NETCONF transport protocol.";
+          }
+
+          leaf source-host {
+            type inet:host;
+            description
+              "Host identifier of the NETCONF client.  The value
+             returned is implementation specific (e.g., hostname,
+             IPv4 address, IPv6 address)";
+          }
+
+          leaf login-time {
+            type yang:date-and-time;
+            mandatory true;
+            description
+              "Time at the server at which the session was established.";
+          }
+
+          uses common-counters {
+            description
+              "Per-session counters.  Zero based with following reset
+             behaviour:
+               - at start of a session
+               - when max value is reached";
+          }
+        }  // list session
+      }  // container sessions
+
+      container statistics {
+        description
+          "Statistical data pertaining to the NETCONF server.";
+        leaf netconf-start-time {
+          type yang:date-and-time;
+          description
+            "Date and time at which the management subsystem was
+           started.";
+        }
+
+        leaf in-bad-hellos {
+          type yang:zero-based-counter32;
+          description
+            "Number of sessions silently dropped because an
+          invalid <hello> message was received.  This includes <hello>
+          messages with a 'session-id' attribute, bad namespace, and
+          bad capability declarations.";
+        }
+
+        leaf in-sessions {
+          type yang:zero-based-counter32;
+          description
+            "Number of sessions started.  This counter is incremented
+           when a <hello> message with a <session-id> is sent.
+
+          'in-sessions' - 'in-bad-hellos' =
+              'number of correctly started netconf sessions'";
+        }
+
+        leaf dropped-sessions {
+          type yang:zero-based-counter32;
+          description
+            "Number of sessions that were abnormally terminated, e.g.,
+           due to idle timeout or transport close.  This counter is not
+           incremented when a session is properly closed by a
+           <close-session> operation, or killed by a <kill-session>
+           operation.";
+        }
+
+        uses common-counters {
+          description
+            "Global counters, accumulated from all sessions.
+           Zero based with following reset behaviour:
+             - re-initialization of NETCONF server
+             - when max value is reached";
+        }
+      }  // container statistics
+    }  // container netconf-state
+
+    rpc get-schema {
+      description
+        "This operation is used to retrieve a schema from the
+       NETCONF server.
+
+       Positive Response:
+         The NETCONF server returns the requested schema.
+
+       Negative Response:
+         If requested schema does not exist, the <error-tag> is
+         'invalid-value'.
+
+         If more than one schema matches the requested parameters, the
+         <error-tag> is 'operation-failed', and <error-app-tag> is
+         'data-not-unique'.";
+      input {
+        leaf identifier {
+          type string;
+          mandatory true;
+          description
+            "Identifier for the schema list entry.";
+        }
+
+        leaf version {
+          type string;
+          description
+            "Version of the schema requested.  If this parameter is not
+           present, and more than one version of the schema exists on
+           the server, a 'data-not-unique' error is returned, as
+           described above.";
+        }
+
+        leaf format {
+          type identityref {
+            base schema-format;
+          }
+          description
+            "The data modeling language of the schema.  If this
+            parameter is not present, and more than one formats of
+            the schema exists on the server, a 'data-not-unique' error
+            is returned, as described above.";
+        }
+      }
+
+      output {
+        anyxml data {
+          description
+            "Contains the schema content.";
+        }
+      }
+    }  // rpc get-schema
+} // module
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/ietf-netconf-notifications@2012-02-06.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/ietf-netconf-notifications@2012-02-06.yang
new file mode 100644 (file)
index 0000000..31352a1
--- /dev/null
@@ -0,0 +1,363 @@
+module ietf-netconf-notifications {
+
+   namespace
+     "urn:ietf:params:xml:ns:yang:ietf-netconf-notifications";
+
+   prefix ncn;
+
+   import ietf-inet-types { prefix inet; revision-date "2013-07-15";}
+   import ietf-netconf { prefix nc; revision-date "2011-06-01";}
+
+   organization
+     "IETF NETCONF (Network Configuration Protocol) Working Group";
+
+   contact
+     "WG Web:   <http://tools.ietf.org/wg/netconf/>
+      WG List:  <mailto:netconf@ietf.org>
+
+      WG Chair: Bert Wijnen
+                <mailto:bertietf@bwijnen.net>
+
+      WG Chair: Mehmet Ersue
+                <mailto:mehmet.ersue@nsn.com>
+
+      Editor:   Andy Bierman
+                <mailto:andy@netconfcentral.org>";
+
+   description
+     "This module defines a YANG data model for use with the
+      NETCONF protocol that allows the NETCONF client to
+      receive common NETCONF base event notifications.
+
+      Copyright (c) 2012 IETF Trust and the persons identified as
+      the document authors.  All rights reserved.
+
+      Redistribution and use in source and binary forms, with or
+      without modification, is permitted pursuant to, and subject
+      to the license terms contained in, the Simplified BSD License
+
+
+
+      set forth in Section 4.c of the IETF Trust's Legal Provisions
+      Relating to IETF Documents
+      (http://trustee.ietf.org/license-info).
+
+      This version of this YANG module is part of RFC 6470; see
+      the RFC itself for full legal notices.";
+
+   revision "2012-02-06" {
+     description
+       "Initial version. Errata 3957 added.";
+     reference
+       "RFC 6470: NETCONF Base Notifications";
+   }
+
+  grouping common-session-parms {
+    description
+      "Common session parameters to identify a
+       management session.";
+
+    leaf username {
+      type string;
+      mandatory true;
+      description
+        "Name of the user for the session.";
+    }
+
+    leaf session-id {
+      type nc:session-id-or-zero-type;
+      mandatory true;
+      description
+        "Identifier of the session.
+         A NETCONF session MUST be identified by a non-zero value.
+         A non-NETCONF session MAY be identified by the value zero.";
+    }
+
+    leaf source-host {
+      type inet:ip-address;
+      description
+        "Address of the remote host for the session.";
+    }
+  }
+
+
+
+
+
+
+
+
+   grouping changed-by-parms {
+    description
+      "Common parameters to identify the source
+       of a change event, such as a configuration
+       or capability change.";
+
+    container changed-by {
+      description
+        "Indicates the source of the change.
+         If caused by internal action, then the
+         empty leaf 'server' will be present.
+         If caused by a management session, then
+         the name, remote host address, and session ID
+         of the session that made the change will be reported.";
+      choice server-or-user {
+        mandatory true;
+        leaf server {
+          type empty;
+          description
+            "If present, the change was caused
+             by the server.";
+        }
+
+        case by-user {
+          uses common-session-parms;
+        }
+      } // choice server-or-user
+    } // container changed-by-parms
+  }
+
+
+  notification netconf-config-change {
+    description
+      "Generated when the NETCONF server detects that the
+       <running> or <startup> configuration datastore
+       has been changed by a management session.
+       The notification summarizes the edits that
+       have been detected.
+
+       The server MAY choose to also generate this
+       notification while loading a datastore during the
+       boot process for the device.";
+
+    uses changed-by-parms;
+
+
+
+
+
+    leaf datastore {
+      type enumeration {
+        enum running {
+          description "The <running> datastore has changed.";
+        }
+        enum startup {
+          description "The <startup> datastore has changed";
+        }
+      }
+      default "running";
+      description
+        "Indicates which configuration datastore has changed.";
+    }
+
+    list edit {
+      description
+        "An edit record SHOULD be present for each distinct
+         edit operation that the server has detected on
+         the target datastore.  This list MAY be omitted
+         if the detailed edit operations are not known.
+         The server MAY report entries in this list for
+         changes not made by a NETCONF session (e.g., CLI).";
+
+      leaf target {
+        type instance-identifier;
+        description
+          "Topmost node associated with the configuration change.
+           A server SHOULD set this object to the node within
+           the datastore that is being altered.  A server MAY
+           set this object to one of the ancestors of the actual
+           node that was changed, or omit this object, if the
+           exact node is not known.";
+      }
+
+      leaf operation {
+        type nc:edit-operation-type;
+        description
+          "Type of edit operation performed.
+           A server MUST set this object to the NETCONF edit
+           operation performed on the target datastore.";
+      }
+    } // list edit
+  } // notification netconf-config-change
+
+
+
+
+
+
+  notification netconf-capability-change {
+    description
+      "Generated when the NETCONF server detects that
+       the server capabilities have changed.
+       Indicates which capabilities have been added, deleted,
+       and/or modified.  The manner in which a server
+       capability is changed is outside the scope of this
+       document.";
+
+    uses changed-by-parms;
+
+    leaf-list added-capability {
+      type inet:uri;
+      description
+        "List of capabilities that have just been added.";
+    }
+
+    leaf-list deleted-capability {
+      type inet:uri;
+      description
+        "List of capabilities that have just been deleted.";
+    }
+
+    leaf-list modified-capability {
+      type inet:uri;
+      description
+        "List of capabilities that have just been modified.
+         A capability is considered to be modified if the
+         base URI for the capability has not changed, but
+         one or more of the parameters encoded at the end of
+         the capability URI have changed.
+         The new modified value of the complete URI is returned.";
+    }
+  } // notification netconf-capability-change
+
+
+  notification netconf-session-start {
+    description
+      "Generated when a NETCONF server detects that a
+       NETCONF session has started.  A server MAY generate
+       this event for non-NETCONF management sessions.
+       Indicates the identity of the user that started
+       the session.";
+    uses common-session-parms;
+  } // notification netconf-session-start
+
+
+
+
+  notification netconf-session-end {
+    description
+      "Generated when a NETCONF server detects that a
+       NETCONF session has terminated.
+       A server MAY optionally generate this event for
+       non-NETCONF management sessions.  Indicates the
+       identity of the user that owned the session,
+       and why the session was terminated.";
+
+    uses common-session-parms;
+
+    leaf killed-by {
+      when "../termination-reason = 'killed'";
+      type nc:session-id-type;
+      description
+        "The ID of the session that directly caused this session
+         to be abnormally terminated.  If this session was abnormally
+         terminated by a non-NETCONF session unknown to the server,
+         then this leaf will not be present.";
+    }
+
+    leaf termination-reason {
+      type enumeration {
+        enum "closed" {
+          description
+            "The session was terminated by the client in normal
+             fashion, e.g., by the NETCONF <close-session>
+             protocol operation.";
+        }
+        enum "killed" {
+          description
+            "The session was terminated in abnormal
+             fashion, e.g., by the NETCONF <kill-session>
+             protocol operation.";
+        }
+        enum "dropped" {
+          description
+            "The session was terminated because the transport layer
+             connection was unexpectedly closed.";
+        }
+        enum "timeout" {
+          description
+            "The session was terminated because of inactivity,
+             e.g., waiting for the <hello> message or <rpc>
+             messages.";
+        }
+
+
+
+        enum "bad-hello" {
+          description
+            "The client's <hello> message was invalid.";
+        }
+        enum "other" {
+          description
+            "The session was terminated for some other reason.";
+        }
+      }
+      mandatory true;
+      description
+        "Reason the session was terminated.";
+    }
+  } // notification netconf-session-end
+
+
+  notification netconf-confirmed-commit {
+    description
+      "Generated when a NETCONF server detects that a
+       confirmed-commit event has occurred.  Indicates the event
+       and the current state of the confirmed-commit procedure
+       in progress.";
+    reference
+      "RFC 6241, Section 8.4";
+
+    uses common-session-parms {
+      when "confirm-event != 'timeout'";
+    }
+
+    leaf confirm-event {
+      type enumeration {
+        enum "start" {
+          description
+            "The confirmed-commit procedure has started.";
+        }
+        enum "cancel" {
+          description
+            "The confirmed-commit procedure has been canceled,
+             e.g., due to the session being terminated, or an
+             explicit <cancel-commit> operation.";
+        }
+        enum "timeout" {
+          description
+            "The confirmed-commit procedure has been canceled
+             due to the confirm-timeout interval expiring.
+             The common session parameters will not be present
+             in this sub-mode.";
+        }
+
+        enum "extend" {
+          description
+            "The confirmed-commit timeout has been extended,
+             e.g., by a new <confirmed-commit> operation.";
+        }
+        enum "complete" {
+          description
+            "The confirmed-commit procedure has been completed.";
+        }
+      }
+      mandatory true;
+      description
+        "Indicates the event that caused the notification.";
+    }
+
+    leaf timeout {
+      when
+        "../confirm-event = 'start' or ../confirm-event = 'extend'";
+      type uint32;
+      units "seconds";
+      description
+        "The configured timeout value if the event type
+         is 'start' or 'extend'.  This value represents
+         the approximate number of seconds from the event
+         time when the 'timeout' event might occur.";
+    }
+  } // notification netconf-confirmed-commit
+
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/ietf-netconf@2011-06-01.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/ietf-netconf@2011-06-01.yang
new file mode 100644 (file)
index 0000000..4bbb1c2
--- /dev/null
@@ -0,0 +1,928 @@
+module ietf-netconf {
+
+  // the namespace for NETCONF XML definitions is unchanged
+  // from RFC 4741, which this document replaces
+  namespace "urn:ietf:params:xml:ns:netconf:base:1.0";
+
+  prefix nc;
+
+  import ietf-inet-types {
+    prefix inet;
+  }
+
+  organization
+    "IETF NETCONF (Network Configuration) Working Group";
+
+  contact
+    "WG Web:   <http://tools.ietf.org/wg/netconf/>
+     WG List:  <netconf@ietf.org>
+
+     WG Chair: Bert Wijnen
+               <bertietf@bwijnen.net>
+
+     WG Chair: Mehmet Ersue
+               <mehmet.ersue@nsn.com>
+
+     Editor:   Martin Bjorklund
+               <mbj@tail-f.com>
+
+     Editor:   Juergen Schoenwaelder
+               <j.schoenwaelder@jacobs-university.de>
+
+     Editor:   Andy Bierman
+               <andy.bierman@brocade.com>";
+  description
+    "NETCONF Protocol Data Types and Protocol Operations.
+
+     Copyright (c) 2011 IETF Trust and the persons identified as
+     the document authors.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject
+     to the license terms contained in, the Simplified BSD License
+     set forth in Section 4.c of the IETF Trust's Legal Provisions
+     Relating to IETF Documents
+     (http://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC 6241; see
+     the RFC itself for full legal notices.";
+
+  revision 2011-06-01 {
+    description
+      "Initial revision;";
+    reference
+      "RFC 6241: Network Configuration Protocol";
+  }
+
+  extension get-filter-element-attributes {
+    description
+      "If this extension is present within an 'anyxml'
+       statement named 'filter', which must be conceptually
+       defined within the RPC input section for the <get>
+       and <get-config> protocol operations, then the
+       following unqualified XML attribute is supported
+       within the <filter> element, within a <get> or
+       <get-config> protocol operation:
+
+         type : optional attribute with allowed
+                value strings 'subtree' and 'xpath'.
+                If missing, the default value is 'subtree'.
+
+       If the 'xpath' feature is supported, then the
+       following unqualified XML attribute is
+       also supported:
+
+         select: optional attribute containing a
+                 string representing an XPath expression.
+                 The 'type' attribute must be equal to 'xpath'
+                 if this attribute is present.";
+  }
+
+  // NETCONF capabilities defined as features
+  feature writable-running {
+    description
+      "NETCONF :writable-running capability;
+       If the server advertises the :writable-running
+       capability for a session, then this feature must
+       also be enabled for that session.  Otherwise,
+       this feature must not be enabled.";
+    reference "RFC 6241, Section 8.2";
+  }
+
+  feature candidate {
+    description
+      "NETCONF :candidate capability;
+       If the server advertises the :candidate
+       capability for a session, then this feature must
+       also be enabled for that session.  Otherwise,
+       this feature must not be enabled.";
+    reference "RFC 6241, Section 8.3";
+  }
+
+  feature confirmed-commit {
+    if-feature candidate;
+    description
+      "NETCONF :confirmed-commit:1.1 capability;
+       If the server advertises the :confirmed-commit:1.1
+       capability for a session, then this feature must
+       also be enabled for that session.  Otherwise,
+       this feature must not be enabled.";
+
+    reference "RFC 6241, Section 8.4";
+  }
+
+  feature rollback-on-error {
+    description
+      "NETCONF :rollback-on-error capability;
+       If the server advertises the :rollback-on-error
+       capability for a session, then this feature must
+       also be enabled for that session.  Otherwise,
+       this feature must not be enabled.";
+    reference "RFC 6241, Section 8.5";
+  }
+
+  feature validate {
+    description
+      "NETCONF :validate:1.1 capability;
+       If the server advertises the :validate:1.1
+       capability for a session, then this feature must
+       also be enabled for that session.  Otherwise,
+       this feature must not be enabled.";
+    reference "RFC 6241, Section 8.6";
+  }
+
+  feature startup {
+    description
+      "NETCONF :startup capability;
+       If the server advertises the :startup
+       capability for a session, then this feature must
+       also be enabled for that session.  Otherwise,
+       this feature must not be enabled.";
+    reference "RFC 6241, Section 8.7";
+  }
+
+  feature url {
+    description
+      "NETCONF :url capability;
+       If the server advertises the :url
+       capability for a session, then this feature must
+       also be enabled for that session.  Otherwise,
+       this feature must not be enabled.";
+    reference "RFC 6241, Section 8.8";
+  }
+
+  feature xpath {
+    description
+      "NETCONF :xpath capability;
+       If the server advertises the :xpath
+       capability for a session, then this feature must
+       also be enabled for that session.  Otherwise,
+       this feature must not be enabled.";
+    reference "RFC 6241, Section 8.9";
+  }
+
+  // NETCONF Simple Types
+
+  typedef session-id-type {
+    type uint32 {
+      range "1..max";
+    }
+    description
+      "NETCONF Session Id";
+  }
+
+  typedef session-id-or-zero-type {
+    type uint32;
+    description
+      "NETCONF Session Id or Zero to indicate none";
+  }
+  typedef error-tag-type {
+    type enumeration {
+       enum in-use {
+         description
+           "The request requires a resource that
+            already is in use.";
+       }
+       enum invalid-value {
+         description
+           "The request specifies an unacceptable value for one
+            or more parameters.";
+       }
+       enum too-big {
+         description
+           "The request or response (that would be generated) is
+            too large for the implementation to handle.";
+       }
+       enum missing-attribute {
+         description
+           "An expected attribute is missing.";
+       }
+       enum bad-attribute {
+         description
+           "An attribute value is not correct; e.g., wrong type,
+            out of range, pattern mismatch.";
+       }
+       enum unknown-attribute {
+         description
+           "An unexpected attribute is present.";
+       }
+       enum missing-element {
+         description
+           "An expected element is missing.";
+       }
+       enum bad-element {
+         description
+           "An element value is not correct; e.g., wrong type,
+            out of range, pattern mismatch.";
+       }
+       enum unknown-element {
+         description
+           "An unexpected element is present.";
+       }
+       enum unknown-namespace {
+         description
+           "An unexpected namespace is present.";
+       }
+       enum access-denied {
+         description
+           "Access to the requested protocol operation or
+            data model is denied because authorization failed.";
+       }
+       enum lock-denied {
+         description
+           "Access to the requested lock is denied because the
+            lock is currently held by another entity.";
+       }
+       enum resource-denied {
+         description
+           "Request could not be completed because of
+            insufficient resources.";
+       }
+       enum rollback-failed {
+         description
+           "Request to roll back some configuration change (via
+            rollback-on-error or <discard-changes> operations)
+            was not completed for some reason.";
+
+       }
+       enum data-exists {
+         description
+           "Request could not be completed because the relevant
+            data model content already exists.  For example,
+            a 'create' operation was attempted on data that
+            already exists.";
+       }
+       enum data-missing {
+         description
+           "Request could not be completed because the relevant
+            data model content does not exist.  For example,
+            a 'delete' operation was attempted on
+            data that does not exist.";
+       }
+       enum operation-not-supported {
+         description
+           "Request could not be completed because the requested
+            operation is not supported by this implementation.";
+       }
+       enum operation-failed {
+         description
+           "Request could not be completed because the requested
+            operation failed for some reason not covered by
+            any other error condition.";
+       }
+       enum partial-operation {
+         description
+           "This error-tag is obsolete, and SHOULD NOT be sent
+            by servers conforming to this document.";
+       }
+       enum malformed-message {
+         description
+           "A message could not be handled because it failed to
+            be parsed correctly.  For example, the message is not
+            well-formed XML or it uses an invalid character set.";
+       }
+     }
+     description "NETCONF Error Tag";
+     reference "RFC 6241, Appendix A";
+  }
+
+  typedef error-severity-type {
+    type enumeration {
+      enum error {
+        description "Error severity";
+      }
+      enum warning {
+        description "Warning severity";
+      }
+    }
+    description "NETCONF Error Severity";
+    reference "RFC 6241, Section 4.3";
+  }
+
+  typedef edit-operation-type {
+    type enumeration {
+      enum merge {
+        description
+          "The configuration data identified by the
+           element containing this attribute is merged
+           with the configuration at the corresponding
+           level in the configuration datastore identified
+           by the target parameter.";
+      }
+      enum replace {
+        description
+          "The configuration data identified by the element
+           containing this attribute replaces any related
+           configuration in the configuration datastore
+           identified by the target parameter.  If no such
+           configuration data exists in the configuration
+           datastore, it is created.  Unlike a
+           <copy-config> operation, which replaces the
+           entire target configuration, only the configuration
+           actually present in the config parameter is affected.";
+      }
+      enum create {
+        description
+          "The configuration data identified by the element
+           containing this attribute is added to the
+           configuration if and only if the configuration
+           data does not already exist in the configuration
+           datastore.  If the configuration data exists, an
+           <rpc-error> element is returned with an
+           <error-tag> value of 'data-exists'.";
+      }
+      enum delete {
+        description
+          "The configuration data identified by the element
+           containing this attribute is deleted from the
+           configuration if and only if the configuration
+           data currently exists in the configuration
+           datastore.  If the configuration data does not
+           exist, an <rpc-error> element is returned with
+           an <error-tag> value of 'data-missing'.";
+      }
+      enum remove {
+        description
+          "The configuration data identified by the element
+           containing this attribute is deleted from the
+           configuration if the configuration
+           data currently exists in the configuration
+           datastore.  If the configuration data does not
+           exist, the 'remove' operation is silently ignored
+           by the server.";
+      }
+    }
+    default "merge";
+    description "NETCONF 'operation' attribute values";
+    reference "RFC 6241, Section 7.2";
+  }
+
+  // NETCONF Standard Protocol Operations
+
+  rpc get-config {
+    description
+      "Retrieve all or part of a specified configuration.";
+
+    reference "RFC 6241, Section 7.1";
+
+    input {
+      container source {
+        description
+          "Particular configuration to retrieve.";
+
+        choice config-source {
+          mandatory true;
+          description
+            "The configuration to retrieve.";
+          leaf candidate {
+            if-feature candidate;
+            type empty;
+            description
+              "The candidate configuration is the config source.";
+          }
+          leaf running {
+            type empty;
+            description
+              "The running configuration is the config source.";
+          }
+          leaf startup {
+            if-feature startup;
+            type empty;
+            description
+              "The startup configuration is the config source.
+               This is optional-to-implement on the server because
+               not all servers will support filtering for this
+               datastore.";
+          }
+        }
+      }
+
+      anyxml filter {
+        description
+          "Subtree or XPath filter to use.";
+        nc:get-filter-element-attributes;
+      }
+    }
+
+    output {
+      anyxml data {
+        description
+          "Copy of the source datastore subset that matched
+           the filter criteria (if any).  An empty data container
+           indicates that the request did not produce any results.";
+      }
+    }
+  }
+
+  rpc edit-config {
+    description
+      "The <edit-config> operation loads all or part of a specified
+       configuration to the specified target configuration.";
+
+    reference "RFC 6241, Section 7.2";
+
+    input {
+      container target {
+        description
+          "Particular configuration to edit.";
+
+        choice config-target {
+          mandatory true;
+          description
+            "The configuration target.";
+
+          leaf candidate {
+            if-feature candidate;
+            type empty;
+            description
+              "The candidate configuration is the config target.";
+          }
+          leaf running {
+            if-feature writable-running;
+            type empty;
+            description
+              "The running configuration is the config source.";
+          }
+        }
+      }
+
+      leaf default-operation {
+        type enumeration {
+          enum merge {
+            description
+              "The default operation is merge.";
+          }
+          enum replace {
+            description
+              "The default operation is replace.";
+          }
+          enum none {
+            description
+              "There is no default operation.";
+          }
+        }
+        default "merge";
+        description
+          "The default operation to use.";
+      }
+
+      leaf test-option {
+        if-feature validate;
+        type enumeration {
+          enum test-then-set {
+            description
+              "The server will test and then set if no errors.";
+          }
+          enum set {
+            description
+              "The server will set without a test first.";
+          }
+
+          enum test-only {
+            description
+              "The server will only test and not set, even
+               if there are no errors.";
+          }
+        }
+        default "test-then-set";
+        description
+          "The test option to use.";
+      }
+
+      leaf error-option {
+        type enumeration {
+          enum stop-on-error {
+            description
+              "The server will stop on errors.";
+          }
+          enum continue-on-error {
+            description
+              "The server may continue on errors.";
+          }
+          enum rollback-on-error {
+            description
+              "The server will roll back on errors.
+               This value can only be used if the 'rollback-on-error'
+               feature is supported.";
+          }
+        }
+        default "stop-on-error";
+        description
+          "The error option to use.";
+      }
+
+      choice edit-content {
+        mandatory true;
+        description
+          "The content for the edit operation.";
+
+        anyxml config {
+          description
+            "Inline Config content.";
+        }
+        leaf url {
+          if-feature url;
+          type inet:uri;
+          description
+            "URL-based config content.";
+        }
+      }
+    }
+  }
+
+  rpc copy-config {
+    description
+      "Create or replace an entire configuration datastore with the
+       contents of another complete configuration datastore.";
+
+    reference "RFC 6241, Section 7.3";
+
+    input {
+      container target {
+        description
+          "Particular configuration to copy to.";
+
+        choice config-target {
+          mandatory true;
+          description
+            "The configuration target of the copy operation.";
+
+          leaf candidate {
+            if-feature candidate;
+            type empty;
+            description
+              "The candidate configuration is the config target.";
+          }
+          leaf running {
+            if-feature writable-running;
+            type empty;
+            description
+              "The running configuration is the config target.
+               This is optional-to-implement on the server.";
+          }
+          leaf startup {
+            if-feature startup;
+            type empty;
+            description
+              "The startup configuration is the config target.";
+          }
+          leaf url {
+            if-feature url;
+            type inet:uri;
+            description
+              "The URL-based configuration is the config target.";
+          }
+        }
+      }
+
+      container source {
+        description
+          "Particular configuration to copy from.";
+
+        choice config-source {
+          mandatory true;
+          description
+            "The configuration source for the copy operation.";
+
+          leaf candidate {
+            if-feature candidate;
+            type empty;
+            description
+              "The candidate configuration is the config source.";
+          }
+          leaf running {
+            type empty;
+            description
+              "The running configuration is the config source.";
+          }
+          leaf startup {
+            if-feature startup;
+            type empty;
+            description
+              "The startup configuration is the config source.";
+          }
+          leaf url {
+            if-feature url;
+            type inet:uri;
+            description
+              "The URL-based configuration is the config source.";
+          }
+          anyxml config {
+            description
+              "Inline Config content: <config> element.  Represents
+               an entire configuration datastore, not
+               a subset of the running datastore.";
+          }
+        }
+      }
+    }
+  }
+
+  rpc delete-config {
+    description
+      "Delete a configuration datastore.";
+
+    reference "RFC 6241, Section 7.4";
+
+    input {
+      container target {
+        description
+          "Particular configuration to delete.";
+
+        choice config-target {
+          mandatory true;
+          description
+            "The configuration target to delete.";
+
+          leaf startup {
+            if-feature startup;
+            type empty;
+            description
+              "The startup configuration is the config target.";
+          }
+          leaf url {
+            if-feature url;
+            type inet:uri;
+            description
+              "The URL-based configuration is the config target.";
+          }
+        }
+      }
+    }
+  }
+
+  rpc lock {
+    description
+      "The lock operation allows the client to lock the configuration
+       system of a device.";
+
+    reference "RFC 6241, Section 7.5";
+
+    input {
+      container target {
+        description
+          "Particular configuration to lock.";
+
+        choice config-target {
+          mandatory true;
+          description
+            "The configuration target to lock.";
+
+          leaf candidate {
+            if-feature candidate;
+            type empty;
+            description
+              "The candidate configuration is the config target.";
+          }
+          leaf running {
+            type empty;
+            description
+              "The running configuration is the config target.";
+          }
+          leaf startup {
+            if-feature startup;
+            type empty;
+            description
+              "The startup configuration is the config target.";
+          }
+        }
+      }
+    }
+  }
+
+  rpc unlock {
+    description
+      "The unlock operation is used to release a configuration lock,
+       previously obtained with the 'lock' operation.";
+
+    reference "RFC 6241, Section 7.6";
+
+    input {
+      container target {
+        description
+          "Particular configuration to unlock.";
+
+        choice config-target {
+          mandatory true;
+          description
+            "The configuration target to unlock.";
+
+          leaf candidate {
+            if-feature candidate;
+            type empty;
+            description
+              "The candidate configuration is the config target.";
+          }
+          leaf running {
+            type empty;
+            description
+              "The running configuration is the config target.";
+          }
+          leaf startup {
+            if-feature startup;
+            type empty;
+            description
+              "The startup configuration is the config target.";
+          }
+        }
+      }
+    }
+  }
+
+  rpc get {
+    description
+      "Retrieve running configuration and device state information.";
+
+    reference "RFC 6241, Section 7.7";
+
+    input {
+      anyxml filter {
+        description
+          "This parameter specifies the portion of the system
+           configuration and state data to retrieve.";
+        nc:get-filter-element-attributes;
+      }
+    }
+
+    output {
+      anyxml data {
+        description
+          "Copy of the running datastore subset and/or state
+           data that matched the filter criteria (if any).
+           An empty data container indicates that the request did not
+           produce any results.";
+      }
+    }
+  }
+
+  rpc close-session {
+    description
+      "Request graceful termination of a NETCONF session.";
+
+    reference "RFC 6241, Section 7.8";
+  }
+
+  rpc kill-session {
+    description
+      "Force the termination of a NETCONF session.";
+
+    reference "RFC 6241, Section 7.9";
+
+    input {
+      leaf session-id {
+        type session-id-type;
+        mandatory true;
+        description
+          "Particular session to kill.";
+      }
+    }
+  }
+
+  rpc commit {
+    if-feature candidate;
+
+    description
+      "Commit the candidate configuration as the device's new
+       current configuration.";
+
+    reference "RFC 6241, Section 8.3.4.1";
+
+    input {
+      leaf confirmed {
+        if-feature confirmed-commit;
+        type empty;
+        description
+          "Requests a confirmed commit.";
+        reference "RFC 6241, Section 8.3.4.1";
+      }
+
+      leaf confirm-timeout {
+        if-feature confirmed-commit;
+        type uint32 {
+          range "1..max";
+        }
+        units "seconds";
+        default "600";   // 10 minutes
+        description
+          "The timeout interval for a confirmed commit.";
+        reference "RFC 6241, Section 8.3.4.1";
+      }
+
+      leaf persist {
+        if-feature confirmed-commit;
+        type string;
+        description
+          "This parameter is used to make a confirmed commit
+           persistent.  A persistent confirmed commit is not aborted
+           if the NETCONF session terminates.  The only way to abort
+           a persistent confirmed commit is to let the timer expire,
+           or to use the <cancel-commit> operation.
+
+           The value of this parameter is a token that must be given
+           in the 'persist-id' parameter of <commit> or
+           <cancel-commit> operations in order to confirm or cancel
+           the persistent confirmed commit.
+
+           The token should be a random string.";
+        reference "RFC 6241, Section 8.3.4.1";
+      }
+
+      leaf persist-id {
+        if-feature confirmed-commit;
+        type string;
+        description
+          "This parameter is given in order to commit a persistent
+           confirmed commit.  The value must be equal to the value
+           given in the 'persist' parameter to the <commit> operation.
+           If it does not match, the operation fails with an
+          'invalid-value' error.";
+        reference "RFC 6241, Section 8.3.4.1";
+      }
+
+    }
+  }
+
+  rpc discard-changes {
+    if-feature candidate;
+
+    description
+      "Revert the candidate configuration to the current
+       running configuration.";
+    reference "RFC 6241, Section 8.3.4.2";
+  }
+
+  rpc cancel-commit {
+    if-feature confirmed-commit;
+    description
+      "This operation is used to cancel an ongoing confirmed commit.
+       If the confirmed commit is persistent, the parameter
+       'persist-id' must be given, and it must match the value of the
+       'persist' parameter.";
+    reference "RFC 6241, Section 8.4.4.1";
+
+    input {
+      leaf persist-id {
+        type string;
+        description
+          "This parameter is given in order to cancel a persistent
+           confirmed commit.  The value must be equal to the value
+           given in the 'persist' parameter to the <commit> operation.
+           If it does not match, the operation fails with an
+          'invalid-value' error.";
+      }
+    }
+  }
+
+  rpc validate {
+    if-feature validate;
+
+    description
+      "Validates the contents of the specified configuration.";
+
+    reference "RFC 6241, Section 8.6.4.1";
+
+    input {
+      container source {
+        description
+          "Particular configuration to validate.";
+
+        choice config-source {
+          mandatory true;
+          description
+            "The configuration source to validate.";
+
+          leaf candidate {
+            if-feature candidate;
+            type empty;
+            description
+              "The candidate configuration is the config source.";
+          }
+          leaf running {
+            type empty;
+            description
+              "The running configuration is the config source.";
+          }
+          leaf startup {
+            if-feature startup;
+            type empty;
+            description
+              "The startup configuration is the config source.";
+          }
+          leaf url {
+            if-feature url;
+            type inet:uri;
+            description
+              "The URL-based configuration is the config source.";
+          }
+          anyxml config {
+            description
+              "Inline Config content: <config> element.  Represents
+               an entire configuration datastore, not
+               a subset of the running datastore.";
+          }
+        }
+      }
+    }
+  }
+
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/ietf-network-topology@2015-06-08.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/ietf-network-topology@2015-06-08.yang
new file mode 100644 (file)
index 0000000..0aeb2e5
--- /dev/null
@@ -0,0 +1,243 @@
+module ietf-network-topology {
+  yang-version 1;
+  namespace "urn:ietf:params:xml:ns:yang:ietf-network-topology";
+  prefix lnk;
+
+  import ietf-inet-types {
+    prefix inet;
+  }
+  import ietf-network {
+    prefix nd;
+  }
+
+  organization "TBD";
+  contact
+    "WILL-BE-DEFINED-LATER";
+  description
+    "This module defines a common base model for network topology,
+     augmenting the base network model with links to connect nodes,
+     as well as termination points to terminate links on nodes.";
+
+  revision 2015-06-08 {
+    description
+      "Initial revision.";
+    reference "draft-ietf-i2rs-yang-network-topo-01";
+  }
+
+  typedef link-id {
+    type inet:uri;
+    description
+      "An identifier for a link in a topology.
+       The identifier may be opaque.
+       The identifier SHOULD be chosen such that the same link in a
+       real network topology will always be identified through the
+       same identifier, even if the model is instantiated in
+       separate datastores. An implementation MAY choose to capture
+       semantics in the identifier, for example to indicate the type
+       of link and/or the type of topology that the link is a part
+       of.";
+  }
+
+  typedef tp-id {
+    type inet:uri;
+    description
+      "An identifier for termination points on a node.
+       The identifier may be opaque.
+       The identifier SHOULD be chosen such that the same TP in a
+       real network topology will always be identified through the
+       same identifier, even if the model is instantiated in
+       separate datastores. An implementation MAY choose to capture
+       semantics in the identifier, for example to indicate the type
+       of TP and/or the type of node and topology that the TP is a
+       part of.";
+  }
+
+  grouping link-ref {
+    description
+      "References a link in a specific network.";
+    leaf link-ref {
+      type leafref {
+        path "/nd:network[nd:network-id=current()/../"+
+          "nd:network-ref]/link/link-id";
+      }
+      description
+        "A type for an absolute reference a link instance.
+         (This type should not be used for relative references.
+         In such a case, a relative path should be used instead.)";
+    }
+    uses nd:network-ref;
+  }
+
+  grouping tp-ref {
+    description
+      "References a termination point in a specific node.";
+    leaf tp-ref {
+      type leafref {
+        path "/nd:network[nd:network-id=current()/../"+
+          "nd:network-ref]/nd:node[nd:node-id=current()/../"+
+          "nd:node-ref]/termination-point/tp-id";
+      }
+      description
+        "A type for an absolute reference to a termination point.
+         (This type should not be used for relative references.
+         In such a case, a relative path should be used instead.)";
+    }
+    uses nd:node-ref;
+  }
+
+  augment "/nd:network" {
+    description
+      "Add links to the network model.";
+    list link {
+      key "link-id";
+      description
+        "A Network Link connects a by Local (Source) node and
+         a Remote (Destination) Network Nodes via a set of the
+         nodes' termination points.
+         As it is possible to have several links between the same
+         source and destination nodes, and as a link could
+         potentially be re-homed between termination points, to
+         ensure that we would always know to distinguish between
+         links, every link is identified by a dedicated link
+         identifier.
+         Note that a link models a point-to-point link, not a
+         multipoint link.
+         Layering dependencies on links in underlay topologies are
+         not represented as the layering information of nodes and of
+         termination points is sufficient.";
+      container source {
+        description
+          "This container holds the logical source of a particular
+           link.";
+        leaf source-node {
+          type leafref {
+            path "../../../nd:node/nd:node-id";
+          }
+          mandatory true;
+          description
+            "Source node identifier, must be in same topology.";
+        }
+        leaf source-tp {
+          type leafref {
+            path "../../../nd:node[nd:node-id=current()/../"+
+              "source-node]/termination-point/tp-id";
+          }
+          description
+            "Termination point within source node that terminates
+             the link.";
+        }
+      }
+      container destination {
+        description
+          "This container holds the logical destination of a
+           particular link.";
+        leaf dest-node {
+          type leafref {
+            path "../../../nd:node/nd:node-id";
+          }
+          mandatory true;
+          description
+            "Destination node identifier, must be in the same
+             network.";
+        }
+        leaf dest-tp {
+          type leafref {
+            path "../../../nd:node[nd:node-id=current()/../"+
+              "dest-node]/termination-point/tp-id";
+          }
+          description
+            "Termination point within destination node that
+             terminates the link.";
+        }
+      }
+      leaf link-id {
+        type link-id;
+        description
+          "The identifier of a link in the topology.
+           A link is specific to a topology to which it belongs.";
+      }
+      list supporting-link {
+        key "network-ref link-ref";
+        description
+          "Identifies the link, or links, that this link
+           is dependent on.";
+        leaf network-ref {
+          type leafref {
+            path "../../../nd:supporting-network/nd:network-ref";
+          }
+          description
+            "This leaf identifies in which underlay topology
+             supporting link is present.";
+        }
+        leaf link-ref {
+          type leafref {
+            path "/nd:network[nd:network-id=current()/.."+
+              "/network-ref]/link/link-id";
+          }
+          description
+            "This leaf identifies a link which is a part
+             of this link's underlay. Reference loops, in which
+             a link identifies itself as its underlay, either
+             directly or transitively, are not allowed.";
+        }
+      }
+    }
+  }
+  augment "/nd:network/nd:node" {
+    description
+      "Augment termination points which terminate links.
+       Termination points can ultimately be mapped to interfaces.";
+    list termination-point {
+      key "tp-id";
+      description
+        "A termination point can terminate a link.
+         Depending on the type of topology, a termination point
+         could, for example, refer to a port or an interface.";
+      leaf tp-id {
+        type tp-id;
+        description
+          "Termination point identifier.";
+      }
+      list supporting-termination-point {
+        key "network-ref node-ref tp-ref";
+        description
+          "The leaf list identifies any termination points that
+           the termination point is dependent on, or maps onto.
+           Those termination points will themselves be contained
+           in a supporting node.
+           This dependency information can be inferred from
+           the dependencies between links.  For this reason,
+           this item is not separately configurable.  Hence no
+           corresponding constraint needs to be articulated.
+           The corresponding information is simply provided by the
+           implementing system.";
+        leaf network-ref {
+          type leafref {
+            path "../../../nd:supporting-node/nd:network-ref";
+          }
+          description
+            "This leaf identifies in which topology the
+             supporting termination point is present.";
+        }
+        leaf node-ref {
+          type leafref {
+            path "../../../nd:supporting-node/nd:node-ref";
+          }
+          description
+            "This leaf identifies in which node the supporting
+             termination point is present.";
+        }
+        leaf tp-ref {
+          type leafref {
+            path "/nd:network[nd:network-id=current()/../"+
+              "network-ref]/nd:node[nd:node-id=current()/../"+
+              "node-ref]/termination-point/tp-id";
+          }
+          description
+            "Reference to the underlay node, must be in a
+             different topology";
+        }
+      }
+    }
+  }
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/ietf-network@2015-06-08.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/ietf-network@2015-06-08.yang
new file mode 100644 (file)
index 0000000..9e2dadf
--- /dev/null
@@ -0,0 +1,144 @@
+module ietf-network {
+  yang-version 1;
+  namespace "urn:ietf:params:xml:ns:yang:ietf-network";
+  prefix nd;
+
+  import ietf-inet-types {
+    prefix inet;
+  }
+
+  organization "TBD";
+  contact
+    "WILL-BE-DEFINED-LATER";
+  description
+    "This module defines a common base model for a collection
+     of nodes in a network. Node definitions s are further used
+     in network topologies and inventories.";
+
+  revision 2015-06-08 {
+    description
+      "Initial revision.";
+    reference "draft-ietf-i2rs-yang-network-topo-01";
+  }
+
+  typedef node-id {
+    type inet:uri;
+    description
+      "Identifier for a node.";
+  }
+
+  typedef network-id {
+    type inet:uri;
+    description
+      "Identifier for a network.";
+  }
+
+  grouping network-ref {
+    description
+      "Contains the information necessary to reference a network,
+       for example an underlay network.";
+    leaf network-ref {
+      type leafref {
+        path "/network/network-id";
+      }
+      description
+        "Used to reference a network, for example an underlay
+         network.";
+    }
+  }
+
+  grouping node-ref {
+    description
+      "Contains the information necessary to reference a node.";
+    leaf node-ref {
+      type leafref {
+        path "/network[network-id=current()/../network-ref]"+
+          "/node/node-id";
+      }
+      description
+        "Used to reference a node.
+         Nodes are identified relative to the network they are
+         contained in.";
+    }
+    uses network-ref;
+  }
+
+  list network {
+    key "network-id";
+    description
+      "Describes a network.
+       A network typically contains an inventory of nodes,
+       topological information (augmented through
+       network-topology model), as well as layering
+       information.";
+    container network-types {
+      description
+        "Serves as an augmentation target.
+         The network type is indicated through corresponding
+         presence containers augmented into this container.";
+    }
+    leaf network-id {
+      type network-id;
+      description
+        "Identifies a network.";
+    }
+    leaf server-provided {
+      type boolean;
+      config false;
+      description
+        "Indicates whether the information concerning this
+         particular network is populated by the server
+         (server-provided true, the general case for network
+         information discovered from the server),
+         or whether it is configured by a client
+         (server-provided true, possible e.g. for
+         service overlays managed through a controller).";
+    }
+    list supporting-network {
+      key "network-ref";
+      description
+        "An underlay network, used to represent layered network
+         topologies.";
+      leaf network-ref {
+        type leafref {
+          path "/network/network-id";
+        }
+        description
+          "References the underlay network.";
+      }
+    }
+    list node {
+      key "node-id";
+      description
+        "The inventory of nodes of this network.";
+      leaf node-id {
+        type node-id;
+        description
+          "Identifies a node uniquely within the containing
+           network.";
+      }
+      list supporting-node {
+        key "network-ref node-ref";
+        description
+          "Represents another node, in an underlay network, that
+           this node is supported by.  Used to represent layering
+           structure.";
+        leaf network-ref {
+          type leafref {
+            path "../../../supporting-network/network-ref";
+          }
+          description
+            "References the underlay network that the
+             underlay node is part of.";
+        }
+        leaf node-ref {
+          type leafref {
+            path "/network/node/node-id";
+          }
+          description
+            "References the underlay node itself.";
+        }
+      }
+    }
+  }
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/ietf-yang-types@2013-07-15.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/ietf-yang-types@2013-07-15.yang
new file mode 100644 (file)
index 0000000..bdff18c
--- /dev/null
@@ -0,0 +1,467 @@
+module ietf-yang-types {
+
+     namespace "urn:ietf:params:xml:ns:yang:ietf-yang-types";
+     prefix "yang";
+
+     organization
+      "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
+
+     contact
+      "WG Web:   <http://tools.ietf.org/wg/netmod/>
+       WG List:  <mailto:netmod@ietf.org>
+       WG Chair: David Kessens
+                 <mailto:david.kessens@nsn.com>
+
+       WG Chair: Juergen Schoenwaelder
+                 <mailto:j.schoenwaelder@jacobs-university.de>
+
+       Editor:   Juergen Schoenwaelder
+                 <mailto:j.schoenwaelder@jacobs-university.de>";
+
+     description
+      "This module contains a collection of generally useful derived
+       YANG data types.
+
+       Copyright (c) 2013 IETF Trust and the persons identified as
+       authors of the code.  All rights reserved.
+
+       Redistribution and use in source and binary forms, with or
+       without modification, is permitted pursuant to, and subject
+       to the license terms contained in, the Simplified BSD License
+       set forth in Section 4.c of the IETF Trust's Legal Provisions
+       Relating to IETF Documents
+       (http://trustee.ietf.org/license-info).
+
+       This version of this YANG module is part of RFC 6991; see
+       the RFC itself for full legal notices.";
+
+     revision 2013-07-15 {
+       description
+        "This revision adds the following new data types:
+         - yang-identifier
+         - hex-string
+         - uuid
+         - dotted-quad";
+       reference
+        "RFC 6991: Common YANG Data Types";
+     }
+
+     revision 2010-09-24 {
+       description
+        "Initial revision.";
+       reference
+        "RFC 6021: Common YANG Data Types";
+     }
+
+     /*** collection of counter and gauge types ***/
+
+     typedef counter32 {
+       type uint32;
+       description
+        "The counter32 type represents a non-negative integer
+         that monotonically increases until it reaches a
+         maximum value of 2^32-1 (4294967295 decimal), when it
+         wraps around and starts increasing again from zero.
+
+         Counters have no defined 'initial' value, and thus, a
+         single value of a counter has (in general) no information
+         content.  Discontinuities in the monotonically increasing
+         value normally occur at re-initialization of the
+         management system, and at other times as specified in the
+         description of a schema node using this type.  If such
+         other times can occur, for example, the creation of
+         a schema node of type counter32 at times other than
+         re-initialization, then a corresponding schema node
+         should be defined, with an appropriate type, to indicate
+         the last discontinuity.
+
+         The counter32 type should not be used for configuration
+         schema nodes.  A default statement SHOULD NOT be used in
+         combination with the type counter32.
+
+         In the value set and its semantics, this type is equivalent
+         to the Counter32 type of the SMIv2.";
+       reference
+        "RFC 2578: Structure of Management Information Version 2
+                   (SMIv2)";
+     }
+
+     typedef zero-based-counter32 {
+       type yang:counter32;
+       default "0";
+       description
+        "The zero-based-counter32 type represents a counter32
+         that has the defined 'initial' value zero.
+
+         A schema node of this type will be set to zero (0) on creation
+         and will thereafter increase monotonically until it reaches
+         a maximum value of 2^32-1 (4294967295 decimal), when it
+         wraps around and starts increasing again from zero.
+
+         Provided that an application discovers a new schema node
+         of this type within the minimum time to wrap, it can use the
+         'initial' value as a delta.  It is important for a management
+         station to be aware of this minimum time and the actual time
+         between polls, and to discard data if the actual time is too
+         long or there is no defined minimum time.
+        In the value set and its semantics, this type is equivalent
+         to the ZeroBasedCounter32 textual convention of the SMIv2.";
+       reference
+         "RFC 4502: Remote Network Monitoring Management Information
+                    Base Version 2";
+     }
+
+     typedef counter64 {
+       type uint64;
+       description
+        "The counter64 type represents a non-negative integer
+         that monotonically increases until it reaches a
+         maximum value of 2^64-1 (18446744073709551615 decimal),
+         when it wraps around and starts increasing again from zero.
+
+         Counters have no defined 'initial' value, and thus, a
+         single value of a counter has (in general) no information
+         content.  Discontinuities in the monotonically increasing
+         value normally occur at re-initialization of the
+         management system, and at other times as specified in the
+         description of a schema node using this type.  If such
+         other times can occur, for example, the creation of
+         a schema node of type counter64 at times other than
+         re-initialization, then a corresponding schema node
+         should be defined, with an appropriate type, to indicate
+         the last discontinuity.
+
+         The counter64 type should not be used for configuration
+         schema nodes.  A default statement SHOULD NOT be used in
+         combination with the type counter64.
+
+         In the value set and its semantics, this type is equivalent
+         to the Counter64 type of the SMIv2.";
+       reference
+        "RFC 2578: Structure of Management Information Version 2
+                   (SMIv2)";
+     }
+
+     typedef zero-based-counter64 {
+       type yang:counter64;
+       default "0";
+       description
+        "The zero-based-counter64 type represents a counter64 that
+         has the defined 'initial' value zero.
+         A schema node of this type will be set to zero (0) on creation
+         and will thereafter increase monotonically until it reaches
+         a maximum value of 2^64-1 (18446744073709551615 decimal),
+         when it wraps around and starts increasing again from zero.
+
+         Provided that an application discovers a new schema node
+         of this type within the minimum time to wrap, it can use the
+         'initial' value as a delta.  It is important for a management
+         station to be aware of this minimum time and the actual time
+         between polls, and to discard data if the actual time is too
+         long or there is no defined minimum time.
+
+         In the value set and its semantics, this type is equivalent
+         to the ZeroBasedCounter64 textual convention of the SMIv2.";
+       reference
+        "RFC 2856: Textual Conventions for Additional High Capacity
+                   Data Types";
+     }
+
+     typedef gauge32 {
+       type uint32;
+       description
+        "The gauge32 type represents a non-negative integer, which
+         may increase or decrease, but shall never exceed a maximum
+         value, nor fall below a minimum value.  The maximum value
+         cannot be greater than 2^32-1 (4294967295 decimal), and
+         the minimum value cannot be smaller than 0.  The value of
+         a gauge32 has its maximum value whenever the information
+         being modeled is greater than or equal to its maximum
+         value, and has its minimum value whenever the information
+         being modeled is smaller than or equal to its minimum value.
+         If the information being modeled subsequently decreases
+         below (increases above) the maximum (minimum) value, the
+         gauge32 also decreases (increases).
+
+         In the value set and its semantics, this type is equivalent
+         to the Gauge32 type of the SMIv2.";
+       reference
+        "RFC 2578: Structure of Management Information Version 2
+                   (SMIv2)";
+     }
+
+     typedef gauge64 {
+       type uint64;
+       description
+        "The gauge64 type represents a non-negative integer, which
+         may increase or decrease, but shall never exceed a maximum
+         value, nor fall below a minimum value.  The maximum value
+         cannot be greater than 2^64-1 (18446744073709551615), and
+         the minimum value cannot be smaller than 0.  The value of
+         a gauge64 has its maximum value whenever the information
+         being modeled is greater than or equal to its maximum
+         value, and has its minimum value whenever the information
+         being modeled is smaller than or equal to its minimum value.
+         If the information being modeled subsequently decreases
+         below (increases above) the maximum (minimum) value, the
+         gauge64 also decreases (increases).
+
+         In the value set and its semantics, this type is equivalent
+         to the CounterBasedGauge64 SMIv2 textual convention defined
+         in RFC 2856";
+       reference
+        "RFC 2856: Textual Conventions for Additional High Capacity
+                   Data Types";
+     }
+
+     /*** collection of identifier-related types ***/
+
+     typedef object-identifier {
+       type string {
+         pattern '(([0-1](\.[1-3]?[0-9]))|(2\.(0|([1-9]\d*))))'
+               + '(\.(0|([1-9]\d*)))*';
+       }
+       description
+        "The object-identifier type represents administratively
+         assigned names in a registration-hierarchical-name tree.
+
+         Values of this type are denoted as a sequence of numerical
+         non-negative sub-identifier values.  Each sub-identifier
+         value MUST NOT exceed 2^32-1 (4294967295).  Sub-identifiers
+         are separated by single dots and without any intermediate
+         whitespace.
+
+         The ASN.1 standard restricts the value space of the first
+         sub-identifier to 0, 1, or 2.  Furthermore, the value space
+         of the second sub-identifier is restricted to the range
+         0 to 39 if the first sub-identifier is 0 or 1.  Finally,
+         the ASN.1 standard requires that an object identifier
+         has always at least two sub-identifiers.  The pattern
+         captures these restrictions.
+
+         Although the number of sub-identifiers is not limited,
+         module designers should realize that there may be
+         implementations that stick with the SMIv2 limit of 128
+         sub-identifiers.
+         This type is a superset of the SMIv2 OBJECT IDENTIFIER type
+         since it is not restricted to 128 sub-identifiers.  Hence,
+         this type SHOULD NOT be used to represent the SMIv2 OBJECT
+         IDENTIFIER type; the object-identifier-128 type SHOULD be
+         used instead.";
+       reference
+        "ISO9834-1: Information technology -- Open Systems
+         Interconnection -- Procedures for the operation of OSI
+         Registration Authorities: General procedures and top
+         arcs of the ASN.1 Object Identifier tree";
+     }
+
+     typedef object-identifier-128 {
+       type object-identifier {
+         pattern '\d*(\.\d*){1,127}';
+       }
+       description
+        "This type represents object-identifiers restricted to 128
+         sub-identifiers.
+
+         In the value set and its semantics, this type is equivalent
+         to the OBJECT IDENTIFIER type of the SMIv2.";
+       reference
+        "RFC 2578: Structure of Management Information Version 2
+                   (SMIv2)";
+     }
+
+     typedef yang-identifier {
+       type string {
+         length "1..max";
+         pattern '[a-zA-Z_][a-zA-Z0-9\-_.]*';
+         pattern '.|..|[^xX].*|.[^mM].*|..[^lL].*';
+       }
+       description
+         "A YANG identifier string as defined by the 'identifier'
+          rule in Section 12 of RFC 6020.  An identifier must
+          start with an alphabetic character or an underscore
+          followed by an arbitrary sequence of alphabetic or
+          numeric characters, underscores, hyphens, or dots.
+
+          A YANG identifier MUST NOT start with any possible
+          combination of the lowercase or uppercase character
+          sequence 'xml'.";
+       reference
+         "RFC 6020: YANG - A Data Modeling Language for the Network
+                    Configuration Protocol (NETCONF)";
+     }
+     /*** collection of types related to date and time***/
+
+     typedef date-and-time {
+       type string {
+         pattern '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?'
+               + '(Z|[\+\-]\d{2}:\d{2})';
+       }
+       description
+        "The date-and-time type is a profile of the ISO 8601
+         standard for representation of dates and times using the
+         Gregorian calendar.  The profile is defined by the
+         date-time production in Section 5.6 of RFC 3339.
+
+         The date-and-time type is compatible with the dateTime XML
+         schema type with the following notable exceptions:
+
+         (a) The date-and-time type does not allow negative years.
+
+         (b) The date-and-time time-offset -00:00 indicates an unknown
+             time zone (see RFC 3339) while -00:00 and +00:00 and Z
+             all represent the same time zone in dateTime.
+
+         (c) The canonical format (see below) of data-and-time values
+             differs from the canonical format used by the dateTime XML
+             schema type, which requires all times to be in UTC using
+             the time-offset 'Z'.
+
+         This type is not equivalent to the DateAndTime textual
+         convention of the SMIv2 since RFC 3339 uses a different
+         separator between full-date and full-time and provides
+         higher resolution of time-secfrac.
+
+         The canonical format for date-and-time values with a known time
+         zone uses a numeric time zone offset that is calculated using
+         the device's configured known offset to UTC time.  A change of
+         the device's offset to UTC time will cause date-and-time values
+         to change accordingly.  Such changes might happen periodically
+         in case a server follows automatically daylight saving time
+         (DST) time zone offset changes.  The canonical format for
+         date-and-time values with an unknown time zone (usually
+         referring to the notion of local time) uses the time-offset
+         -00:00.";
+       reference
+        "RFC 3339: Date and Time on the Internet: Timestamps
+         RFC 2579: Textual Conventions for SMIv2
+         XSD-TYPES: XML Schema Part 2: Datatypes Second Edition";
+     }
+     typedef timeticks {
+       type uint32;
+       description
+        "The timeticks type represents a non-negative integer that
+         represents the time, modulo 2^32 (4294967296 decimal), in
+         hundredths of a second between two epochs.  When a schema
+         node is defined that uses this type, the description of
+         the schema node identifies both of the reference epochs.
+
+         In the value set and its semantics, this type is equivalent
+         to the TimeTicks type of the SMIv2.";
+       reference
+        "RFC 2578: Structure of Management Information Version 2
+                   (SMIv2)";
+     }
+
+     typedef timestamp {
+       type yang:timeticks;
+       description
+        "The timestamp type represents the value of an associated
+         timeticks schema node at which a specific occurrence
+         happened.  The specific occurrence must be defined in the
+         description of any schema node defined using this type.  When
+         the specific occurrence occurred prior to the last time the
+         associated timeticks attribute was zero, then the timestamp
+         value is zero.  Note that this requires all timestamp values
+         to be reset to zero when the value of the associated timeticks
+         attribute reaches 497+ days and wraps around to zero.
+
+         The associated timeticks schema node must be specified
+         in the description of any schema node using this type.
+
+         In the value set and its semantics, this type is equivalent
+         to the TimeStamp textual convention of the SMIv2.";
+       reference
+        "RFC 2579: Textual Conventions for SMIv2";
+     }
+
+     /*** collection of generic address types ***/
+
+     typedef phys-address {
+       type string {
+         pattern '([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?';
+       }
+       description
+        "Represents media- or physical-level addresses represented
+         as a sequence octets, each octet represented by two hexadecimal
+         numbers.  Octets are separated by colons.  The canonical
+         representation uses lowercase characters.
+
+         In the value set and its semantics, this type is equivalent
+         to the PhysAddress textual convention of the SMIv2.";
+       reference
+        "RFC 2579: Textual Conventions for SMIv2";
+     }
+
+     typedef mac-address {
+       type string {
+         pattern '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}';
+       }
+       description
+        "The mac-address type represents an IEEE 802 MAC address.
+         The canonical representation uses lowercase characters.
+
+         In the value set and its semantics, this type is equivalent
+         to the MacAddress textual convention of the SMIv2.";
+       reference
+        "IEEE 802: IEEE Standard for Local and Metropolitan Area
+                   Networks: Overview and Architecture
+         RFC 2579: Textual Conventions for SMIv2";
+     }
+
+     /*** collection of XML-specific types ***/
+
+     typedef xpath1.0 {
+       type string;
+       description
+        "This type represents an XPATH 1.0 expression.
+
+         When a schema node is defined that uses this type, the
+         description of the schema node MUST specify the XPath
+         context in which the XPath expression is evaluated.";
+       reference
+        "XPATH: XML Path Language (XPath) Version 1.0";
+     }
+
+     /*** collection of string types ***/
+
+     typedef hex-string {
+       type string {
+         pattern '([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?';
+       }
+       description
+        "A hexadecimal string with octets represented as hex digits
+         separated by colons.  The canonical representation uses
+         lowercase characters.";
+     }
+
+     typedef uuid {
+       type string {
+         pattern '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-'
+               + '[0-9a-fA-F]{4}-[0-9a-fA-F]{12}';
+       }
+       description
+        "A Universally Unique IDentifier in the string representation
+         defined in RFC 4122.  The canonical representation uses
+         lowercase characters.
+
+         The following is an example of a UUID in string representation:
+         f81d4fae-7dec-11d0-a765-00a0c91e6bf6
+         ";
+       reference
+        "RFC 4122: A Universally Unique IDentifier (UUID) URN
+                   Namespace";
+     }
+
+     typedef dotted-quad {
+       type string {
+         pattern
+           '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+         + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])';
+       }
+       description
+         "An unsigned 32-bit number expressed in the dotted-quad
+          notation, i.e., four octets written as decimal numbers
+          and separated with the '.' (full stop) character.";
+     }
+   }
\ No newline at end of file
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/notifications@2008-07-14.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/notifications@2008-07-14.yang
new file mode 100644 (file)
index 0000000..77fbe98
--- /dev/null
@@ -0,0 +1,83 @@
+module notifications {
+
+    namespace "urn:ietf:params:xml:ns:netconf:notification:1.0";
+    prefix "ncEvent";
+
+    import ietf-yang-types { prefix yang; revision-date "2013-07-15";}
+
+    organization
+      "IETF NETCONF WG";
+
+    contact
+      "netconf@ops.ietf.org";
+
+    description
+      "Conversion of the 'ncEvent' XSD in the
+       NETCONF Notifications RFC.";
+
+    reference
+      "RFC 5277.";
+
+    revision 2008-07-14 {
+      description "RFC 5277 version.";
+    }
+
+    typedef streamNameType {
+      description
+        "The name of an event stream.";
+      type string;
+    }
+
+    rpc create-subscription {
+      description
+        "The command to create a notification subscription. It
+         takes as argument the name of the notification stream
+         and filter. Both of those options limit the content of
+         the subscription. In addition, there are two time-related
+         parameters, startTime and stopTime, which can be used to
+         select the time interval of interest to the notification
+         replay feature.";
+
+      input {
+        leaf stream {
+          description
+            "An optional parameter that indicates which stream of events
+             is of interest. If not present, then events in the default
+             NETCONF stream will be sent.";
+          type streamNameType;
+          default "NETCONF";
+        }
+
+        anyxml filter {
+          description
+            "An optional parameter that indicates which subset of all
+             possible events is of interest. The format of this
+             parameter is the same as that of the filter parameter
+             in the NETCONF protocol operations. If not present,
+             all events not precluded by other parameters will
+             be sent.";
+        }
+
+        leaf startTime {
+          description
+            "A parameter used to trigger the replay feature and
+             indicates that the replay should start at the time
+             specified. If start time is not present, this is not a
+             replay subscription.";
+          type yang:date-and-time;
+        }
+
+        leaf stopTime {
+          // must ". >= ../startTime";
+          description
+            "An optional parameter used with the optional replay
+             feature to indicate the newest notifications of
+             interest. If stop time is not present, the notifications
+             will continue until the subscription is terminated.
+             Must be used with startTime.";
+          type yang:date-and-time;
+        }
+      }
+    }
+}
+
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/org-openroadm-common-types@2018-10-19.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/org-openroadm-common-types@2018-10-19.yang
new file mode 100755 (executable)
index 0000000..c83e074
--- /dev/null
@@ -0,0 +1,675 @@
+module org-openroadm-common-types {
+  namespace "http://org/openroadm/common-types";
+  prefix org-openroadm-common-types;
+
+  organization
+    "Open ROADM MSA";
+  contact
+    "OpenROADM.org";
+  description
+    "YANG definitions of common types.
+       
+      Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, 
+      AT&T Intellectual Property.  All other rights reserved.
+      
+      Redistribution and use in source and binary forms, with or without modification, 
+      are permitted provided that the following conditions are met:
+      
+      * Redistributions of source code must retain the above copyright notice, this 
+        list of conditions and the following disclaimer.
+      * Redistributions in binary form must reproduce the above copyright notice, 
+        this list of conditions and the following disclaimer in the documentation and/or 
+        other materials provided with the distribution.
+      * Neither the Members of the Open ROADM MSA Agreement nor the names of its 
+        contributors may be used to endorse or promote products derived from this software 
+        without specific prior written permission.
+      
+      THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT ''AS IS'' 
+      AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+      WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+      IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT BE LIABLE FOR ANY DIRECT, 
+      INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+      NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE, DATA, 
+      OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+      WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+      ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+      POSSIBILITY OF SUCH DAMAGE";
+
+  revision 2018-10-19 {
+    description
+      "Version 2.2.1";
+  }
+  revision 2017-12-15 {
+    description
+      "Version 2.2";
+  }
+  revision 2017-09-29 {
+    description
+      "Version 2.1";
+  }
+  revision 2017-06-26 {
+    description
+      "Version 2.0";
+  }
+  revision 2016-10-14 {
+    description
+      "Version 1.2";
+  }
+
+  identity och-rate-identity {
+    description
+      "A unique och rate identification";
+  }
+
+  identity R200G {
+    base och-rate-identity;
+    description
+      "Identity for 200G Rate";
+  }
+
+  identity R100G {
+    base och-rate-identity;
+    description
+      "Identity for 100G Rate";
+  }
+
+  identity R10.7G {
+    base och-rate-identity;
+    description
+      "Identity for 10.7G Rate";
+  }
+
+  identity R11.1G {
+    base och-rate-identity;
+    description
+      "Identity for 11.1G Rate";
+  }
+
+  typedef node-types {
+    type enumeration {
+      enum "rdm" {
+        value 1;
+      }
+      enum "xpdr" {
+        value 2;
+      }
+      enum "ila" {
+        value 3;
+      }
+      enum "extplug" {
+        value 4;
+      }
+    }
+    description
+      "Identifier for node type
+       1. rdm for ROADM
+       2. xpdr for Transponder, Regen
+       3. ila for in-line amplifier
+       4. extplug for external plugable";
+  }
+
+  typedef node-id-type {
+    type string {
+      length "7..63";
+      pattern "([a-zA-Z][a-zA-Z0-9-]{5,18}[a-zA-Z0-9])" {
+        error-message
+          "A node-id must be 7 to 63 characters in length.
+           A node-id can contain letters, numbers, and hyphens.
+           The first character must be a letter.
+           The last character must be a letter or number.";
+      }
+    }
+    description
+      "Globally unique identifer for a device.";
+  }
+
+  typedef xpdr-node-types {
+    type enumeration {
+      enum "tpdr" {
+        value 1;
+      }
+      enum "mpdr" {
+        value 2;
+      }
+      enum "switch" {
+        value 3;
+      }
+      enum "regen" {
+        value 4;
+      }
+      enum "regen-uni" {
+        value 5;
+      }
+    }
+    description
+      "Identifier for Xponder node type
+       1. Transponder
+       2. Muxponder
+       3. OTN switchponder
+       4. Regenerator
+       5. Regenerator based on unidirectional model";
+  }
+
+  typedef frequency-THz {
+    type decimal64 {
+      fraction-digits 8;
+    }
+    units "THz";
+    description
+      "Frequency value in THz.";
+  }
+
+  typedef frequency-GHz {
+    type decimal64 {
+      fraction-digits 5;
+    }
+    units "GHz";
+    description
+      "Frequency value in GHz.";
+  }
+
+  typedef power-dBm {
+    type decimal64 {
+      fraction-digits 2;
+    }
+    units "dBm";
+    description
+      "Power value in dBm.";
+  }
+
+  typedef ratio-dB {
+    type decimal64 {
+      fraction-digits 3;
+    }
+    units "dB";
+    description
+      "Power ratio in dB.";
+  }
+
+  typedef fiber-pmd {
+    type decimal64 {
+      fraction-digits 2;
+    }
+    units "ps/(km[1/2])";
+    description
+      "Polarization Mode Dispersion expressed in ps/km(1/2).";
+  }
+
+  typedef amplifier-types {
+    type enumeration {
+      enum "standard" {
+        value 1;
+      }
+    }
+    description
+      "identifier for amplifier type
+       1. standard for amplifier as defined initially in the ROADM MSA specifications
+       To be completed if/when additional amplifier types are required ";
+  }
+
+  typedef line-amplifier-control-mode {
+    type enumeration {
+      enum "gainLoss" {
+        value 2;
+      }
+      enum "off" {
+        value 3;
+      }
+    }
+    description
+      "Identifies the line amplifier control mode, either off or gain.";
+  }
+
+  typedef amplifier-gain-range {
+    type enumeration {
+      enum "gain-range-1" {
+        value 1;
+      }
+      enum "gain-range-2" {
+        value 2;
+      }
+      enum "gain-range-3" {
+        value 3;
+      }
+      enum "gain-range-4" {
+        value 4;
+      }
+    }
+    description
+      "Operational mode for the amplifier:  
+       this parameter allows modeling different operational modes (gain ranges) ,notably for switched-gain amplifiers.
+       It indicates which performance model shall be used by the path feasibility engine. 
+       For standard amplifier, or when performance evaluation is based on incremental noise, use gain-range-1.
+       When performance evaluation is based on advanced parameters, specify used gain-range (1 to 4).
+       Up to release 2.1, only gain-range-1 is to be used (default value) ";
+  }
+
+  typedef severity {
+    type enumeration {
+      enum "critical" {
+        value 1;
+      }
+      enum "major" {
+        value 2;
+      }
+      enum "minor" {
+        value 3;
+      }
+      enum "warning" {
+        value 4;
+      }
+      enum "clear" {
+        value 5;
+      }
+      enum "indeterminate" {
+        value 6;
+      }
+    }
+    description
+      "Severity, based on X.733 perceived severity";
+  }
+
+  typedef activate-notification-type {
+    type enumeration {
+      enum "activate" {
+        value 1;
+        description
+          "software or database activation";
+      }
+      enum "commit" {
+        value 2;
+        description
+          "commit the software or database. 
+           For software activate, this event can happen in the following scenarios:
+             1) immediately when user issue db-activate command without rollBackTimer
+                or if the rollBackTimer is specified as 00-00-00;
+             2) when user issue cancel-rollback-timer before it expires and with accept=true.
+           For database activate, this event can occur in the following scenarios:
+             1) immediately when user issue db-activate command without rollBackTimer
+                or if the rollBackTimer is specified as 00-00-00;
+             2) when user issue cancel-rollback-timer before it expires and with accept=true.";
+      }
+      enum "cancel" {
+        value 3;
+        description
+          "cancel the database or software activation operation.
+           For software activate, this event can happen in the following cases:
+             1) when the rollBackTimer expires;
+             2) when the user issues cancel-rollback-timer with accept=false.  
+           For database activate, this event can happen in the following cases:
+             1) when the rollBackTimer expires;
+             2) when the user issues cancel-rollback-timer with accept=false.";
+      }
+    }
+    description
+      "Type of notification on software or database activation events";
+  }
+
+  typedef rpc-status {
+    type enumeration {
+      enum "Successful" {
+        value 1;
+      }
+      enum "Failed" {
+        value 2;
+      }
+    }
+    description
+      "status of RPC ";
+  }
+
+  typedef extended-rpc-status {
+    type enumeration {
+      enum "Successful" {
+        value 1;
+      }
+      enum "Failed" {
+        value 2;
+      }
+      enum "In-progress" {
+        value 3;
+      }
+    }
+    description
+      "status of RPC ";
+  }
+
+  typedef openroadm-version-type {
+    type enumeration {
+      enum "1.0" {
+        value 1;
+        description
+          "value for 1.0";
+      }
+      enum "2.0" {
+        value 2;
+        description
+          "value for 2.0";
+      }
+      enum "2.1" {
+        value 3;
+        description
+          "value for 2.1";
+      }
+      enum "2.2" {
+        value 4;
+        description
+          "value for 2.2";
+      }
+      enum "2.2.1" {
+        value 8;
+        description
+          "value for 2.2";
+      }
+    }
+    description
+      "OpenROADM version enum type";
+  }
+
+  typedef lifecycle-state {
+    type enumeration {
+      enum "deployed" {
+        value 1;
+      }
+      enum "planned" {
+        value 2;
+      }
+      enum "maintenance" {
+        value 3;
+      }
+      enum "deploying" {
+        value 4;
+      }
+      enum "undeploying" {
+        value 5;
+      }
+      enum "undeployed" {
+        value 6;
+      }
+      enum "proposed" {
+        value 7;
+      }
+      enum "draft" {
+        value 8;
+      }
+      enum "deploy-failed" {
+        value 9;
+      }
+      enum "undeploy-failed" {
+        value 10;
+      }
+    }
+    description
+      "Lifecycle state.";
+  }
+
+  typedef state {
+    type enumeration {
+      enum "inService" {
+        value 1;
+      }
+      enum "outOfService" {
+        value 2;
+      }
+      enum "degraded" {
+        value 3;
+      }
+    }
+    description
+      "State that indicates whether the resource is able to provide fullfill its role - carry traffic, etc.";
+  }
+
+  typedef optic-types {
+    type enumeration {
+      enum "gray" {
+        value 1;
+      }
+      enum "dwdm" {
+        value 2;
+      }
+    }
+  }
+
+  typedef equipment-type-enum {
+    type enumeration {
+      enum "other" {
+        value 1;
+      }
+      enum "powerSupply" {
+        value 2;
+      }
+      enum "shelfProcessor" {
+        value 3;
+      }
+      enum "crossConnect" {
+        value 4;
+      }
+      enum "fan" {
+        value 5;
+      }
+      enum "accessPanel" {
+        value 6;
+      }
+      enum "circuitPack" {
+        value 7;
+      }
+    }
+  }
+
+  typedef optical-control-mode {
+    type enumeration {
+      enum "power" {
+        value 1;
+      }
+      enum "gainLoss" {
+        value 2;
+      }
+      enum "off" {
+        value 3;
+      }
+    }
+    description
+      "Optical Control Mode: identifies specific algorithm related to power management and general optical control.";
+    reference "openroadm.org: Open ROADM MSA Specification.";
+  }
+
+  typedef direction {
+    type enumeration {
+      enum "tx" {
+        value 1;
+      }
+      enum "rx" {
+        value 2;
+      }
+      enum "bidirectional" {
+        value 3;
+      }
+      enum "notApplicable" {
+        value 4;
+      }
+    }
+  }
+
+  typedef location {
+    type enumeration {
+      enum "notApplicable" {
+        value 1;
+      }
+      enum "nearEnd" {
+        value 2;
+      }
+      enum "farEnd" {
+        value 3;
+      }
+    }
+  }
+
+  typedef wavelength-duplication-type {
+    type enumeration {
+      enum "one-per-srg" {
+        value 1;
+        description
+          "The SRG cannot handle wavelength duplication. Attempting to provision a connection on this SRG that uses the same wavelength as an existing service will result in failure.";
+      }
+      enum "one-per-degree" {
+        value 2;
+        description
+          "The SRG can handle wavelength duplication, but only one per degree. Attempting to provision a connection on this SRG that uses the same wavelength as an existing service will succeed, so long as the connections are not using the same degree.";
+      }
+    }
+    description
+      "One per srg is applied to C/D add/drop group
+       one per degree is applied to C/D/C add drop group";
+  }
+
+  typedef port-qual {
+    type enumeration {
+      enum "roadm-internal" {
+        value 1;
+      }
+      enum "roadm-external" {
+        value 2;
+      }
+      enum "xpdr-network" {
+        value 3;
+      }
+      enum "xpdr-client" {
+        value 4;
+      }
+      enum "otdr" {
+        value 5;
+      }
+      enum "switch-network" {
+        value 6;
+      }
+      enum "switch-client" {
+        value 7;
+      }
+      enum "ila-external" {
+        value 8;
+      }
+      enum "ila-internal" {
+        value 9;
+      }
+    }
+  }
+
+  typedef modulation-format {
+    type enumeration {
+      enum "bpsk" {
+        value 0;
+        description
+          "binary phase-shift keying";
+      }
+      enum "dc-dp-bpsk" {
+        value 1;
+        description
+          "DC dual-polarization binary phase-shift keying";
+      }
+      enum "qpsk" {
+        value 2;
+        description
+          "quadrature phase-shift keying";
+      }
+      enum "dp-qpsk" {
+        value 3;
+        description
+          "dual-polarization binary phase-shift keying";
+      }
+      enum "qam16" {
+        value 4;
+        description
+          "quadrature amplitude modulation 16";
+      }
+      enum "dp-qam16" {
+        value 5;
+        description
+          "dual-polarization quadrature amplitude modulation 16";
+      }
+      enum "dc-dp-qam16" {
+        value 6;
+        description
+          "DC dual-polarization quadrature amplitude modulation 16";
+      }
+      enum "qam8" {
+        value 7;
+        description
+          "quadrature amplitude modulation 8";
+      }
+      enum "dp-qam8" {
+        value 8;
+        description
+          "dual-polarization quadrature amplitude modulation 8";
+      }
+      enum "dc-dp-qam8" {
+        value 9;
+        description
+          "DC dual-polarization quadrature amplitude modulation 8";
+      }
+    }
+    description
+      "Modulation format";
+  }
+
+  grouping physical-location {
+    leaf rack {
+      type string;
+      mandatory false;
+    }
+    leaf shelf {
+      type string;
+      mandatory false;
+    }
+    leaf slot {
+      type string;
+      mandatory false;
+    }
+    leaf subSlot {
+      type string;
+      mandatory false;
+    }
+  }
+
+  grouping rpc-response-status {
+    leaf status {
+      type rpc-status;
+      mandatory true;
+      description
+        "Successful or Failed";
+    }
+    leaf status-message {
+      type string;
+      description
+        "Gives a more detailed status";
+    }
+  }
+
+  grouping extended-rpc-response-status {
+    leaf status {
+      type extended-rpc-status;
+      mandatory true;
+      description
+        "Successful, Failed or In-progress";
+    }
+    leaf status-message {
+      type string;
+      description
+        "Gives a more detailed status.";
+    }
+  }
+
+  grouping equipment-type {
+    leaf type {
+      type equipment-type-enum;
+      config false;
+      mandatory true;
+    }
+    leaf extension {
+      type string;
+      config false;
+      mandatory false;
+      description
+        "Populated with equipment type when enum value is set to vendorExtension";
+    }
+  }
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/org-openroadm-equipment-states-types@2017-12-15.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/org-openroadm-equipment-states-types@2017-12-15.yang
new file mode 100644 (file)
index 0000000..72ec70e
--- /dev/null
@@ -0,0 +1,139 @@
+module org-openroadm-equipment-states-types {
+  namespace "http://org/openroadm/equipment/states/types";
+  prefix org-openroadm-equipment-states-types;
+
+  organization
+    "Open ROADM MSA";
+  contact
+    "OpenROADM.org";
+  description
+    "YANG definitions for types of states of equipment (slot/subslot).
+     
+     Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, 
+     AT&T Intellectual Property.  All other rights reserved.
+     
+     Redistribution and use in source and binary forms, with or without modification, 
+     are permitted provided that the following conditions are met:
+     
+     * Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+     * Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation and/or 
+       other materials provided with the distribution.
+     * Neither the Members of the Open ROADM MSA Agreement nor the names of its 
+       contributors may be used to endorse or promote products derived from this software 
+       without specific prior written permission.
+     
+     THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT ''AS IS'' 
+     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+     IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT BE LIABLE FOR ANY DIRECT, 
+     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE, DATA, 
+     OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+     WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+     POSSIBILITY OF SUCH DAMAGE.";
+
+  revision 2017-12-15 {
+    description
+      "Version 2.2";
+  }
+  revision 2017-06-26 {
+    description
+      "Version 2.0";
+  }
+  revision 2016-10-14 {
+    description
+      "Version 1.2";
+  }
+
+  typedef admin-states {
+    type enumeration {
+      enum "inService" {
+        value 1;
+      }
+      enum "outOfService" {
+        value 2;
+      }
+      enum "maintenance" {
+        value 3;
+      }
+    }
+  }
+
+  typedef states {
+    type enumeration {
+      enum "reserved-for-facility-planned" {
+        value 1;
+        description
+          "equipment is planned for use by a service";
+      }
+      enum "not-reserved-planned" {
+        value 2;
+        description
+          "equipment is planned by not reserved for any purpose";
+      }
+      enum "reserved-for-maintenance-planned" {
+        value 3;
+        description
+          "equipment is planned for use as a maintenance spare";
+      }
+      enum "reserved-for-facility-unvalidated" {
+        value 4;
+        description
+          "equipment is reserved for use by a service but not
+           validated against planned equipment";
+      }
+      enum "not-reserved-unvalidated" {
+        value 5;
+        description
+          "equipment is not reserved for any purpose and
+           not validated against planned equipment";
+      }
+      enum "unknown-unvalidated" {
+        value 6;
+        description
+          "unknown equipment not validated against planned equipment";
+      }
+      enum "reserved-for-maintenance-unvalidated" {
+        value 7;
+        description
+          "equipment is to be used for use as a maintenance spare
+           but not validated against planned equipment";
+      }
+      enum "reserved-for-facility-available" {
+        value 8;
+        description
+          "reserved for use by a service and available";
+      }
+      enum "not-reserved-available" {
+        value 9;
+        description
+          "not reserved for use by a service and available";
+      }
+      enum "reserved-for-maintenance-available" {
+        value 10;
+        description
+          "reserved as a maintenance spare and available";
+      }
+      enum "reserved-for-reversion-inuse" {
+        value 11;
+        description
+          "equipment that is reserved as part of a home path
+           for a service that has been temporarily re-routed";
+      }
+      enum "not-reserved-inuse" {
+        value 12;
+        description
+          "equipment in use for a service";
+      }
+      enum "reserved-for-maintenance-inuse" {
+        value 13;
+        description
+          "maintenance spare equipment that is in use as a
+           maintenance spare";
+      }
+    }
+  }
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/org-openroadm-otn-common-types@2017-12-15.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/org-openroadm-otn-common-types@2017-12-15.yang
new file mode 100644 (file)
index 0000000..62f2b93
--- /dev/null
@@ -0,0 +1,246 @@
+module org-openroadm-otn-common-types {
+  namespace "http://org/openroadm/otn-common-types";
+  prefix org-openroadm-otn-common-types;
+
+  organization
+    "Open ROADM MSA";
+  contact
+    "OpenROADM.org";
+  description
+    "YANG definitions for common otn related type definitions.
+     
+     Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, 
+     AT&T Intellectual Property.  All other rights reserved.
+     
+     Redistribution and use in source and binary forms, with or without modification, 
+     are permitted provided that the following conditions are met:
+     
+     * Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+     * Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation and/or 
+       other materials provided with the distribution.
+     * Neither the Members of the Open ROADM MSA Agreement nor the names of its 
+       contributors may be used to endorse or promote products derived from this software 
+       without specific prior written permission.
+     
+     THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT ''AS IS'' 
+     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+     IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT BE LIABLE FOR ANY DIRECT, 
+     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE, DATA, 
+     OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+     WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+     POSSIBILITY OF SUCH DAMAGE.
+     
+     Also contains code components extracted from IETF Interfaces.  These code components
+     are copyrighted and licensed as follows:
+     
+     Copyright (c) 2016 IETF Trust and the persons identified as the document authors.
+     All rights reserved.
+     
+     This document is subject to BCP 78 and the IETF Trust’s Legal Provisions Relating
+     to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of
+     publication of this document. Please review these documents carefully, as they
+     describe your rights and restrictions with respect to this document. Code Components
+     extracted from this document must include Simplified BSD License text as described in
+     Section 4.e of the Trust Legal Provisions and are provided without warranty as
+     described in the Simplified BSD License.";
+
+  revision 2017-12-15 {
+    description
+      "Version 2.2";
+  }
+  revision 2017-09-29 {
+    description
+      "Version 2.1";
+  }
+
+  identity otu-rate-identity {
+    description
+      "A unique rate identification of the OTU.";
+  }
+
+  identity OTU4 {
+    base otu-rate-identity;
+    description
+      "Identity for an OTU4";
+  }
+
+  identity OTU3 {
+    base otu-rate-identity;
+    description
+      "Identity for an OTU3";
+  }
+
+  identity OTU2 {
+    base otu-rate-identity;
+    description
+      "Identity for an OTU2";
+  }
+
+  identity OTU2e {
+    base otu-rate-identity;
+    description
+      "Identity for an OTU2e";
+  }
+
+  identity OTU1 {
+    base otu-rate-identity;
+    description
+      "Identity for an OTU1";
+  }
+
+  identity OTU0 {
+    base otu-rate-identity;
+    description
+      "Identity for an OTU0";
+  }
+
+  identity OTUflex {
+    base otu-rate-identity;
+    description
+      "Identity for an OTUflex";
+  }
+
+  identity odu-rate-identity {
+    description
+      "A unique rate identification of the ODU.";
+  }
+
+  identity ODU4 {
+    base odu-rate-identity;
+    description
+      "Identity for an ODU4";
+  }
+
+  identity ODU3 {
+    base odu-rate-identity;
+    description
+      "Identity for an ODU3";
+  }
+
+  identity ODU2 {
+    base odu-rate-identity;
+    description
+      "Identity for an ODU2";
+  }
+
+  identity ODU2e {
+    base odu-rate-identity;
+    description
+      "Identity for an ODU2e";
+  }
+
+  identity ODU1 {
+    base odu-rate-identity;
+    description
+      "Identity for an ODU1";
+  }
+
+  identity ODU0 {
+    base odu-rate-identity;
+    description
+      "Identity for an ODU0";
+  }
+
+  identity ODUflex-cbr {
+    base odu-rate-identity;
+    description
+      "Identity for an ODUflex-cbr";
+  }
+
+  identity ODUflex-gfp {
+    base odu-rate-identity;
+    description
+      "Identity for an ODUflex-gfp";
+  }
+
+  identity odtu-type-identity {
+    description
+      "A unique identification for the MSI odtu type.";
+  }
+
+  identity ODTU4.ts-Allocated {
+    base odtu-type-identity;
+    description
+      "OPU4 MSI - ODTU4.ts, OPU4 MSI TS is occupied/allocated.
+       Applies to all ODTU4.x mappings";
+  }
+
+  identity ODTU01 {
+    base odtu-type-identity;
+    description
+      "ODTU01 MSI type";
+  }
+
+  identity ODTU12 {
+    base odtu-type-identity;
+    description
+      "ODTU12 MSI type";
+  }
+
+  identity ODTU13 {
+    base odtu-type-identity;
+    description
+      "ODTU13 MSI type";
+  }
+
+  identity ODTU23 {
+    base odtu-type-identity;
+    description
+      "ODTU23 MSI type";
+  }
+
+  identity ODTU2.ts {
+    base odtu-type-identity;
+    description
+      "ODTU2.ts MSI type";
+  }
+
+  identity ODTU3.ts {
+    base odtu-type-identity;
+    description
+      "ODTU3.ts MSI type";
+  }
+
+  identity unallocated {
+    base odtu-type-identity;
+    description
+      "Unallocated MSI type";
+  }
+
+  identity odu-function-identity {
+    description
+      "A unique identification of the ODUk interface function.";
+  }
+
+  identity ODU-TTP {
+    base odu-function-identity;
+    description
+      "ODU TTP facility facing trail termination";
+  }
+
+  identity ODU-CTP {
+    base odu-function-identity;
+    description
+      "ODU CTP connection termination";
+  }
+
+  identity ODU-TTP-CTP {
+    base odu-function-identity;
+    description
+      "ODU CTP mapper level connection termination with trail termination and client adaptation";
+  }
+
+  typedef payload-type-def {
+    type string {
+      length "2";
+      pattern "[0-9a-fA-F]*";
+    }
+    description
+      "Common type definition for odu payload-type";
+  }
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/org-openroadm-pm-types@2017-12-15.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/org-openroadm-pm-types@2017-12-15.yang
new file mode 100644 (file)
index 0000000..2501ee3
--- /dev/null
@@ -0,0 +1,483 @@
+module org-openroadm-pm-types {
+  namespace "http://org/openroadm/pm-types";
+  prefix org-openroadm-pm-types;
+
+  organization
+    "Open ROADM MSA";
+  contact
+    "OpenROADM.org";
+  description
+    "YANG definitions of performance management types.
+
+      Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016,
+      AT&T Intellectual Property.  All other rights reserved.
+
+      Redistribution and use in source and binary forms, with or without modification,
+      are permitted provided that the following conditions are met:
+
+      * Redistributions of source code must retain the above copyright notice, this
+        list of conditions and the following disclaimer.
+      * Redistributions in binary form must reproduce the above copyright notice,
+        this list of conditions and the following disclaimer in the documentation and/or
+        other materials provided with the distribution.
+      * Neither the Members of the Open ROADM MSA Agreement nor the names of its
+        contributors may be used to endorse or promote products derived from this software
+        without specific prior written permission.
+
+      THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT ''AS IS''
+      AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+      WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+      IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT BE LIABLE FOR ANY DIRECT,
+      INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+      NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE, DATA,
+      OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+      WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+      ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+      POSSIBILITY OF SUCH DAMAGE";
+
+  revision 2017-12-15 {
+    description
+      "Version 2.2";
+  }
+  revision 2017-09-29 {
+    description
+      "Version 2.1";
+  }
+  revision 2017-06-26 {
+    description
+      "Version 2.0";
+  }
+  revision 2016-10-14 {
+    description
+      "Version 1.2";
+  }
+
+  typedef pm-granularity {
+    type enumeration {
+      enum "notApplicable" {
+        value 1;
+        description
+          "This is for total statistic counters on devices that support
+              them.";
+      }
+      enum "15min" {
+        value 2;
+      }
+      enum "24Hour" {
+        value 3;
+      }
+    }
+    description
+      "Granularity of PM bin";
+  }
+
+  typedef pm-data-type {
+    type union {
+      type uint64;
+      type int64;
+      type decimal64 {
+        fraction-digits 2;
+      }
+      type decimal64 {
+        fraction-digits 17;
+      }
+    }
+  }
+
+  typedef validity {
+    type enumeration {
+      enum "complete" {
+        value 1;
+      }
+      enum "partial" {
+        value 2;
+      }
+      enum "suspect" {
+        value 3;
+      }
+    }
+    description
+      "Validity of data";
+  }
+
+  typedef pm-names-enum {
+    type enumeration {
+      enum "vendorExtension" {
+        value 1;
+        description
+          "vendor extension";
+      }
+      enum "bitErrorRate" {
+        value 2;
+        description
+          "Bit error rate (BER)";
+      }
+      enum "opticalPowerOutput" {
+        value 3;
+        description
+          "Optical Power Output (OPOUT-OTS, OPOUT-OMS, OPT-OCH). Total optical power includes Variable Optical Attenuator (VOA) attenuation";
+      }
+      enum "opticalReturnLoss" {
+        value 4;
+        description
+          "Optical Return Loss (ORL-OTS) - at MW port(s) B";
+      }
+      enum "opticalPowerInput" {
+        value 5;
+        description
+          "Optical Power Input (OPIN-OTS, OPIN-OMS, OPR-OCH). Total optical power";
+      }
+      enum "codeViolations" {
+        value 8;
+        description
+          "Code Violations (CV)";
+      }
+      enum "erroredSeconds" {
+        value 9;
+        description
+          "Errored Seconds (ES)";
+      }
+      enum "severelyErroredSeconds" {
+        value 10;
+        description
+          "Severely Errored Seconds (SES)";
+      }
+      enum "unavailableSeconds" {
+        value 11;
+        description
+          "Unavailable Seconds (UAS)";
+      }
+      enum "inFrames" {
+        value 12;
+        description
+          "In frames (INFRAMES-E)";
+      }
+      enum "inFramesErrored" {
+        value 13;
+        description
+          "In frames errored (INFRAMESERR-E)";
+      }
+      enum "outFrames" {
+        value 14;
+        description
+          "Out frames (OUTFRAMES-E)";
+      }
+      enum "erroredSecondsEthernet" {
+        value 15;
+        description
+          "Errored Seconds Ethernet (ES-E)";
+      }
+      enum "severelyErroredSecondsEthernet" {
+        value 16;
+        description
+          "Severly Errored Seconds, Ethernet (SES-E)";
+      }
+      enum "unavailableSecondsEthernet" {
+        value 17;
+        description
+          "Unavailable Seconds, Ethernet (UAS-E)";
+      }
+      enum "erroredBlockCount" {
+        value 18;
+        description
+          "Errored block count";
+      }
+      enum "delay" {
+        value 19;
+        description
+          "Number of frames between a DMValue toggle event and the received DMp signal value toggle event";
+      }
+      enum "defectSeconds" {
+        value 20;
+        description
+          "Defect Seconds (DS)";
+      }
+      enum "backwardIncomingAlignmentError" {
+        value 21;
+        description
+          "Backward Incoming Alignment Error (BIAE)";
+      }
+      enum "incomingAlignmentError" {
+        value 22;
+        description
+          "Incoming Alignment Error (IAE)";
+      }
+      enum "opticalPowerOutputMin" {
+        value 23;
+        description
+          "Minimum Optical Power Output (OPOUT-OTS). Total optical power includes Variable Optical Attenuator (VOA) attenuation";
+      }
+      enum "opticalPowerOutputMax" {
+        value 24;
+        description
+          "Maximum Optical Power Output (OPOUT-OTS). Total optical power includes Variable Optical Attenuator (VOA) attenuation";
+      }
+      enum "opticalPowerOutputAvg" {
+        value 25;
+        description
+          "Average Optical Power Output (OPOUT-OTS). Total optical power includes Variable Optical Attenuator (VOA) attenuation";
+      }
+      enum "opticalPowerInputMin" {
+        value 26;
+        description
+          "Minimum Optical Power Input (OPIN-OTS). Total optical power";
+      }
+      enum "opticalPowerInputMax" {
+        value 27;
+        description
+          "Maximum Optical Power Input (OPIN-OTS). Total optical power";
+      }
+      enum "opticalPowerInputAvg" {
+        value 28;
+        description
+          "Average Optical Power Input (OPIN-OTS). Total optical power";
+      }
+      enum "opticalPowerOutputOSC" {
+        value 29;
+        description
+          "OSC Optical Power Output (OPT-OSC). OSC Transmit power on MW port";
+      }
+      enum "opticalPowerOutputOSCMin" {
+        value 30;
+        description
+          "Minimum OSC Optical Power Output (OPT-OSC). OSC Transmit power on MW port";
+      }
+      enum "opticalPowerOutputOSCMax" {
+        value 31;
+        description
+          "Maximum OSC Optical Power Output (OPT-OSC). OSC Transmit power on MW port";
+      }
+      enum "opticalPowerOutputOSCAvg" {
+        value 32;
+        description
+          "Average OSC Optical Power Output (OPT-OSC). OSC Transmit power on MW port";
+      }
+      enum "opticalPowerInputOSC" {
+        value 33;
+        description
+          "OSC Optical Power Input (OPR-OSC). OSC Receive power on MW port";
+      }
+      enum "opticalPowerInputOSCMin" {
+        value 34;
+        description
+          "Minimum OSC Optical Power Input (OPR-OSC). OSC Receive power on MW port";
+      }
+      enum "opticalPowerInputOSCMax" {
+        value 35;
+        description
+          "Maximum OSC Optical Power Input (OPR-OSC). OSC Receive power on MW port";
+      }
+      enum "opticalPowerInputOSCAvg" {
+        value 36;
+        description
+          "Average OSC Optical Power Input (OPR-OSC). OSC Receive power on MW port";
+      }
+      enum "preFECCorrectedErrors" {
+        value 37;
+        description
+          "pFEC corrected Errors";
+      }
+      enum "totalOpticalPowerInput" {
+        value 38;
+        description
+          "Total Optical Power Input.";
+      }
+      enum "totalOpticalPowerInputMin" {
+        value 39;
+        description
+          "Minumun Total Optical Power Input.";
+      }
+      enum "totalOpticalPowerInputMax" {
+        value 40;
+        description
+          "Maximum Total Optical Power Input.";
+      }
+      enum "totalOpticalPowerInputAvg" {
+        value 41;
+        description
+          "Average Total Optical Power Input.";
+      }
+      enum "FECCorrectableBlocks" {
+        value 42;
+        description
+          "FEC Correctable Blocks.";
+      }
+      enum "FECUncorrectableBlocks" {
+        value 43;
+        description
+          "FEC Uncorrectable Blocks.";
+      }
+      enum "BIPErrorCounter" {
+        value 56;
+        description
+          "BIP Error Counter";
+      }
+      enum "protectionSwitchingCount" {
+        value 57;
+        description
+          "Protection Switching Count (PSC)";
+      }
+      enum "protectionSwitchingDuration" {
+        value 58;
+        description
+          "Protection Switching Duration in seconds (PSD)";
+      }
+      enum "erroredBlockCountTCM1-up" {
+        value 59;
+        description
+          "errored Blocks Count on TCM1 up direction.";
+      }
+      enum "erroredBlockCountTCM2-up" {
+        value 60;
+        description
+          "errored Blocks Count on TCM2 up direction.";
+      }
+      enum "erroredBlockCountTCM3-up" {
+        value 61;
+        description
+          "errored Blocks Count on TCM3 up direction.";
+      }
+      enum "erroredBlockCountTCM4-up" {
+        value 62;
+        description
+          "errored Blocks Count on TCM4 up direction.";
+      }
+      enum "erroredBlockCountTCM5-up" {
+        value 63;
+        description
+          "errored Blocks Count on TCM5 up direction.";
+      }
+      enum "erroredBlockCountTCM6-up" {
+        value 64;
+        description
+          "errored Blocks Count on TCM6 up direction.";
+      }
+      enum "delayTCM1-up" {
+        value 65;
+        description
+          "Delay on TCM1 up direction.";
+      }
+      enum "delayTCM2-up" {
+        value 66;
+        description
+          "Delay on TCM2 up direction.";
+      }
+      enum "delayTCM3-up" {
+        value 67;
+        description
+          "Delay on TCM3 up direction.";
+      }
+      enum "delayTCM4-up" {
+        value 68;
+        description
+          "Delay on TCM4 up direction.";
+      }
+      enum "delayTCM5-up" {
+        value 69;
+        description
+          "Delay on TCM5 up direction.";
+      }
+      enum "delayTCM6-up" {
+        value 70;
+        description
+          "Delay on TCM6 up direction.";
+      }
+      enum "erroredBlockCountTCM1-down" {
+        value 71;
+        description
+          "errored Blocks Count on TCM1 down direction.";
+      }
+      enum "erroredBlockCountTCM2-down" {
+        value 72;
+        description
+          "errored Blocks Count on TCM2 down direction.";
+      }
+      enum "erroredBlockCountTCM3-down" {
+        value 73;
+        description
+          "errored Blocks Count on TCM3 down direction.";
+      }
+      enum "erroredBlockCountTCM4-down" {
+        value 74;
+        description
+          "errored Blocks Count on TCM4 down direction.";
+      }
+      enum "erroredBlockCountTCM5-down" {
+        value 75;
+        description
+          "errored Blocks Count on TCM5 down direction.";
+      }
+      enum "erroredBlockCountTCM6-down" {
+        value 76;
+        description
+          "errored Blocks Count on TCM6 down direction.";
+      }
+      enum "delayTCM1-down" {
+        value 77;
+        description
+          "Delay on TCM1 down direction.";
+      }
+      enum "delayTCM2-down" {
+        value 78;
+        description
+          "Delay on TCM2 down direction.";
+      }
+      enum "delayTCM3-down" {
+        value 79;
+        description
+          "Delay on TCM3 down direction.";
+      }
+      enum "delayTCM4-down" {
+        value 80;
+        description
+          "Delay on TCM4 down direction.";
+      }
+      enum "delayTCM5-down" {
+        value 81;
+        description
+          "Delay on TCM5 down direction.";
+      }
+      enum "delayTCM6-down" {
+        value 82;
+        description
+          "Delay on TCM6 down direction.";
+      }
+    }
+  }
+
+  grouping pm-measurement {
+    description
+      "Set of parameters related to a PM Measurement";
+    leaf pmParameterValue {
+      type pm-data-type;
+      config false;
+      mandatory true;
+    }
+    leaf pmParameterUnit {
+      type string;
+      mandatory false;
+      description
+        "Unit PM parameter has been measured - frames, packets, u, etc";
+    }
+    leaf validity {
+      type validity;
+      mandatory false;
+    }
+  }
+
+  grouping pm-names {
+    description
+      "Name of PM parameter. Consisists of a set list of parameters,
+       plus an extension field to support addition parameters.";
+    leaf type {
+      type pm-names-enum;
+      mandatory true;
+    }
+    leaf extension {
+      type string;
+      description
+        "name of parameter, when enum value set to vendorExtension because
+         name not found in pm-names-enum";
+    }
+  }
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/org-openroadm-pm@2018-10-19.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/org-openroadm-pm@2018-10-19.yang
new file mode 100755 (executable)
index 0000000..c1985c9
--- /dev/null
@@ -0,0 +1,299 @@
+module org-openroadm-pm {
+  namespace "http://org/openroadm/pm";
+  prefix org-openroadm-pm;
+
+  import ietf-yang-types {
+    prefix yang;
+    revision-date 2013-07-15;
+  }
+  import org-openroadm-common-types {
+    prefix org-openroadm-common-types;
+    revision-date 2018-10-19;
+  }
+  import org-openroadm-resource {
+    prefix org-openroadm-resource;
+    revision-date 2018-10-19;
+  }
+  import org-openroadm-resource-types {
+    prefix org-openroadm-resource-types;
+    revision-date 2018-10-19;
+  }
+  import org-openroadm-pm-types {
+    prefix org-openroadm-pm-types;
+    revision-date 2017-12-15;
+  }
+
+  organization
+    "Open ROADM MSA";
+  contact
+    "OpenROADM.org";
+  description
+    "YANG definitions of performance management.
+       
+      Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, 
+      AT&T Intellectual Property.  All other rights reserved.
+      
+      Redistribution and use in source and binary forms, with or without modification, 
+      are permitted provided that the following conditions are met:
+      
+      * Redistributions of source code must retain the above copyright notice, this 
+        list of conditions and the following disclaimer.
+      * Redistributions in binary form must reproduce the above copyright notice, 
+        this list of conditions and the following disclaimer in the documentation and/or 
+        other materials provided with the distribution.
+      * Neither the Members of the Open ROADM MSA Agreement nor the names of its 
+        contributors may be used to endorse or promote products derived from this software 
+        without specific prior written permission.
+      
+      THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT ''AS IS'' 
+      AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+      WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+      IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT BE LIABLE FOR ANY DIRECT, 
+      INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+      NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE, DATA, 
+      OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+      WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+      ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+      POSSIBILITY OF SUCH DAMAGE";
+
+  revision 2018-10-19 {
+    description
+      "Version 2.2.1";
+  }
+  revision 2017-12-15 {
+    description
+      "Version 2.2";
+  }
+  revision 2017-09-29 {
+    description
+      "Version 2.1";
+  }
+  revision 2017-07-28 {
+    description
+      "Version 2.0.1 - added revision-date to imports";
+  }
+  revision 2017-06-26 {
+    description
+      "Version 2.0";
+  }
+  revision 2016-10-14 {
+    description
+      "Version 1.2";
+  }
+
+  grouping current-pm-group {
+    description
+      "PM Data with current values - both realtime (granularity=notApplicable)
+       and binned (granularity=15 minute, 24h))";
+    leaf pm-resource-instance {
+      type instance-identifier;
+      config false;
+      mandatory true;
+      description
+        "Retrieves all PM associate with the resource instance";
+    }
+    leaf pm-resource-type {
+      type org-openroadm-resource-types:resource-type-enum;
+      config false;
+      mandatory true;
+      description
+        "The supported pm-resource-type associated with the given resource instance.";
+    }
+    leaf pm-resource-type-extension {
+      type string;
+      config false;
+      description
+        "The resource type extension when the type is not defined in the resource-type-enum.";
+    }
+    leaf retrieval-time {
+      type yang:date-and-time;
+      config false;
+      mandatory true;
+      description
+        "Represents the time when the data is being read, not the bin start or end time.";
+    }
+    list current-pm {
+      key "type extension location direction";
+      config false;
+      uses current-pm-val-group;
+    }
+  }
+
+  grouping current-pm-val-group {
+    uses org-openroadm-pm-types:pm-names;
+    leaf location {
+      type org-openroadm-common-types:location;
+    }
+    leaf direction {
+      type org-openroadm-common-types:direction;
+    }
+    list measurement {
+      key "granularity";
+      leaf granularity {
+        type org-openroadm-pm-types:pm-granularity;
+      }
+      uses org-openroadm-pm-types:pm-measurement;
+    }
+  }
+
+  grouping historical-pm-group {
+    description
+      "PM Data with historical values - binned (granularity=15 minute, 24h))";
+    leaf pm-resource-instance {
+      type instance-identifier;
+      config false;
+      mandatory true;
+      description
+        "Retrieves all PM associate with the resource instance";
+    }
+    leaf pm-resource-type {
+      type org-openroadm-resource-types:resource-type-enum;
+      config false;
+      mandatory true;
+    }
+    leaf pm-resource-type-extension {
+      type string;
+      config false;
+      description
+        "The resource type extension when the type is not defined in the resource-type-enum.";
+    }
+    list historical-pm {
+      key "type extension location direction";
+      uses historical-pm-val-group;
+    }
+  }
+
+  grouping historical-pm-val-group {
+    description
+      "PM Data with historical values";
+    uses org-openroadm-pm-types:pm-names;
+    leaf location {
+      type org-openroadm-common-types:location;
+    }
+    leaf direction {
+      type org-openroadm-common-types:direction;
+    }
+    list measurement {
+      key "granularity bin-number";
+      leaf granularity {
+        type org-openroadm-pm-types:pm-granularity;
+        mandatory true;
+      }
+      leaf bin-number {
+        type uint16 {
+          range "1..max";
+        }
+        config false;
+        mandatory true;
+      }
+      uses org-openroadm-pm-types:pm-measurement;
+      leaf completion-time {
+        type yang:date-and-time;
+        config false;
+        mandatory true;
+        description
+          "The time at the end of the period; For example if bin starts at 
+           01:15:00 and ends at 01:29:59, the completion-time is 01:29:59";
+      }
+    }
+  }
+
+  grouping collect-history-pm-group {
+    leaf pm-filename {
+      type string {
+        length "10..255";
+      }
+      description
+        "The file name to write the historical PM data. 
+         The controller should be able to use this name to retrieve the file via ftp/sftp.
+         The file name should be unique for each RPC request since a new RPC request 
+         could be initiated while the file transfer of the previous file is still in progress.
+         
+         The file content should be written in xml format based on the historical-pm-list 
+         yang definition and the file should be gzip compressed.";
+    }
+    uses org-openroadm-common-types:rpc-response-status;
+  }
+
+  rpc clear-pm {
+    description
+      "Command to initialize PM data";
+    input {
+      uses org-openroadm-resource:resource;
+      leaf pm-type {
+        type enumeration {
+          enum "current" {
+            value 1;
+          }
+          enum "all" {
+            value 2;
+          }
+        }
+        default "current";
+      }
+      leaf granularity {
+        type org-openroadm-pm-types:pm-granularity;
+        default "15min";
+      }
+    }
+    output {
+      uses org-openroadm-common-types:rpc-response-status;
+    }
+  }
+  rpc collect-historical-pm-file {
+    description
+      "Command to query historical PM data.
+       The device should be able to process an rpc request for 15min data 
+       and a separate request for 24hour data in parallel.";
+    input {
+      leaf from-bin-number {
+        type uint16 {
+          range "1..max";
+        }
+        default "1";
+        description
+          "The start bin-number of the range";
+      }
+      leaf to-bin-number {
+        type uint16 {
+          range "1..max";
+        }
+        default "1";
+        description
+          "The end bin-number of the range";
+      }
+      leaf granularity {
+        type org-openroadm-pm-types:pm-granularity;
+        default "15min";
+        description
+          "The granularity of the retrieve, default to 15 minitues PM";
+      }
+    }
+    output {
+      uses collect-history-pm-group;
+    }
+  }
+  notification historical-pm-collect-result {
+    description
+      "This Notification is sent when the pm collection is succesful or failed.";
+    uses collect-history-pm-group;
+  }
+  container current-pm-list {
+    config false;
+    description
+      "List of current PMs.";
+    list current-pm-entry {
+      key "pm-resource-type pm-resource-type-extension pm-resource-instance";
+      uses current-pm-group;
+    }
+  }
+  container historical-pm-list {
+    config false;
+    description
+      "List of historical PM";
+    list historical-pm-entry {
+      key "pm-resource-type pm-resource-type-extension pm-resource-instance";
+      uses historical-pm-group;
+    }
+  }
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/org-openroadm-port-types@2018-10-19.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/org-openroadm-port-types@2018-10-19.yang
new file mode 100755 (executable)
index 0000000..8db93cc
--- /dev/null
@@ -0,0 +1,225 @@
+module org-openroadm-port-types {
+  namespace "http://org/openroadm/port/types";
+  prefix org-openroadm-port-types;
+
+  import org-openroadm-common-types {
+    prefix org-openroadm-common-types;
+    revision-date 2018-10-19;
+  }
+
+  organization
+    "Open ROADM MSA";
+  contact
+    "OpenROADM.org";
+  description
+    "YANG definitions for port types.
+     
+     Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, 
+     AT&T Intellectual Property.  All other rights reserved.
+     
+     Redistribution and use in source and binary forms, with or without modification, 
+     are permitted provided that the following conditions are met:
+     
+     * Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+     * Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation and/or 
+       other materials provided with the distribution.
+     * Neither the Members of the Open ROADM MSA Agreement nor the names of its 
+       contributors may be used to endorse or promote products derived from this software 
+       without specific prior written permission.
+     
+     THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT ''AS IS'' 
+     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+     IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT BE LIABLE FOR ANY DIRECT, 
+     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE, DATA, 
+     OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+     WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+     POSSIBILITY OF SUCH DAMAGE.";
+
+  revision 2018-10-19 {
+    description
+      "Version 2.2.1";
+  }
+  revision 2017-12-15 {
+    description
+      "Version 2.2";
+  }
+  revision 2017-09-29 {
+    description
+      "Version 2.1";
+  }
+  revision 2017-07-28 {
+    description
+      "Version 2.0.1 - added revision-date to imports";
+  }
+  revision 2017-06-26 {
+    description
+      "Version 2.0";
+  }
+  revision 2016-10-14 {
+    description
+      "Version 1.2";
+  }
+
+  identity supported-if-capability {
+    description
+      "Base identity from which specific supported interfaces are derived";
+  }
+
+  identity if-100GE {
+    base supported-if-capability;
+  }
+
+  identity if-OMS {
+    base supported-if-capability;
+  }
+
+  identity if-OTS {
+    base supported-if-capability;
+  }
+
+  identity if-OCH {
+    base supported-if-capability;
+  }
+
+  identity if-1GE {
+    base supported-if-capability;
+  }
+
+  identity if-10GE {
+    base supported-if-capability;
+  }
+
+  identity if-40GE {
+    base supported-if-capability;
+  }
+
+  identity if-OCH-OTU1-ODU1 {
+    base supported-if-capability;
+  }
+
+  identity if-OCH-OTU2-ODU2 {
+    base supported-if-capability;
+  }
+
+  identity if-OCH-OTU2E-ODU2E {
+    base supported-if-capability;
+  }
+
+  identity if-OCH-OTU3-ODU3 {
+    base supported-if-capability;
+  }
+
+  identity if-OCH-OTU4-ODU4 {
+    base supported-if-capability;
+  }
+
+  identity if-OTU4-ODU4 {
+    base supported-if-capability;
+  }
+
+  identity if-OTU1-ODU1 {
+    base supported-if-capability;
+  }
+
+  identity if-OTU2-ODU2 {
+    base supported-if-capability;
+  }
+
+  identity if-OTU2e-ODU2e {
+    base supported-if-capability;
+  }
+
+  identity if-OTU3-ODU3 {
+    base supported-if-capability;
+  }
+
+  identity if-1GE-ODU0 {
+    base supported-if-capability;
+  }
+
+  identity if-10GE-ODU2 {
+    base supported-if-capability;
+  }
+
+  identity if-10GE-ODU2e {
+    base supported-if-capability;
+  }
+
+  identity if-40GE-ODU3 {
+    base supported-if-capability;
+  }
+
+  identity if-100GE-ODU4 {
+    base supported-if-capability;
+  }
+
+  identity supported-xpdr-capability {
+    description
+      "Base identity from which specific supported xponder are derived";
+  }
+
+  identity Transponder {
+    base supported-xpdr-capability;
+  }
+
+  identity Regen {
+    base supported-xpdr-capability;
+  }
+
+  typedef port-wavelength-types {
+    type enumeration {
+      enum "wavelength" {
+        value 1;
+        description
+          "Port on a transponder or ROADM SRG add drop";
+      }
+      enum "multi-wavelength" {
+        value 2;
+        description
+          "External port connecting to other roadm.";
+      }
+    }
+    description
+      "Port types.";
+  }
+
+  grouping common-port {
+    leaf port-power-capability-min-rx {
+      type org-openroadm-common-types:power-dBm;
+      config false;
+      description
+        "Based on port capabilities, the minimum power in the system spec for this port to
+         provide optimum function in rx direction";
+    }
+    leaf port-power-capability-min-tx {
+      type org-openroadm-common-types:power-dBm;
+      config false;
+      description
+        "Based on port capabilities, the minimum power in the system spec for this port to
+         provide optimum function in tx direction.";
+    }
+    leaf port-power-capability-max-rx {
+      type org-openroadm-common-types:power-dBm;
+      config false;
+      description
+        "Based on port capabilities, the maximum power in the system spec for this port to
+         provide optimum function in rx direction.";
+    }
+    leaf port-power-capability-max-tx {
+      type org-openroadm-common-types:power-dBm;
+      config false;
+      description
+        "Based on port capabilities, the maximum power in the system spec for this port to
+         provide optimum function in tx direction.";
+    }
+  }
+
+  grouping roadm-port {
+    uses common-port;
+  }
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/org-openroadm-resource-types@2018-10-19.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/org-openroadm-resource-types@2018-10-19.yang
new file mode 100755 (executable)
index 0000000..374ff1d
--- /dev/null
@@ -0,0 +1,362 @@
+module org-openroadm-resource-types {
+  namespace "http://org/openroadm/resource/types";
+  prefix org-openroadm-resource-types;
+
+  import org-openroadm-common-types {
+    prefix org-openroadm-common-types;
+    revision-date 2018-10-19;
+  }
+
+  organization
+    "Open ROADM MSA";
+  contact
+    "OpenROADM.org";
+  description
+    "YANG definitions of common resource types.
+       
+      Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, 
+      AT&T Intellectual Property.  All other rights reserved.
+      
+      Redistribution and use in source and binary forms, with or without modification, 
+      are permitted provided that the following conditions are met:
+      
+      * Redistributions of source code must retain the above copyright notice, this 
+        list of conditions and the following disclaimer.
+      * Redistributions in binary form must reproduce the above copyright notice, 
+        this list of conditions and the following disclaimer in the documentation and/or 
+        other materials provided with the distribution.
+      * Neither the Members of the Open ROADM MSA Agreement nor the names of its 
+        contributors may be used to endorse or promote products derived from this software 
+        without specific prior written permission.
+      
+      THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT ''AS IS'' 
+      AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+      WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+      IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT BE LIABLE FOR ANY DIRECT, 
+      INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+      NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE, DATA, 
+      OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+      WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+      ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+      POSSIBILITY OF SUCH DAMAGE";
+
+  revision 2018-10-19 {
+    description
+      "Version 2.2.1";
+  }
+  revision 2017-12-15 {
+    description
+      "Version 2.2";
+  }
+  revision 2017-09-29 {
+    description
+      "Version 2.1";
+  }
+  revision 2017-06-26 {
+    description
+      "Version 2.0";
+  }
+  revision 2016-10-14 {
+    description
+      "Version 1.2";
+  }
+
+  typedef resource-type-enum {
+    type enumeration {
+      enum "other" {
+        value 1;
+        description
+          "Resource of type not found in list.";
+      }
+      enum "device" {
+        value 2;
+        description
+          "device - ROAMD, Xponder, etc";
+      }
+      enum "degree" {
+        value 3;
+        description
+          "degree";
+      }
+      enum "shared-risk-group" {
+        value 4;
+        description
+          "shared-risk-group";
+      }
+      enum "connection" {
+        value 5;
+        description
+          "connection - this is used by roadm-connection and odu-connection
+           since they are mutually exclusive in the model";
+      }
+      enum "connection-map" {
+        value 6;
+        description
+          "connection-map";
+      }
+      enum "port" {
+        value 7;
+        description
+          "port";
+      }
+      enum "circuit-pack" {
+        value 8;
+        description
+          "circuit pack";
+      }
+      enum "internal-link" {
+        value 9;
+        description
+          "internal-link";
+      }
+      enum "physical-link" {
+        value 10;
+        description
+          "physical-link";
+      }
+      enum "interface" {
+        value 11;
+        description
+          "interface";
+      }
+      enum "shelf" {
+        value 12;
+        description
+          "shelf";
+      }
+      enum "service" {
+        value 13;
+        description
+          "service";
+      }
+      enum "odu-sncp-pg" {
+        value 14;
+        description
+          "odu-sncp-pg";
+      }
+      enum "line-amplifier" {
+        value 15;
+        description
+          "line-amplifier";
+      }
+      enum "xponder" {
+        value 16;
+        description
+          "xponder";
+      }
+      enum "versioned-service" {
+        value 17;
+        description
+          "versioned-service";
+      }
+      enum "temp-service" {
+        value 18;
+        description
+          "temp-service";
+      }
+    }
+  }
+
+  typedef resource-notification-type {
+    type enumeration {
+      enum "resourceCreation" {
+        value 1;
+        description
+          "A new instance of a resource has been created.";
+      }
+      enum "resourceModification" {
+        value 2;
+        description
+          "An exhisting instance of a resource has been modified. This shall be triggered by changes in configuration, state, status etc.
+           It shall not be triggered by changes in performance measurements, power and temperature readings or any other data that is highlyvolatile. ";
+      }
+      enum "resourceDeletion" {
+        value 3;
+        description
+          "An exhisting instance of a resource has been removed.";
+      }
+    }
+    description
+      "Type of notification about a resource";
+  }
+
+  grouping resource-type {
+    leaf type {
+      type resource-type-enum;
+      mandatory true;
+    }
+    leaf extension {
+      type string;
+      mandatory false;
+    }
+  }
+
+  grouping device-id {
+    description
+      "Device identifier. Unique within the Controller.";
+    leaf node-id {
+      type org-openroadm-common-types:node-id-type;
+      description
+        "Node Id is a globally unique identifier for a device. 
+         Same as leafref value in model, if applicable.";
+    }
+  }
+
+  grouping circuit-pack-name {
+    leaf circuit-pack-name {
+      type string;
+      mandatory true;
+      description
+        "Circuit-Pack identifier. Unique within the context of a device.
+         Same as leafref value in model, if applicable.";
+    }
+  }
+
+  grouping port-name {
+    uses circuit-pack-name;
+    leaf port-name {
+      type string;
+      description
+        "Port identifier. Unique within the context of a circuit-pack. 
+         Same as leafref value in model, if applicable.";
+    }
+  }
+
+  grouping physical-link-name {
+    leaf physical-link-name {
+      type string;
+      mandatory true;
+      description
+        "Physical Link identifier. Unique within the context of a device. 
+         Same as leafref value in model, if applicable.";
+    }
+  }
+
+  grouping internal-link-name {
+    leaf internal-link-name {
+      type string;
+      mandatory true;
+      description
+        "Internal Link identifier. Unique within the context of a device. 
+         Same as leafref value in model, if applicable.";
+    }
+  }
+
+  grouping connection-name {
+    leaf connection-name {
+      type string;
+      description
+        "Connection name. Unique within the context of a device. 
+         Same as leafref value in model, if applicable.";
+    }
+  }
+
+  grouping degree-number {
+    leaf degree-number {
+      type uint16;
+      description
+        "Degree identifier. Unique within the context of a device. 
+         Same as leafref value in model, if applicable.";
+    }
+  }
+
+  grouping srg-number {
+    leaf srg-number {
+      type uint16;
+      description
+        "Shared Risk Group identifier. Unique within the context of a device. 
+         Same as leafref value in model, if applicable.";
+    }
+  }
+
+  grouping shelf-name {
+    leaf shelf-name {
+      type string;
+      mandatory true;
+      description
+        "Shelf-id identifier. Unique within the context of a device.  
+         Same as leafref value in model, if applicable.";
+    }
+  }
+
+  grouping service-name {
+    leaf service-name {
+      type string;
+      mandatory true;
+      description
+        "Service identifier. Unique within the context of a network.  
+         Same as leafref value in model, if applicable.";
+    }
+  }
+
+  grouping versioned-service-name {
+    leaf versioned-service-name {
+      type string;
+      mandatory true;
+      description
+        "Service identifier. Unique within the context of a network.  
+         Same as leafref value in model, if applicable.";
+    }
+    leaf version-number {
+      type uint64;
+      mandatory true;
+      description
+        "version-number of the service";
+    }
+  }
+
+  grouping temp-service-name {
+    leaf common-id {
+      type string;
+      mandatory true;
+      description
+        "Service identifier. Unique within the context of a network.  
+         Same as leafref value in model, if applicable.";
+    }
+  }
+
+  grouping interface-name {
+    leaf interface-name {
+      type string;
+      mandatory true;
+      description
+        "Interface identifier.";
+    }
+  }
+
+  grouping other-resource-id {
+    leaf other-resource-id {
+      type string;
+      mandatory true;
+      description
+        "resource-id for other.";
+    }
+  }
+
+  grouping odu-sncp-pg-name {
+    leaf odu-sncp-pg-name {
+      type string;
+      mandatory true;
+      description
+        "name of the odu-snc-pg";
+    }
+  }
+
+  grouping amp-number {
+    leaf amp-number {
+      type uint8;
+      mandatory true;
+      description
+        "number of the line-amplifier";
+    }
+  }
+
+  grouping xpdr-number {
+    leaf xpdr-number {
+      type uint16;
+      mandatory true;
+      description
+        "number of the xponder";
+    }
+  }
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/org-openroadm-resource@2018-10-19.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/org-openroadm-resource@2018-10-19.yang
new file mode 100755 (executable)
index 0000000..c7afac4
--- /dev/null
@@ -0,0 +1,156 @@
+module org-openroadm-resource {
+  namespace "http://org/openroadm/resource";
+  prefix org-openroadm-resource;
+
+  import org-openroadm-resource-types {
+    prefix org-openroadm-resource-types;
+    revision-date 2018-10-19;
+  }
+
+  organization
+    "Open ROADM MSA";
+  contact
+    "OpenROADM.org";
+  description
+    "YANG definitions of resources.
+       
+      Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, 
+      AT&T Intellectual Property.  All other rights reserved.
+      
+      Redistribution and use in source and binary forms, with or without modification, 
+      are permitted provided that the following conditions are met:
+      
+      * Redistributions of source code must retain the above copyright notice, this 
+        list of conditions and the following disclaimer.
+      * Redistributions in binary form must reproduce the above copyright notice, 
+        this list of conditions and the following disclaimer in the documentation and/or 
+        other materials provided with the distribution.
+      * Neither the Members of the Open ROADM MSA Agreement nor the names of its 
+        contributors may be used to endorse or promote products derived from this software 
+        without specific prior written permission.
+      
+      THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT ''AS IS'' 
+      AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+      WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+      IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT BE LIABLE FOR ANY DIRECT, 
+      INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+      NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE, DATA, 
+      OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+      WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+      ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+      POSSIBILITY OF SUCH DAMAGE";
+
+  revision 2018-10-19 {
+    description
+      "Version 2.2.1";
+  }
+  revision 2017-12-15 {
+    description
+      "Version 2.2";
+  }
+  revision 2017-09-29 {
+    description
+      "Version 2.1";
+  }
+  revision 2017-07-28 {
+    description
+      "Version 2.0.1 - added revision-date to imports";
+  }
+  revision 2017-06-26 {
+    description
+      "Version 2.0";
+  }
+  revision 2016-10-14 {
+    description
+      "Version 1.2";
+  }
+
+  grouping resource {
+    description
+      "This resource identifier is intended to provide a generic identifer
+       for any resource that can be used without specific knowledge of
+       the resource.";
+    container device {
+      description
+        "Device of the resource, used only when the system using this
+         model report on more than one device. ";
+      uses org-openroadm-resource-types:device-id;
+    }
+    container resource {
+      choice resource {
+        case circuit-pack {
+          uses org-openroadm-resource-types:circuit-pack-name;
+        }
+        case port {
+          container port {
+            uses org-openroadm-resource-types:port-name;
+          }
+        }
+        case connection {
+          uses org-openroadm-resource-types:connection-name {
+            refine "connection-name" {
+              mandatory true;
+            }
+          }
+        }
+        case physical-link {
+          uses org-openroadm-resource-types:physical-link-name;
+        }
+        case internal-link {
+          uses org-openroadm-resource-types:internal-link-name;
+        }
+        case shelf {
+          uses org-openroadm-resource-types:shelf-name;
+        }
+        case srg {
+          uses org-openroadm-resource-types:srg-number {
+            refine "srg-number" {
+              mandatory true;
+            }
+          }
+        }
+        case degree {
+          uses org-openroadm-resource-types:degree-number {
+            refine "degree-number" {
+              mandatory true;
+            }
+          }
+        }
+        case service {
+          uses org-openroadm-resource-types:service-name;
+        }
+        case interface {
+          uses org-openroadm-resource-types:interface-name;
+        }
+        case odu-sncp-pg {
+          uses org-openroadm-resource-types:odu-sncp-pg-name;
+        }
+        case other {
+          uses org-openroadm-resource-types:other-resource-id;
+        }
+        case device {
+          uses org-openroadm-resource-types:device-id {
+            refine "node-id" {
+              mandatory true;
+            }
+          }
+        }
+        case line-amplifier {
+          uses org-openroadm-resource-types:amp-number;
+        }
+        case xponder {
+          uses org-openroadm-resource-types:xpdr-number;
+        }
+        case versioned-service {
+          uses org-openroadm-resource-types:versioned-service-name;
+        }
+        case temp-service {
+          uses org-openroadm-resource-types:temp-service-name;
+        }
+      }
+    }
+    container resourceType {
+      uses org-openroadm-resource-types:resource-type;
+    }
+  }
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/org-openroadm-switching-pool-types@2017-12-15.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/org-openroadm-switching-pool-types@2017-12-15.yang
new file mode 100644 (file)
index 0000000..fc6cd08
--- /dev/null
@@ -0,0 +1,55 @@
+module org-openroadm-switching-pool-types {
+  namespace "http://org/openroadm/switching-pool-types";
+  prefix org-openroadm-switching-pool-types;
+
+  organization
+    "Open ROADM MSA";
+  contact
+    "OpenROADM.org";
+  description
+    "YANG definitions of common types.
+       
+      Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, 
+      AT&T Intellectual Property.  All other rights reserved.
+      
+      Redistribution and use in source and binary forms, with or without modification, 
+      * Redistributions of source code must retain the above copyright notice, this 
+        list of conditions and the following disclaimer.
+      * Redistributions in binary form must reproduce the above copyright notice, 
+        this list of conditions and the following disclaimer in the documentation and/or 
+        other materials provided with the distribution.
+      * Neither the Members of the Open ROADM MSA Agreement nor the names of its 
+        contributors may be used to endorse or promote products derived from this software 
+        without specific prior written permission.
+      
+      THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT ''AS IS'' 
+      AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+      WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+      IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT BE LIABLE FOR ANY DIRECT, 
+      INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+      NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE, DATA, 
+      OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+      WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+      ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+      POSSIBILITY OF SUCH DAMAGE";
+
+  revision 2017-12-15 {
+    description
+      "Version 2.2";
+  }
+
+  typedef switching-pool-types {
+    type enumeration {
+      enum "non-blocking" {
+        value 1;
+        description
+          "Single non-blocking element";
+      }
+      enum "blocking" {
+        value 2;
+        description
+          "Multiple connected non-blocking lists";
+      }
+    }
+  }
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/org-openroadm-user-mgmt@2017-12-15.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/common/org-openroadm-user-mgmt@2017-12-15.yang
new file mode 100644 (file)
index 0000000..7e3227d
--- /dev/null
@@ -0,0 +1,153 @@
+module org-openroadm-user-mgmt {
+  namespace "http://org/openroadm/user-mgmt";
+  prefix org-openroadm-user-mgmt;
+
+  organization
+    "Open ROADM MSA";
+  contact
+    "OpenROADM.org";
+  description
+    "YANG definitions of user managements.
+       
+      Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, 
+      AT&T Intellectual Property.  All other rights reserved.
+      
+      Redistribution and use in source and binary forms, with or without modification, 
+      are permitted provided that the following conditions are met:
+      
+      * Redistributions of source code must retain the above copyright notice, this 
+        list of conditions and the following disclaimer.
+      * Redistributions in binary form must reproduce the above copyright notice, 
+        this list of conditions and the following disclaimer in the documentation and/or 
+        other materials provided with the distribution.
+      * Neither the Members of the Open ROADM MSA Agreement nor the names of its 
+        contributors may be used to endorse or promote products derived from this software 
+        without specific prior written permission.
+      
+      THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT ''AS IS'' 
+      AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+      WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+      IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT BE LIABLE FOR ANY DIRECT, 
+      INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+      NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE, DATA, 
+      OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+      WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+      ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+      POSSIBILITY OF SUCH DAMAGE";
+
+  revision 2017-12-15 {
+    description
+      "Version 2.2";
+  }
+  revision 2017-09-29 {
+    description
+      "Version 2.1";
+  }
+  revision 2017-06-26 {
+    description
+      "Version 2.0";
+  }
+  revision 2016-10-14 {
+    description
+      "Version 1.2";
+  }
+
+  typedef username-type {
+    type string {
+      length "3..32";
+      pattern "[a-z][a-z0-9]{2,31}" {
+        error-message
+          "A username must begin with a lowercase letter, The remainder 
+           of the string may contain lowercase letters, or numbers 0 through 9.";
+      }
+    }
+    description
+      "The user name string identifying this entry.";
+  }
+
+  typedef password-type {
+    type string {
+      length "8..128";
+      pattern "[a-zA-Z0-9!$%\\^()\\[\\]_\\-~{}.+]*" {
+        error-message "Password content does not meet the requirements";
+      }
+    }
+    description
+      "The password for this entry. This shouldn't be in clear text 
+       The Password must contain at least 2 characters from 
+       each of the following groups: 
+       a) Lower case alphabetic (a-z) 
+       b) Upper case alphabetic (A-Z) 
+       c) Numeric 0-9 
+       d) Special characters Allowed !$%^()[]_-~{}.+ 
+       Password must not contain Username.";
+  }
+
+  grouping user-profile {
+    list user {
+      key "name";
+      description
+        "The list of local users configured on this device.";
+      leaf name {
+        type username-type;
+        description
+          "The user name string identifying this entry.";
+      }
+      leaf password {
+        type password-type;
+        description
+          "The password for this entry.";
+      }
+      leaf group {
+        type enumeration {
+          enum "sudo";
+        }
+        description
+          "The group to which the user is associated to.";
+      }
+    }
+  }
+
+  rpc chg-password {
+    input {
+      leaf currentPassword {
+        type password-type;
+        mandatory true;
+        description
+          "provide the current password";
+      }
+      leaf newPassword {
+        type password-type;
+        mandatory true;
+        description
+          "provide a new password";
+      }
+      leaf newPasswordConfirm {
+        type password-type;
+        mandatory true;
+        description
+          "re-enter the new password ";
+      }
+    }
+    output {
+      leaf status {
+        type enumeration {
+          enum "Successful" {
+            value 1;
+          }
+          enum "Failed" {
+            value 2;
+          }
+        }
+        mandatory true;
+        description
+          "Successful or Failed";
+      }
+      leaf status-message {
+        type string;
+        description
+          "Gives a more detailed reason for success / failure";
+      }
+    }
+  }
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-device@2018-10-19.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-device@2018-10-19.yang
new file mode 100755 (executable)
index 0000000..32700cc
--- /dev/null
@@ -0,0 +1,1848 @@
+module org-openroadm-device {
+  namespace "http://org/openroadm/device";
+  prefix org-openroadm-device;
+
+  import ietf-yang-types {
+    prefix ietf-yang-types;
+    revision-date 2013-07-15;
+  }
+  import ietf-inet-types {
+    prefix ietf-inet-types;
+    revision-date 2013-07-15;
+  }
+  import ietf-netconf {
+    prefix ietf-nc;
+    revision-date 2011-06-01;
+  }
+  import org-openroadm-common-types {
+    prefix org-openroadm-common-types;
+    revision-date 2018-10-19;
+  }
+  import org-openroadm-resource-types {
+    prefix org-openroadm-resource-types;
+    revision-date 2018-10-19;
+  }
+  import org-openroadm-physical-types {
+    prefix org-openroadm-physical-types;
+    revision-date 2018-10-19;
+  }
+  import org-openroadm-user-mgmt {
+    prefix org-openroadm-user-mgmt;
+    revision-date 2017-12-15;
+  }
+  import org-openroadm-port-types {
+    prefix org-openroadm-port-types;
+    revision-date 2018-10-19;
+  }
+  import org-openroadm-interfaces {
+    prefix org-openroadm-interfaces;
+    revision-date 2017-06-26;
+  }
+  import org-openroadm-swdl {
+    prefix org-openroadm-swdl;
+    revision-date 2018-10-19;
+  }
+  import org-openroadm-equipment-states-types {
+    prefix org-openroadm-equipment-states-types;
+    revision-date 2017-12-15;
+  }
+  import org-openroadm-switching-pool-types {
+    prefix org-openroadm-switching-pool-types;
+    revision-date 2017-12-15;
+  }
+
+  organization
+    "Open ROADM MSA";
+  contact
+    "OpenROADM.org";
+  description
+    "YANG definitions of ROADM device
+     
+     Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, 
+     AT&T Intellectual Property.  All other rights reserved.
+     
+     Redistribution and use in source and binary forms, with or without modification, 
+     are permitted provided that the following conditions are met:
+     
+     * Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+     * Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation and/or 
+       other materials provided with the distribution.
+     * Neither the Members of the Open ROADM MSA Agreement nor the names of its 
+       contributors may be used to endorse or promote products derived from this software 
+       without specific prior written permission.
+     
+     THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT ''AS IS'' 
+     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+     IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT BE LIABLE FOR ANY DIRECT, 
+     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE, DATA, 
+     OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+     WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+     POSSIBILITY OF SUCH DAMAGE.
+     
+     Also contains code components extracted from IETF netconf.  These code components 
+     are copyrighted and licensed as follows:
+     
+     Copyright (c) 2016 IETF Trust and the persons identified as the document authors. 
+     All rights reserved. 
+     
+     This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating 
+     to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of 
+     publication of this document. Please review these documents carefully, as they 
+     describe your rights and restrictions with respect to this document. Code Components 
+     extracted from this document must include Simplified BSD License text as described in
+     Section 4.e of the Trust Legal Provisions and are provided without warranty as 
+     described in the Simplified BSD License.";
+
+  revision 2018-10-19 {
+    description
+      "Version 2.2.1";
+  }
+  revision 2017-12-15 {
+    description
+      "Version 2.2";
+  }
+  revision 2017-09-29 {
+    description
+      "Version 2.1";
+  }
+  revision 2017-07-28 {
+    description
+      "Version 2.0.1 - added revision-date to imports";
+  }
+  revision 2017-06-26 {
+    description
+      "Version 2.0";
+  }
+  revision 2017-02-06 {
+    description
+      "Version 1.2.1 - removed pattern for current-datetime in info tree and rpc";
+  }
+  revision 2016-10-14 {
+    description
+      "Version 1.2";
+  }
+
+  grouping create-tech-info-group {
+    leaf shelf-id {
+      type leafref {
+        path "/org-openroadm-device/shelves/shelf-name";
+      }
+      description
+        "shelf ID";
+    }
+    leaf log-file-name {
+      type string;
+      description
+        "The log file name a vendor can specify for a given log collection operation";
+    }
+  }
+
+  grouping device-common {
+    leaf node-id {
+      type org-openroadm-common-types:node-id-type;
+      default "openroadm";
+      description
+        "Globally unique identifier for a device.";
+    }
+    leaf node-number {
+      type uint32;
+      description
+        "Number assigned to a ROADM node at a 
+         given office";
+    }
+    leaf node-type {
+      type org-openroadm-common-types:node-types;
+      config true;
+      mandatory true;
+      description
+        "Identifier for node-type e.g Roadm, xponder.
+         Once the node-type is configured, it should not be modified.";
+    }
+    leaf clli {
+      type string;
+      description
+        "Common Language Location Identifier.";
+    }
+    uses org-openroadm-physical-types:node-info;
+    leaf ipAddress {
+      type ietf-inet-types:ip-address;
+      description
+        "IP Address of device";
+    }
+    leaf prefix-length {
+      type uint8 {
+        range "0..128";
+      }
+      description
+        "The length of the subnet prefix";
+    }
+    leaf defaultGateway {
+      type ietf-inet-types:ip-address;
+      description
+        "Default Gateway";
+    }
+    leaf source {
+      type enumeration {
+        enum "static" {
+          value 1;
+        }
+        enum "dhcp" {
+          value 2;
+        }
+      }
+      config false;
+    }
+    leaf current-ipAddress {
+      type ietf-inet-types:ip-address;
+      config false;
+      description
+        "Current IP Address of device";
+    }
+    leaf current-prefix-length {
+      type uint8 {
+        range "0..128";
+      }
+      config false;
+      description
+        "The current length of the subnet prefix";
+    }
+    leaf current-defaultGateway {
+      type ietf-inet-types:ip-address;
+      config false;
+      description
+        "Current Default Gateway";
+    }
+    leaf macAddress {
+      type ietf-yang-types:mac-address;
+      config false;
+      description
+        "MAC Address of device";
+    }
+    leaf softwareVersion {
+      type string;
+      config false;
+      description
+        "Software version";
+    }
+    leaf openroadm-version {
+      type org-openroadm-common-types:openroadm-version-type;
+      config false;
+      description
+        "openroadm version used on the device";
+    }
+    leaf template {
+      type string;
+      description
+        "Template information used in the deployment.";
+    }
+    leaf current-datetime {
+      type ietf-yang-types:date-and-time;
+      config false;
+      description
+        "The current system date and time in UTC. Format: YYYY-MM-DDTHH:MM:SS.mm+ ";
+    }
+    container geoLocation {
+      description
+        "GPS location";
+      leaf latitude {
+        type decimal64 {
+          fraction-digits 16;
+          range "-90 .. 90";
+        }
+        description
+          "[From wikipedia] Latitude is an angle (defined below)
+           which ranges from 0 at the Equator to 90 (North or
+           South) at the poles";
+      }
+      leaf longitude {
+        type decimal64 {
+          fraction-digits 16;
+          range "-180 .. 180";
+        }
+        description
+          "[From wikipedia] The longitude is measured as the
+           angle east or west from the Prime Meridian, ranging
+           from 0 at the Prime Meridian to +180 eastward and
+           -180 westward.";
+      }
+    }
+  }
+
+  grouping slot-info {
+    description
+      "slots information. To be populated by NE during retrieval.";
+    leaf slot-name {
+      type string;
+      description
+        "The name of this slot.";
+    }
+    leaf label {
+      type string;
+      description
+        "Faceplate label";
+    }
+    leaf provisioned-circuit-pack {
+      type leafref {
+        path "/org-openroadm-device/circuit-packs/circuit-pack-name";
+      }
+      description
+        "The supported circuit-pack. It will be empty if holder status is empty-not-prov, or installed-not-prov";
+    }
+    leaf slot-status {
+      type enumeration {
+        enum "empty-not-prov" {
+          value 1;
+          description
+            "Slot is empty and not provisioned";
+        }
+        enum "empty-prov-match" {
+          value 2;
+          description
+            "Slot is empty and expected type is provisioned";
+        }
+        enum "empty-prov-mismatch" {
+          value 3;
+          description
+            "Slot is empty and an unsupported type is provisioned";
+        }
+        enum "installed-not-prov" {
+          value 4;
+          description
+            "Slot is occupied but not provisioned";
+        }
+        enum "installed-prov-match" {
+          value 5;
+          description
+            "Slot is occupied with matching provisioned type";
+        }
+        enum "installed-prov-mismatch" {
+          value 6;
+          description
+            "Slot is occupied with mismatched provisioned type";
+        }
+      }
+    }
+  }
+
+  grouping shelves {
+    list shelves {
+      key "shelf-name";
+      uses shelf;
+    }
+  }
+
+  grouping shelf {
+    leaf shelf-name {
+      type string;
+      description
+        "Unique identifier for this shelf within a device";
+    }
+    leaf shelf-type {
+      type string;
+      mandatory true;
+      description
+        "The shelf type: describe the shelf with a unique string.";
+    }
+    leaf rack {
+      type string;
+      description
+        "Reflect the shelf physical location data including floor, aisle, bay values.";
+    }
+    leaf shelf-position {
+      type string;
+      description
+        "Reflect the shelf vertical position within an equipment bay.";
+    }
+    leaf administrative-state {
+      type org-openroadm-equipment-states-types:admin-states;
+      description
+        "Admin State of the shelf";
+    }
+    uses org-openroadm-physical-types:common-info;
+    leaf equipment-state {
+      type org-openroadm-equipment-states-types:states;
+      description
+        "equipment state for the shelf, used to track the lifecycle state.";
+    }
+    leaf due-date {
+      type ietf-yang-types:date-and-time;
+      description
+        "due date for the shelf.";
+    }
+    list slots {
+      key "slot-name";
+      config false;
+      description
+        "List of slots on this shelf. To be populated by NE during retrieval.";
+      uses slot-info;
+    }
+  }
+
+  grouping circuit-packs {
+    list circuit-packs {
+      key "circuit-pack-name";
+      description
+        "List of circuit packs. This includes common equipment, like fans, power supplies, etc.";
+      leaf circuit-pack-type {
+        type string;
+        mandatory true;
+        description
+          "Type of circuit-pack";
+      }
+      leaf circuit-pack-product-code {
+        type string;
+        description
+          "Product Code for the circuit-pack";
+      }
+      uses circuit-pack;
+    }
+  }
+
+  grouping circuit-pack-features {
+    leaf software-load-version {
+      type string;
+      config false;
+      description
+        "Software version running on the circuit pack.";
+    }
+    list circuit-pack-features {
+      config false;
+      container feature {
+        description
+          "List of features supported by the installed load and indications on whether the features have been applied or not.";
+        leaf description {
+          type string;
+          description
+            "Feature description.";
+        }
+        leaf activated {
+          type boolean;
+          description
+            "Indicator if the feature has been activated.";
+        }
+      }
+    }
+    list circuit-pack-components {
+      config false;
+      container component {
+        description
+          "Optional list of components on the circuit-pack and the load information applicable to those components.  If a load is not up to date and will upgrade when a cold restart occurs, the version that will be applied should also be listed.  If there is no misalignment, this does not need to be reported.";
+        leaf name {
+          type string;
+          description
+            "Name of a component on the circuit-pack that can have a load applied to it.";
+        }
+        leaf current-version {
+          type string;
+          description
+            "Name of the load version currently running on the component.";
+        }
+        leaf version-to-apply {
+          type string;
+          description
+            "Name of the load version for the component that will be applied when cold restart occurs on the circuit-pack.";
+        }
+      }
+    }
+  }
+
+  grouping circuit-pack {
+    leaf circuit-pack-name {
+      type string;
+      description
+        "Unique identifier for this circuit-pack within a device";
+    }
+    leaf administrative-state {
+      type org-openroadm-equipment-states-types:admin-states;
+      description
+        "Administrative state of circuit-pack";
+    }
+    uses org-openroadm-physical-types:common-info;
+    container circuit-pack-category {
+      config false;
+      description
+        "General type of circuit-pack";
+      uses org-openroadm-common-types:equipment-type;
+    }
+    leaf equipment-state {
+      type org-openroadm-equipment-states-types:states;
+      description
+        "Equipment state, which complements operational state.";
+    }
+    leaf circuit-pack-mode {
+      type string;
+      default "NORMAL";
+      description
+        "Circuit-pack mode allowed. e.g. NORMAL or REGEN";
+    }
+    leaf shelf {
+      type leafref {
+        path "/org-openroadm-device/shelves/shelf-name";
+      }
+      mandatory true;
+    }
+    leaf slot {
+      type string;
+      mandatory true;
+    }
+    leaf subSlot {
+      type string;
+      mandatory false;
+    }
+    leaf is-pluggable-optics {
+      type boolean;
+      config false;
+      mandatory true;
+      description
+        "True if circuitpack is pluggable optics";
+    }
+    leaf due-date {
+      type ietf-yang-types:date-and-time;
+      description
+        "due date for this circuit-pack.";
+    }
+    container parent-circuit-pack {
+      description
+        "In the case of circuit packs that contain other equipment (modules or pluggables), this captures the hierarchy of that equipment.  It is a vendor specific design decision if the ports for single-port pluggables are modeled as children of the parent circuit-pack, or as children of the pluggable circuit-pack contained in the parent circuit-pack.  For modules with multiple ports, it is recommended that ports be children of the module and not the carrier, to help in fault correlation and isolation in the case of a module failure.";
+      uses circuit-pack-name;
+      leaf cp-slot-name {
+        type string;
+        description
+          "Slot name on parent-circuit-pack.";
+      }
+    }
+    list cp-slots {
+      key "slot-name";
+      config false;
+      description
+        "List of circuit-pack slots on this circuit-pack. To be populated by NE during retrieval.";
+      uses slot-info;
+      leaf slot-type {
+        type enumeration {
+          enum "pluggable-optics-holder" {
+            value 1;
+            description
+              "slot accepts dedicated pluggable port circuit-pack";
+          }
+          enum "other" {
+            value 2;
+            description
+              "slot accepts parent circuit-pack";
+          }
+        }
+      }
+    }
+    uses circuit-pack-features;
+    list ports {
+      key "port-name";
+      description
+        "List of ports on this circuit-pack. Note that pluggables are considered independent circuit-packs.  All ports that are physically present on a pluggable, need to be modeled as a port against that pluggable circuit-pack, and not against the parent circuit-pack.";
+      uses port;
+      container roadm-port {
+        when "../port-qual='roadm-external'";
+        uses org-openroadm-port-types:roadm-port;
+      }
+      container transponder-port {
+        when "../port-qual='xpdr-network' or ../port-qual='xpdr-client' or ../port-qual='switch-network' or ../port-qual='switch-client'";
+        uses org-openroadm-port-types:common-port;
+      }
+      container otdr-port {
+        when "../port-qual='otdr'";
+        description
+          "Settings for otdr port.";
+        leaf launch-cable-length {
+          type uint32;
+          units "m";
+          default "30";
+        }
+        leaf port-direction {
+          type org-openroadm-common-types:direction;
+        }
+      }
+      container ila-port {
+        when "../port-qual='ila-external'";
+        uses org-openroadm-port-types:common-port;
+      }
+    }
+  }
+
+  grouping odu-connection {
+    description
+      "Grouping used to define odu-connections.";
+    leaf connection-name {
+      type string;
+      description
+        "roadm-connection and odu-connection share the same resource-type and resource definition (e.g. connection)";
+    }
+    leaf direction {
+      type enumeration {
+        enum "unidirectional" {
+          value 1;
+        }
+        enum "bidirectional" {
+          value 2;
+        }
+      }
+      default "bidirectional";
+      description
+        "Directionality of connection. If bidirectional, both directions are created.";
+    }
+    container source {
+      leaf src-if {
+        type leafref {
+          path "/org-openroadm-device/interface/name";
+        }
+        mandatory true;
+      }
+    }
+    container destination {
+      leaf dst-if {
+        type leafref {
+          path "/org-openroadm-device/interface/name";
+        }
+        mandatory true;
+      }
+    }
+  }
+
+  grouping connection {
+    description
+      "Grouping used to define connections.";
+    leaf connection-name {
+      type string;
+    }
+    leaf opticalControlMode {
+      type org-openroadm-common-types:optical-control-mode;
+      default "off";
+      description
+        "Whether connection is currently in power or gain/loss mode";
+      reference "openroadm.org: Open ROADM MSA Specification.";
+    }
+    leaf target-output-power {
+      type org-openroadm-common-types:power-dBm;
+      description
+        "The output target power for this connection. When set, the ROADM will work to ensure that current-output-power reaches this level.";
+    }
+    container source {
+      leaf src-if {
+        type leafref {
+          path "/org-openroadm-device/interface/name";
+        }
+        mandatory true;
+      }
+    }
+    container destination {
+      leaf dst-if {
+        type leafref {
+          path "/org-openroadm-device/interface/name";
+        }
+        mandatory true;
+      }
+    }
+  }
+
+  grouping degree {
+    leaf degree-number {
+      type uint16;
+      must "not( current() > /org-openroadm-device/info/max-degrees) and current() > 0" {
+        error-message "Degree not supported by device ";
+        description
+          "Validating if the degree is supported by device";
+      }
+    }
+    leaf max-wavelengths {
+      type uint16;
+      config false;
+      mandatory true;
+      description
+        "maximum number of wavelengths";
+    }
+    list circuit-packs {
+      key "index";
+      description
+        "list for Cards associated with a degree";
+      leaf index {
+        type uint32;
+      }
+      uses circuit-pack-name {
+        refine "circuit-pack-name" {
+          mandatory true;
+        }
+      }
+    }
+    list connection-ports {
+      key "index";
+      description
+        "Port associated with degree: One if bi-directional; two if uni-directional";
+      leaf index {
+        type uint32;
+      }
+      uses port-name {
+        refine "circuit-pack-name" {
+          mandatory true;
+        }
+        refine "port-name" {
+          mandatory true;
+        }
+      }
+    }
+    container otdr-port {
+      description
+        "otdr port associated with degree.";
+      uses port-name;
+    }
+    uses mc-capabilities-g;
+  }
+
+  grouping amplifier {
+    leaf amp-number {
+      type uint8 {
+        range "1..128";
+      }
+      description
+        "Unique identifier/number for the amplifier entry which corresponds to a logical amplifier";
+    }
+    leaf amp-type {
+      type org-openroadm-common-types:amplifier-types;
+      config false;
+      mandatory true;
+      description
+        "Amplifier type";
+    }
+    leaf control-mode {
+      type org-openroadm-common-types:line-amplifier-control-mode;
+      default "off";
+      description
+        "Whether the line amplifier is currently in off or gainLoss mode. control-mode can only be set to gainLoss when target-gain, target-tilt and egress-average-channel-power are set and the OMS interfaces are provisioned. The amplifier will be turned off when the control-mode is set to off";
+    }
+    leaf amp-gain-range {
+      type org-openroadm-common-types:amplifier-gain-range;
+      default "gain-range-1";
+      config false;
+      description
+        "Amplifier gain-range (gain-range 1 to 4 for switched gain amplifiers)
+         gain-range-1 (default value) for standard amplifiers";
+    }
+    leaf target-gain {
+      type org-openroadm-common-types:ratio-dB;
+      config true;
+      description
+        "Target overall Amplifier Signal gain, excluding ASE, including VOA attenuation.
+         Defined as optional for ODL support, but shall be considered as mandatory and provided
+         by the controller when the control-mode is set to gainLoss for amplifier setting";
+    }
+    leaf target-tilt {
+      type org-openroadm-common-types:ratio-dB;
+      config true;
+      description
+        "Target tilt configured in case of smart EDFA.
+         Tilt value provided as specified in Open-ROADM-MSA-specifications spreadsheet
+         Defined as optional for ODL support, but shall be considered as mandatory and provided
+         by the controller when the control-mode is set to gainLoss for amplifier setting";
+    }
+    leaf egress-average-channel-power {
+      type org-openroadm-common-types:power-dBm;
+      config true;
+      description
+        "Based upon the total max power across the 4.8 THz passband.
+         Defined as optional for ODL support, but shall be considered as mandatory and provided
+         by the controller when the control-mode is set to gainLoss for amplifier setting";
+    }
+    leaf out-voa-att {
+      type org-openroadm-common-types:ratio-dB;
+      config false;
+      description
+        "Used to provide the value output VOA attenuation, optional";
+    }
+    leaf partner-amp {
+      type leafref {
+        path "../amp-number";
+      }
+      config false;
+      description
+        "amp-number of amp module that is functionally associated to the amplifier  
+         in the opposite direction";
+    }
+    leaf ila-direction-label {
+      type string;
+      description
+        "Amplifier direction. Each operators may have its own naming convention.
+         Shall be consistent with tx-instance-port-direction-label and rx-instance-port-direction-label.";
+    }
+  }
+
+  grouping external-links {
+    description
+      "YANG definitions for external links.. 
+       - physical links between ROADMs and between the ROADMs and XPonders, which can be added and removed manually.";
+    list external-link {
+      key "external-link-name";
+      uses external-link;
+    }
+  }
+
+  grouping external-link {
+    leaf external-link-name {
+      type string;
+    }
+    container source {
+      uses org-openroadm-resource-types:device-id {
+        refine "node-id" {
+          mandatory true;
+        }
+      }
+      uses org-openroadm-resource-types:port-name {
+        refine "circuit-pack-name" {
+          mandatory true;
+        }
+        refine "port-name" {
+          mandatory true;
+        }
+      }
+    }
+    container destination {
+      uses org-openroadm-resource-types:device-id {
+        refine "node-id" {
+          mandatory true;
+        }
+      }
+      uses org-openroadm-resource-types:port-name {
+        refine "circuit-pack-name" {
+          mandatory true;
+        }
+        refine "port-name" {
+          mandatory true;
+        }
+      }
+    }
+  }
+
+  grouping internal-links {
+    list internal-link {
+      key "internal-link-name";
+      config false;
+      uses internal-link;
+    }
+  }
+
+  grouping internal-link {
+    leaf internal-link-name {
+      type string;
+    }
+    container source {
+      uses port-name {
+        refine "circuit-pack-name" {
+          mandatory true;
+        }
+        refine "port-name" {
+          mandatory true;
+        }
+      }
+    }
+    container destination {
+      uses port-name {
+        refine "circuit-pack-name" {
+          mandatory true;
+        }
+        refine "port-name" {
+          mandatory true;
+        }
+      }
+    }
+  }
+
+  grouping physical-links {
+    description
+      "YANG definitions for physical links.
+       - physical links (fiber, cables,etc.) between ports within a node. ";
+    list physical-link {
+      key "physical-link-name";
+      uses physical-link;
+    }
+  }
+
+  grouping physical-link {
+    leaf physical-link-name {
+      type string;
+    }
+    container source {
+      uses port-name {
+        refine "circuit-pack-name" {
+          mandatory true;
+        }
+        refine "port-name" {
+          mandatory true;
+        }
+      }
+    }
+    container destination {
+      uses port-name {
+        refine "circuit-pack-name" {
+          mandatory true;
+        }
+        refine "port-name" {
+          mandatory true;
+        }
+      }
+    }
+  }
+
+  grouping srg {
+    leaf max-add-drop-ports {
+      type uint16;
+      config false;
+      mandatory true;
+      description
+        "The max number of ports available for a given srg";
+    }
+    leaf current-provisioned-add-drop-ports {
+      type uint16;
+      config false;
+      mandatory true;
+      description
+        "The number of ports currently provisioned for a given srg.";
+    }
+    leaf srg-number {
+      type uint16;
+      must "not(current()>/org-openroadm-device/info/max-srgs) and current()>0" {
+        error-message "invalid SRG";
+        description
+          "Validating if the srg is supported by add/drop group";
+      }
+    }
+    leaf wavelength-duplication {
+      type org-openroadm-common-types:wavelength-duplication-type;
+      config false;
+      mandatory true;
+      description
+        "Whether the SRG can handle duplicate wavelengths and if so to what extent.";
+    }
+    list circuit-packs {
+      key "index";
+      description
+        "list for Cards associated with an add/drop group and srg";
+      leaf index {
+        type uint32;
+      }
+      uses circuit-pack-name {
+        refine "circuit-pack-name" {
+          mandatory true;
+        }
+      }
+    }
+    uses mc-capabilities-g;
+  }
+
+  grouping xponder {
+    leaf xpdr-number {
+      type uint16;
+      must "current() > 0" {
+        error-message "Xponder not supported by device ";
+        description
+          "Validating if the Xponder is supported by device";
+      }
+    }
+    leaf xpdr-type {
+      type org-openroadm-common-types:xpdr-node-types;
+      mandatory true;
+      description
+        "Identifier for xponder-type e.g Transponder, Muxponder";
+    }
+    leaf recolor {
+      type boolean;
+      config false;
+      description
+        "Indication if recolor is supported";
+    }
+    list xpdr-port {
+      key "index";
+      description
+        "Network Ports with in a Xponder";
+      leaf index {
+        type uint32;
+      }
+      uses port-name {
+        refine "circuit-pack-name" {
+          mandatory true;
+        }
+        refine "port-name" {
+          mandatory true;
+        }
+      }
+      leaf eqpt-srg-id {
+        type uint32;
+        description
+          "Shared Risk Group identifier. All ports in a circuit-pack will have same srg-id";
+      }
+    }
+  }
+
+  grouping degree-number {
+    leaf degree-number {
+      type leafref {
+        path "/org-openroadm-device/degree/degree-number";
+      }
+      description
+        "Degree identifier. Unique within the context of a device.";
+    }
+  }
+
+  grouping circuit-pack-name {
+    leaf circuit-pack-name {
+      type leafref {
+        path "/org-openroadm-device/circuit-packs/circuit-pack-name";
+      }
+      description
+        "Circuit-Pack identifier. Unique within the context of a device.";
+    }
+  }
+
+  grouping port-name {
+    uses circuit-pack-name;
+    leaf port-name {
+      type leafref {
+        path "/org-openroadm-device/circuit-packs[circuit-pack-name=current()/../circuit-pack-name]/ports/port-name";
+      }
+      description
+        "Port identifier. Unique within the context of a circuit-pack.";
+    }
+  }
+
+  grouping srg-number {
+    leaf srg-number {
+      type leafref {
+        path "/org-openroadm-device/shared-risk-group/srg-number";
+      }
+      description
+        "Shared Risk Group identifier. Unique within the context of a device.";
+    }
+  }
+
+  grouping supporting-port-name {
+    leaf supporting-circuit-pack-name {
+      type leafref {
+        path "/org-openroadm-device/circuit-packs/circuit-pack-name";
+      }
+      description
+        "Identifier of the supporting circuit-pack.";
+    }
+    leaf supporting-port {
+      type leafref {
+        path "/org-openroadm-device/circuit-packs[circuit-pack-name=current()/../supporting-circuit-pack-name]/ports/port-name";
+      }
+      description
+        "Identifier of the supporting port.";
+    }
+  }
+
+  grouping interface-name {
+    leaf interface-name {
+      type leafref {
+        path "/org-openroadm-device/interface/name";
+      }
+      config false;
+      description
+        "Name of an interface. Unique within the context of a device.";
+    }
+  }
+
+  grouping interfaces-grp {
+    description
+      "OpenROADM Interface configuration parameters.";
+    list interface {
+      key "name";
+      description
+        "The list of configured interfaces on the device.";
+      leaf name {
+        type string;
+        description
+          "The name of the interface.";
+      }
+      leaf description {
+        type string;
+        description
+          "A textual description of the interface.";
+      }
+      leaf type {
+        type identityref {
+          base org-openroadm-interfaces:interface-type;
+        }
+        mandatory true;
+        description
+          "The type of the interface.";
+      }
+      leaf administrative-state {
+        type org-openroadm-equipment-states-types:admin-states;
+      }
+      leaf operational-state {
+        type org-openroadm-common-types:state;
+        config false;
+      }
+      leaf circuit-id {
+        type string {
+          length "0..45";
+        }
+        description
+          "circuit identifier/user label,
+           can be used in alarm correlation and/or connection management ";
+      }
+      leaf supporting-interface {
+        type leafref {
+          path "/org-openroadm-device/interface/name";
+        }
+      }
+      uses supporting-port-name;
+    }
+  }
+
+  grouping protection-groups {
+    description
+      "OpenROADM facility protection configuration parameters.";
+    container protection-grps {
+      description
+        "The list of configured protection groups on the device.";
+    }
+  }
+
+  grouping port {
+    description
+      "Grouping of attributes related to a port object.";
+    leaf port-name {
+      type string;
+      mandatory true;
+      description
+        "Identifier for a port, unique within a circuit pack";
+    }
+    leaf port-type {
+      type string;
+      description
+        "Type of the pluggable or fixed port.";
+    }
+    leaf port-qual {
+      type org-openroadm-common-types:port-qual;
+    }
+    leaf port-wavelength-type {
+      type org-openroadm-port-types:port-wavelength-types;
+      config false;
+      description
+        "Type of port - single, multiple-wavelength, etc.";
+    }
+    leaf port-direction {
+      type org-openroadm-common-types:direction;
+      config false;
+      mandatory true;
+      description
+        "Whether port is uni (tx/rx) or bi-directional and";
+    }
+    leaf label {
+      type string;
+      config false;
+      description
+        "Faceplate label";
+    }
+    leaf circuit-id {
+      type string {
+        length "0..45";
+      }
+      description
+        "circuit identifier/user label,
+         can be used in alarm correlation and/or connection management ";
+    }
+    leaf administrative-state {
+      type org-openroadm-equipment-states-types:admin-states;
+      default "outOfService";
+      description
+        "Administrative state of port. The value of this field independent of the state of its contained and containing resources.  Setting this a port to administratively down will impact both its operational state, as well the operational state of its contained resources.  If this port is an endpoint to a connection, internal-link, physical-link, etc, then administratively disabling this port will impact the operational state of those items unless they are using some form of port-protection schema.";
+    }
+    leaf operational-state {
+      type org-openroadm-common-types:state;
+      config false;
+      mandatory true;
+      description
+        "Operational state of a port";
+    }
+    leaf-list supported-interface-capability {
+      type identityref {
+        base org-openroadm-port-types:supported-if-capability;
+      }
+      config false;
+      description
+        "Interface types supported on this port";
+    }
+    leaf logical-connection-point {
+      type string;
+      description
+        "delete or replace with list logical-ports or connections?";
+    }
+    container partner-port {
+      config false;
+      description
+        "For ports which are not identified as having a direction of bidirectional, this field is used to identify the port which corresponds to the reverse direction. A port pair should include a port for each direction (tx, rx) and report their mate as partner-port.";
+      uses port-name;
+    }
+    container parent-port {
+      config false;
+      description
+        "In the case of port hierarchy, this is the parent port, which is also modeled as port within this circuit-pack. This is used in the case of a port that supports a parallel connector that contains subports.  The parent-port of the subport will be the port that contains this subport.  This can be used to help isolate faults when a single fault on a parallel connector introduces symptomatic failures on the contained subports.";
+      uses port-name;
+    }
+    list interfaces {
+      config false;
+      description
+        "List of the interfaces this port supports.  This is a list of names of instances in the flat instance list";
+      uses interface-name;
+    }
+  }
+
+  grouping org-openroadm-device-container {
+    container org-openroadm-device {
+      container info {
+        uses device-common;
+        leaf max-degrees {
+          type uint16;
+          config false;
+          description
+            "Max. number of degrees supported by device";
+        }
+        leaf max-srgs {
+          type uint16;
+          config false;
+          description
+            "Max. number of SRGs in an add/drop group";
+        }
+        leaf max-num-bin-15min-historical-pm {
+          type uint16;
+          config false;
+          description
+            "Max. number of bin the NE support for 15min historical PM";
+        }
+        leaf max-num-bin-24hour-historical-pm {
+          type uint16;
+          config false;
+          description
+            "Max. number of bin the NE support for 24hour historical PM";
+        }
+      }
+      container users {
+        description
+          "Stores a list of users";
+        uses org-openroadm-user-mgmt:user-profile;
+      }
+      container pending-sw {
+        config false;
+        uses org-openroadm-swdl:sw-bank;
+      }
+      uses shelves;
+      uses circuit-packs;
+      uses interfaces-grp;
+      uses protection-groups;
+      container protocols {
+        description
+          "Contains the supported protocols";
+      }
+      uses internal-links;
+      uses physical-links;
+      uses external-links;
+      list degree {
+        when "/org-openroadm-device/info/node-type='rdm'";
+        key "degree-number";
+        uses degree;
+      }
+      list shared-risk-group {
+        when "/org-openroadm-device/info/node-type='rdm'";
+        key "srg-number";
+        uses srg;
+      }
+      list line-amplifier {
+        when "/org-openroadm-device/info/node-type='ila'";
+        key "amp-number";
+        description
+          "lists amplifiers in different directions";
+        uses amplifier;
+        list circuit-pack {
+          key "index";
+          description
+            "list for Cards associated with an amplifier";
+          leaf index {
+            type uint32;
+          }
+          uses circuit-pack-name {
+            refine "circuit-pack-name" {
+              mandatory true;
+            }
+          }
+        }
+        list line-port {
+          key "port-direction";
+          description
+            "Port associated with an amplifier which face the line (ila-external): traffic port.";
+          leaf port-direction {
+            type org-openroadm-common-types:direction;
+            config true;
+            mandatory true;
+            description
+              "partly allows identifying ports associated with logical amp :TX for egress, RX for ingress
+               TXRX in case of bidirectional port";
+          }
+          leaf tx-instance-port-direction-label {
+            type string;
+            config true;
+            description
+              "Complements ports identification. Used notably in case of bidirectional ports, 
+               and/or in multi-degree amplifier nodes. Allows associating one of the directions
+               specified in ila-direction-label. Shall be consistent with ila-direction-label";
+          }
+          leaf rx-instance-port-direction-label {
+            type string;
+            config true;
+            description
+              "Complements ports identification. Used notably in case of bidirectional ports, 
+               and/or in multi-degree amplifier nodes. Allows associating one of the directions
+               specified in ila-direction-label. Shall be consistent with ila-direction-label";
+          }
+          uses port-name {
+            refine "circuit-pack-name" {
+              mandatory true;
+            }
+            refine "port-name" {
+              mandatory true;
+            }
+          }
+        }
+        list osc-port {
+          key "port-direction";
+          description
+            "Ports associated with OSC";
+          leaf port-direction {
+            type org-openroadm-common-types:direction;
+            config true;
+            mandatory true;
+            description
+              "allows identifying ports associated with logical amp : 
+               TX for OSC circuit-pack IN RX for OSC circuit-pack OUT";
+          }
+          uses port-name {
+            refine "circuit-pack-name" {
+              mandatory true;
+            }
+            refine "port-name" {
+              mandatory true;
+            }
+          }
+        }
+        list otdr-port {
+          key "otdr-direction";
+          description
+            "otdr ports associated with an ILA";
+          leaf otdr-direction {
+            type string;
+            config true;
+            description
+              "allows identifying associated logical amp port in which OTDR is launched: 
+               corresponds to rx-instance-port-direction-label of corresponding amplifier line-port";
+          }
+          uses port-name {
+            refine "circuit-pack-name" {
+              mandatory true;
+            }
+            refine "port-name" {
+              mandatory true;
+            }
+          }
+        }
+      }
+      list xponder {
+        when "/org-openroadm-device/info/node-type='xpdr'";
+        key "xpdr-number";
+        uses xponder;
+      }
+      list roadm-connections {
+        when "/org-openroadm-device/info/node-type='rdm'";
+        key "connection-name";
+        uses connection;
+      }
+      list odu-connection {
+        when "/org-openroadm-device/info/node-type='xpdr'";
+        key "connection-name";
+        uses odu-connection;
+      }
+      list connection-map {
+        key "connection-map-number";
+        config false;
+        leaf connection-map-number {
+          type uint32;
+          description
+            "Unique identifier for this connection-map entry";
+        }
+        container source {
+          leaf circuit-pack-name {
+            type leafref {
+              path "/org-openroadm-device/circuit-packs/circuit-pack-name";
+            }
+            mandatory true;
+          }
+          leaf port-name {
+            type leafref {
+              path "/org-openroadm-device/circuit-packs[circuit-pack-name=current()/../circuit-pack-name]/ports/port-name";
+            }
+            mandatory true;
+            description
+              "Port identifier. Unique within the context of a circuit-pack.";
+          }
+        }
+        list destination {
+          key "circuit-pack-name port-name";
+          min-elements 1;
+          leaf circuit-pack-name {
+            type leafref {
+              path "/org-openroadm-device/circuit-packs/circuit-pack-name";
+            }
+            mandatory true;
+          }
+          leaf port-name {
+            type leafref {
+              path "/org-openroadm-device/circuit-packs[circuit-pack-name=current()/../circuit-pack-name]/ports/port-name";
+            }
+            mandatory true;
+            description
+              "Port identifier. Unique within the context of a circuit-pack.";
+          }
+        }
+      }
+      list odu-switching-pools {
+        when "/org-openroadm-device/info/node-type='xpdr'";
+        key "switching-pool-number";
+        config false;
+        leaf switching-pool-number {
+          type uint16;
+          description
+            "Unique identifier for this odu-switching-pool";
+        }
+        leaf switching-pool-type {
+          type org-openroadm-switching-pool-types:switching-pool-types;
+        }
+        list non-blocking-list {
+          key "nbl-number";
+          config false;
+          description
+            "List of ports in a non-blocking switch element";
+          leaf nbl-number {
+            type uint16;
+            description
+              "Identifier for this non-blocking-list. Unique within odu-switching-pool";
+          }
+          leaf interconnect-bandwidth-unit {
+            type uint32;
+            config false;
+            description
+              "Switch fabric interconnect bandwidth unit rate in bits per second. 
+               Represents granularity of switch fabric";
+          }
+          leaf interconnect-bandwidth {
+            type uint32;
+            config false;
+            description
+              "Total interconnect bandwidth for a non-blocking element expressed as 
+               number of inter-connect-bandwidth units";
+          }
+          list port-list {
+            key "circuit-pack-name port-name";
+            leaf circuit-pack-name {
+              type leafref {
+                path "/org-openroadm-device/circuit-packs/circuit-pack-name";
+              }
+              config false;
+            }
+            leaf port-name {
+              type leafref {
+                path "/org-openroadm-device/circuit-packs/ports/port-name";
+              }
+              config false;
+              description
+                "Port name. Unique within device";
+            }
+          }
+          list pluggable-optics-holder-list {
+            key "circuit-pack-name slot-name";
+            leaf circuit-pack-name {
+              type leafref {
+                path "/org-openroadm-device/circuit-packs/circuit-pack-name";
+              }
+              config false;
+              description
+                "Name of parent circuit-pack";
+            }
+            leaf slot-name {
+              type leafref {
+                path "/org-openroadm-device/circuit-packs/cp-slots/slot-name";
+              }
+              config false;
+              description
+                "Name of pluggable-optics-holder";
+            }
+          }
+        }
+      }
+    }
+  }
+
+  grouping mc-capabilities-g {
+    container mc-capabilities {
+      config false;
+      description
+        "Capabilities of the media channel on a degree or SRG.  This is used to validate mc-ttp provisioning on degrees and SRGs.";
+      leaf slot-width-granularity {
+        type org-openroadm-common-types:frequency-GHz;
+        default "50";
+        config false;
+        description
+          "Width of a slot measured in GHz.";
+      }
+      leaf center-freq-granularity {
+        type org-openroadm-common-types:frequency-GHz;
+        default "50";
+        config false;
+        description
+          "Granularity of allowed center frequencies.  The base frequency for this computation is 193.1 THz (G.694.1)";
+      }
+      leaf min-slots {
+        type uint32;
+        default "1";
+        config false;
+        description
+          "Minimum number of slots permitted to be joined together to form a media channel.  Must be less than or equal to the max-slots";
+      }
+      leaf max-slots {
+        type uint32;
+        default "1";
+        config false;
+        description
+          "Maximum number of slots permitted to be joined together to form a media channel.  Must be greater than or equal to the min-slots";
+      }
+    }
+  }
+
+  grouping common-session-parms {
+    description
+      "Common session parameters to identify a
+       management session.";
+    leaf username {
+      type org-openroadm-user-mgmt:username-type;
+      mandatory true;
+      description
+        "Name of the user for the session.";
+    }
+    leaf session-id {
+      type ietf-nc:session-id-or-zero-type;
+      mandatory true;
+      description
+        "Identifier of the session.
+         A NETCONF session MUST be identified by a non-zero value.
+         A non-NETCONF session MAY be identified by the value zero.";
+    }
+    leaf source-host {
+      type ietf-inet-types:ip-address;
+      description
+        "Address of the remote host for the session.";
+    }
+  }
+
+  grouping changed-by-parms {
+    description
+      "Common parameters to identify the source
+       of a change event, such as a configuration
+       or capability change.";
+    container changed-by {
+      description
+        "Indicates the source of the change.
+         If caused by internal action, then the
+         empty leaf 'server' will be present.
+         If caused by a management session, then
+         the name, remote host address, and session ID
+         of the session that made the change will be reported.";
+      choice server-or-user {
+        leaf server {
+          type empty;
+          description
+            "If present, the change was caused
+             by the server.";
+        }
+        case by-user {
+          uses common-session-parms;
+        }
+      }
+    }
+  }
+
+  rpc led-control {
+    description
+      "This command is used to allow user to find an entity on the NE,
+       The specified entity will have LED blinking.
+       The equipmentLedOn alarm will be raised and cleared for the indication";
+    input {
+      choice equipment-entity {
+        mandatory true;
+        case shelf {
+          leaf shelf-name {
+            type leafref {
+              path "/org-openroadm-device/shelves/shelf-name";
+            }
+            mandatory true;
+            description
+              "shelf-name for the operation";
+          }
+        }
+        case circuit-pack {
+          leaf circuit-pack-name {
+            type leafref {
+              path "/org-openroadm-device/circuit-packs/circuit-pack-name";
+            }
+            mandatory true;
+            description
+              "circuit-pack-name for the operation";
+          }
+        }
+      }
+      leaf enabled {
+        type boolean;
+        mandatory true;
+        description
+          "led-control enabled flag.
+           when enabled=true,  equipmentLedOn alarm will be raised
+           when enabled=false, equipmentLedOn alarm will be cleared";
+      }
+    }
+    output {
+      uses org-openroadm-common-types:rpc-response-status;
+    }
+  }
+  rpc create-tech-info {
+    description
+      "Collects all log data for debugging and place it in a location accessible via ftp/sftp.
+       This model assumes ASYNC operation, i.e. the command will return after the device accepts the command,
+       A create-tech-info-notification will be send out later for the result of the operation.
+       The log-file is cleared at the start of every create-tech-info operation in order to ensure 
+       the up-to-date logs are collected. If a vendor does not support concurrent log collection, the second 
+       create-tech-info command will be rejected.";
+    input {
+      leaf shelf-id {
+        type leafref {
+          path "/org-openroadm-device/shelves/shelf-name";
+        }
+        description
+          "This optional field is used to specify the shelf for log collection. 
+           When this filed is not provided, it is expected to collect logs for the whole node.
+           Vendor should reject the command if the whole node log collection is not supported.";
+      }
+      leaf log-option {
+        type string;
+        description
+          "The log type a vendor can specify. Maybe used in future";
+      }
+    }
+    output {
+      uses create-tech-info-group;
+      uses org-openroadm-common-types:rpc-response-status;
+    }
+  }
+  rpc get-connection-port-trail {
+    input {
+      leaf connection-name {
+        type string;
+        mandatory true;
+      }
+    }
+    output {
+      uses org-openroadm-common-types:rpc-response-status;
+      list ports {
+        uses org-openroadm-common-types:physical-location;
+        uses port-name {
+          refine "circuit-pack-name" {
+            mandatory true;
+          }
+          refine "port-name" {
+            mandatory true;
+          }
+        }
+      }
+    }
+  }
+  rpc disable-automatic-shutoff {
+    input {
+      choice degree-or-amp {
+        mandatory true;
+        description
+          "The choice describes the option to specify the entity for the disable-automatic-shutoff RPC. It can be degree-number for rdm and amp-number for ila";
+        case degree {
+          leaf degree-number {
+            type leafref {
+              path "/org-openroadm-device/degree/degree-number";
+            }
+            mandatory true;
+            description
+              "The degree-number defined in degree";
+          }
+        }
+        case amp {
+          leaf amp-number {
+            type leafref {
+              path "/org-openroadm-device/line-amplifier/amp-number";
+            }
+            mandatory true;
+            description
+              "The amp-number defined in line-amplifier";
+          }
+        }
+      }
+      leaf support-timer {
+        type uint16 {
+          range "1..600";
+        }
+        default "20";
+      }
+    }
+    output {
+      uses org-openroadm-common-types:rpc-response-status;
+    }
+  }
+  rpc start-scan {
+    input {
+      choice degree-or-amp {
+        mandatory true;
+        description
+          "The choice describes the option to specify the entity for the start-scan RPC. It can be degree-number for rdm and amp-number for ila";
+        case degree {
+          leaf degree-number {
+            type leafref {
+              path "/org-openroadm-device/degree/degree-number";
+            }
+            mandatory true;
+            description
+              "The degree-number defined in degree";
+          }
+        }
+        case amp {
+          leaf amp-number {
+            type leafref {
+              path "/org-openroadm-device/line-amplifier/amp-number";
+            }
+            mandatory true;
+            description
+              "The amp-number defined in line-amplifier";
+          }
+        }
+      }
+      leaf port-direction {
+        type org-openroadm-common-types:direction;
+      }
+      leaf distance {
+        type uint32;
+      }
+      leaf resolution {
+        type uint32;
+      }
+    }
+    output {
+      uses org-openroadm-common-types:rpc-response-status;
+    }
+  }
+  rpc set-current-datetime {
+    description
+      "Set the info/current-datetime leaf to the specified value.";
+    input {
+      leaf current-datetime {
+        type ietf-yang-types:date-and-time;
+        mandatory true;
+        description
+          "The current system date and time in UTC. Format: YYYY-MM-DDTHH:MM:SS";
+      }
+    }
+    output {
+      uses org-openroadm-common-types:rpc-response-status;
+    }
+  }
+  notification create-tech-info-notification {
+    description
+      "This Notification is sent when the create-tech-info is complete or failed.";
+    uses create-tech-info-group;
+    uses org-openroadm-common-types:rpc-response-status;
+  }
+  notification otdr-scan-result {
+    leaf status {
+      type enumeration {
+        enum "Completed" {
+          value 1;
+        }
+        enum "Failed" {
+          value 2;
+        }
+      }
+      mandatory true;
+      description
+        "Completed or Failed for the scan's final status";
+    }
+    leaf result-file {
+      type string;
+    }
+  }
+  notification change-notification {
+    description
+      "The Notification that a resource has been added, modified or removed.
+       This notification can be triggered by changes in configuration and operational data.
+       It shall contain the changed field pointed by the xpath. 
+       Typically it is not intended for frequently changing volatile data e.g. PM, power levels";
+    leaf change-time {
+      type ietf-yang-types:date-and-time;
+      description
+        "The time the change occurs.";
+    }
+    uses changed-by-parms;
+    leaf datastore {
+      type enumeration {
+        enum "running" {
+          description
+            "The <running> datastore has changed.";
+        }
+        enum "startup" {
+          description
+            "The <startup> datastore has changed";
+        }
+      }
+      default "running";
+      description
+        "Indicates which configuration datastore has changed.";
+    }
+    list edit {
+      description
+        "An edit (change) record SHOULD be present for each distinct
+         edit operation that the server has detected on
+         the target datastore.  This list MAY be omitted
+         if the detailed edit operations are not known.
+         The server MAY report entries in this list for
+         changes not made by a NETCONF session.";
+      leaf target {
+        type instance-identifier;
+        description
+          "Top most node associated with the configuration or operational change.
+           A server SHOULD set this object to the node within
+           the datastore that is being altered.  A server MAY
+           set this object to one of the ancestors of the actual
+           node that was changed, or omit this object, if the
+           exact node is not known.";
+      }
+      leaf operation {
+        type ietf-nc:edit-operation-type;
+        description
+          "Type of edit operation performed.
+           A server MUST set this object to the NETCONF edit
+           operation performed on the target datastore.";
+      }
+    }
+  }
+  uses org-openroadm-device-container;
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-ethernet-interfaces@2018-10-19.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-ethernet-interfaces@2018-10-19.yang
new file mode 100755 (executable)
index 0000000..494f4ce
--- /dev/null
@@ -0,0 +1,165 @@
+module org-openroadm-ethernet-interfaces {
+  namespace "http://org/openroadm/ethernet-interfaces";
+  prefix org-openroadm-eth-interfaces;
+
+  import org-openroadm-device {
+    prefix org-openroadm-device;
+    revision-date 2018-10-19;
+  }
+  import org-openroadm-interfaces {
+    prefix openROADM-if;
+    revision-date 2017-06-26;
+  }
+
+  organization
+    "Open ROADM MSA";
+  contact
+    "OpenROADM.org";
+  description
+    "YANG definitions for device facility ethernet interfaces.
+     
+     Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, 
+     AT&T Intellectual Property.  All other rights reserved.
+     
+     Redistribution and use in source and binary forms, with or without modification, 
+     are permitted provided that the following conditions are met:
+     
+     * Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+     * Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation and/or 
+       other materials provided with the distribution.
+     * Neither the Members of the Open ROADM MSA Agreement nor the names of its 
+       contributors may be used to endorse or promote products derived from this software 
+       without specific prior written permission.
+     
+     THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT ''AS IS'' 
+     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+     IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT BE LIABLE FOR ANY DIRECT, 
+     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE, DATA, 
+     OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+     WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+     POSSIBILITY OF SUCH DAMAGE.
+     
+     Also contains code components extracted from IETF Interfaces.  These code components 
+     are copyrighted and licensed as follows:
+     
+     Copyright (c) 2016 IETF Trust and the persons identified as the document authors. 
+     All rights reserved. 
+     
+     This document is subject to BCP 78 and the IETF Trust’s Legal Provisions Relating 
+     to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of 
+     publication of this document. Please review these documents carefully, as they 
+     describe your rights and restrictions with respect to this document. Code Components 
+     extracted from this document must include Simplified BSD License text as described in
+     Section 4.e of the Trust Legal Provisions and are provided without warranty as 
+     described in the Simplified BSD License.";
+
+  revision 2018-10-19 {
+    description
+      "Version 2.2.1";
+  }
+  revision 2017-12-15 {
+    description
+      "Version 2.2";
+  }
+  revision 2017-09-29 {
+    description
+      "Version 2.1";
+  }
+  revision 2017-07-28 {
+    description
+      "Version 2.0.1 - added revision-date to imports";
+  }
+  revision 2016-10-14 {
+    description
+      "Version 1.2";
+  }
+
+  grouping eth-attributes {
+    leaf speed {
+      type uint32;
+      description
+        "Set speed of the interface, unit mbps. 
+         This is for ETH facility. ";
+    }
+    leaf fec {
+      type enumeration {
+        enum "off";
+        enum "rsfec";
+      }
+      description
+        "Forward Error Correction Choices. ";
+    }
+    leaf duplex {
+      type enumeration {
+        enum "half" {
+          value 0;
+          description
+            "half duplex";
+        }
+        enum "full" {
+          value 1;
+          description
+            "full duplex";
+        }
+      }
+      default "full";
+      description
+        "Set duplex selections.";
+    }
+    leaf mtu {
+      type uint32 {
+        range "1518..9000";
+      }
+      default "1522";
+      description
+        "Set Maximum Frame Size.";
+    }
+    leaf auto-negotiation {
+      type enumeration {
+        enum "enabled" {
+          value 1;
+          description
+            "Auto Negotiation enabled";
+        }
+        enum "disabled" {
+          value 0;
+          description
+            "Auto Negotiation disabled";
+        }
+      }
+      default "enabled";
+      description
+        "Set Auto Negotiation: Enabled/Disabled.";
+    }
+    leaf curr-speed {
+      type string;
+      config false;
+      description
+        "speed (UNKNOWN/AUTO/10/100/1000/10000) corresponding to the interface";
+    }
+    leaf curr-duplex {
+      type string;
+      config false;
+      description
+        "duplex (HALF/FULL) corresponding to the interface";
+    }
+  }
+
+  grouping ethernet-container {
+    container ethernet {
+      description
+        "Ethernet Interfaces";
+      uses eth-attributes;
+    }
+  }
+
+  augment "/org-openroadm-device:org-openroadm-device/org-openroadm-device:interface" {
+    when "org-openroadm-device:type = 'openROADM-if:ethernetCsmacd'";
+    uses ethernet-container;
+  }
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-interfaces@2017-06-26.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-interfaces@2017-06-26.yang
new file mode 100644 (file)
index 0000000..88001a6
--- /dev/null
@@ -0,0 +1,125 @@
+module org-openroadm-interfaces {
+  namespace "http://org/openroadm/interfaces";
+  prefix openROADM-if;
+
+  organization
+    "Open ROADM MSA";
+  contact
+    "OpenROADM.org";
+  description
+    "YANG definitions for device facility interfaces. 
+     Reused ietf-interfaces and some interface-type defined in iana-if-type.
+     
+     Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, 
+     AT&T Intellectual Property.  All other rights reserved.
+     
+     Redistribution and use in source and binary forms, with or without modification, 
+     are permitted provided that the following conditions are met:
+     
+     * Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+     * Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation and/or 
+       other materials provided with the distribution.
+     * Neither the Members of the Open ROADM MSA Agreement nor the names of its 
+       contributors may be used to endorse or promote products derived from this software 
+       without specific prior written permission.
+     
+     THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT ''AS IS'' 
+     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+     IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT BE LIABLE FOR ANY DIRECT, 
+     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE, DATA, 
+     OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+     WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+     POSSIBILITY OF SUCH DAMAGE.
+     
+     Also contains code components extracted from IETF Interfaces.  These code components 
+     are copyrighted and licensed as follows:
+     
+     Copyright (c) 2016 IETF Trust and the persons identified as the document authors. 
+     All rights reserved. 
+     
+     This document is subject to BCP 78 and the IETF Trust’s Legal Provisions Relating 
+     to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of 
+     publication of this document. Please review these documents carefully, as they 
+     describe your rights and restrictions with respect to this document. Code Components 
+     extracted from this document must include Simplified BSD License text as described in
+     Section 4.e of the Trust Legal Provisions and are provided without warranty as 
+     described in the Simplified BSD License.";
+
+  revision 2017-06-26 {
+    description
+      "Version 2.0";
+  }
+  revision 2016-10-14 {
+    description
+      "Version 1.2";
+  }
+
+  identity interface-type {
+    description
+      "Base identity from which specific interface types are
+       derived.";
+  }
+
+  identity ethernetCsmacd {
+    base interface-type;
+    description
+      "For all Ethernet-like interfaces, regardless of speed,
+       as per RFC 3635.";
+    reference
+      "RFC 3635 - Definitions of Managed Objects for the
+                  Ethernet-like Interface Types";
+  }
+
+  identity ip {
+    base interface-type;
+    description
+      "IP (for APPN HPR in IP networks).";
+  }
+
+  identity mediaChannelTrailTerminationPoint {
+    base interface-type;
+    description
+      "Media Channel Trail Termination Point";
+  }
+
+  identity networkMediaChannelConnectionTerminationPoint {
+    base interface-type;
+    description
+      "Network Media Channel Connection Termination Point";
+  }
+
+  identity opticalChannel {
+    base interface-type;
+    description
+      "Optical Channel.";
+  }
+
+  identity opticalTransport {
+    base interface-type;
+    description
+      "Optical Transport.";
+  }
+
+  identity otnOdu {
+    base interface-type;
+    description
+      "OTN Optical Data Unit.";
+  }
+
+  identity otnOtu {
+    base interface-type;
+    description
+      "OTN Optical channel Transport Unit.";
+  }
+
+  identity openROADMOpticalMultiplex {
+    base interface-type;
+    description
+      "Optical Transport Multiplex type for openROADM";
+  }
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-lldp@2018-10-19.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-lldp@2018-10-19.yang
new file mode 100755 (executable)
index 0000000..0b85ce1
--- /dev/null
@@ -0,0 +1,328 @@
+module org-openroadm-lldp {
+  namespace "http://org/openroadm/lldp";
+  prefix org-openroadm-lldp;
+
+  import ietf-inet-types {
+    prefix inet;
+    revision-date 2013-07-15;
+  }
+  import org-openroadm-device {
+    prefix org-openroadm-device;
+    revision-date 2018-10-19;
+  }
+  import iana-afn-safi {
+    prefix ianaaf;
+    revision-date 2013-07-04;
+  }
+  import org-openroadm-resource-types {
+    prefix org-openroadm-resource-types;
+    revision-date 2018-10-19;
+  }
+  import ietf-yang-types {
+    prefix yang;
+    revision-date 2013-07-15;
+  }
+
+  organization
+    "Open ROADM MSA";
+  contact
+    "OpenROADM.org";
+  description
+    "YANG definitions for lldp protocol.
+     
+     Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, 
+     AT&T Intellectual Property.  All other rights reserved.
+     
+     Redistribution and use in source and binary forms, with or without modification, 
+     are permitted provided that the following conditions are met:
+     
+     * Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+     * Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation and/or 
+       other materials provided with the distribution.
+     * Neither the Members of the Open ROADM MSA Agreement nor the names of its 
+       contributors may be used to endorse or promote products derived from this software 
+       without specific prior written permission.
+     
+     THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT ''AS IS'' 
+     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+     IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT BE LIABLE FOR ANY DIRECT, 
+     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE, DATA, 
+     OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+     WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+     POSSIBILITY OF SUCH DAMAGE.";
+
+  revision 2018-10-19 {
+    description
+      "Version 2.2.1";
+  }
+  revision 2017-12-15 {
+    description
+      "Version 2.2";
+  }
+  revision 2017-09-29 {
+    description
+      "Version 2.1";
+  }
+  revision 2017-07-28 {
+    description
+      "Version 2.0.1 - added revision-date to imports";
+  }
+  revision 2017-06-26 {
+    description
+      "Version 2.0";
+  }
+  revision 2016-10-14 {
+    description
+      "Version 1.2";
+  }
+
+  grouping nbr-info-grp {
+    description
+      "Display LLDP Neighbour ";
+    leaf remoteSysName {
+      type string;
+      description
+        "remote neighbour system name";
+    }
+    leaf remoteMgmtAddressSubType {
+      type ianaaf:address-family;
+      description
+        "remote neighbour Management Address Subtype Enumeration";
+    }
+    leaf remoteMgmtAddress {
+      type inet:ip-address;
+      description
+        "remote neighbour management address";
+    }
+    leaf remotePortIdSubType {
+      type enumeration {
+        enum "other" {
+          value 0;
+          description
+            "reserved";
+        }
+        enum "ifalias" {
+          value 1;
+          description
+            "Interface Alias (IfAlias - IETF RFC 2863) ";
+        }
+        enum "portcomponent" {
+          value 2;
+          description
+            "Port component (EntPhysicalAlias IETF RFC 4133)";
+        }
+        enum "macaddress" {
+          value 3;
+          description
+            "MAC address (IEEE Std 802) ";
+        }
+        enum "networkaddress" {
+          value 4;
+          description
+            "Network Address";
+        }
+        enum "ifname" {
+          value 5;
+          description
+            "Interface Name (ifName - IETF RFC 2863)";
+        }
+        enum "agentcircuitid" {
+          value 6;
+          description
+            "Agent Circuit Id (IETF RFC 3046)";
+        }
+        enum "local" {
+          value 7;
+          description
+            "Locally assigned";
+        }
+      }
+      description
+        "remote neighbour Port ID Subtype Enumeration";
+    }
+    leaf remotePortId {
+      type string;
+      description
+        "remote neighbour port Id";
+    }
+    leaf remoteChassisIdSubType {
+      type enumeration {
+        enum "reserved" {
+          value 0;
+          description
+            "reserved";
+        }
+        enum "chassiscomponent" {
+          value 1;
+          description
+            "Chassis component (EntPhysicalAlias IETF RFC 4133)";
+        }
+        enum "ifalias" {
+          value 2;
+          description
+            "Interface Alias (IfAlias - IETF RFC 2863) ";
+        }
+        enum "portcomponent" {
+          value 3;
+          description
+            "Port component (EntPhysicalAlias IETF RFC 4133)";
+        }
+        enum "macaddress" {
+          value 4;
+          description
+            "MAC address (IEEE Std 802) ";
+        }
+        enum "networkaddress" {
+          value 5;
+          description
+            "Network Address";
+        }
+        enum "ifname" {
+          value 6;
+          description
+            "Interface Name (ifName - IETF RFC 2863)";
+        }
+        enum "local" {
+          value 7;
+          description
+            "Locally assigned";
+        }
+      }
+      description
+        "Chassis ID Subtype Enumeration";
+    }
+    leaf remoteChassisId {
+      type string;
+      description
+        "remote neighbour Chassis Id";
+    }
+  }
+
+  grouping lldp-container {
+    container lldp {
+      description
+        "LLDP configurable and retrievable";
+      container global-config {
+        description
+          "LLDP global configurations";
+        leaf adminStatus {
+          type enumeration {
+            enum "disable" {
+              value 0;
+              description
+                "Disable the LLDP feature per NE";
+            }
+            enum "enable" {
+              value 1;
+              description
+                "Enable the LLDP feature per NE";
+            }
+          }
+          default "enable";
+          description
+            "LLDP feature Enable/Disable per NE";
+        }
+        leaf msgTxInterval {
+          type uint16 {
+            range "5..32768";
+          }
+          default "30";
+          description
+            "LLDP frame Retransmit Interval in seconds";
+        }
+        leaf msgTxHoldMultiplier {
+          type uint8 {
+            range "2..10";
+          }
+          default "4";
+          description
+            "TTL value for the TLVs transmitter over wire in seconds";
+        }
+      }
+      list port-config {
+        key "ifName";
+        description
+          "LLDP port configurations";
+        leaf ifName {
+          type leafref {
+            path "/org-openroadm-device:org-openroadm-device/org-openroadm-device:interface/org-openroadm-device:name";
+          }
+          description
+            "Ethernet interface name where LLDP runs";
+        }
+        leaf adminStatus {
+          type enumeration {
+            enum "disable" {
+              value 0;
+              description
+                "Disables the LLDP frames transmit and receive on specific interface";
+            }
+            enum "txandrx" {
+              value 1;
+              description
+                "Enable Transmit and Receive LLDP frames on specific interface";
+            }
+          }
+          default "txandrx";
+          description
+            "LLDP enable per port basis";
+        }
+      }
+      container nbr-list {
+        config false;
+        description
+          "LLDP Oper data - Neighbour List information";
+        list if-name {
+          key "ifName";
+          leaf ifName {
+            type string;
+            description
+              "Ethernet interface name where LLDP runs";
+          }
+          uses nbr-info-grp;
+        }
+      }
+    }
+  }
+
+  notification lldp-nbr-info-change {
+    description
+      "LLDP: Neighbor Information Changed
+       remoteSysName
+       remoteSysMgmtAddressSubType
+       remoteSysMgmtAddress
+       remotePortIdSubType
+       remotePortId
+       remoteChassisIdSubType
+       remoteChassisId
+       All of the above attributes are sent in event";
+    leaf notification-type {
+      type org-openroadm-resource-types:resource-notification-type;
+    }
+    leaf resource-type {
+      type org-openroadm-resource-types:resource-type-enum;
+      description
+        "resource-type for this notification is interface";
+    }
+    leaf resource {
+      type string;
+      description
+        "resource interface-name";
+    }
+    container nbr-info {
+      uses nbr-info-grp;
+    }
+    leaf event-time {
+      type yang:date-and-time;
+    }
+  }
+  augment "/org-openroadm-device:org-openroadm-device/org-openroadm-device:protocols" {
+    when "/org-openroadm-device:org-openroadm-device/org-openroadm-device:info/org-openroadm-device:node-type='rdm' or /org-openroadm-device:org-openroadm-device/org-openroadm-device:info/org-openroadm-device:node-type='ila'";
+    uses lldp-container;
+  }
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-maintenance-loopback@2017-12-15.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-maintenance-loopback@2017-12-15.yang
new file mode 100644 (file)
index 0000000..da8f5cd
--- /dev/null
@@ -0,0 +1,80 @@
+module org-openroadm-maintenance-loopback {
+  namespace "http://org/openroadm/maintenance-loopback";
+  prefix org-openroadm-maint-loopback;
+
+  organization
+    "Open ROADM MSA";
+  contact
+    "OpenROADM.org";
+  description
+    "YANG definitions for maintenance loopback.
+     
+     Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, 
+     AT&T Intellectual Property.  All other rights reserved.
+     
+     Redistribution and use in source and binary forms, with or without modification, 
+     are permitted provided that the following conditions are met:
+     
+     * Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+     * Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation and/or 
+       other materials provided with the distribution.
+     * Neither the Members of the Open ROADM MSA Agreement nor the names of its 
+       contributors may be used to endorse or promote products derived from this software 
+       without specific prior written permission.
+     
+     THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT ''AS IS'' 
+     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+     IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT BE LIABLE FOR ANY DIRECT, 
+     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE, DATA, 
+     OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+     WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+     POSSIBILITY OF SUCH DAMAGE.";
+
+  revision 2017-12-15 {
+    description
+      "Version 2.2";
+  }
+  revision 2016-10-14 {
+    description
+      "Version 1.2";
+  }
+
+  grouping maint-loopback {
+    container maint-loopback {
+      leaf enabled {
+        type boolean;
+        default "false";
+        description
+          "loopback operation enable flag";
+      }
+      leaf type {
+        when "../enabled = 'true'";
+        type enumeration {
+          enum "fac" {
+            value 0;
+            description
+              "pre-FEC Loopback in the facility direction";
+          }
+          enum "term" {
+            value 1;
+            description
+              "Loopback in the terminal direction";
+          }
+          enum "fac2" {
+            value 2;
+            description
+              "post-FEC Loopback in the facility direction";
+          }
+        }
+        default "fac";
+        description
+          "Set Loopback type (or direction).";
+      }
+    }
+  }
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-maintenance-testsignal@2017-12-15.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-maintenance-testsignal@2017-12-15.yang
new file mode 100644 (file)
index 0000000..9816505
--- /dev/null
@@ -0,0 +1,139 @@
+module org-openroadm-maintenance-testsignal {
+  namespace "http://org/openroadm/maintenance-testsignal";
+  prefix org-openroadm-maint-testsignal;
+
+  organization
+    "Open ROADM MSA";
+  contact
+    "OpenROADM.org";
+  description
+    "YANG definitions for maintenance testsignal.
+     
+     Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, 
+     AT&T Intellectual Property.  All other rights reserved.
+     
+     Redistribution and use in source and binary forms, with or without modification, 
+     are permitted provided that the following conditions are met:
+     
+     * Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+     * Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation and/or 
+       other materials provided with the distribution.
+     * Neither the Members of the Open ROADM MSA Agreement nor the names of its 
+       contributors may be used to endorse or promote products derived from this software 
+       without specific prior written permission.
+     
+     THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT ''AS IS'' 
+     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+     IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT BE LIABLE FOR ANY DIRECT, 
+     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE, DATA, 
+     OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+     WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+     POSSIBILITY OF SUCH DAMAGE.";
+
+  revision 2017-12-15 {
+    description
+      "Version 2.2";
+  }
+  revision 2016-10-14 {
+    description
+      "Version 1.2";
+  }
+
+  grouping maint-testsignal {
+    container maint-testsignal {
+      leaf enabled {
+        type boolean;
+        default "false";
+        description
+          "testsignal enabled flag";
+      }
+      leaf testPattern {
+        when "../enabled = 'true'";
+        type enumeration {
+          enum "PRBS" {
+            value 0;
+            description
+              "Unframed, inverted PN-31 pattern or PRBS31 pattern per IEEE 802.3 clause 50.3.8.2 (inverted PN-31at line rate)";
+          }
+          enum "PRBS31" {
+            value 1;
+            description
+              "PRBS31 with standard mapping per G.709";
+          }
+          enum "PRBS23" {
+            value 2;
+            description
+              "SONET/SDH Framed,inverted PN-23 pattern.";
+          }
+          enum "PRZEROS" {
+            value 3;
+            description
+              "pseudo-random with zeros data pattern per IEEE 802.3 clause 49.2.8";
+          }
+          enum "IDLE" {
+            value 4;
+            description
+              "Scrambled IDLE test-pattern per IEEE 802.3ba";
+          }
+        }
+        description
+          "Set test signal pattern";
+      }
+      leaf type {
+        when "../enabled = 'true'";
+        type enumeration {
+          enum "fac" {
+            value 0;
+            description
+              "test signal in the facility direction";
+          }
+          enum "term" {
+            value 1;
+            description
+              "test signal in the terminal direction";
+          }
+        }
+        default "fac";
+        description
+          "Set test signal type (or direction).";
+      }
+      leaf bitErrors {
+        when "../enabled = 'true' and ../type = 'fac'";
+        type uint32 {
+          range "0..4294967295";
+        }
+        config false;
+        description
+          "bit errors for test signal in facility direction.";
+      }
+      leaf bitErrorsTerminal {
+        when "../enabled = 'true' and ../type = 'term'";
+        type uint32 {
+          range "0..4294967295";
+        }
+        config false;
+        description
+          "bit errors for test signal in terminal direction.";
+      }
+      leaf syncSeconds {
+        when "../enabled = 'true' and ../type = 'fac'";
+        type string;
+        config false;
+        description
+          "number of seconds the received facility test signal is in sync.";
+      }
+      leaf syncSecondsTerminal {
+        when "../enabled = 'true' and ../type = 'term'";
+        type string;
+        config false;
+        description
+          "number of seconds the received terminal test signal is in sync.";
+      }
+    }
+  }
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-media-channel-interfaces@2018-10-19.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-media-channel-interfaces@2018-10-19.yang
new file mode 100755 (executable)
index 0000000..4693a21
--- /dev/null
@@ -0,0 +1,127 @@
+module org-openroadm-media-channel-interfaces {
+  namespace "http://org/openroadm/media-channel-interfaces";
+  prefix org-openroadm-media-channel-interfaces;
+
+  import org-openroadm-device {
+    prefix org-openroadm-device;
+    revision-date 2018-10-19;
+  }
+  import org-openroadm-interfaces {
+    prefix openROADM-if;
+    revision-date 2017-06-26;
+  }
+  import org-openroadm-common-types {
+    prefix org-openroadm-common-types;
+    revision-date 2018-10-19;
+  }
+
+  organization
+    "Open ROADM MSA";
+  contact
+    "OpenROADM.org";
+  description
+    "YANG definitions for device facility och interfaces.
+     
+     Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, 
+     AT&T Intellectual Property.  All other rights reserved.
+     
+     Redistribution and use in source and binary forms, with or without modification, 
+     are permitted provided that the following conditions are met:
+     
+     * Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+     * Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation and/or 
+       other materials provided with the distribution.
+     * Neither the Members of the Open ROADM MSA Agreement nor the names of its 
+       contributors may be used to endorse or promote products derived from this software 
+       without specific prior written permission.
+     
+     THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT ''AS IS'' 
+     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+     IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT BE LIABLE FOR ANY DIRECT, 
+     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE, DATA, 
+     OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+     WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+     POSSIBILITY OF SUCH DAMAGE.
+     
+     Also contains code components extracted from IETF Interfaces.  These code components
+     are copyrighted and licensed as follows:
+     
+     Copyright (c) 2016 IETF Trust and the persons identified as the document authors.
+     All rights reserved.
+     
+     This document is subject to BCP 78 and the IETF Trust’s Legal Provisions Relating
+     to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of
+     publication of this document. Please review these documents carefully, as they
+     describe your rights and restrictions with respect to this document. Code Components
+     extracted from this document must include Simplified BSD License text as described in
+     Section 4.e of the Trust Legal Provisions and are provided without warranty as
+     described in the Simplified BSD License.";
+
+  revision 2018-10-19 {
+    description
+      "Version 2.2.1";
+  }
+  revision 2017-12-15 {
+    description
+      "Version 2.2";
+  }
+  revision 2017-09-29 {
+    description
+      "Version 2.1";
+  }
+  revision 2017-07-28 {
+    description
+      "Version 2.0.1 - added revision-date to imports";
+  }
+  revision 2017-06-26 {
+    description
+      "Version 2.0";
+  }
+
+  grouping mc-ttp-attributes {
+    description
+      "Media channel termination point. Models bandwidth allocation in physical media. Network media channels may be provisioned in the spectrum characterized by the frequency limits.";
+    leaf min-freq {
+      type org-openroadm-common-types:frequency-THz;
+      config true;
+      description
+        "Minimum Frequency in THz. Granularity is hardware dependent, based on pixel resolution. eg. ITU 12.5GHz frequency slots. Range covers C+L";
+    }
+    leaf max-freq {
+      type org-openroadm-common-types:frequency-THz;
+      config true;
+      description
+        "Maximum Frequency in THz. Granularity is hardware dependent, based on pixel resolution. eg. ITU 12.5GHz frequency slots. Range covers C+L";
+    }
+    leaf center-freq {
+      type org-openroadm-common-types:frequency-THz;
+      config false;
+      description
+        "Center Frequency in THz. Granularity is hardware dependent, based on center-freq-granularity.";
+    }
+    leaf slot-width {
+      type org-openroadm-common-types:frequency-GHz;
+      config false;
+      description
+        "Width of the slot.  Granularity is hardware dependent, based on slot-width-granularity";
+    }
+  }
+
+  grouping mc-ttp-container {
+    container mc-ttp {
+      description
+        "Media Channel Trail Termination Point (MC-TTP)";
+      uses mc-ttp-attributes;
+    }
+  }
+
+  augment "/org-openroadm-device:org-openroadm-device/org-openroadm-device:interface" {
+    when "org-openroadm-device:type = 'openROADM-if:mediaChannelTrailTerminationPoint'";
+    uses mc-ttp-container;
+  }
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-network-media-channel-interfaces@2018-10-19.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-network-media-channel-interfaces@2018-10-19.yang
new file mode 100755 (executable)
index 0000000..3eded06
--- /dev/null
@@ -0,0 +1,115 @@
+module org-openroadm-network-media-channel-interfaces {
+  namespace "http://org/openroadm/network-media-channel-interfaces";
+  prefix org-openroadm-network-media-channel-interfaces;
+
+  import org-openroadm-device {
+    prefix org-openroadm-device;
+    revision-date 2018-10-19;
+  }
+  import org-openroadm-interfaces {
+    prefix openROADM-if;
+    revision-date 2017-06-26;
+  }
+  import org-openroadm-common-types {
+    prefix org-openroadm-common-types;
+    revision-date 2018-10-19;
+  }
+
+  organization
+    "Open ROADM MSA";
+  contact
+    "OpenROADM.org";
+  description
+    "YANG definitions for device facility och interfaces.
+     
+     Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, 
+     AT&T Intellectual Property.  All other rights reserved.
+     
+     Redistribution and use in source and binary forms, with or without modification, 
+     are permitted provided that the following conditions are met:
+     
+     * Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+     * Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation and/or 
+       other materials provided with the distribution.
+     * Neither the Members of the Open ROADM MSA Agreement nor the names of its 
+       contributors may be used to endorse or promote products derived from this software 
+       without specific prior written permission.
+     
+     THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT ''AS IS'' 
+     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+     IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT BE LIABLE FOR ANY DIRECT, 
+     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE, DATA, 
+     OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+     WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+     POSSIBILITY OF SUCH DAMAGE.
+     
+     Also contains code components extracted from IETF Interfaces.  These code components
+     are copyrighted and licensed as follows:
+     
+     Copyright (c) 2016 IETF Trust and the persons identified as the document authors.
+     All rights reserved.
+     
+     This document is subject to BCP 78 and the IETF Trust’s Legal Provisions Relating
+     to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of
+     publication of this document. Please review these documents carefully, as they
+     describe your rights and restrictions with respect to this document. Code Components
+     extracted from this document must include Simplified BSD License text as described in
+     Section 4.e of the Trust Legal Provisions and are provided without warranty as
+     described in the Simplified BSD License.";
+
+  revision 2018-10-19 {
+    description
+      "Version 2.2.1";
+  }
+  revision 2017-12-15 {
+    description
+      "Version 2.2";
+  }
+  revision 2017-09-29 {
+    description
+      "Version 2.1";
+  }
+  revision 2017-07-28 {
+    description
+      "Version 2.0.1 - added revision-date to imports";
+  }
+  revision 2017-06-26 {
+    description
+      "Version 2.0";
+  }
+
+  grouping nmc-ctp-attributes {
+    description
+      "Network Media Channel attributes";
+    leaf frequency {
+      type org-openroadm-common-types:frequency-THz;
+      config true;
+      description
+        "Center Frequency in THz.  This is not constrained by mc-capabilities.  It must fit (when combined with width) inside any containing media channel.";
+    }
+    leaf width {
+      type org-openroadm-common-types:frequency-GHz;
+      config true;
+      description
+        "Frequency width in GHz.  This is not constrained by mc-capabilities.  It must fit (when combined with frequency) inside any containing media channel.";
+    }
+  }
+
+  grouping nmc-ctp-container {
+    container nmc-ctp {
+      description
+        "Network Media Channel Connection Termination Point (NMC-CTP)";
+      uses nmc-ctp-attributes;
+    }
+  }
+
+  augment "/org-openroadm-device:org-openroadm-device/org-openroadm-device:interface" {
+    when "org-openroadm-device:type = 'openROADM-if:networkMediaChannelConnectionTerminationPoint'";
+    uses nmc-ctp-container;
+  }
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-optical-channel-interfaces@2018-10-19.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-optical-channel-interfaces@2018-10-19.yang
new file mode 100755 (executable)
index 0000000..6020d8e
--- /dev/null
@@ -0,0 +1,135 @@
+module org-openroadm-optical-channel-interfaces {
+  namespace "http://org/openroadm/optical-channel-interfaces";
+  prefix org-openroadm-optical-channel-interfaces;
+
+  import org-openroadm-device {
+    prefix org-openroadm-device;
+    revision-date 2018-10-19;
+  }
+  import org-openroadm-interfaces {
+    prefix openROADM-if;
+    revision-date 2017-06-26;
+  }
+  import org-openroadm-common-types {
+    prefix org-openroadm-common-types;
+    revision-date 2018-10-19;
+  }
+
+  organization
+    "Open ROADM MSA";
+  contact
+    "OpenROADM.org";
+  description
+    "YANG definitions for device facility och interfaces.
+     
+     Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, 
+     AT&T Intellectual Property.  All other rights reserved.
+     
+     Redistribution and use in source and binary forms, with or without modification, 
+     are permitted provided that the following conditions are met:
+     
+     * Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+     * Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation and/or 
+       other materials provided with the distribution.
+     * Neither the Members of the Open ROADM MSA Agreement nor the names of its 
+       contributors may be used to endorse or promote products derived from this software 
+       without specific prior written permission.
+     
+     THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT ''AS IS'' 
+     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+     IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT BE LIABLE FOR ANY DIRECT, 
+     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE, DATA, 
+     OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+     WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+     POSSIBILITY OF SUCH DAMAGE.
+     
+     Also contains code components extracted from IETF Interfaces.  These code components
+     are copyrighted and licensed as follows:
+     
+     Copyright (c) 2016 IETF Trust and the persons identified as the document authors.
+     All rights reserved.
+     
+     This document is subject to BCP 78 and the IETF Trust’s Legal Provisions Relating
+     to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of
+     publication of this document. Please review these documents carefully, as they
+     describe your rights and restrictions with respect to this document. Code Components
+     extracted from this document must include Simplified BSD License text as described in
+     Section 4.e of the Trust Legal Provisions and are provided without warranty as
+     described in the Simplified BSD License.";
+
+  revision 2018-10-19 {
+    description
+      "Version 2.2.1";
+  }
+  revision 2017-12-15 {
+    description
+      "Version 2.2";
+  }
+  revision 2017-09-29 {
+    description
+      "Version 2.1";
+  }
+  revision 2017-07-28 {
+    description
+      "Version 2.0.1 - added revision-date to imports";
+  }
+  revision 2017-06-26 {
+    description
+      "Version 2.0";
+  }
+  revision 2016-10-14 {
+    description
+      "Version 1.2";
+  }
+
+  grouping och-attributes {
+    description
+      "Optical Channel attributes";
+    leaf rate {
+      type identityref {
+        base org-openroadm-common-types:och-rate-identity;
+      }
+      description
+        "rate";
+    }
+    leaf frequency {
+      type org-openroadm-common-types:frequency-THz;
+      config true;
+      description
+        "Center Frequency in THz.";
+    }
+    leaf width {
+      type org-openroadm-common-types:frequency-GHz;
+      config false;
+      description
+        "Frequency width in GHz.";
+    }
+    leaf modulation-format {
+      type org-openroadm-common-types:modulation-format;
+    }
+    leaf transmit-power {
+      type org-openroadm-common-types:power-dBm;
+      description
+        "The target transmit power for this channel. When set, the xponder will work to ensure that port-current-power reaches this level. Applicable only to channel on top of xpdr-network port";
+    }
+  }
+
+  grouping och-container {
+    container och {
+      description
+        "Optical Channel (OCh):
+         Models the optical channel interfaces for an Optical White Box.";
+      uses och-attributes;
+    }
+  }
+
+  augment "/org-openroadm-device:org-openroadm-device/org-openroadm-device:interface" {
+    when "org-openroadm-device:type = 'openROADM-if:opticalChannel'";
+    uses och-container;
+  }
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-optical-transport-interfaces@2018-10-19.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-optical-transport-interfaces@2018-10-19.yang
new file mode 100755 (executable)
index 0000000..1476de2
--- /dev/null
@@ -0,0 +1,187 @@
+module org-openroadm-optical-transport-interfaces {
+  namespace "http://org/openroadm/optical-transport-interfaces";
+  prefix org-openroadm-optical-transport-interfaces;
+
+  import org-openroadm-device {
+    prefix org-openroadm-device;
+    revision-date 2018-10-19;
+  }
+  import org-openroadm-interfaces {
+    prefix openROADM-if;
+    revision-date 2017-06-26;
+  }
+  import org-openroadm-common-types {
+    prefix org-openroadm-common-types;
+    revision-date 2018-10-19;
+  }
+
+  organization
+    "Open ROADM MSA";
+  contact
+    "OpenROADM.org";
+  description
+    "This module contains YANG definitions
+     for the Optical Transport Interfaces.
+     
+     Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, 
+     AT&T Intellectual Property.  All other rights reserved.
+     
+     Redistribution and use in source and binary forms, with or without modification, 
+     are permitted provided that the following conditions are met:
+     
+     * Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+     * Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation and/or 
+       other materials provided with the distribution.
+     * Neither the Members of the Open ROADM MSA Agreement nor the names of its 
+       contributors may be used to endorse or promote products derived from this software 
+       without specific prior written permission.
+     
+     THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT ''AS IS'' 
+     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+     IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT BE LIABLE FOR ANY DIRECT, 
+     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE, DATA, 
+     OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+     WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+     POSSIBILITY OF SUCH DAMAGE.
+     
+     Also contains code components extracted from IETF Interfaces.  These code components
+     are copyrighted and licensed as follows:
+     
+     Copyright (c) 2016 IETF Trust and the persons identified as the document authors.
+     All rights reserved.
+     
+     This document is subject to BCP 78 and the IETF Trust’s Legal Provisions Relating
+     to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of
+     publication of this document. Please review these documents carefully, as they
+     describe your rights and restrictions with respect to this document. Code Components
+     extracted from this document must include Simplified BSD License text as described in
+     Section 4.e of the Trust Legal Provisions and are provided without warranty as
+     described in the Simplified BSD License.";
+
+  revision 2018-10-19 {
+    description
+      "Version 2.2.1";
+  }
+  revision 2017-12-15 {
+    description
+      "Version 2.2";
+  }
+  revision 2017-09-29 {
+    description
+      "Version 2.1";
+  }
+  revision 2017-07-28 {
+    description
+      "Version 2.0.1 - added revision-date to imports";
+  }
+  revision 2017-06-26 {
+    description
+      "Version 2.0";
+  }
+  revision 2016-10-14 {
+    description
+      "Version 1.2";
+  }
+
+  grouping ots-attributes {
+    description
+      "Optical Transport Section (OTS) attributes";
+    leaf fiber-type {
+      type enumeration {
+        enum "smf" {
+          value 0;
+          description
+            "Single Mode Fiber";
+        }
+        enum "eleaf" {
+          value 1;
+          description
+            "ELEAF";
+        }
+        enum "oleaf" {
+          value 2;
+          description
+            "OLEAF";
+        }
+        enum "dsf" {
+          value 3;
+          description
+            "DSF";
+        }
+        enum "truewave" {
+          value 4;
+          description
+            "TRUEWAVE Reduced Slope";
+        }
+        enum "truewavec" {
+          value 5;
+          description
+            "TRUEWAVE Classic";
+        }
+        enum "nz-dsf" {
+          value 6;
+          description
+            "NZ-DSF";
+        }
+        enum "ull" {
+          value 7;
+          description
+            "Ultra Low Loss (ULL)";
+        }
+      }
+      default "smf";
+      description
+        "fiber type
+         Default    : SMF ";
+    }
+    leaf span-loss-receive {
+      type org-openroadm-common-types:ratio-dB;
+      description
+        "Span loss on the receiver side. Set by the controller and used by device to set AMP gain.";
+    }
+    leaf span-loss-transmit {
+      type org-openroadm-common-types:ratio-dB;
+      description
+        "Span loss on the transmitter side. Set by the controller and used by device to configure MSA compliant channel launch power";
+    }
+    leaf ingress-span-loss-aging-margin {
+      type org-openroadm-common-types:ratio-dB;
+      default "0";
+      config true;
+      description
+        "Span-loss margin used to set optical amplifier gain and output-voa.
+         Day one attenuation of the link, at initial commissioning may increase across wdm link life.
+         span-loss-aging-margin defines the maximum additional loss the wdm link may experience in addition
+         to initial loss without requiring a new design (new amplifier settings). ";
+    }
+    leaf eol-max-load-pIn {
+      type org-openroadm-common-types:power-dBm;
+      config true;
+      description
+        "End Of Life Total input power at maximum load used for amplifier control.
+         Calculated during the design, this value shall be used by the amplifier device
+         for the setting so that the reasonable margin is kept to reach this value
+         at the end of life of the wdm link, considering span-loss aging margins are reached ";
+    }
+  }
+
+  grouping ots-container {
+    container ots {
+      description
+        "Optical Transport Section (OTS):
+          Models the optical interfaces for an Optical White Box.
+          The network side is represented by the OTS/OMS.";
+      uses ots-attributes;
+    }
+  }
+
+  augment "/org-openroadm-device:org-openroadm-device/org-openroadm-device:interface" {
+    when "org-openroadm-device:type = 'openROADM-if:opticalTransport'";
+    uses ots-container;
+  }
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-otn-common@2017-06-26.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-otn-common@2017-06-26.yang
new file mode 100644 (file)
index 0000000..3270a5e
--- /dev/null
@@ -0,0 +1,160 @@
+module org-openroadm-otn-common {
+  namespace "http://org/openroadm/otn-common";
+  prefix org-openroadm-otn-common;
+
+  organization
+    "Open ROADM MSA";
+  contact
+    "OpenROADM.org";
+  description
+    "YANG definitions for common OTN interface atrtributes and types. 
+         
+     Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, 
+     AT&T Intellectual Property.  All other rights reserved.
+     
+     Redistribution and use in source and binary forms, with or without modification, 
+     are permitted provided that the following conditions are met:
+     
+     * Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+     * Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation and/or 
+       other materials provided with the distribution.
+     * Neither the Members of the Open ROADM MSA Agreement nor the names of its 
+       contributors may be used to endorse or promote products derived from this software 
+       without specific prior written permission.
+     
+     THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT ''AS IS'' 
+     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+     IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT BE LIABLE FOR ANY DIRECT, 
+     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE, DATA, 
+     OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+     WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+     POSSIBILITY OF SUCH DAMAGE.
+     
+     Also contains code components extracted from IETF Interfaces.  These code components 
+     are copyrighted and licensed as follows:
+     
+     Copyright (c) 2016 IETF Trust and the persons identified as the document authors. 
+     All rights reserved. 
+     
+     This document is subject to BCP 78 and the IETF Trust’s Legal Provisions Relating 
+     to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of 
+     publication of this document. Please review these documents carefully, as they 
+     describe your rights and restrictions with respect to this document. Code Components 
+     extracted from this document must include Simplified BSD License text as described in
+     Section 4.e of the Trust Legal Provisions and are provided without warranty as 
+     described in the Simplified BSD License.";
+
+  revision 2017-06-26 {
+    description
+      "Version 2.0";
+  }
+
+  grouping trail-trace {
+    leaf tx-sapi {
+      type string {
+        length "0 .. 15";
+      }
+      description
+        "The provisioned 15 character transmit trace SAPI. Implementations shall add the [0] field automatically per ITU-T G.709";
+    }
+    leaf tx-dapi {
+      type string {
+        length "0 .. 15";
+      }
+      description
+        "The provisioned 15 character transmit trace DAPI. Implementations shall add the [0] field automatically per ITU-T G.709";
+    }
+    leaf tx-operator {
+      type string {
+        length "0 .. 32";
+      }
+      description
+        "The provisioned 32 character Operator Specific field";
+    }
+    leaf accepted-sapi {
+      type string;
+      config false;
+      description
+        "The accepted SAPI recovered from the recieved multi-frame TTI field.
+         Received SAPI contains the receive data, minus the sapi[0] and any 0x00 padding at the end";
+    }
+    leaf accepted-dapi {
+      type string;
+      config false;
+      description
+        "The accepted DAPI recovered from the recieved multi-frame TTI field
+         Received DAPI contains the receive data, minus the dapi[0] and any 0x00 padding at the end";
+    }
+    leaf accepted-operator {
+      type string;
+      config false;
+      description
+        "The accepted Operator Specific field recovered from the recieved multi-frame TTI field";
+    }
+    leaf expected-sapi {
+      type string {
+        length "0 .. 15";
+      }
+      description
+        "The provisioned expected SAPI, to be compared with accepted TTI";
+    }
+    leaf expected-dapi {
+      type string {
+        length "0 .. 15";
+      }
+      description
+        "The provisioned expected DAPI, to be compared with accepted TTI";
+    }
+    leaf tim-act-enabled {
+      type boolean;
+      default "false";
+      description
+        "Enables TTI Mismatch consequent actions.";
+    }
+    leaf tim-detect-mode {
+      type enumeration {
+        enum "Disabled" {
+          description
+            "TTI is ignored";
+        }
+        enum "SAPI" {
+          description
+            "Expected SAPI is compared to the Accpeted TTI. Other TTI fields are ignored";
+        }
+        enum "DAPI" {
+          description
+            "Expected DAPI is compared to the Accpeted TTI. Other TTI fields are ignored";
+        }
+        enum "SAPI-and-DAPI" {
+          description
+            "Expected SAPI and Expected DAPI are compared to the Accpeted TTI. Operator specific TTI field is ignored";
+        }
+      }
+      default "Disabled";
+    }
+  }
+
+  grouping deg-threshold {
+    leaf degm-intervals {
+      type uint8 {
+        range "2 .. 10";
+      }
+      default "2";
+      description
+        "G.806 - Consecutive bad intervals required for declare dDEG";
+    }
+    leaf degthr-percentage {
+      type uint16 {
+        range "1 .. 10000";
+      }
+      default "100";
+      description
+        "Percentage of errored blocks required to declare an interval bad, in units of 0.01%";
+    }
+  }
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-otn-odu-interfaces@2018-10-19.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-otn-odu-interfaces@2018-10-19.yang
new file mode 100755 (executable)
index 0000000..a57e34f
--- /dev/null
@@ -0,0 +1,344 @@
+module org-openroadm-otn-odu-interfaces {
+  namespace "http://org/openroadm/otn-odu-interfaces";
+  prefix org-openroadm-otn-odu-interfaces;
+
+  import org-openroadm-device {
+    prefix org-openroadm-device;
+    revision-date 2018-10-19;
+  }
+  import org-openroadm-interfaces {
+    prefix openROADM-if;
+    revision-date 2017-06-26;
+  }
+  import org-openroadm-maintenance-testsignal {
+    prefix org-openroadm-maint-testsignal;
+    revision-date 2017-12-15;
+  }
+  import org-openroadm-otn-common {
+    prefix org-openroadm-otn-common;
+    revision-date 2017-06-26;
+  }
+  import org-openroadm-otn-common-types {
+    prefix org-openroadm-otn-common-types;
+    revision-date 2017-12-15;
+  }
+
+  organization
+    "Open ROADM MSA";
+  contact
+    "OpenROADM.org";
+  description
+    "YANG definitions for device facility otnodu interfaces.
+     
+     Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, 
+     AT&T Intellectual Property.  All other rights reserved.
+     
+     Redistribution and use in source and binary forms, with or without modification, 
+     are permitted provided that the following conditions are met:
+     
+     * Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+     * Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation and/or 
+       other materials provided with the distribution.
+     * Neither the Members of the Open ROADM MSA Agreement nor the names of its 
+       contributors may be used to endorse or promote products derived from this software 
+       without specific prior written permission.
+     
+     THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT ''AS IS'' 
+     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+     IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT BE LIABLE FOR ANY DIRECT, 
+     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE, DATA, 
+     OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+     WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+     POSSIBILITY OF SUCH DAMAGE.
+     
+     Also contains code components extracted from IETF Interfaces.  These code components
+     are copyrighted and licensed as follows:
+     
+     Copyright (c) 2016 IETF Trust and the persons identified as the document authors.
+     All rights reserved.
+     
+     This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating
+     to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of
+     publication of this document. Please review these documents carefully, as they
+     describe your rights and restrictions with respect to this document. Code Components
+     extracted from this document must include Simplified BSD License text as described in
+     Section 4.e of the Trust Legal Provisions and are provided without warranty as
+     described in the Simplified BSD License.";
+
+  revision 2018-10-19 {
+    description
+      "Version 2.2.1";
+  }
+  revision 2017-12-15 {
+    description
+      "Version 2.2";
+  }
+  revision 2017-09-29 {
+    description
+      "Version 2.1";
+  }
+  revision 2017-07-28 {
+    description
+      "Version 2.0.1 - added revision-date to imports";
+  }
+  revision 2017-06-26 {
+    description
+      "Version 2.0";
+  }
+  revision 2016-10-14 {
+    description
+      "Version 1.2";
+  }
+
+  grouping msi-entry {
+    leaf trib-slot {
+      type uint16;
+      description
+        "tributary slot (TS)";
+    }
+    leaf odtu-type {
+      type identityref {
+        base org-openroadm-otn-common-types:odtu-type-identity;
+      }
+      description
+        "ODTU type, part of the MSI (Multiplex Structure Identifier)";
+    }
+    leaf trib-port {
+      type uint16;
+      description
+        "Tributary Port Number (0-based), part of the MSI";
+    }
+    leaf trib-port-payload {
+      type string;
+      description
+        "interface name being mapped to trib-port";
+    }
+  }
+
+  grouping odu-attributes {
+    description
+      "ODU attributes";
+    leaf rate {
+      type identityref {
+        base org-openroadm-otn-common-types:odu-rate-identity;
+      }
+      description
+        "rate identity of the ODU. 'identityref' is used
+         to allow to extend for future higher rates";
+    }
+    leaf odu-function {
+      type identityref {
+        base org-openroadm-otn-common-types:odu-function-identity;
+      }
+      description
+        "function of the ODU interface";
+    }
+    leaf monitoring-mode {
+      type enumeration {
+        enum "not-terminated" {
+          description
+            "Not Terminated: no detection or generation.
+             Overhead is passed through the interface transparently in receive direction";
+        }
+        enum "terminated" {
+          description
+            "Terminated: detection and generation enabled.
+             Overhead is erased (replaced with all zeros) in receive direction";
+        }
+        enum "monitored" {
+          description
+            "Monitored: detection enabled.
+             Overhead is passed through the interface transparently in receive direction";
+        }
+      }
+      description
+        "Monitoring mode of the ODU Overhead";
+    }
+    leaf no-oam-function {
+      type empty;
+      description
+        "No OAM functionality exists for this ODU interface, the entity exists in software only. This entity does not report alarms or PM and does not support TCM, TTI, delay measurement, loopbacks, test signal and other hardware-based functions. This is an optional parameter, only needs to be present when no-oam-function supported for this interface.";
+    }
+    leaf proactive-delay-measurement-enabled {
+      type boolean;
+      description
+        "enable/disable proactive Delay Measurement";
+    }
+    uses parent-odu-allocation;
+    uses org-openroadm-otn-common:trail-trace;
+    uses org-openroadm-otn-common:deg-threshold;
+    list tcm {
+      key "layer tcm-direction";
+      max-elements "6";
+      description
+        "Tandem Connection Management";
+      uses tcm-attributes;
+    }
+    uses opu;
+  }
+
+  grouping parent-odu-allocation {
+    container parent-odu-allocation {
+      when "/org-openroadm-device:org-openroadm-device/org-openroadm-device:interface[org-openroadm-device:name = current()/../../org-openroadm-device:supporting-interface]/org-openroadm-device:type = 'openROADM-if:otnOdu'";
+      presence "Explicit assignment of parent ODU trib-slot and trib-port allocation. ";
+      leaf trib-port-number {
+        type uint16 {
+          range "1 .. 80";
+        }
+        mandatory true;
+        description
+          "Assigned tributary port number in parent OPU";
+      }
+      leaf-list trib-slots {
+        type uint16 {
+          range "1 .. 80";
+        }
+        min-elements 1;
+        max-elements "80";
+        description
+          "Assigned trib slots occupied in parent OPU MSI";
+      }
+    }
+  }
+
+  grouping opu {
+    container opu {
+      when "../monitoring-mode = 'terminated' or ../monitoring-mode = 'monitored'";
+      description
+        "Optical Channel Payload Unit (OPU)";
+      leaf payload-type {
+        type org-openroadm-otn-common-types:payload-type-def;
+        description
+          "Payload Type";
+      }
+      leaf rx-payload-type {
+        type org-openroadm-otn-common-types:payload-type-def;
+        description
+          "Received Payload Type";
+      }
+      leaf exp-payload-type {
+        type org-openroadm-otn-common-types:payload-type-def;
+        description
+          "Expected Payload Type";
+      }
+      leaf payload-interface {
+        type string;
+        description
+          "Expected Payload of OPU. It designates client interface name";
+      }
+      container msi {
+        when "../payload-type = '20' or ../payload-type = '21'";
+        list tx-msi {
+          key "trib-slot";
+          description
+            "Transmit MSI";
+          uses msi-entry;
+        }
+        list rx-msi {
+          key "trib-slot";
+          description
+            "Receive MSI";
+          uses msi-entry;
+        }
+        list exp-msi {
+          key "trib-slot";
+          description
+            "Expected MSI";
+          uses msi-entry;
+        }
+      }
+    }
+  }
+
+  grouping tcm-attributes {
+    description
+      "Tandem Connection Monitoring (TCM) attributes";
+    leaf layer {
+      type uint8 {
+        range "1..6";
+      }
+      description
+        "TCM layer";
+    }
+    leaf monitoring-mode {
+      type enumeration {
+        enum "not-terminated" {
+          description
+            "Not Terminated: no detection or generation.
+             Overhead is passed through the interface transparently in receive direction 
+             unless extension is set for erase";
+        }
+        enum "terminated" {
+          description
+            "Terminated: detection and generation enabled.
+             Overhead is erased (replaced with all zeros) in receive direction, unless
+             extension is set to passthrough";
+        }
+        enum "monitored" {
+          description
+            "Monitored: detection enabled.
+             Overhead is passed through the interface transparently in receive direction 
+             unless extension is set for erase";
+        }
+      }
+      description
+        "Monitoring mode of the TCM layer";
+    }
+    leaf ltc-act-enabled {
+      type boolean;
+      description
+        "enable/disable alarm transfer on detection of Loss of Tandem Connection (LTC)";
+    }
+    leaf proactive-delay-measurement-enabled {
+      type boolean;
+      description
+        "enable/disable proactive Delay Measurement for TCM";
+    }
+    leaf tcm-direction {
+      type enumeration {
+        enum "up-tcm" {
+          description
+            "TCM termination direction faces the switch fabric.";
+        }
+        enum "down-tcm" {
+          description
+            "TCM termination direction faces the facility";
+        }
+      }
+      description
+        "Direction of TCM.";
+    }
+    uses org-openroadm-otn-common:trail-trace;
+    uses org-openroadm-otn-common:deg-threshold;
+  }
+
+  grouping odu-container {
+    container odu {
+      presence "Attribute Nodes for Optical Data Unit (ODU)";
+      description
+        "Optical Channel Data Unit (ODU)";
+      uses odu-attributes {
+        refine "opu/rx-payload-type" {
+          config false;
+        }
+        refine "opu/msi" {
+          config false;
+        }
+        refine "no-oam-function" {
+          config false;
+        }
+      }
+      uses org-openroadm-maint-testsignal:maint-testsignal;
+    }
+  }
+
+  augment "/org-openroadm-device:org-openroadm-device/org-openroadm-device:interface" {
+    when "org-openroadm-device:type = 'openROADM-if:otnOdu'";
+    uses odu-container;
+  }
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-otn-otu-interfaces@2018-10-19.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-otn-otu-interfaces@2018-10-19.yang
new file mode 100755 (executable)
index 0000000..76f0833
--- /dev/null
@@ -0,0 +1,172 @@
+module org-openroadm-otn-otu-interfaces {
+  namespace "http://org/openroadm/otn-otu-interfaces";
+  prefix org-openroadm-otn-otu-interfaces;
+
+  import org-openroadm-device {
+    prefix org-openroadm-device;
+    revision-date 2018-10-19;
+  }
+  import org-openroadm-interfaces {
+    prefix openROADM-if;
+    revision-date 2017-06-26;
+  }
+  import org-openroadm-maintenance-loopback {
+    prefix org-openroadm-maint-loopback;
+    revision-date 2017-12-15;
+  }
+  import org-openroadm-otn-common {
+    prefix org-openroadm-otn-common;
+    revision-date 2017-06-26;
+  }
+  import org-openroadm-otn-common-types {
+    prefix org-openroadm-otn-common-types;
+    revision-date 2017-12-15;
+  }
+
+  organization
+    "Open ROADM MSA";
+  contact
+    "OpenROADM.org";
+  description
+    "YANG definitions for device facility otnotu interfaces.
+     
+     Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, 
+     AT&T Intellectual Property.  All other rights reserved.
+     
+     Redistribution and use in source and binary forms, with or without modification, 
+     are permitted provided that the following conditions are met:
+     
+     * Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+     * Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation and/or 
+       other materials provided with the distribution.
+     * Neither the Members of the Open ROADM MSA Agreement nor the names of its 
+       contributors may be used to endorse or promote products derived from this software 
+       without specific prior written permission.
+     
+     THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT ''AS IS'' 
+     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+     IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT BE LIABLE FOR ANY DIRECT, 
+     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE, DATA, 
+     OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+     WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+     POSSIBILITY OF SUCH DAMAGE.
+     
+     Also contains code components extracted from IETF Interfaces.  These code components
+     are copyrighted and licensed as follows:
+     
+     Copyright (c) 2016 IETF Trust and the persons identified as the document authors.
+     All rights reserved.
+     
+     This document is subject to BCP 78 and the IETF Trust’s Legal Provisions Relating
+     to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of
+     publication of this document. Please review these documents carefully, as they
+     describe your rights and restrictions with respect to this document. Code Components
+     extracted from this document must include Simplified BSD License text as described in
+     Section 4.e of the Trust Legal Provisions and are provided without warranty as
+     described in the Simplified BSD License.";
+
+  revision 2018-10-19 {
+    description
+      "Version 2.2.1";
+  }
+  revision 2017-12-15 {
+    description
+      "Version 2.2";
+  }
+  revision 2017-09-29 {
+    description
+      "Version 2.1";
+  }
+  revision 2017-07-28 {
+    description
+      "Version 2.0.1 - added revision-date to imports";
+  }
+  revision 2017-06-26 {
+    description
+      "Version 2.0";
+  }
+  revision 2016-10-14 {
+    description
+      "Version 1.2";
+  }
+
+  grouping otu-attributes {
+    description
+      "OTU attributes";
+    leaf rate {
+      type identityref {
+        base org-openroadm-otn-common-types:otu-rate-identity;
+      }
+      description
+        "rate identity of the OTU. 'identityref' is used
+         to allow to extend for future higher rates";
+    }
+    leaf fec {
+      type enumeration {
+        enum "off" {
+          value 0;
+          description
+            "fec off";
+        }
+        enum "rsfec" {
+          value 1;
+          description
+            "rsfec";
+        }
+        enum "sdfeca1" {
+          value 2;
+          description
+            "Clariphy SDFEC";
+        }
+        enum "efec" {
+          value 3;
+          description
+            "G.975.1 I.4";
+        }
+        enum "ufec" {
+          value 4;
+          description
+            "G.975.1 I.7";
+        }
+        enum "sdfec" {
+          value 5;
+          description
+            "Soft decision FEC";
+        }
+        enum "sdfecb1" {
+          value 6;
+          description
+            "SDFEC with SCFEC";
+        }
+        enum "scfec" {
+          value 7;
+          description
+            "Stair case FEC";
+        }
+      }
+      description
+        "Forward Error Correction";
+    }
+    uses org-openroadm-otn-common:trail-trace;
+    uses org-openroadm-otn-common:deg-threshold;
+  }
+
+  grouping otu-container {
+    container otu {
+      description
+        "Optical Channel Transport Unit (OTU)";
+      uses otu-attributes;
+      uses org-openroadm-maint-loopback:maint-loopback;
+    }
+  }
+
+  augment "/org-openroadm-device:org-openroadm-device/org-openroadm-device:interface" {
+    when "org-openroadm-device:type = 'openROADM-if:otnOtu'";
+    uses otu-container;
+  }
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-physical-types@2018-10-19.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-physical-types@2018-10-19.yang
new file mode 100755 (executable)
index 0000000..1bf1903
--- /dev/null
@@ -0,0 +1,140 @@
+module org-openroadm-physical-types {
+  namespace "http://org/openroadm/physical/types";
+  prefix org-openroadm-physical-types;
+
+  import org-openroadm-common-types {
+    prefix org-openroadm-common-types;
+    revision-date 2018-10-19;
+  }
+  import ietf-yang-types {
+    prefix yang;
+    revision-date 2013-07-15;
+  }
+
+  organization
+    "Open ROADM MSA";
+  contact
+    "OpenROADM.org";
+  description
+    "YANG definitions of physical types.
+     
+     Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, 
+     AT&T Intellectual Property.  All other rights reserved.
+     
+     Redistribution and use in source and binary forms, with or without modification, 
+     are permitted provided that the following conditions are met:
+     
+     * Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+     * Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation and/or 
+       other materials provided with the distribution.
+     * Neither the Members of the Open ROADM MSA Agreement nor the names of its 
+       contributors may be used to endorse or promote products derived from this software 
+       without specific prior written permission.
+     
+     THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT ''AS IS'' 
+     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+     IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT BE LIABLE FOR ANY DIRECT, 
+     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE, DATA, 
+     OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+     WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+     POSSIBILITY OF SUCH DAMAGE.";
+
+  revision 2018-10-19 {
+    description
+      "Version 2.2.1";
+  }
+  revision 2017-12-15 {
+    description
+      "Version 2.2";
+  }
+  revision 2017-09-29 {
+    description
+      "Version 2.1";
+  }
+  revision 2017-07-28 {
+    description
+      "Version 2.0.1 - added revision-date to imports";
+  }
+  revision 2017-06-26 {
+    description
+      "Version 2.0";
+  }
+  revision 2016-10-14 {
+    description
+      "Version 1.2";
+  }
+
+  grouping node-info {
+    description
+      "Physical inventory data used by the node";
+    leaf vendor {
+      type string;
+      config false;
+      mandatory true;
+      description
+        "Vendor of the equipment";
+    }
+    leaf model {
+      type string;
+      config false;
+      mandatory true;
+      description
+        "Physical resource model information.";
+    }
+    leaf serial-id {
+      type string;
+      config false;
+      mandatory true;
+      description
+        "Product Code for this physical resource";
+    }
+  }
+
+  grouping common-info {
+    description
+      "Physical inventory data used by all other entities";
+    uses node-info;
+    leaf type {
+      type string;
+      config false;
+      description
+        "The specific type of this physical resource - ie the type of
+         shelf, type of circuit-pack, etc.";
+    }
+    leaf product-code {
+      type string;
+      config false;
+      description
+        "Product Code for this physical resource";
+    }
+    leaf manufacture-date {
+      type yang:date-and-time;
+      config false;
+      description
+        "Manufacture date of physical resource";
+    }
+    leaf clei {
+      type string;
+      config false;
+      description
+        "CLEI for this physical resource";
+    }
+    leaf hardware-version {
+      type string;
+      config false;
+      description
+        "The version of the hardware.";
+    }
+    leaf operational-state {
+      type org-openroadm-common-types:state;
+      config false;
+      description
+        "Operational state of the physical resource";
+    }
+  }
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-swdl@2018-10-19.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-swdl@2018-10-19.yang
new file mode 100755 (executable)
index 0000000..39a649a
--- /dev/null
@@ -0,0 +1,155 @@
+module org-openroadm-swdl {
+  namespace "http://org/openroadm/de/swdl";
+  prefix org-openroadm-swdl;
+
+  import ietf-yang-types {
+    prefix yang;
+    revision-date 2013-07-15;
+  }
+  import org-openroadm-common-types {
+    prefix org-openroadm-common-types;
+    revision-date 2018-10-19;
+  }
+
+  organization
+    "Open ROADM MSA";
+  contact
+    "OpenROADM.org";
+  description
+    "Yang definitions for System Management.
+     
+     Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, 
+     AT&T Intellectual Property.  All other rights reserved.
+     
+     Redistribution and use in source and binary forms, with or without modification, 
+     are permitted provided that the following conditions are met:
+     
+     * Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+     * Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation and/or 
+       other materials provided with the distribution.
+     * Neither the Members of the Open ROADM MSA Agreement nor the names of its 
+       contributors may be used to endorse or promote products derived from this software 
+       without specific prior written permission.
+     
+     THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT ''AS IS'' 
+     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+     IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT BE LIABLE FOR ANY DIRECT, 
+     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE, DATA, 
+     OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+     WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+     POSSIBILITY OF SUCH DAMAGE.";
+
+  revision 2018-10-19 {
+    description
+      "Version 2.2.1";
+  }
+  revision 2017-12-15 {
+    description
+      "Version 2.2";
+  }
+  revision 2017-09-29 {
+    description
+      "Version 2.1";
+  }
+  revision 2017-07-28 {
+    description
+      "Version 2.0.1 - added revision-date to imports";
+  }
+  revision 2017-06-26 {
+    description
+      "Version 2.0";
+  }
+  revision 2016-10-14 {
+    description
+      "Version 1.2";
+  }
+
+  grouping sw-bank {
+    leaf sw-version {
+      type string;
+      description
+        "Gissue of the SW in this bank";
+    }
+    leaf sw-validation-timer {
+      type string {
+        pattern "(([0-1][0-9]|2[0-3])-([0-5][0-9])-([0-5][0-9]))";
+      }
+      description
+        "value of validation timer in hh-mm-ss";
+    }
+    leaf activation-date-time {
+      type yang:date-and-time;
+      description
+        "activation date and time: The date load was activated";
+    }
+  }
+
+  rpc sw-stage {
+    description
+      "SW stage - copies the SW from repo to staging bank";
+    input {
+      leaf filename {
+        type string {
+          length "10..255";
+        }
+        description
+          "file name which has the load";
+      }
+    }
+    output {
+      uses org-openroadm-common-types:rpc-response-status;
+    }
+  }
+  rpc sw-activate {
+    description
+      "Activate new load";
+    input {
+      leaf version {
+        type string;
+        description
+          " software version of the new load which is being activated";
+      }
+      leaf validationTimer {
+        type string;
+        description
+          "validation timer hh-mm-ss";
+      }
+    }
+    output {
+      uses org-openroadm-common-types:rpc-response-status;
+    }
+  }
+  rpc cancel-validation-timer {
+    description
+      "Cancel validation timer which user provisioned as part of activate command";
+    input {
+      leaf accept {
+        type boolean;
+        default "true";
+        description
+          " TRUE means  validation timer is cancelled and new load is accepted";
+      }
+    }
+    output {
+      uses org-openroadm-common-types:rpc-response-status;
+    }
+  }
+  notification sw-stage-notification {
+    description
+      "notification for sw-stage.";
+    uses org-openroadm-common-types:rpc-response-status;
+  }
+  notification sw-activate-notification {
+    description
+      "notification for sw-activate events.";
+    leaf sw-active-notification-type {
+      type org-openroadm-common-types:activate-notification-type;
+    }
+    uses org-openroadm-common-types:rpc-response-status;
+  }
+}
diff --git a/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-syslog@2017-12-15.yang b/tests/honeynode221/honeynode-plugin-api/src/main/yang/device221/org-openroadm-syslog@2017-12-15.yang
new file mode 100644 (file)
index 0000000..54af614
--- /dev/null
@@ -0,0 +1,353 @@
+module org-openroadm-syslog {
+  namespace "http://org/openroadm/syslog";
+  prefix org-openroadm-syslog;
+
+  import ietf-inet-types {
+    prefix inet;
+    revision-date 2013-07-15;
+  }
+
+  organization
+    "Open ROADM MSA";
+  contact
+    "OpenROADM.org";
+  description
+    "This module contains a collection of YANG definitions 
+     for Syslog configuration.                                               
+     
+     Copyright of the Members of the Open ROADM MSA Agreement dated (c) 2016, 
+     AT&T Intellectual Property.  All other rights reserved.
+     
+     Redistribution and use in source and binary forms, with or without modification, 
+     are permitted provided that the following conditions are met:
+     
+     * Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+     * Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation and/or 
+       other materials provided with the distribution.
+     * Neither the Members of the Open ROADM MSA Agreement nor the names of its 
+       contributors may be used to endorse or promote products derived from this software 
+       without specific prior written permission.
+     
+     THIS SOFTWARE IS PROVIDED BY THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT ''AS IS'' 
+     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+     IN NO EVENT THE MEMBERS OF THE OPEN ROADM MSA  AGREEMENT BE LIABLE FOR ANY DIRECT, 
+     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE, DATA, 
+     OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+     WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+     POSSIBILITY OF SUCH DAMAGE.
+     
+     Also contains code components extracted from IETF Interfaces.  These code components
+     are copyrighted and licensed as follows:
+     
+     Copyright (c) 2016 IETF Trust and the persons identified as the document authors.
+     All rights reserved.
+     
+     This document is subject to BCP 78 and the IETF Trust’s Legal Provisions Relating
+     to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of
+     publication of this document. Please review these documents carefully, as they
+     describe your rights and restrictions with respect to this document. Code Components
+     extracted from this document must include Simplified BSD License text as described in
+     Section 4.e of the Trust Legal Provisions and are provided without warranty as
+     described in the Simplified BSD License.";
+  reference "RFC 5424: The Syslog Protocol";
+
+  revision 2017-12-15 {
+    description
+      "Version 2.2";
+  }
+  revision 2017-09-29 {
+    description
+      "Version 2.1";
+  }
+  revision 2017-07-28 {
+    description
+      "Version 2.0.1 - added revision-date to imports";
+  }
+  revision 2016-10-14 {
+    description
+      "Version 1.2";
+  }
+
+  feature selector-sevop-config {
+    description
+      "This feature represents the ability to select messages 
+       using the additional operators equal to, or not equal to 
+       when comparing the Syslog message severity.";
+  }
+
+  feature selector-match-config {
+    description
+      "This feature represents the ability to select messages based
+       on a Posix 1003.2 regular expression pattern match.";
+  }
+
+  identity syslog-facility {
+    description
+      "The base identity to represent syslog facilities";
+  }
+
+  typedef severity {
+    type enumeration {
+      enum "emergency" {
+        value 0;
+        description
+          "Emergency Level Msg";
+      }
+      enum "alert" {
+        value 1;
+        description
+          "Alert Level Msg";
+      }
+      enum "critical" {
+        value 2;
+        description
+          "Critical Level Msg";
+      }
+      enum "error" {
+        value 3;
+        description
+          "Error Level Msg";
+      }
+      enum "warning" {
+        value 4;
+        description
+          "Warning Level Msg";
+      }
+      enum "notice" {
+        value 5;
+        description
+          "Notification Level Msg";
+      }
+      enum "info" {
+        value 6;
+        description
+          "Informational Level Msg";
+      }
+      enum "debug" {
+        value 7;
+        description
+          "Debugging Level Msg";
+      }
+      enum "all" {
+        value 8;
+        description
+          "This enum describes the case where all severities 
+           are selected.";
+      }
+      enum "none" {
+        value 9;
+        description
+          "This enum describes the case where no severities 
+           are selected.";
+      }
+    }
+    description
+      "The definitions for Syslog message severity as per RFC 5424.
+       Extended the RFC definition with enums for all and none";
+  }
+
+  grouping syslog-severity {
+    description
+      "This grouping defines the Syslog severity which is used to 
+       select log messages.";
+    leaf severity {
+      type severity;
+      mandatory true;
+      description
+        "This leaf specifies the Syslog message severity. When 
+         severity is specified, the default severity comparison 
+         is all messages of the specified severity and greater are 
+         selected. 'all' is a special case which means all severities
+         are selected. 'none' is a special case which means that
+         no selection should occur or disable this filter.";
+    }
+    leaf severity-operator {
+      when
+        "../severity != 'all' and
+                    ../severity != 'none'" {
+        description
+          "The severity-operator is not applicable for severity 'all' or 
+           severity 'none'";
+      }
+      if-feature "selector-sevop-config";
+      type enumeration {
+        enum "equals-or-higher" {
+          description
+            "This enum specifies all messages of the specified 
+             severity and higher are logged according to the 
+             given log-action";
+        }
+        enum "equals" {
+          description
+            "This enum specifies all messages that are for 
+             the specified severity are logged according to the 
+             given log-action";
+        }
+        enum "not-equals" {
+          description
+            "This enum specifies all messages that are not for 
+             the specified severity are logged according to the 
+             given log-action";
+        }
+      }
+      default "equals-or-higher";
+      description
+        "This leaf describes the option to specify how the 
+         severity comparison is performed.";
+    }
+  }
+
+  grouping syslog-selector {
+    description
+      "This grouping defines a Syslog selector which is used to 
+       select log messages for the log-action (buffer, file, 
+       etc). Choose one of the following:
+         no-log-facility
+         log-facility [<facility> <severity>...]";
+    container log-selector {
+      description
+        "This container describes the log selector parameters 
+         for Syslog.";
+      choice selector-facility {
+        mandatory true;
+        description
+          "This choice describes the option to specify no 
+           facilities, or a specific facility which can be
+           all for all facilities.";
+        case no-log-facility {
+          description
+            "This case specifies no facilities will match when 
+             comparing the Syslog message facility. This is a 
+             method that can be used to effectively disable a 
+             particular log-action (buffer, file, etc).";
+          leaf no-facilities {
+            type empty;
+            description
+              "This leaf specifies that no facilities are selected 
+               for this log-action.";
+          }
+        }
+        case log-facility {
+          description
+            "This case specifies one or more specified facilities 
+             will match when comparing the Syslog message facility.";
+          list log-facility {
+            key "facility";
+            description
+              "This list describes a collection of Syslog 
+               facilities and severities.";
+            leaf facility {
+              type union {
+                type identityref {
+                  base syslog-facility;
+                }
+                type enumeration {
+                  enum "all" {
+                    description
+                      "This enum describes the case where all 
+                       facilities are requested.";
+                  }
+                }
+              }
+              description
+                "The leaf uniquely identifies a Syslog facility.";
+            }
+            uses syslog-severity;
+          }
+        }
+      }
+    }
+  }
+
+  container syslog {
+    description
+      "This container describes the configuration parameters for 
+       Syslog.";
+    leaf local-syslog-filename {
+      type string;
+      config false;
+      mandatory true;
+      description
+        "The syslog file name. It should be a fully qualified name 
+         so that the user can get the file using transfer RPC.";
+    }
+    container log-actions {
+      description
+        "This container describes the log-action parameters 
+         for Syslog.";
+      container remote {
+        description
+          "This container describes the configuration parameters for 
+           remote logging.";
+        list destination {
+          key "name";
+          description
+            "This list describes a collection of remote logging 
+             destinations.";
+          leaf name {
+            type string;
+            description
+              "An arbitrary name for the endpoint to connect to.";
+          }
+          choice transport {
+            mandatory true;
+            description
+              "This choice describes the transport option.";
+            case tcp {
+              container tcp {
+                description
+                  "This container describes the TCP transport
+                   options.";
+                reference "RFC 6587: Transmission of Syslog Messages over TCP";
+                leaf address {
+                  type inet:host;
+                  description
+                    "The leaf uniquely specifies the address of 
+                     the remote host. One of the following must 
+                     be specified: an ipv4 address, an ipv6 
+                     address, or a host name.";
+                }
+                leaf port {
+                  type inet:port-number;
+                  default "514";
+                  description
+                    "This leaf specifies the port number used to 
+                     deliver messages to the remote server.";
+                }
+              }
+            }
+            case udp {
+              container udp {
+                description
+                  "This container describes the UDP transport
+                   options.";
+                reference "RFC 5426: Transmission of Syslog Messages over UDP";
+                leaf address {
+                  type inet:host;
+                  description
+                    "The leaf uniquely specifies the address of 
+                     the remote host. One of the following must be 
+                     specified: an ipv4 address, an ipv6 address, 
+                     or a host name.";
+                }
+                leaf port {
+                  type inet:port-number;
+                  default "514";
+                  description
+                    "This leaf specifies the port number used to 
+                     deliver messages to the remote server.";
+                }
+              }
+            }
+          }
+          uses syslog-selector;
+        }
+      }
+    }
+  }
+}
diff --git a/tests/honeynode221/honeynode-plugin-impl/asciidoc/Readme.adoc b/tests/honeynode221/honeynode-plugin-impl/asciidoc/Readme.adoc
new file mode 100644 (file)
index 0000000..5c2a93d
--- /dev/null
@@ -0,0 +1,3 @@
+= honeynode-plugin-impl
+
+Overview of honeynode-plugin-impl
\ No newline at end of file
diff --git a/tests/honeynode221/honeynode-plugin-impl/pom.xml b/tests/honeynode221/honeynode-plugin-impl/pom.xml
new file mode 100644 (file)
index 0000000..13f015a
--- /dev/null
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2015 Cisco and/or its affiliates.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at:
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+--><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">
+    <parent>
+        <groupId>io.fd.honeycomb.common</groupId>
+        <artifactId>impl-parent</artifactId>
+        <version>1.18.01</version>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>io.fd.honeycomb.transportpce</groupId>
+    <artifactId>honeynode-plugin-impl</artifactId>
+    <name>honeynode-plugin-impl</name>
+    <version>1.18.01</version>
+    <packaging>bundle</packaging>
+
+    <properties>
+        <honeycomb.infra.version>1.18.01</honeycomb.infra.version>
+    </properties>
+
+    <dependencies>
+        <!-- Transportpce -->
+       <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>honeynode-common</artifactId>
+            <version>${project.version}</version>
+       </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>honeynode-plugin-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>minimal-distribution-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <!-- Honeycomb infrastructure-->
+        <dependency>
+            <groupId>io.fd.honeycomb</groupId>
+            <artifactId>translate-api</artifactId>
+            <version>${honeycomb.infra.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>io.fd.honeycomb</groupId>
+            <artifactId>translate-spi</artifactId>
+            <version>${honeycomb.infra.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>io.fd.honeycomb</groupId>
+            <artifactId>cfg-init</artifactId>
+            <version>${honeycomb.infra.version}</version>
+        </dependency>
+
+        <!-- DI -->
+        <dependency>
+            <groupId>com.google.inject</groupId>
+            <artifactId>guice</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>net.jmob</groupId>
+            <artifactId>guice.conf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.inject.extensions</groupId>
+            <artifactId>guice-multibindings</artifactId>
+        </dependency>
+
+        <!-- Testing Dependencies -->
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/DeviceBindingDataBrokerProvider.java b/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/DeviceBindingDataBrokerProvider.java
new file mode 100644 (file)
index 0000000..f1452cd
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2018 Orange and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.transportpce.device;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+
+import io.fd.honeycomb.binding.init.ProviderTrait;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.impl.BindingDOMDataBrokerAdapter;
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+
+/**
+ * @author Martial COULIBALY ( mcoulibaly.ext@orange.com ) on behalf of Orange
+ */
+public final class DeviceBindingDataBrokerProvider  extends ProviderTrait<DataBroker> {
+
+    @Inject
+    @Named(DeviceModule.DEVICE_DATABROKER)
+    private DOMDataBroker domDataBroker;
+    @Inject
+    private BindingToNormalizedNodeCodec mappingService;
+
+    @Override
+    protected BindingDOMDataBrokerAdapter create() {
+        return new BindingDOMDataBrokerAdapter(domDataBroker, mappingService);
+    }
+}
diff --git a/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/DeviceModule.java b/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/DeviceModule.java
new file mode 100644 (file)
index 0000000..f781349
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.transportpce.device;
+
+import com.google.inject.PrivateModule;
+import com.google.inject.Singleton;
+import com.google.inject.name.Names;
+
+import io.fd.honeycomb.infra.distro.data.DataStoreProvider;
+import io.fd.honeycomb.infra.distro.data.InmemoryDOMDataBrokerProvider;
+import io.fd.honeycomb.transportpce.device.configuration.DeviceConfigurationModule;
+import io.fd.honeycomb.transportpce.device.configuration.NetconfConfigurationModule;
+import io.fd.honeycomb.transportpce.device.configuration.PmConfigurationModule;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Module class instantiating device-plugin plugin components.
+ */
+
+public final class DeviceModule extends PrivateModule {
+
+    private static final Logger LOG = LoggerFactory.getLogger(DeviceModule.class);
+    public static final String DEVICE_DATABROKER = "device-databroker";
+    public static final String DEVICE_DATABROKER_NONPERSIST = "device-databroker-nopersist";
+
+    @Override
+    protected void configure() {
+        LOG.info("Initializing Device Module");
+        // Create inmemory config data store for DEVICE
+        bind(InMemoryDOMDataStore.class).annotatedWith(Names.named(InmemoryDOMDataBrokerProvider.CONFIG))
+            .toProvider(new DataStoreProvider(InmemoryDOMDataBrokerProvider.CONFIG, LogicalDatastoreType.CONFIGURATION))
+            .in(Singleton.class);
+        // Create inmemory operational data store for DEVICE
+        bind(InMemoryDOMDataStore.class).annotatedWith(Names.named(InmemoryDOMDataBrokerProvider.OPERATIONAL))
+            .toProvider(new DataStoreProvider(InmemoryDOMDataBrokerProvider.OPERATIONAL, LogicalDatastoreType.OPERATIONAL))
+            .in(Singleton.class);
+
+        // Wrap datastores as DOMDataBroker
+        // TODO make executor service configurable
+        bind(DOMDataBroker.class).annotatedWith(Names.named(DEVICE_DATABROKER))
+            .toProvider(InmemoryDOMDataBrokerProvider.class).in(Singleton.class);
+        expose(DOMDataBroker.class).annotatedWith(Names.named(DEVICE_DATABROKER));
+
+        // Wrap DOMDataBroker as BA data broker
+        bind(DataBroker.class).annotatedWith(Names.named(DEVICE_DATABROKER)).toProvider(DeviceBindingDataBrokerProvider.class)
+            .in(Singleton.class);
+        expose(DataBroker.class).annotatedWith(Names.named(DEVICE_DATABROKER));
+
+        //install device configuration module
+        install(new DeviceConfigurationModule());
+
+        //install pm configuration module
+        install(new PmConfigurationModule());
+        LOG.info("Device Module intitailized !");
+
+      //install netconf configuration module
+        install(new NetconfConfigurationModule());
+        LOG.info("Netconf Module intitailized !");
+    }
+
+}
+
diff --git a/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/DeviceNotificationModule.java b/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/DeviceNotificationModule.java
new file mode 100644 (file)
index 0000000..56ec875
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2018 Orange and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.transportpce.device;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.multibindings.Multibinder;
+
+import io.fd.honeycomb.notification.ManagedNotificationProducer;
+import io.fd.honeycomb.transportpce.device.notifications.DeviceNotificationProducer;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Martial COULIBALY ( mcoulibaly.ext@orange.com ) on behalf of Orange
+ */
+public class DeviceNotificationModule extends AbstractModule {
+
+    private static final Logger LOG = LoggerFactory.getLogger(DeviceNotificationModule.class);
+
+    @Override
+    protected void configure() {
+        LOG.info("Initializing Device Notification Module");
+        final Multibinder<ManagedNotificationProducer> notifFactoryBinder = Multibinder.newSetBinder(binder(),
+                ManagedNotificationProducer.class);
+        notifFactoryBinder.addBinding().to(DeviceNotificationProducer.class);
+    }
+
+}
diff --git a/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/DeviceReaderModule.java b/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/DeviceReaderModule.java
new file mode 100644 (file)
index 0000000..b2b4525
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2018 Orange and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.transportpce.device;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.multibindings.Multibinder;
+
+import io.fd.honeycomb.translate.read.ReaderFactory;
+import io.fd.honeycomb.transportpce.device.read.DeviceReaderFactory;
+import io.fd.honeycomb.transportpce.device.read.PmReaderFactory;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Martial COULIBALY ( martial.coulibaly@gfi.com ) on behalf of Orange
+ */
+public class DeviceReaderModule extends AbstractModule {
+    private static final Logger LOG = LoggerFactory.getLogger(DeviceReaderModule.class);
+    /* (non-Javadoc)
+     * @see com.google.inject.AbstractModule#configure()
+     */
+    @Override
+    protected void configure() {
+        LOG.info("Initializing Device, PM and Netconf Readers Module");
+        final Multibinder<ReaderFactory> binder = Multibinder.newSetBinder(binder(), ReaderFactory.class);
+        binder.addBinding().to(DeviceReaderFactory.class);
+        binder.addBinding().to(PmReaderFactory.class);
+    }
+
+}
diff --git a/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/DeviceRpcModule.java b/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/DeviceRpcModule.java
new file mode 100644 (file)
index 0000000..2700cff
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2018 Orange and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.transportpce.device;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.multibindings.Multibinder;
+
+import io.fd.honeycomb.rpc.RpcService;
+import io.fd.honeycomb.transportpce.device.rpcs.ConnectionPortTrailService;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Martial COULIBALY ( mcoulibaly.ext@orange.com ) on behalf of Orange
+ */
+public class DeviceRpcModule extends AbstractModule {
+    private static final Logger LOG = LoggerFactory.getLogger(DeviceRpcModule.class);
+
+    /* (non-Javadoc)
+     * @see com.google.inject.AbstractModule#configure()
+     */
+    @Override
+    protected void configure() {
+        LOG.info("Initializing Device Rpcs Module");
+        // TODO Auto-generated method stub
+        final Multibinder<RpcService> rpcsBinder = Multibinder.newSetBinder(binder(), RpcService.class);
+        rpcsBinder.addBinding().to(ConnectionPortTrailService.class);
+    }
+
+}
\ No newline at end of file
diff --git a/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/DeviceWriterModule.java b/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/DeviceWriterModule.java
new file mode 100644 (file)
index 0000000..2fa266c
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2018 Orange and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.transportpce.device;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.multibindings.Multibinder;
+
+import io.fd.honeycomb.translate.write.WriterFactory;
+import io.fd.honeycomb.transportpce.device.write.DeviceWriterFactory;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Martial COULIBALY ( martial.coulibaly@gfi.com ) on behalf of Orange
+ */
+public class DeviceWriterModule extends AbstractModule {
+
+    private static final Logger LOG = LoggerFactory.getLogger(DeviceWriterModule.class);
+
+    @Override
+    protected void configure() {
+        LOG.info("Initializing Device Writers Module");
+        final Multibinder<WriterFactory> writerFactoryBinder = Multibinder.newSetBinder(binder(), WriterFactory.class);
+        writerFactoryBinder.addBinding().to(DeviceWriterFactory.class);
+    }
+}
diff --git a/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/configuration/DeviceConfiguration.java b/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/configuration/DeviceConfiguration.java
new file mode 100644 (file)
index 0000000..e1e6916
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.transportpce.device.configuration;
+
+import io.fd.honeycomb.transportpce.device.tools.DefaultDeviceFactory;
+import io.fd.honeycomb.transportpce.test.common.DataStoreContext;
+import io.fd.honeycomb.transportpce.test.common.DataStoreContextImpl;
+
+import java.io.File;
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.OrgOpenroadmDevice;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.jmob.guice.conf.core.BindConfig;
+import net.jmob.guice.conf.core.InjectConfig;
+import net.jmob.guice.conf.core.Syntax;
+
+/**
+ * Class containing static configuration for honeynode-plugin module<br>
+ * <p/>
+ * Further documentation for the configuration injection can be found at:
+ * https://github.com/yyvess/gconf
+ */
+@BindConfig(value = "honeycomb", syntax = Syntax.JSON)
+public final class DeviceConfiguration {
+    private static final Logger LOG = LoggerFactory.getLogger(DeviceConfiguration.class);
+    private static final String DEVICE_XSL = "device/OperToConfig.xsl";
+    private static final String CONFIG_XSL = "device/config.xsl";
+    private static final String NAMESPACE_TRIMER_XSL = "device/NamespaceTrimmer.xslt";
+    //private static final String DEVICE_DATA_SAMPLE_OPER_XML = "device/sample-config-ROADM.xml";
+
+    public String config_device;
+    public OrgOpenroadmDevice oper_device;
+    private DataStoreContext dataStoreContextUtil;
+    private DefaultDeviceFactory defaultDeviceFactory;
+    private ClassLoader classLoader;
+    private Boolean register;
+
+    @InjectConfig("persisted-config-path")
+    public String peristConfigPath;
+
+    @InjectConfig("netconf-initial-config-xml")
+    public String DEVICE_DATA_SAMPLE_OPER_XML;
+
+    public DeviceConfiguration() {
+        classLoader = Thread.currentThread().getContextClassLoader();
+        dataStoreContextUtil = new DataStoreContextImpl();
+        defaultDeviceFactory = new DefaultDeviceFactory();
+        register = false;
+    }
+
+
+    public String getConfigDevice() {
+        return operToConfig();
+    }
+
+    public String getPeristConfigPath() {
+        return peristConfigPath;
+    }
+
+    public String getNetconfInitialConfigXml() {
+        return DEVICE_DATA_SAMPLE_OPER_XML;
+    }
+
+    public Boolean getRegister() {
+        return register;
+    }
+
+    public void setRegister(Boolean reg) {
+        this.register = reg;
+    }
+
+    public OrgOpenroadmDevice getDataDevice() {
+        OrgOpenroadmDevice result = null;
+        File device_data = new File(classLoader.getResource(DEVICE_DATA_SAMPLE_OPER_XML).getFile());
+        result = defaultDeviceFactory.createDefaultDevice(dataStoreContextUtil,device_data);
+        if (result != null) {
+            LOG.info("result info : {}", result.getInfo().getNodeId());
+        }
+        return result;
+    }
+
+    public OrgOpenroadmDevice getDeviceFromXML(String xml) {
+        String config_result =null;
+        LOG.info("process to transform xml file to config data");
+        TransformerFactory factory = TransformerFactory.newInstance();
+        Source xslt = new StreamSource(new File(classLoader.getResource(CONFIG_XSL).getFile()));
+        Transformer transformer;
+        Source text;
+        StringWriter device_config = new StringWriter();
+        OrgOpenroadmDevice result = null;
+        try {
+            LOG.info("transforming xml string to config device ...");
+            transformer = factory.newTransformer(xslt);
+            text = new StreamSource(new StringReader(xml));
+            transformer.transform(text, new StreamResult(device_config));
+            config_result = device_config.toString();
+            //LOG.info("config_result: {}",config_result);
+            result  = defaultDeviceFactory.createDefaultDevice(dataStoreContextUtil,config_result);
+            if (result != null) {
+                LOG.info("result info : {}", result.getInfo().getNodeId());
+            }
+        } catch (TransformerException e) {
+            LOG.error("Transformer failed ");
+        }
+
+        return result;
+    }
+
+
+   /**
+    * Convert data xml to config xml device.
+    * @return String result
+    */
+    public String operToConfig() {
+        String result =null;
+        LOG.info("process to transform xml file ");
+        TransformerFactory factory = TransformerFactory.newInstance();
+        Source xslt = new StreamSource(new File(classLoader.getResource(DEVICE_XSL).getFile()));
+        Transformer transformer;
+        Source text;
+        StringWriter tmpwriter = new StringWriter();
+        StringReader reader;
+        try {
+            LOG.info("transforming xml data to config device ...");
+            transformer = factory.newTransformer(xslt);
+            text = new StreamSource(new File(classLoader.getResource(DEVICE_DATA_SAMPLE_OPER_XML).getFile()));
+            transformer.transform(text, new StreamResult(tmpwriter));
+            LOG.info("removing namespace ...");
+            xslt = new StreamSource(new File(classLoader.getResource(NAMESPACE_TRIMER_XSL).getFile()));
+            transformer = factory.newTransformer(xslt);
+            reader = new StringReader(tmpwriter.toString());
+            StringWriter device_config = new StringWriter();
+            text = new StreamSource(reader);
+            transformer.transform(text, new StreamResult(device_config));
+            result = device_config.toString();
+//            LOG.info("DeviceConfiguration - operToCconfig - result = {}", result);
+        } catch (TransformerException e) {
+            LOG.error("Transformer failed ");
+        }
+        return result;
+    }
+}
diff --git a/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/configuration/DeviceConfigurationModule.java b/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/configuration/DeviceConfigurationModule.java
new file mode 100644 (file)
index 0000000..728d8fa
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018 Orange and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.transportpce.device.configuration;
+
+import com.google.inject.AbstractModule;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.jmob.guice.conf.core.ConfigurationModule;
+
+/**
+ * @author Martial COULIBALY ( martial.coulibaly@gfi.com ) on behalf of Orange
+ */
+public final class DeviceConfigurationModule extends AbstractModule {
+
+    private static final Logger LOG = LoggerFactory.getLogger(DeviceConfigurationModule.class);
+
+    @Override
+    protected void configure() {
+        LOG.info("Initializing Device Readers Module");
+        install(ConfigurationModule.create());
+        requestInjection(DeviceConfiguration.class);
+    }
+
+}
diff --git a/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/configuration/NetconfConfiguration.java b/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/configuration/NetconfConfiguration.java
new file mode 100644 (file)
index 0000000..5f90a7d
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.transportpce.device.configuration;
+
+import io.fd.honeycomb.transportpce.device.tools.DefaultNetconfFactory;
+import io.fd.honeycomb.transportpce.test.common.DataStoreContext;
+import io.fd.honeycomb.transportpce.test.common.DataStoreContextImpl;
+
+import java.io.File;
+
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.Netconf;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.Streams;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.jmob.guice.conf.core.BindConfig;
+import net.jmob.guice.conf.core.InjectConfig;
+import net.jmob.guice.conf.core.Syntax;
+
+/**
+ * Class containing static configuration for honeynode-plugin module<br>
+ * <p/>
+ * Further documentation for the configuration injection can be found at:
+ * https://github.com/yyvess/gconf
+ */
+@BindConfig(value = "honeycomb", syntax = Syntax.JSON)
+public final class NetconfConfiguration {
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfConfiguration.class);
+
+    private DataStoreContext dataStoreContextUtil;
+    private DefaultNetconfFactory defaultNetconf;
+    private ClassLoader classLoader;
+
+    @InjectConfig("netconf-initial-config-xml")
+    public String NETCONF_DATA_SAMPLE_OPER_XML;
+
+    public NetconfConfiguration() {
+        classLoader = Thread.currentThread().getContextClassLoader();
+        dataStoreContextUtil = new DataStoreContextImpl();
+        defaultNetconf = new DefaultNetconfFactory();
+    }
+
+    public String getNetconfInitialXml() {
+        return NETCONF_DATA_SAMPLE_OPER_XML;
+    }
+
+    public Streams getNetconfStreamsData() {
+        Streams result = null;
+        File netconf_data = new File(classLoader.getResource(NETCONF_DATA_SAMPLE_OPER_XML).getFile());
+        Netconf netconf = defaultNetconf.createDefaultNetconf(dataStoreContextUtil, netconf_data);
+        if (netconf != null) {
+            try {
+                result = netconf.getStreams();
+                LOG.info("netconf streams result : {}", netconf.getStreams());
+            } catch (NullPointerException e) {
+                LOG.error("failed to get Netconf Streams");
+            }
+        }
+        return result;
+    }
+}
diff --git a/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/configuration/NetconfConfigurationModule.java b/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/configuration/NetconfConfigurationModule.java
new file mode 100644 (file)
index 0000000..1feec55
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2018 Orange and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.transportpce.device.configuration;
+
+import com.google.inject.AbstractModule;
+
+import io.fd.honeycomb.northbound.NetconfConfiguration;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.jmob.guice.conf.core.ConfigurationModule;
+
+/**
+ * @author Martial COULIBALY ( mcoulibaly.ext@orange.com ) on behalf of Orange
+ */
+public final class NetconfConfigurationModule extends AbstractModule {
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfConfigurationModule.class);
+
+    @Override
+    protected void configure() {
+        LOG.info("Initializing Netconf Readers Module");
+        install(ConfigurationModule.create());
+        requestInjection(NetconfConfiguration.class);
+    }
+
+}
diff --git a/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/configuration/PmConfiguration.java b/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/configuration/PmConfiguration.java
new file mode 100644 (file)
index 0000000..376968e
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.transportpce.device.configuration;
+
+import io.fd.honeycomb.transportpce.device.tools.DefaultPmListFactory;
+import io.fd.honeycomb.transportpce.test.common.DataStoreContext;
+import io.fd.honeycomb.transportpce.test.common.DataStoreContextImpl;
+
+import java.io.File;
+
+import org.opendaylight.yang.gen.v1.http.org.openroadm.pm.rev181019.CurrentPmList;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.jmob.guice.conf.core.BindConfig;
+import net.jmob.guice.conf.core.InjectConfig;
+import net.jmob.guice.conf.core.Syntax;
+
+/**
+ * Class containing static configuration for honeynode-plugin module<br>
+ * <p/>
+ * Further documentation for the configuration injection can be found at:
+ * https://github.com/yyvess/gconf
+ */
+@BindConfig(value = "honeycomb", syntax = Syntax.JSON)
+public final class PmConfiguration {
+    private static final Logger LOG = LoggerFactory.getLogger(PmConfiguration.class);
+
+    private DataStoreContext dataStoreContextUtil;
+    private DefaultPmListFactory defaultPmListFactory;
+    private ClassLoader classLoader;
+
+    @InjectConfig("netconf-initial-config-xml")
+    public String PM_DATA_SAMPLE_OPER_XML;
+
+    public PmConfiguration() {
+        classLoader = Thread.currentThread().getContextClassLoader();
+        dataStoreContextUtil = new DataStoreContextImpl();
+        defaultPmListFactory = new DefaultPmListFactory();
+    }
+
+    public String getNetconfInitialPmXml() {
+        return PM_DATA_SAMPLE_OPER_XML;
+    }
+
+    public CurrentPmList getDataPm() {
+       CurrentPmList result = null;
+        File pm_list_data = new File(classLoader.getResource(PM_DATA_SAMPLE_OPER_XML).getFile());
+        result = defaultPmListFactory.createDefaultPmList(dataStoreContextUtil,pm_list_data);
+        if (result != null) {
+            LOG.info("result pm list size : {}", result.getCurrentPmEntry().size());
+        } else {
+               LOG.error("no current-pm-list retreived from initial xml file");
+        }
+        return result;
+    }
+}
diff --git a/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/configuration/PmConfigurationModule.java b/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/configuration/PmConfigurationModule.java
new file mode 100644 (file)
index 0000000..f9d8ee0
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018 Orange and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.transportpce.device.configuration;
+
+import com.google.inject.AbstractModule;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.jmob.guice.conf.core.ConfigurationModule;
+
+/**
+ * @author Martial COULIBALY ( martial.coulibaly@gfi.com ) on behalf of Orange
+ */
+public final class PmConfigurationModule extends AbstractModule {
+
+    private static final Logger LOG = LoggerFactory.getLogger(PmConfigurationModule.class);
+
+    @Override
+    protected void configure() {
+        LOG.info("Initializing Pm Readers Module");
+        install(ConfigurationModule.create());
+        requestInjection(PmConfiguration.class);
+    }
+
+}
diff --git a/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/notifications/DeviceNotificationProducer.java b/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/notifications/DeviceNotificationProducer.java
new file mode 100644 (file)
index 0000000..22d634e
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2018 Orange and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.transportpce.device.notifications;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+
+import io.fd.honeycomb.notification.ManagedNotificationProducer;
+import io.fd.honeycomb.notification.NotificationCollector;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.ChangeNotification;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.ChangeNotification.Datastore;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.ChangeNotificationBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.change.notification.Edit;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.change.notification.EditBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.changed.by.parms.ChangedBy;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.changed.by.parms.ChangedByBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.changed.by.parms.changed.by.server.or.user.ServerBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.circuit.pack.Ports;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.circuit.pack.PortsKey;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.circuit.packs.CircuitPacks;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.circuit.packs.CircuitPacksKey;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.interfaces.grp.Interface;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.OrgOpenroadmDevice;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.EditOperationType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.Notification;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Martial COULIBALY ( mcoulibaly.ext@orange.com ) on behalf of Orange
+ */
+public class DeviceNotificationProducer implements ManagedNotificationProducer {
+    private static final Logger LOG = LoggerFactory.getLogger(DeviceNotificationProducer.class);
+    private static final InstanceIdentifier<OrgOpenroadmDevice> DEVICE_CONTAINER_ID = InstanceIdentifier
+            .create(OrgOpenroadmDevice.class);
+    private static final String INTERFACE_CLASS = Interface.class.getName();
+
+    @Inject
+    @Named("device-databroker")
+    private DataBroker dataBroker;
+
+    @Override
+    public Collection<Class<? extends Notification>> getNotificationTypes() {
+        final ArrayList<Class<? extends Notification>> classes = Lists.newArrayList();
+        classes.add(ChangeNotification.class);
+        return classes;
+    }
+
+    @Override
+    public void close() throws Exception {
+        stop();
+    }
+
+    @Override
+    public void start(NotificationCollector collector) {
+        LOG.info("Starting notification stream for OrgOpenroadmDevice");
+        Preconditions.checkArgument(this.dataBroker != null, "Device datastore is null");
+        this.dataBroker.registerDataTreeChangeListener(
+                new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, DEVICE_CONTAINER_ID),
+                new DataTreeChangeListener<OrgOpenroadmDevice>() {
+                    @Override
+                    public void onDataTreeChanged(Collection<DataTreeModification<OrgOpenroadmDevice>> changes) {
+                        LOG.info("onDataTreeChanged");
+                        ChangeNotification changeNotification = null;
+                        try {
+                            changeNotification = transformToNotification(changes);
+                            LOG.info("Emitting notification : {}", changeNotification);
+                            collector.onNotification(changeNotification);
+                        } catch (NullPointerException e) {
+                            LOG.warn("Failed to emit notification");
+                        }
+                    }
+                });
+    }
+
+    @Override
+    public void stop() {
+        LOG.info("Stopping OrgOpenroadmDevice change notification");
+    }
+
+    /**
+     * Transform {@link Collection} of {@link DataTreeModification } to {@link ChangeNotification}
+     *
+     * @return changeNotification {@link ChangeNotification}
+     */
+    private ChangeNotification transformToNotification(Collection<DataTreeModification<OrgOpenroadmDevice>> changes) {
+        LOG.info("transforming changes to notification...");
+        ChangeNotification result = null;
+        List<Edit> editList = new ArrayList<Edit>();
+        for (DataTreeModification<OrgOpenroadmDevice> change : changes) {
+            LOG.info("Received Device change :\n{}", change.getRootNode().getModificationType());
+            final DataObjectModification<OrgOpenroadmDevice> rootNode = change.getRootNode();
+            final DataTreeIdentifier<OrgOpenroadmDevice> rootPath = change.getRootPath();
+            if (rootNode != null) {
+                Collection<DataObjectModification<? extends DataObject>> modifiedChildren = rootNode.getModifiedChildren();
+                switch (rootNode.getModificationType()) {
+                case SUBTREE_MODIFIED: // OrgOpenroadmDevice
+                    if (!modifiedChildren.isEmpty()) {
+                        Iterator<DataObjectModification<? extends DataObject>> iterator = modifiedChildren.iterator();
+                        while (iterator.hasNext()) {
+                            DataObjectModification<? extends DataObject> modified = iterator.next();
+                            LOG.info(
+                                    "modified = \ndataType : {}\nid : {}\nmodifiedType : {}\noldData : {}\nnewData : {} \n",
+                                    modified.getDataType(), modified.getIdentifier(), modified.getModificationType(),
+                                    modified.getDataBefore(), modified.getDataAfter());
+                            String dataType = modified.getDataType().getName();
+                            if (dataType.equals(INTERFACE_CLASS)) {
+                                Interface data = null;
+                                LOG.info("Interface type update !");
+                                switch (modified.getModificationType()) {
+                                case SUBTREE_MODIFIED:
+                                    data = (Interface) modified.getDataAfter();
+                                    break;
+                                case WRITE:
+                                    data = (Interface) modified.getDataAfter();
+                                    break;
+                                case DELETE:
+                                    data = (Interface) modified.getDataBefore();
+                                    break;
+                                default:
+                                    break;
+                                }
+                                if (data!= null) {
+                                    String circuitPackName = data.getSupportingCircuitPackName();
+                                    String port = data.getSupportingPort().toString();
+                                    String interfaceName = data.getName();
+                                    if (circuitPackName != null && port != null && interfaceName != null) {
+                                        InstanceIdentifier<Ports> portIId = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(
+                                                CircuitPacks.class, new CircuitPacksKey(circuitPackName)).child(Ports.class,
+                                                    new PortsKey(port));
+                                        Edit edit = new EditBuilder()
+                                                .setOperation(EditOperationType.Merge)
+                                                .setTarget(portIId)
+                                                .build();
+                                        editList.add(edit);
+                                    }
+                                } else {
+                                    LOG.warn("Interface data is null !");
+                                }
+                            } else {
+                                LOG.warn("modifiedChild is not an interface !");
+                            }
+                        }
+                    }
+                    break;
+                case WRITE:
+                    LOG.info("device operational datastore is created !");
+                    break;
+                case DELETE:
+                    LOG.info("device operational datastore is deleted !");
+                    break;
+                default:
+                    break;
+                }
+            } else {
+                LOG.error("rootNode is null !");
+            }
+        }
+        if (!editList.isEmpty()) {
+            ChangedBy changedBy = new ChangedByBuilder().setServerOrUser(new ServerBuilder().setServer(true).build())
+                    .build();
+            String time = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSXXX").format(new Date());
+            result = new ChangeNotificationBuilder().setChangedBy(changedBy).setChangeTime(new DateAndTime(time))
+                    .setDatastore(Datastore.Running).setEdit(editList).build();
+        } else {
+            LOG.warn("edit List is empty !");
+        }
+        return result;
+    }
+}
diff --git a/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/read/DeviceReaderFactory.java b/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/read/DeviceReaderFactory.java
new file mode 100644 (file)
index 0000000..82407bc
--- /dev/null
@@ -0,0 +1,348 @@
+/*
+ * Copyright (c) 2018 Orange and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.transportpce.device.read;
+
+import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.Futures;
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+
+import io.fd.honeycomb.translate.read.ReaderFactory;
+import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder;
+import io.fd.honeycomb.translate.util.read.BindingBrokerReader;
+import io.fd.honeycomb.transportpce.device.configuration.DeviceConfiguration;
+import io.fd.honeycomb.transportpce.device.configuration.NetconfConfiguration;
+
+import java.io.File;
+import java.io.IOException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+import org.opendaylight.controller.config.util.capability.Capability;
+import org.opendaylight.controller.config.util.capability.YangModuleCapability;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.OrgOpenroadmDevice;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.OrgOpenroadmDeviceBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.Netconf;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.Streams;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.StreamsBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.StreamBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.StreamKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfStateBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.Yang;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Schemas;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.SchemasBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.Schema;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.Schema.Location;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.Schema.Location.Enumeration;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.SchemaBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceFilter;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation;
+import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
+import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
+import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource;
+import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceListener;
+import org.opendaylight.yangtools.yang.model.repo.util.FilesystemSchemaSourceCache;
+import org.opendaylight.yangtools.yang.parser.repo.SharedSchemaRepository;
+import org.opendaylight.yangtools.yang.parser.util.TextToASTTransformer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Martial COULIBALY ( martial.coulibaly@gfi.com ) on behalf of Orange
+ */
+public final class DeviceReaderFactory implements ReaderFactory {
+
+    private static final Logger LOG = LoggerFactory.getLogger(DeviceReaderFactory.class);
+    public static final InstanceIdentifier<OrgOpenroadmDevice> DEVICE_CONTAINER_ID =
+            InstanceIdentifier.create(OrgOpenroadmDevice.class);
+    private static final String YANG_MODELS = "yang";
+
+    @Inject
+    @Named("device-databroker")
+    private DataBroker dataBroker;
+
+    @Inject
+    private DeviceConfiguration deviceConfiguration;
+
+    @Inject
+    private NetconfConfiguration netconfConfiguration;
+
+
+    @Override
+    public void init(final ModifiableReaderRegistryBuilder registry) {
+        registry.add(new BindingBrokerReader<>(DEVICE_CONTAINER_ID, dataBroker,LogicalDatastoreType.OPERATIONAL,
+                OrgOpenroadmDeviceBuilder.class));
+        if(writeXMLDataToOper()) {
+            writeNetconfState();
+            writeNetconfStream();
+            loadConfigData();
+        }
+    }
+
+    /**
+     * Write xml data from {@link DeviceConfiguration}
+     * to operational data.
+     *
+     */
+    public boolean writeXMLDataToOper() {
+        Boolean res = false;
+        LOG.info("writting xml file data to oper datastore");
+        OrgOpenroadmDevice device = this.deviceConfiguration.getDataDevice();
+        if (device !=null) {
+            String deviceId = device.getInfo().getNodeId().getValue();
+            LOG.info("Getting device info from xml file for device '{}'", deviceId);
+            OrgOpenroadmDeviceBuilder result  = new OrgOpenroadmDeviceBuilder(device);
+            InstanceIdentifier<OrgOpenroadmDevice> iid = InstanceIdentifier.create(OrgOpenroadmDevice.class);
+            WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
+            if (writeTx != null ) {
+                LOG.info("WriteTransaction is ok, copy device info to oper datastore");
+                writeTx.put(LogicalDatastoreType.OPERATIONAL, iid, result.build());
+                Future<Void> future = writeTx.submit();
+                try {
+                    Futures.getChecked(future, ExecutionException.class);
+                    LOG.info("device '{}' writed to oper datastore", deviceId);
+                    res = true;
+                } catch (ExecutionException e) {
+                    LOG.error("Failed to write Element '{}' to oper datastore", deviceId);
+                }
+            } else {
+                LOG.error("WriteTransaction object is null");
+            }
+        } else {
+            LOG.error("device data operation gets from xml file is null !");
+        }
+        return res;
+    }
+
+    /**
+     * Load data to config
+     * device datastore.
+     *
+     */
+    public boolean loadConfigData() {
+        Boolean res = false;
+        LOG.info("loading device configuration info from xml file...");
+        String xml = this.deviceConfiguration.getConfigDevice();
+        LOG.info("device info gets from xml file !");
+        if (xml != null) {
+            OrgOpenroadmDevice result  = this.deviceConfiguration.getDeviceFromXML(xml);
+            if (result != null) {
+                LOG.info("OrgOpenroadmDevice info gets : {}", result.getInfo().getNodeId());
+                WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
+                if (writeTx != null ) {
+                    LOG.info("WriteTransaction is ok, copy device info to config datastore");
+                    writeTx.put(LogicalDatastoreType.CONFIGURATION, DEVICE_CONTAINER_ID, result);
+                    Future<Void> future = writeTx.submit();
+                    try {
+                        Futures.getChecked(future, ExecutionException.class);
+                        LOG.info("device writed to config datastore");
+                      } catch (ExecutionException e) {
+                          LOG.error("Failed to write device to config datastore");
+                      }
+                } else {
+                    LOG.error("WriteTransaction object is null");
+                }
+            } else {
+                LOG.error("device gets from xml is null !!");
+            }
+        } else {
+            LOG.error("device ID from input is not the same from xml file");
+        }
+        return res;
+    }
+
+    /**
+     * write {@link Streams} data
+     * to operational device datastore.
+     *
+     * @return result {@link Boolean}
+     */
+    public boolean writeNetconfStream() {
+        Boolean result = false;
+        LOG.info("writting netconf stream to oper datastore");
+        Streams streams = this.netconfConfiguration.getNetconfStreamsData();
+        if (streams != null) {
+            LOG.info("Netconf Data gets from xml file is present");
+            InstanceIdentifier<Streams> iid = InstanceIdentifier.create(Netconf.class).child(Streams.class);
+//            StreamNameType name = new StreamNameType("OPENROADM");
+//            Streams netconfStreams = new StreamsBuilder()
+//                    .setStream(Arrays.asList(new StreamBuilder()
+//                            .setKey(new StreamKey(name))
+//                            .setName(name)
+//                            .build()))
+//                    .build();
+            Streams netconfStreams = new StreamsBuilder(streams).build();
+            WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
+            if (writeTx != null ) {
+                LOG.info("WriteTransaction is ok");
+                writeTx.put(LogicalDatastoreType.OPERATIONAL, iid, netconfStreams);
+                Future<Void> future = writeTx.submit();
+                try {
+                    Futures.getChecked(future, ExecutionException.class);
+                    LOG.info("netconf stream writed to oper datastore");
+                    result = true;
+                } catch (ExecutionException e) {
+                    LOG.error("Failed to write netconf stream to oper datastore");
+                }
+            } else {
+                LOG.error("WriteTransaction object is null");
+            }
+        } else {
+            LOG.error("Netconf data gets from xml file is null !");
+        }
+        return result;
+    }
+
+    /**
+     * Write {@link NetconfState} data
+     * to operational device datastore.
+     *
+     *@return result {@link Boolean}
+     */
+    public boolean writeNetconfState() {
+        Boolean res = false;
+        LOG.info("writting netconf state to oper datastore");
+        final SharedSchemaRepository schemaRepo = new SharedSchemaRepository("honeynode-simulator");
+        final Set<Capability> capabilities = parseSchemasToModuleCapabilities(schemaRepo);
+        final Set<Capability> transformedCapabilities = Sets.newHashSet(capabilities);
+        DummyMonitoringService monitor = new DummyMonitoringService(transformedCapabilities);
+        List<Schema> schemaList = new ArrayList<Schema>();
+        List<Location> locationList = new ArrayList<Location>();
+        Location location = new Location(Enumeration.NETCONF);
+        locationList.add(location );
+        Schema schematobuild = null;
+        for (final Schema schema : monitor.getSchemas().getSchema()) {
+            schematobuild = new SchemaBuilder()
+                    .setIdentifier(schema.getIdentifier())
+                    .setNamespace(schema.getNamespace())
+                    .setVersion(schema.getVersion())
+                    .setFormat(Yang.class)
+                    .setLocation(locationList)
+                    .build();
+            schemaList.add(schematobuild);
+        }
+        Schemas schemas = new SchemasBuilder()
+                .setSchema(schemaList)
+                .build();
+        NetconfState netconfState = new NetconfStateBuilder()
+                .setSchemas(schemas)
+                .build();
+        if (netconfState !=null) {
+            InstanceIdentifier<NetconfState> iid = InstanceIdentifier.create(NetconfState.class);
+            WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
+            if (writeTx != null ) {
+                LOG.info("WriteTransaction is ok, copy device info to oper datastore");
+                writeTx.put(LogicalDatastoreType.OPERATIONAL, iid, netconfState);
+                Future<Void> future = writeTx.submit();
+                try {
+                    Futures.getChecked(future, ExecutionException.class);
+                    LOG.info("netconf state writed to oper datastore");
+                    res = true;
+                } catch (ExecutionException e) {
+                    LOG.error("Failed to write netconf state to oper datastore");
+                }
+            } else {
+                LOG.error("WriteTransaction object is null");
+            }
+        } else {
+            LOG.error("device data operation gets from xml file is null !");
+        }
+        return res;
+    }
+
+    private Set<Capability> parseSchemasToModuleCapabilities(final SharedSchemaRepository consumer) {
+        final Set<SourceIdentifier> loadedSources = Sets.newHashSet();
+        consumer.registerSchemaSourceListener(TextToASTTransformer.create(consumer, consumer));
+        consumer.registerSchemaSourceListener(new SchemaSourceListener() {
+            @Override
+            public void schemaSourceEncountered(final SchemaSourceRepresentation schemaSourceRepresentation) {}
+
+            @Override
+            public void schemaSourceRegistered(final Iterable<PotentialSchemaSource<?>> potentialSchemaSources) {
+                for (final PotentialSchemaSource<?> potentialSchemaSource : potentialSchemaSources) {
+                    loadedSources.add(potentialSchemaSource.getSourceIdentifier());
+                }
+            }
+
+            @Override
+            public void schemaSourceUnregistered(final PotentialSchemaSource<?> potentialSchemaSource) {}
+        });
+        LOG.info("Loading models from directory.");
+        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+        File models = new File(classLoader.getResource(YANG_MODELS).getFile());
+        if (models.exists() && models.isDirectory()) {
+            LOG.info("folder '{}' exists !", models.getAbsolutePath());
+            final FilesystemSchemaSourceCache<YangTextSchemaSource> cache = new FilesystemSchemaSourceCache<>(
+                    consumer, YangTextSchemaSource.class, models);
+                consumer.registerSchemaSourceListener(cache);
+        } else {
+            LOG.warn("folder '{}' not exists !", models.getAbsolutePath());
+            LOG.info("Custom module loading skipped.");
+        }
+        SchemaContext schemaContext;
+        try {
+            //necessary for creating mdsal data stores and operations
+            schemaContext = consumer.createSchemaContextFactory(SchemaSourceFilter.ALWAYS_ACCEPT)
+                .createSchemaContext(loadedSources).get();
+        } catch (final InterruptedException | ExecutionException e) {
+            throw new RuntimeException("Cannot parse schema context", e);
+        }
+
+        final Set<Capability> capabilities = Sets.newHashSet();
+
+        for (final Module module : schemaContext.getModules()) {
+            for (final Module subModule : module.getSubmodules()) {
+                addModuleCapability(consumer, capabilities, subModule);
+            }
+            addModuleCapability(consumer, capabilities, module);
+        }
+        return capabilities;
+    }
+
+    private static void addModuleCapability(final SharedSchemaRepository consumer, final Set<Capability> capabilities,
+                                     final Module module) {
+        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+
+        //to convert Date to String, use format method of SimpleDateFormat class.
+        String revision = dateFormat.format(module.getRevision());
+        final SourceIdentifier moduleSourceIdentifier = RevisionSourceIdentifier.create(module.getName(),
+            revision);
+        try {
+            final String moduleContent = new String(
+                consumer.getSchemaSource(moduleSourceIdentifier, YangTextSchemaSource.class).get().read());
+            capabilities.add(new YangModuleCapability(module, moduleContent));
+            //IOException would be thrown in creating SchemaContext already
+        } catch (ExecutionException | InterruptedException | IOException e) {
+            LOG.warn("Cannot retrieve schema source for module {} from schema repository",
+                    moduleSourceIdentifier.toString(), e);
+        }
+    }
+}
diff --git a/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/read/DummyMonitoringService.java b/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/read/DummyMonitoringService.java
new file mode 100644 (file)
index 0000000..ea13dd4
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2018 Orange and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.transportpce.device.read;
+
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+import java.util.Collections;
+import java.util.Set;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opendaylight.controller.config.util.capability.Capability;
+import org.opendaylight.netconf.api.monitoring.NetconfManagementSession;
+import org.opendaylight.netconf.api.monitoring.NetconfMonitoringService;
+import org.opendaylight.netconf.api.monitoring.SessionEvent;
+import org.opendaylight.netconf.api.monitoring.SessionListener;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.Yang;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Capabilities;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.CapabilitiesBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Schemas;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.SchemasBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Sessions;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.SessionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.Schema;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.Schema.Location;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.Schema.Location.Enumeration;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.SchemaBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.SchemaKey;
+
+public class DummyMonitoringService implements NetconfMonitoringService {
+
+    private static final Sessions EMPTY_SESSIONS = new SessionsBuilder().setSession(Collections.emptyList()).build();
+    private static final Function<Capability, Uri> CAPABILITY_URI_FUNCTION =
+        capability -> new Uri(capability.getCapabilityUri());
+
+    private static final Function<Capability, Schema> CAPABILITY_SCHEMA_FUNCTION = new Function<Capability, Schema>() {
+        @Nullable
+        @Override
+        public Schema apply(@Nonnull final Capability capability) {
+            return new SchemaBuilder()
+                    .setIdentifier(capability.getModuleName().get())
+                    .setNamespace(new Uri(capability.getModuleNamespace().get()))
+                    .setFormat(Yang.class)
+                    .setVersion(capability.getRevision().get())
+                    .setLocation(Collections.singletonList(new Location(Enumeration.NETCONF)))
+                    .setKey(new SchemaKey(Yang.class, capability.getModuleName().get(),
+                        capability.getRevision().get()))
+                    .build();
+        }
+    };
+
+    private final Capabilities capabilities;
+    private final ArrayListMultimap<String, Capability> capabilityMultiMap;
+    private final Schemas schemas;
+
+    public DummyMonitoringService(final Set<Capability> capabilities) {
+
+        this.capabilities = new CapabilitiesBuilder().setCapability(
+                Lists.newArrayList(Collections2.transform(capabilities, CAPABILITY_URI_FUNCTION))).build();
+
+        Set<Capability> moduleCapabilities = Sets.newHashSet();
+        this.capabilityMultiMap = ArrayListMultimap.create();
+        for (Capability cap : capabilities) {
+            if (cap.getModuleName().isPresent()) {
+                capabilityMultiMap.put(cap.getModuleName().get(), cap);
+                moduleCapabilities.add(cap);
+            }
+        }
+
+        this.schemas = new SchemasBuilder().setSchema(
+            Lists.newArrayList(Collections2.transform(moduleCapabilities, CAPABILITY_SCHEMA_FUNCTION))).build();
+    }
+
+    @Override
+    public Sessions getSessions() {
+        return EMPTY_SESSIONS;
+    }
+
+    @Override
+    public SessionListener getSessionListener() {
+        return new SessionListener() {
+            @Override
+            public void onSessionUp(final NetconfManagementSession session) {
+                //no op
+            }
+
+            @Override
+            public void onSessionDown(final NetconfManagementSession session) {
+                //no op
+            }
+
+            @Override
+            public void onSessionEvent(final SessionEvent event) {
+                //no op
+            }
+        };
+    }
+
+    @Override
+    public Schemas getSchemas() {
+        return schemas;
+    }
+
+    @Override
+    public String getSchemaForCapability(final String moduleName, final Optional<String> revision) {
+
+        for (Capability capability : capabilityMultiMap.get(moduleName)) {
+            if (capability.getRevision().get().equals(revision.get())) {
+                return capability.getCapabilitySchema().get();
+            }
+        }
+        throw new IllegalArgumentException(
+            "Module with name: " + moduleName + " and revision: " + revision + " does not exist");
+    }
+
+    @Override
+    public Capabilities getCapabilities() {
+        return capabilities;
+    }
+
+    @Override
+    public AutoCloseable registerCapabilitiesListener(final CapabilitiesListener listener) {
+        return null;
+    }
+
+    @Override
+    public AutoCloseable registerSessionsListener(final SessionsListener listener) {
+        return null;
+    }
+
+}
diff --git a/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/read/PmReaderFactory.java b/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/read/PmReaderFactory.java
new file mode 100644 (file)
index 0000000..8514791
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2018 Orange and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.transportpce.device.read;
+
+import com.google.common.util.concurrent.Futures;
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+
+import io.fd.honeycomb.translate.read.ReaderFactory;
+import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder;
+import io.fd.honeycomb.translate.util.read.BindingBrokerReader;
+import io.fd.honeycomb.transportpce.device.configuration.PmConfiguration;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.pm.rev181019.CurrentPmList;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.pm.rev181019.CurrentPmListBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Martial COULIBALY ( mcoulibaly.ext@orange.com ) on behalf of Orange
+ */
+public class PmReaderFactory implements ReaderFactory {
+
+    private static final Logger LOG = LoggerFactory.getLogger(PmReaderFactory.class);
+    public static final InstanceIdentifier<CurrentPmList> PM_CONTAINER_ID =
+            InstanceIdentifier.create(CurrentPmList.class);
+
+    @Inject
+    @Named("device-databroker")
+    private DataBroker dataBroker;
+
+    @Inject
+    private PmConfiguration pmConfiguration;
+
+
+    @Override
+    public void init(final ModifiableReaderRegistryBuilder registry) {
+        registry.add(new BindingBrokerReader<>(PM_CONTAINER_ID, dataBroker,LogicalDatastoreType.OPERATIONAL,
+                CurrentPmListBuilder.class));
+        writeXMLDataToOper();
+    }
+
+    /**
+     * Write xml data from {@link PmConfiguration}
+     * to operational data.
+     *
+     */
+    public boolean writeXMLDataToOper() {
+        Boolean res = false;
+        LOG.info("writting xml pm file data to oper datastore");
+        CurrentPmList pmList = this.pmConfiguration.getDataPm();
+        if (pmList !=null && pmList.getCurrentPmEntry().size() > 0) {
+            LOG.info("Getting pm info from xml file for device ");
+            CurrentPmListBuilder result  = new CurrentPmListBuilder(pmList);
+            InstanceIdentifier<CurrentPmList> iid = InstanceIdentifier.create(CurrentPmList.class);
+            WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
+            if (writeTx != null ) {
+                LOG.info("WriteTransaction is ok, copy currentPmList to oper datastore");
+                writeTx.put(LogicalDatastoreType.OPERATIONAL, iid, result.build());
+                Future<Void> future = writeTx.submit();
+                try {
+                    Futures.getChecked(future, ExecutionException.class);
+                    LOG.info("currentPmList writed to oper datastore");
+                    res = true;
+                } catch (ExecutionException e) {
+                    LOG.error("Failed to write currentPmList  to oper datastore");
+                }
+            } else {
+                LOG.error("WriteTransaction object is null");
+            }
+        } else {
+            LOG.error("currentPmList data operation gets from xml file is null !");
+        }
+        return res;
+    }
+
+}
diff --git a/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/rpcs/ConnectionPortTrailService.java b/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/rpcs/ConnectionPortTrailService.java
new file mode 100644 (file)
index 0000000..462003c
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2018 Orange and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.transportpce.device.rpcs;
+
+import io.fd.honeycomb.rpc.RpcService;
+
+import java.util.Arrays;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+
+import org.opendaylight.yang.gen.v1.http.org.openroadm.common.types.rev181019.RpcStatus;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.GetConnectionPortTrailInput;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.GetConnectionPortTrailOutput;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.GetConnectionPortTrailOutputBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.get.connection.port.trail.output.Ports;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.get.connection.port.trail.output.PortsBuilder;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Class to simulate get-connection-port-trail rpc.
+ *
+ * @author Martial COULIBALY ( mcoulibaly.ext@orange.com ) on behalf of Orange
+ */
+public class ConnectionPortTrailService implements RpcService<GetConnectionPortTrailInput, GetConnectionPortTrailOutput> {
+    private static final Logger LOG = LoggerFactory.getLogger(ConnectionPortTrailService.class);
+    private static final String localName = "get-connection-port-trail";
+    private static final QName name = QName.create(GetConnectionPortTrailInput.QNAME, localName);
+    private static final SchemaPath schemaPath = SchemaPath.ROOT.createChild(name);
+
+    @Override
+    public SchemaPath getManagedNode() {
+        return schemaPath;
+    }
+
+    /* (non-Javadoc)
+     * @see io.fd.honeycomb.rpc.RpcService#invoke(org.opendaylight.yangtools.yang.binding.DataObject)
+     */
+    @Override
+    public CompletionStage<GetConnectionPortTrailOutput> invoke(GetConnectionPortTrailInput arg0) {
+        LOG.info("RPC GetConnectionPortTrail request received !");
+        Ports port = new PortsBuilder()
+                .setCircuitPackName("2/0")
+                .setPortName("L1")
+                .build();
+        GetConnectionPortTrailOutput output = new GetConnectionPortTrailOutputBuilder()
+                .setStatusMessage("OK")
+                .setStatus(RpcStatus.Successful)
+                .setPorts(Arrays.asList(port))
+                .build();
+        CompletableFuture<GetConnectionPortTrailOutput> result = new CompletableFuture<>();
+        result.complete(output);
+        return result;
+    }
+
+}
diff --git a/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/tools/DefaultDeviceFactory.java b/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/tools/DefaultDeviceFactory.java
new file mode 100644 (file)
index 0000000..fb65017
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2018 Orange and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.transportpce.device.tools;
+
+import io.fd.honeycomb.transportpce.binding.converter.XMLDataObjectConverter;
+import io.fd.honeycomb.transportpce.test.common.DataStoreContext;
+
+import java.io.BufferedWriter;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Writer;
+import java.util.Optional;
+
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.OrgOpenroadmDevice;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Factory for creating the default device from the XML stored in
+ * classpath.
+ *
+ * @author Martial COULIBALY ( martial.coulibaly@gfi.com ) on behalf of Orange
+ */
+public class DefaultDeviceFactory {
+
+    private static final Logger LOG = LoggerFactory.getLogger(DefaultDeviceFactory.class);
+
+    /**
+     * Returns a new instance of {@link OrgOpenroadmDevice} from the loaded XML stored
+     * in File.
+     *
+     * @return {@link OrgOpenroadmDevice}
+     */
+    public OrgOpenroadmDevice createDefaultDevice(DataStoreContext dataStoreContextUtil, File device_data_config) {
+        OrgOpenroadmDevice result = null;
+        if (device_data_config.exists()) {
+            String config = device_data_config.getName();
+            LOG.info("file '{}' exists at location : {}", config, device_data_config.getAbsolutePath());
+            InputStream targetStream;
+            try {
+                targetStream = new FileInputStream(device_data_config);
+                Optional<NormalizedNode<?, ?>> transformIntoNormalizedNode = null;
+                transformIntoNormalizedNode =
+                        XMLDataObjectConverter.createWithDataStoreUtil(dataStoreContextUtil)
+                        .transformIntoNormalizedNode(targetStream);
+                if (!transformIntoNormalizedNode.isPresent()) {
+                    throw new IllegalStateException(String.format("Could not transform the input %s into normalized nodes",
+                            config));
+                }
+                Optional<DataObject> dataObject = XMLDataObjectConverter.createWithDataStoreUtil(dataStoreContextUtil)
+                        .getDataObject(transformIntoNormalizedNode.get(), OrgOpenroadmDevice.QNAME);
+                if (!dataObject.isPresent()) {
+                    throw new IllegalStateException("Could not transform normalized nodes into data object");
+                }
+                result =  (OrgOpenroadmDevice) dataObject.get();
+            } catch (FileNotFoundException e) {
+                LOG.error("File not found : {} at {}", e.getMessage(), e.getLocalizedMessage());
+            }
+        } else {
+            LOG.info("xml file not existed at : '{}'", device_data_config.getAbsolutePath());
+        }
+        return result;
+    }
+    /**
+     * Returns a new instance of {@link OrgOpenroadmDevice} from the loaded XML stored
+     * in String.
+     *
+     * @return {@link OrgOpenroadmDevice}
+     */
+    public OrgOpenroadmDevice createDefaultDevice(DataStoreContext dataStoreContextUtil, String device_data_config) {
+        OrgOpenroadmDevice result = null;
+        if (device_data_config != null) {
+            LOG.info("device data config string is ok ");
+            InputStream targetStream;
+            targetStream = new ByteArrayInputStream(device_data_config.getBytes());
+            Optional<NormalizedNode<?, ?>> transformIntoNormalizedNode = null;
+            transformIntoNormalizedNode =
+                    XMLDataObjectConverter.createWithDataStoreUtil(dataStoreContextUtil)
+                    .transformIntoNormalizedNode(targetStream);
+            if (!transformIntoNormalizedNode.isPresent()) {
+                throw new IllegalStateException(String.format("Could not transform the input %s into normalized nodes"));
+            }
+            Optional<DataObject> dataObject = XMLDataObjectConverter.createWithDataStoreUtil(dataStoreContextUtil)
+                    .getDataObject(transformIntoNormalizedNode.get(), OrgOpenroadmDevice.QNAME);
+            if (!dataObject.isPresent()) {
+                throw new IllegalStateException("Could not transform normalized nodes into data object");
+            }
+            result =  (OrgOpenroadmDevice) dataObject.get();
+        } else {
+            LOG.info("device data config string is null!");
+        }
+        return result;
+    }
+
+
+    public void createXMLFromDevice(DataStoreContext dataStoreContextUtil, OrgOpenroadmDevice device, String output) {
+        if (device != null) {
+            Optional<NormalizedNode<?, ?>> transformIntoNormalizedNode = null;
+            transformIntoNormalizedNode =
+                    XMLDataObjectConverter.createWithDataStoreUtil(dataStoreContextUtil)
+                    .toNormalizedNodes(device, OrgOpenroadmDevice.class);
+            if (!transformIntoNormalizedNode.isPresent()) {
+                throw new IllegalStateException(String.format("Could not transform the input %s into normalized nodes",
+                        device));
+            }
+            XMLDataObjectConverter createWithDataStoreUtil = XMLDataObjectConverter.createWithDataStoreUtil(dataStoreContextUtil);
+            Writer writerFromDataObject =
+                    createWithDataStoreUtil.writerFromDataObject(device, OrgOpenroadmDevice.class, createWithDataStoreUtil.dataContainer());
+            try {
+                BufferedWriter writer = new BufferedWriter(new FileWriter(output));
+                writer.write(writerFromDataObject.toString());
+                writer.close();
+            } catch (IOException e) {
+                LOG.error("Bufferwriter error ");
+            }
+            LOG.info("device xml : {}", writerFromDataObject.toString());
+        }
+    }
+}
diff --git a/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/tools/DefaultNetconfFactory.java b/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/tools/DefaultNetconfFactory.java
new file mode 100644 (file)
index 0000000..227d31c
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2018 Orange and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.transportpce.device.tools;
+
+import io.fd.honeycomb.transportpce.binding.converter.XMLDataObjectConverter;
+import io.fd.honeycomb.transportpce.test.common.DataStoreContext;
+
+import java.io.BufferedWriter;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Writer;
+import java.util.Optional;
+
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.Netconf;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Factory for creating the {@link Netconf} from the XML stored in
+ * classpath.
+ *
+ * @author Martial COULIBALY ( martial.coulibaly@gfi.com ) on behalf of Orange
+ */
+public class DefaultNetconfFactory {
+
+    private static final Logger LOG = LoggerFactory.getLogger(DefaultNetconfFactory.class);
+
+    /**
+     * Returns a new instance of {@link Netconf} from the loaded XML stored
+     * in File.
+     *
+     * @return {@link Netconf}
+     */
+    public Netconf createDefaultNetconf(DataStoreContext dataStoreContextUtil, File netconf_data_config) {
+        Netconf result = null;
+        if (netconf_data_config.exists()) {
+            String config = netconf_data_config.getName();
+            LOG.info("file '{}' exists at location : {}", config, netconf_data_config.getAbsolutePath());
+            InputStream targetStream;
+            try {
+                targetStream = new FileInputStream(netconf_data_config);
+                Optional<NormalizedNode<?, ?>> transformIntoNormalizedNode = null;
+                transformIntoNormalizedNode =
+                        XMLDataObjectConverter.createWithDataStoreUtil(dataStoreContextUtil)
+                        .transformIntoNormalizedNode(targetStream);
+                if (!transformIntoNormalizedNode.isPresent()) {
+                    throw new IllegalStateException(
+                            String.format("Could not transform the input %s into normalized nodes",
+                            config));
+                }
+                Optional<DataObject> dataObject = XMLDataObjectConverter.createWithDataStoreUtil(dataStoreContextUtil)
+                        .getDataObject(transformIntoNormalizedNode.get(), Netconf.QNAME);
+                if (!dataObject.isPresent()) {
+                    throw new IllegalStateException("Could not transform normalized nodes into data object");
+                }
+                result =  (Netconf) dataObject.get();
+            } catch (FileNotFoundException e) {
+                LOG.error("File not found : {} at {}", e.getMessage(), e.getLocalizedMessage());
+            }
+        } else {
+            LOG.info("netconf xml file not existed at : '{}'", netconf_data_config.getAbsolutePath());
+        }
+        return result;
+    }
+    /**
+     * Returns a new instance of {@link Netconf} from the loaded XML stored
+     * in String.
+     *
+     * @return {@link Netconf}
+     */
+    public Netconf createDefaultNetconf(DataStoreContext dataStoreContextUtil, String netconf_data_config) {
+        Netconf result = null;
+        if (netconf_data_config != null) {
+            LOG.info("Netconf data config string is ok ");
+            InputStream targetStream;
+            targetStream = new ByteArrayInputStream(netconf_data_config.getBytes());
+            Optional<NormalizedNode<?, ?>> transformIntoNormalizedNode = null;
+            transformIntoNormalizedNode =
+                    XMLDataObjectConverter.createWithDataStoreUtil(dataStoreContextUtil)
+                    .transformIntoNormalizedNode(targetStream);
+            if (!transformIntoNormalizedNode.isPresent()) {
+                throw new IllegalStateException(
+                        String.format("Could not transform the input %s into normalized nodes"));
+            }
+            Optional<DataObject> dataObject = XMLDataObjectConverter.createWithDataStoreUtil(dataStoreContextUtil)
+                    .getDataObject(transformIntoNormalizedNode.get(), Netconf.QNAME);
+            if (!dataObject.isPresent()) {
+                throw new IllegalStateException("Could not transform normalized nodes into data object");
+            }
+            result =  (Netconf) dataObject.get();
+        } else {
+            LOG.info("netconf data config string is null!");
+        }
+        return result;
+    }
+
+
+    /**
+     * create an XML String from an instance of {@link Netconf}.
+     *
+     */
+    public void createXMLFromNetconf(DataStoreContext dataStoreContextUtil, Netconf netconf, String output) {
+        if (netconf != null) {
+            Optional<NormalizedNode<?, ?>> transformIntoNormalizedNode = null;
+            transformIntoNormalizedNode =
+                    XMLDataObjectConverter.createWithDataStoreUtil(dataStoreContextUtil)
+                    .toNormalizedNodes(netconf, Netconf.class);
+            if (!transformIntoNormalizedNode.isPresent()) {
+                throw new IllegalStateException(String.format("Could not transform the input %s into normalized nodes",
+                        netconf));
+            }
+            XMLDataObjectConverter createWithDataStoreUtil = XMLDataObjectConverter
+                    .createWithDataStoreUtil(dataStoreContextUtil);
+            Writer writerFromDataObject =
+                    createWithDataStoreUtil.writerFromDataObject(netconf, Netconf.class,
+                            createWithDataStoreUtil.dataContainer());
+            try {
+                BufferedWriter writer = new BufferedWriter(new FileWriter(output));
+                writer.write(writerFromDataObject.toString());
+                writer.close();
+            } catch (IOException e) {
+                LOG.error("Bufferwriter error ");
+            }
+            LOG.info("netconf xml : {}", writerFromDataObject.toString());
+        }
+    }
+}
diff --git a/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/tools/DefaultPmListFactory.java b/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/tools/DefaultPmListFactory.java
new file mode 100644 (file)
index 0000000..2c33fe5
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2018 Orange and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.transportpce.device.tools;
+
+import io.fd.honeycomb.transportpce.binding.converter.XMLDataObjectConverter;
+import io.fd.honeycomb.transportpce.test.common.DataStoreContext;
+
+import java.io.BufferedWriter;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Writer;
+import java.util.Optional;
+
+import org.opendaylight.yang.gen.v1.http.org.openroadm.pm.rev181019.CurrentPmList;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Factory for creating the default device from the XML stored in
+ * classpath.
+ *
+ * @author Martial COULIBALY ( martial.coulibaly@gfi.com ) on behalf of Orange
+ */
+public class DefaultPmListFactory {
+
+    private static final Logger LOG = LoggerFactory.getLogger(DefaultPmListFactory.class);
+
+    /**
+     * Returns a new instance of {@link CurrentPmlist} from the loaded XML stored
+     * in File.
+     *
+     * @return {@link CurrentPmlist}
+     */
+    public CurrentPmList createDefaultPmList(DataStoreContext dataStoreContextUtil, File pm_data_config) {
+       CurrentPmList result = null;
+        if (pm_data_config.exists()) {
+            String config = pm_data_config.getName();
+            LOG.info("file with pm '{}' exists at location : {}", config, pm_data_config.getAbsolutePath());
+            InputStream targetStream;
+            try {
+                targetStream = new FileInputStream(pm_data_config);
+                Optional<NormalizedNode<?, ?>> transformIntoNormalizedNode = null;
+                transformIntoNormalizedNode =
+                        XMLDataObjectConverter.createWithDataStoreUtil(dataStoreContextUtil)
+                        .transformIntoNormalizedNode(targetStream);
+                if (!transformIntoNormalizedNode.isPresent()) {
+                    throw new IllegalStateException(String.format("Could not transform the input %s into normalized nodes",
+                            config));
+                }
+                Optional<DataObject> dataObject = XMLDataObjectConverter.createWithDataStoreUtil(dataStoreContextUtil)
+                        .getDataObject(transformIntoNormalizedNode.get(), CurrentPmList.QNAME);
+                if (!dataObject.isPresent()) {
+                    throw new IllegalStateException("Could not transform normalized nodes into data object");
+                }
+                result =  (CurrentPmList) dataObject.get();
+            } catch (FileNotFoundException | IllegalStateException e) {
+                LOG.error("File not found : {} at {}", e);
+            }
+        } else {
+            LOG.info("xml file not existed at : '{}'", pm_data_config.getAbsolutePath());
+        }
+        return result;
+    }
+    /**
+     * Returns a new instance of {@link CurrentPmlist} from the loaded XML stored
+     * in String.
+     *
+     * @return {@link CurrentPmlist}
+     */
+    public CurrentPmList createDefaultPmList(DataStoreContext dataStoreContextUtil, String pm_data_config) {
+       CurrentPmList result = null;
+        if (pm_data_config != null) {
+            LOG.info("Pm List data config string is ok ");
+            InputStream targetStream;
+            targetStream = new ByteArrayInputStream(pm_data_config.getBytes());
+            Optional<NormalizedNode<?, ?>> transformIntoNormalizedNode = null;
+            transformIntoNormalizedNode =
+                    XMLDataObjectConverter.createWithDataStoreUtil(dataStoreContextUtil)
+                    .transformIntoNormalizedNode(targetStream);
+            if (!transformIntoNormalizedNode.isPresent()) {
+                throw new IllegalStateException(String.format("Could not transform the input %s into normalized nodes"));
+            }
+            Optional<DataObject> dataObject = XMLDataObjectConverter.createWithDataStoreUtil(dataStoreContextUtil)
+                    .getDataObject(transformIntoNormalizedNode.get(), CurrentPmList.QNAME);
+            if (!dataObject.isPresent()) {
+                throw new IllegalStateException("Could not transform normalized nodes into data object");
+            }
+            result =  (CurrentPmList) dataObject.get();
+        } else {
+            LOG.info("pm data config string is null!");
+        }
+        return result;
+    }
+
+
+    /**
+     * create an XML String from an instance of {@link CurrentPmlist}.
+     *
+     */
+    public void createXMLFromPmList(DataStoreContext dataStoreContextUtil, CurrentPmList pm_list, String output) {
+        if (pm_list != null) {
+            Optional<NormalizedNode<?, ?>> transformIntoNormalizedNode = null;
+            transformIntoNormalizedNode =
+                    XMLDataObjectConverter.createWithDataStoreUtil(dataStoreContextUtil)
+                    .toNormalizedNodes(pm_list, CurrentPmList.class);
+            if (!transformIntoNormalizedNode.isPresent()) {
+                throw new IllegalStateException(String.format("Could not transform the input %s into normalized nodes",
+                        pm_list));
+            }
+            XMLDataObjectConverter createWithDataStoreUtil = XMLDataObjectConverter.createWithDataStoreUtil(dataStoreContextUtil);
+            Writer writerFromDataObject =
+                    createWithDataStoreUtil.writerFromDataObject(pm_list, CurrentPmList.class, createWithDataStoreUtil.dataContainer());
+            try {
+                BufferedWriter writer = new BufferedWriter(new FileWriter(output));
+                writer.write(writerFromDataObject.toString());
+                writer.close();
+            } catch (IOException e) {
+                LOG.error("Bufferwriter error ");
+            }
+            LOG.info("device xml : {}", writerFromDataObject.toString());
+        }
+    }
+}
diff --git a/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/write/DeviceChangeListener.java b/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/write/DeviceChangeListener.java
new file mode 100644 (file)
index 0000000..5975f44
--- /dev/null
@@ -0,0 +1,417 @@
+/*
+ * Copyright (c) 2018 Orange and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.transportpce.device.write;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.circuit.pack.Ports;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.circuit.pack.PortsBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.circuit.packs.CircuitPacks;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.circuit.packs.CircuitPacksKey;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.interfaces.grp.Interface;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.interfaces.grp.InterfaceKey;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.OrgOpenroadmDevice;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.OrgOpenroadmDeviceBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.org.openroadm.device.RoadmConnections;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.org.openroadm.device.RoadmConnectionsKey;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.port.Interfaces;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.port.InterfacesBuilder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Martial COULIBALY ( mcoulibaly.ext@orange.com ) on behalf of Orange
+ */
+final class DeviceChangeListener implements DataTreeChangeListener<OrgOpenroadmDevice> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(DeviceChangeListener.class);
+    private final DataBroker dataBroker;
+
+    public DeviceChangeListener(DataBroker deviceDataBroker) {
+        this.dataBroker = deviceDataBroker;
+        Preconditions.checkArgument(this.dataBroker != null, "Device datastore is null");
+    }
+
+    @Override
+    public void onDataTreeChanged(Collection<DataTreeModification<OrgOpenroadmDevice>> changes) {
+        LOG.info("onDataTreeChanged");
+        for (DataTreeModification<OrgOpenroadmDevice> change : changes) {
+            final DataObjectModification<OrgOpenroadmDevice> rootNode = change.getRootNode();
+            final DataTreeIdentifier<OrgOpenroadmDevice> rootPath = change.getRootPath();
+            if (rootNode != null ) {
+                final OrgOpenroadmDevice dataBefore = rootNode.getDataBefore();
+                final OrgOpenroadmDevice dataAfter = rootNode.getDataAfter();
+                LOG.info("Received Device change({}):\n before={} \n after={}", rootNode.getModificationType(), dataBefore,
+                        dataAfter);
+                Collection<DataObjectModification<? extends DataObject>> modifiedChildren = rootNode.getModifiedChildren();
+                switch (rootNode.getModificationType()) {
+                    case SUBTREE_MODIFIED:
+                        if (!modifiedChildren.isEmpty()) {
+                            Iterator<DataObjectModification<? extends DataObject>> iterator = modifiedChildren.iterator();
+                            while (iterator.hasNext()) {
+                                DataObjectModification<? extends DataObject> modified = iterator.next();
+                                LOG.info("modified = \ndataType : {}\nid : {}\nmodifiedType : {}\noldData : {}\nnewData : {} \n",
+                                        modified.getDataType(), modified.getIdentifier(),modified.getModificationType(),
+                                        modified.getDataBefore(), modified.getDataAfter());
+                                switch (modified.getModificationType()) {
+                                  case SUBTREE_MODIFIED:
+                                  case WRITE :
+                                      processChange(rootPath.getRootIdentifier(), modified, dataAfter);
+                                      updateCircuitPackInterface(rootPath.getRootIdentifier(), modified, false);
+                                      break;
+                                  case DELETE:
+                                      updateCircuitPackInterface(rootPath.getRootIdentifier(), modified, true);
+                                      deleteContainer(rootPath, modified);
+                                      break;
+                                  default:
+                                      break;
+                               }
+                            }
+                        }
+                        //processChange(rootPath.getRootIdentifier(), dataAfter);
+                        break;
+                    case WRITE :
+                        processChange(rootPath.getRootIdentifier(), null, dataAfter);
+                        break;
+                    case DELETE:
+                        LOG.info("device config datastore is deleted !");
+                        break;
+                    default:
+                        break;
+                }
+            } else {
+                LOG.error("rootNode is null !");
+            }
+        }
+    }
+
+    /**
+     * Delete change from device
+     * oper datastore.
+     *
+     * @param id container identifier
+     */
+    private void deleteContainer(DataTreeIdentifier<OrgOpenroadmDevice> rootPath,
+            DataObjectModification<? extends DataObject> modified) {
+        final String ROADM_CONNECTIONS = "interface org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019"
+                + ".org.openroadm.device.container.org.openroadm.device.RoadmConnections";
+        final String INTERFACE_GRP = "interface org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019"
+                + ".interfaces.grp.Interface";
+        Class<? extends DataObject> type = modified.getDataType();
+        PathArgument path = modified.getIdentifier();
+        LOG.info("deleting container type '{}' with id '{}' ...", type.toString(), path);
+        String key = extractKey(path.toString());
+        if ( key != null) {
+            InstanceIdentifier<?> iid = null;
+            switch (type.toString()) {
+                case ROADM_CONNECTIONS:
+                    LOG.info("roadm-connections ...");
+                    iid = rootPath.getRootIdentifier().child(RoadmConnections.class,
+                        new RoadmConnectionsKey(key));
+                    break;
+                case INTERFACE_GRP:
+                    LOG.info("interface ....");
+                    iid = rootPath.getRootIdentifier().child(Interface.class,
+                            new InterfaceKey(key));
+                default:
+                    break;
+            }
+            LOG.info("iid : {}", iid);
+            WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
+            if (writeTx != null) {
+                LOG.info("WriteTransaction is ok, delete container device from device oper datastore");
+                try {
+                    LOG.info("deleting container element from device oper DS ...");
+                    writeTx.delete(LogicalDatastoreType.OPERATIONAL, iid);
+                    Future<Void> future = writeTx.submit();
+                    future.get();
+                    LOG.info("container element '{}' deleted from device oper datastore", iid);
+                } catch (InterruptedException | ExecutionException e) {
+                    LOG.error("Failed to process WriteTransactions",e);
+                }
+            } else {
+                LOG.error("WriteTransaction object is null");
+            }
+        } else {
+            LOG.error("extract key is null");
+        }
+    }
+
+
+
+    private String extractKey(String path) {
+        LOG.info("getting key from pathArgument ...");
+        String result = null;
+        if (path != null && path.length() > 2) {
+            result = path.substring(path.lastIndexOf("=") + 1, path.length()-2);
+            LOG.info("result : {}", result);
+        } else {
+            LOG.error("String pathArgument is not compliant !!");
+        }
+        return result;
+    }
+
+
+    /**
+     * Merge change to Honeycomb
+     * config datastore and device
+     * config datastore.
+     *
+     * @param id OrgOpenroadmDevice identifier
+     * @param dataAfter OrgOpenroadmDevice to be merged
+     */
+    private void processChange(final InstanceIdentifier<OrgOpenroadmDevice> id,
+            DataObjectModification<? extends DataObject> modified, final OrgOpenroadmDevice dataAfter) {
+        LOG.info("processing change ...");
+        WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
+        if (writeTx != null) {
+            LOG.info("WriteTransactions are ok, merge device info to datastores");
+            if(dataAfter != null) {
+                String deviceId = dataAfter.getInfo().getNodeId().getValue();
+                writeTx.merge(LogicalDatastoreType.OPERATIONAL, id, dataAfter);
+                Future<Void> future = writeTx.submit();
+                try {
+                    future.get();
+                    LOG.info("device '{}' merged to device oper datastore", deviceId);
+                } catch (InterruptedException | ExecutionException e) {
+                    LOG.error("Failed to merge Element '{}' to datastores", deviceId);
+                }
+            } else {
+                LOG.error("device is null");
+            }
+        } else {
+            LOG.error("WriteTransaction object is null");
+        }
+    }
+
+    /**
+     *Update Interface info on
+     *Ports list in CircuitPacks.
+     *
+     * @param id device InstanceIdentifier
+     * @param modified DataObjectModification
+     * @param deviceData OrgOpenroadmDevice
+     * @param delete if yes delete interface from circuitpacks else adding interface
+     */
+    private void updateCircuitPackInterface(final InstanceIdentifier<OrgOpenroadmDevice> id,
+            DataObjectModification<? extends DataObject> modified, boolean delete) {
+        LOG.info("Updating circuit packs interface ...");
+        final String INTERFACE_GRP = "interface org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019"
+                + ".interfaces.grp.Interface";
+        InstanceIdentifier<CircuitPacks> iid = null;
+        if (modified != null) {
+            Class<? extends DataObject> type = modified.getDataType();
+            LOG.info("getting container type '{}' ...", type.toString());
+            if (type != null) {
+                if (type.toString().compareTo(INTERFACE_GRP) == 0) {
+                    LOG.warn("interface update ! ");
+                    Interface data = null;
+                    if (delete) {
+                        data = (Interface) modified.getDataBefore();
+                    } else {
+                        data = (Interface) modified.getDataAfter();
+                    }
+                    LOG.info("Interface data gets : {}", data.toString());
+                    if (data!= null) {
+                        String circuitPackName = data.getSupportingCircuitPackName();
+                        String port = data.getSupportingPort().toString();
+                        String interfaceName = data.getName();
+                        if (circuitPackName != null && port != null && interfaceName != null) {
+                            iid = id.child(CircuitPacks.class,
+                                    new CircuitPacksKey(circuitPackName));
+                            OrgOpenroadmDevice operDevice = readDeviceOperData(id);
+                            if (operDevice != null) {
+                                OrgOpenroadmDeviceBuilder builder = new OrgOpenroadmDeviceBuilder(operDevice);
+                                List<CircuitPacks> list = builder.getCircuitPacks();
+                                LOG.info("Getting circuit packs ...");
+                                for (CircuitPacks circuitPacks : list) {
+                                    if (circuitPacks.getCircuitPackName().compareTo(circuitPackName) == 0) {
+                                        LOG.info("circuitpack found");
+                                        List<Ports> portList = circuitPacks.getPorts();
+                                        LOG.info("Getting ports for circuit pack '{}' ...", circuitPackName);
+                                        for (Ports ports : portList) {
+                                            if (ports.getPortName().compareTo(port) == 0) {
+                                                LOG.info("port found");
+                                                PortsBuilder newPorts = new PortsBuilder(ports);
+                                                List<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019
+                                                .port.Interfaces> value = newPorts.getInterfaces();
+                                                if (!delete) {
+                                                    LOG.info("adding interface info to port '{}'", port);
+                                                    if (value == null || value.isEmpty()) {
+                                                        LOG.info("Interfaces List is empty !");
+                                                        value = new ArrayList<org.opendaylight.yang.gen.v1.http.org
+                                                                .openroadm.device.rev181019.port.Interfaces>();
+                                                        value.add(new InterfacesBuilder().setInterfaceName(interfaceName)
+                                                                .build());
+                                                    } else { // value is not empty
+                                                        org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019
+                                                        .port.Interfaces tmp = getInterfaces(value, interfaceName);
+                                                        if( tmp != null) {
+                                                            LOG.warn("Interfaces with name '{}' already exists !",interfaceName);
+                                                            break;
+                                                        } else { // no interface found
+                                                            value.add(new InterfacesBuilder().setInterfaceName(interfaceName)
+                                                                    .build());
+                                                        }
+                                                    }
+                                                } else {
+                                                    LOG.info("removing interface info from port '{}'", port);
+                                                    org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019
+                                                    .port.Interfaces tmp = getInterfaces(value, interfaceName);
+                                                    if( tmp != null) {
+                                                        LOG.info("Interfaces with name '{}' gets",interfaceName);
+                                                        value.remove(tmp);
+                                                    }else {
+                                                        LOG.error("Interfaces list is null");
+                                                        value = new ArrayList<org.opendaylight.yang.gen.v1.http.org.openroadm
+                                                                .device.rev181019.port.Interfaces>();
+                                                    }
+                                                }
+                                                newPorts.setInterfaces(value);
+                                                portList.remove(ports);
+                                                portList.add(newPorts.build());
+                                                LOG.info("port list updated !");
+                                                update(circuitPacks, iid);
+                                                break;
+                                            }
+                                        }
+                                        break;
+                                    }
+                                }
+                            } else {
+                                LOG.error("reading operational device data failed !");
+                            }
+
+                        } else {
+                            LOG.error("SupportingCircuitPackName / SupportingPort / Interface Name are/is null !");
+                        }
+                    }
+                } else {
+                    LOG.warn("not an interface update ! ");
+                }
+            }
+        } else {
+            LOG.error("DataObjectModification is null");
+        }
+    }
+
+    /**
+     * Search in {@link Interfaces} list
+     * if an interfaces already exists.
+     *
+     * @param value Interfaces List
+     * @param interfaceName Interface Name
+     * @return Interfaces
+     */
+    private org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.port.Interfaces getInterfaces(
+            List<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.port.Interfaces> value,
+            String interfaceName) {
+        org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.port.Interfaces result = null;
+        if (value != null && !value.isEmpty()) {
+            LOG.info("Getting interfaces list ...");
+            for (org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019
+                    .port.Interfaces tmp : value) {
+                if( tmp != null
+                        && tmp.getInterfaceName().compareTo(interfaceName) == 0) {
+                    LOG.info("Interfaces with name '{}' gets",interfaceName);
+                    result = tmp;
+                    break;
+                }
+            }
+        } else {
+            LOG.error("Interfaces list is empty");
+        }
+        return result;
+    }
+
+    /**
+     * Update circuitPacks information
+     * in device oper datastore.
+     *
+     * @param circuitPacks CircuitPacks data
+     * @param iid CircuitPacks InstanceIdentifier
+     * @param id OrgOpenroadmDevice InstanceIdentifier
+     * @param deviceData OrgOpenroadmDevice data
+     */
+    private void update(CircuitPacks circuitPacks, final InstanceIdentifier<CircuitPacks> iid) {
+        LOG.info("updating oper Datastore with iid : {}", iid);
+        WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
+        if (writeTx != null) {
+            LOG.info("WriteTransaction is ok, update container circuitpacks from device oper datastore");
+            try {
+                LOG.info("updating container circuitpacks from device oper DS ...");
+                writeTx.merge(LogicalDatastoreType.OPERATIONAL, iid,circuitPacks);
+                Future<Void> future = writeTx.submit();
+                future.get();
+                LOG.info("container circuitpacks '{}' merged to device oper datastore", iid);
+            } catch (InterruptedException | ExecutionException e) {
+                LOG.error("Failed to process WriteTransactions",e);
+            }
+        } else {
+            LOG.error("WriteTransaction object is null");
+        }
+    }
+
+    /**
+     * Get {@link OrgOpenroadmDevice} data
+     * from operational datastore
+     *
+     * @param id OrgOpenroadmDevice InstanceIdentifier
+     * @return OrgOpenroadmDevice result
+     */
+    private OrgOpenroadmDevice readDeviceOperData(final InstanceIdentifier<OrgOpenroadmDevice> id) {
+        OrgOpenroadmDevice result = null;
+        LOG.info("reading device operational datastore ...");
+        ReadTransaction readTx = this.dataBroker.newReadOnlyTransaction();
+        if (readTx != null) {
+            LOG.info("ReadTransaction is ok");
+            try {
+                LOG.info("reading device from device oper DS ...");
+                Optional<OrgOpenroadmDevice> device = readTx.read(LogicalDatastoreType.OPERATIONAL, id).get();
+                if (device.isPresent()) {
+                    result = device.get();
+                    LOG.info("device gets from device oper datastore");
+                }
+            } catch (InterruptedException | ExecutionException e) {
+                LOG.error("Failed to process ReadTransaction",e);
+            }
+        } else {
+            LOG.error("ReadTransaction object is null");
+        }
+        return result;
+
+    }
+
+}
diff --git a/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/write/DeviceWriterFactory.java b/tests/honeynode221/honeynode-plugin-impl/src/main/java/io/fd/honeycomb/transportpce/device/write/DeviceWriterFactory.java
new file mode 100644 (file)
index 0000000..794567d
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2018 Orange and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.transportpce.device.write;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+
+import io.fd.honeycomb.translate.util.write.BindingBrokerWriter;
+import io.fd.honeycomb.translate.write.WriterFactory;
+import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder;
+
+import javax.annotation.Nonnull;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.OrgOpenroadmDevice;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class DeviceWriterFactory implements WriterFactory {
+    private static final InstanceIdentifier<OrgOpenroadmDevice> DEVICE_CONTAINER_ID = InstanceIdentifier
+            .create(OrgOpenroadmDevice.class);
+
+
+    @Inject
+    @Named("device-databroker")
+    private DataBroker deviceDataBroker;
+
+    @Override
+    public void init(@Nonnull final ModifiableWriterRegistryBuilder registry) {
+        registry.wildcardedSubtreeAdd(new BindingBrokerWriter<>(DEVICE_CONTAINER_ID, deviceDataBroker));
+        deviceDataBroker.registerDataTreeChangeListener(new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
+                DEVICE_CONTAINER_ID), new DeviceChangeListener(deviceDataBroker));
+    }
+}
diff --git a/tests/honeynode221/honeynode-plugin-impl/src/main/resources/honeycomb-minimal-resources/config/device/NamespaceTrimmer.xslt b/tests/honeynode221/honeynode-plugin-impl/src/main/resources/honeycomb-minimal-resources/config/device/NamespaceTrimmer.xslt
new file mode 100644 (file)
index 0000000..7667f57
--- /dev/null
@@ -0,0 +1,39 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+    <xsl:template match="*/*/*" name="nodes">
+        <xsl:element name="{local-name()}">
+            <xsl:apply-templates select="@*|node()" />
+        </xsl:element>
+    </xsl:template>
+    <xsl:template match="*/*/*/*">
+        <xsl:if test="not(name(.)='type' or name(.)='lldp' or name(.)='ethernet' or name(.)='ots')">
+            <xsl:element name="{local-name()}">
+                <xsl:apply-templates select="@*|node()" />
+            </xsl:element>
+        </xsl:if>
+        <xsl:if test="name(.)='type'" xmlns="http://org/openroadm/device">
+            <type xmlns:openROADM-if="http://org/openroadm/interfaces">
+                <xsl:apply-templates select="@*|node()"/>
+            </type>
+        </xsl:if>
+        <xsl:if test="name(.)='ots'">
+            <ots xmlns="http://org/openroadm/optical-transport-interfaces">
+                <xsl:apply-templates select="@*|node()"/>
+            </ots>
+        </xsl:if>
+        <xsl:if test="name(.)='lldp'">
+            <lldp xmlns="http://org/openroadm/lldp">
+                <xsl:apply-templates select="@*|node()"/>
+            </lldp>
+        </xsl:if>
+        <xsl:if test="name(.)='ethernet'">
+            <ethernet xmlns="http://org/openroadm/ethernet-interfaces">
+                <xsl:apply-templates select="@*|node()"/>
+            </ethernet>
+        </xsl:if>
+    </xsl:template>
+    <xsl:template match="/">
+        <org-openroadm-device xmlns="http://org/openroadm/device">
+            <xsl:apply-templates select="*"/>
+        </org-openroadm-device>
+    </xsl:template>
+</xsl:stylesheet>
\ No newline at end of file
diff --git a/tests/honeynode221/honeynode-plugin-impl/src/main/resources/honeycomb-minimal-resources/config/device/OperToConfig.xsl b/tests/honeynode221/honeynode-plugin-impl/src/main/resources/honeycomb-minimal-resources/config/device/OperToConfig.xsl
new file mode 100644 (file)
index 0000000..81081bf
--- /dev/null
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<xsl:stylesheet version="1.0"\r
+xmlns:xsl="http://www.w3.org/1999/XSL/Transform"\r
+xmlns:d="urn:ietf:params:xml:ns:netconf:base:1.0"\r
+xmlns:oor="http://org/openroadm/device"\r
+exclude-result-prefixes="oor d">\r
+\r
+  <xsl:output method="xml" encoding="UTF-8" indent="yes"/>\r
+  \r
+  <xsl:template match="/">\r
+    <xsl:element name="config" namespace="urn:ietf:params:xml:ns:netconf:base:1.0">\r
+    <xsl:element name="org-openroadm-device" namespace="http://org/openroadm/device">\r
+    <xsl:element name="info">\r
+      <xsl:apply-templates select="d:data/oor:org-openroadm-device/oor:info"/>\r
+    </xsl:element>\r
+\r
+    <xsl:copy-of select="d:data/oor:org-openroadm-device/oor:users" />\r
+\r
+    <xsl:for-each select="d:data/oor:org-openroadm-device/oor:shelves">\r
+      <xsl:element name="shelves" >\r
+        <xsl:call-template name="shelve-body"/>\r
+      </xsl:element>\r
+    </xsl:for-each>\r
+\r
+    <xsl:for-each select="d:data/oor:org-openroadm-device/oor:circuit-packs">\r
+      <xsl:element name="circuit-packs" >\r
+        <xsl:call-template name="cp-body"/>\r
+      </xsl:element>\r
+    </xsl:for-each>\r
+    \r
+    <xsl:for-each select="d:data/oor:org-openroadm-device/oor:interface">\r
+        <xsl:element name="interface" namespace="http://org/openroadm/device">\r
+            <xsl:call-template name="inter-body"/>\r
+        </xsl:element>\r
+    </xsl:for-each>\r
+    \r
+    <xsl:for-each select="d:data/oor:org-openroadm-device/oor:protocols">\r
+        <xsl:element name="protocols" >\r
+            <xsl:call-template name="proto-body"/>\r
+        </xsl:element>\r
+    </xsl:for-each>\r
+\r
+    <xsl:for-each select="d:data/oor:org-openroadm-device/oor:degree">\r
+      <xsl:element name="degree" >\r
+        <xsl:call-template name="degree-body"/>\r
+      </xsl:element>\r
+    </xsl:for-each>\r
+\r
+    <xsl:for-each select="d:data/oor:org-openroadm-device/oor:shared-risk-group">\r
+      <xsl:element name="shared-risk-group" >\r
+        <xsl:call-template name="srg-body"/>\r
+      </xsl:element>\r
+    </xsl:for-each>\r
+\r
+    </xsl:element>\r
+    </xsl:element>\r
+  </xsl:template>\r
+  \r
+  <xsl:template match="oor:info">\r
+    <xsl:for-each select="./*">\r
+      <xsl:if test="name(.) = 'node-id' or name(.) = 'node-number' or name(.) = 'node-type' or name(.) = 'clli' or name(.) = 'ipAddress' or name(.) = 'prefix-length' or name(.) = 'defaultGateway' or name(.) = 'template' or name(.) = 'geoLocation'">\r
+        <xsl:copy-of select="." />\r
+      </xsl:if>\r
+     </xsl:for-each> \r
+  </xsl:template>\r
+\r
+  <xsl:template name="shelve-body">\r
+    <xsl:for-each select="./*">\r
+      <xsl:if test="name(.) ='shelf-name' or name(.) = 'shelf-type' or name(.) = 'rack' or name(.) = 'shelf-position' or name(.) = 'administrative-state' or name(.) = 'equipment-state' or name(.) = 'due-date'">\r
+        <xsl:copy-of select="." />\r
+      </xsl:if>\r
+    </xsl:for-each>\r
+  </xsl:template>\r
+\r
+  <xsl:template name="cp-body">\r
+    <xsl:for-each select="./*">\r
+      <xsl:if test="name(.) = 'circuit-pack-type' or name(.) = 'circuit-pack-product-code' or name(.) = 'circuit-pack-name' or name(.) = 'administrative-state' or name(.) = 'equipment-state' or name(.) = 'circuit-pack-mode' or name(.) = 'shelf' or name(.) = 'slot' or name(.) = 'subSlot' or name(.) = 'due-date' or name(.) = 'parent-circuit-pack'">\r
+        <xsl:copy-of select="." />\r
+      </xsl:if>\r
+      <xsl:if test="name(.) = 'ports'">\r
+        <xsl:for-each select=".">\r
+          <xsl:element name="ports" >\r
+            <xsl:call-template name="ports-body"/>\r
+          </xsl:element>\r
+        </xsl:for-each>\r
+      </xsl:if>\r
+     </xsl:for-each> \r
+  </xsl:template>\r
+\r
+  <xsl:template name="inter-body">\r
+    <xsl:for-each select="./*">\r
+        <xsl:if test="not(name(.) = 'operational-state' or name(.) = 'ethernet')">\r
+          <xsl:copy-of select="." />\r
+        </xsl:if>\r
+        <xsl:if test="name(.)='ethernet'">\r
+          <xsl:element name="ethernet">\r
+            <xsl:call-template name="eth-body"/>\r
+          </xsl:element>\r
+        </xsl:if>\r
+    </xsl:for-each>\r
+  </xsl:template>\r
+  \r
+   <xsl:template name="eth-body">\r
+    <xsl:for-each select="./*">\r
+      <xsl:if test="not(name(.) = 'curr-speed' or name(.)='curr-duplex') ">\r
+         <xsl:copy-of select="." />\r
+      </xsl:if>\r
+    </xsl:for-each>\r
+  </xsl:template>\r
+\r
+  <xsl:template name="proto-body">\r
+    <xsl:for-each select="./*">\r
+      <xsl:if test="name(.) = 'lldp'">\r
+        <xsl:for-each select=".">\r
+          <xsl:element name="lldp" >\r
+            <xsl:call-template name="lldp-body"/>\r
+          </xsl:element>\r
+        </xsl:for-each>\r
+      </xsl:if>\r
+     </xsl:for-each> \r
+  </xsl:template>\r
+\r
+  <xsl:template name="ports-body">\r
+    <xsl:for-each select="./*">\r
+      <xsl:if test="name(.) = 'port-name' or name(.) = 'port-type' or name(.) = 'port-qual' or name(.) = 'circuit-id' or name(.) = 'administrative-state' or name(.) = 'logical-connection-point' or name(.) = 'roadm-port' or name(.) = 'otdr-port' or name(.) = 'ila-port' ">\r
+         <xsl:copy-of select="." />\r
+      </xsl:if>\r
+    </xsl:for-each>\r
+  </xsl:template>\r
+  \r
+  <xsl:template name="lldp-body">\r
+    <xsl:for-each select="./*">\r
+      <xsl:if test="not(name(.) = 'nbr-list') ">\r
+         <xsl:copy-of select="." />\r
+      </xsl:if>\r
+    </xsl:for-each>\r
+  </xsl:template>\r
+  \r
+  <xsl:template name="degree-body">\r
+    <xsl:for-each select="./*">\r
+      <xsl:if test="not(name(.) = 'max-wavelengths')">\r
+         <xsl:copy-of select="." />\r
+      </xsl:if>\r
+    </xsl:for-each>\r
+  </xsl:template>\r
+\r
+  <xsl:template name="srg-body">\r
+    <xsl:for-each select="./*">\r
+      <xsl:if test="not(name(.) = 'max-add-drop-ports' or name(.) = 'wavelength-duplication' or name(.) = 'current-provisioned-add-drop-ports')">\r
+         <xsl:copy-of select="." />\r
+      </xsl:if>\r
+    </xsl:for-each>\r
+  </xsl:template>\r
+\r
+ </xsl:stylesheet>\r
diff --git a/tests/honeynode221/honeynode-plugin-impl/src/main/resources/honeycomb-minimal-resources/config/device/config.xsl b/tests/honeynode221/honeynode-plugin-impl/src/main/resources/honeycomb-minimal-resources/config/device/config.xsl
new file mode 100644 (file)
index 0000000..50350a8
--- /dev/null
@@ -0,0 +1,12 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+    <xsl:template match="@* | node()">
+        <xsl:copy>
+            <xsl:apply-templates select="@* | node()"/>
+        </xsl:copy>
+    </xsl:template>
+    <xsl:template match="/">
+        <config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+            <xsl:apply-templates/>
+        </config>
+    </xsl:template>
+</xsl:stylesheet>
\ No newline at end of file
diff --git a/tests/honeynode221/honeynode-plugin-impl/src/test/java/io/fd/honeycomb/transportpce/device/test/CreateDeviceFromXMLFileTest.java b/tests/honeynode221/honeynode-plugin-impl/src/test/java/io/fd/honeycomb/transportpce/device/test/CreateDeviceFromXMLFileTest.java
new file mode 100644 (file)
index 0000000..3b1ad87
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2018 Orange and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.transportpce.device.test;
+
+import io.fd.honeycomb.transportpce.device.tools.DefaultDeviceFactory;
+import io.fd.honeycomb.transportpce.test.common.DataStoreContext;
+import io.fd.honeycomb.transportpce.test.common.DataStoreContextImpl;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.OrgOpenroadmDevice;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Test to create {@link OrgOpenroadmDevice} object
+ * from xml file or String using Yangtools
+ *
+ * @author Martial COULIBALY ( martial.coulibaly@gfi.com ) on behalf of Orange
+ */
+@RunWith(Parameterized.class)
+public class CreateDeviceFromXMLFileTest {
+    private static final Logger LOG = LoggerFactory.getLogger(CreateDeviceFromXMLFileTest.class);
+    private static final String DEVICE_OPER_IN = "src/test/resources/oper-ROADMA.xml";
+    private String xml;
+
+
+    public CreateDeviceFromXMLFileTest(String xmlData) {
+        this.xml = xmlData;
+    }
+
+    @Parameterized.Parameters
+    public static Collection<Object[]> stringXML() {
+        return Arrays.asList(new Object[][]{
+            {DeviceOperToConfig.getDeviceFromXML(DeviceOperToConfig.operToConfig())}
+//                {DeviceOperToConfig.operToConfig()}
+
+        });
+    }
+
+    /**
+     * This test  create instance of
+     * {@link OrgOpenroadmDevice} with String xml
+     * from {@link DeviceOperToConfig#operToConfig()}
+     * function as parameters.
+     *
+     * @throws NullPointerException
+     */
+    @Test
+    public void createDeviceFromString() throws NullPointerException {
+        OrgOpenroadmDevice result = null;
+        LOG.info("Parameterized string is : {}", xml);
+        DataStoreContext dataStoreContextUtil = new DataStoreContextImpl();
+        DefaultDeviceFactory defaultDeviceFactory = new DefaultDeviceFactory();
+        result = defaultDeviceFactory.createDefaultDevice(dataStoreContextUtil,xml);
+        if (result != null) {
+            LOG.info("result info : {}", result.getInfo().getNodeId());
+            Assert.assertEquals("ROADMA", result.getInfo().getNodeId());
+        }
+        LOG.info("Test Succeed");
+    }
+
+
+    /**
+     * This test create Device from File
+     * located at {@link CreateDeviceFromXMLFileTest#DEVICE_OPER_IN}.
+     *
+     * @throws NullPointerException
+     */
+    @Test
+    public void createDeviceFromFile() throws NullPointerException{
+        LOG.info("test createDeviceFromFile ...");
+        OrgOpenroadmDevice result = null;
+        result = null;
+        File device_data = new File(DEVICE_OPER_IN);
+        DataStoreContext dataStoreContextUtil = new DataStoreContextImpl();
+        DefaultDeviceFactory defaultDeviceFactory = new DefaultDeviceFactory();
+        result = defaultDeviceFactory.createDefaultDevice(dataStoreContextUtil,device_data);
+        if (result != null) {
+            LOG.info("result info : {}", result.getInfo().getNodeId());
+            Assert.assertEquals("ROADMA", result.getInfo().getNodeId());
+        }
+        LOG.info("Test Succeed");
+    }
+}
\ No newline at end of file
diff --git a/tests/honeynode221/honeynode-plugin-impl/src/test/java/io/fd/honeycomb/transportpce/device/test/CreatePmListFromXMLFileTest.java b/tests/honeynode221/honeynode-plugin-impl/src/test/java/io/fd/honeycomb/transportpce/device/test/CreatePmListFromXMLFileTest.java
new file mode 100644 (file)
index 0000000..5495e75
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2018 Orange and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.transportpce.device.test;
+
+import io.fd.honeycomb.transportpce.device.tools.DefaultPmListFactory;
+import io.fd.honeycomb.transportpce.test.common.DataStoreContext;
+import io.fd.honeycomb.transportpce.test.common.DataStoreContextImpl;
+
+import java.io.File;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.pm.rev181019.CurrentPmList;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Test to create {@link CurrentPmlist} object
+ * from xml file or String using Yangtools
+ *
+ * @author Martial COULIBALY ( martial.coulibaly@gfi.com ) on behalf of Orange
+ */
+public class CreatePmListFromXMLFileTest {
+    private static final Logger LOG = LoggerFactory.getLogger(CreatePmListFromXMLFileTest.class);
+    private static final String PM_LIST_OPER_IN = "src/test/resources/oper-ROADMA-cpm.xml";
+
+    /**
+     * This test create Device from File
+     * located at {@link CreatePmListFromXMLFileTest#DEVICE_OPER_IN}.
+     *
+     * @throws NullPointerException
+     */
+    @Test
+    public void createPmListFromFile() throws NullPointerException{
+        LOG.info("test createPmListFromFile ...");
+        CurrentPmList result = null;
+        File pm_list_data = new File(PM_LIST_OPER_IN);
+        DataStoreContext dataStoreContextUtil = new DataStoreContextImpl();
+        DefaultPmListFactory defaultPmListFactory = new DefaultPmListFactory();
+        result = defaultPmListFactory.createDefaultPmList(dataStoreContextUtil,pm_list_data);
+        if (result != null) {
+            LOG.info("result pm list size : {}", result.getCurrentPmEntry().size());
+            Assert.assertEquals("result pm list size : {}", result.getCurrentPmEntry().size());
+        }
+        LOG.info("Test Succeed");
+    }
+}
\ No newline at end of file
diff --git a/tests/honeynode221/honeynode-plugin-impl/src/test/java/io/fd/honeycomb/transportpce/device/test/DeviceOperToConfig.java b/tests/honeynode221/honeynode-plugin-impl/src/test/java/io/fd/honeycomb/transportpce/device/test/DeviceOperToConfig.java
new file mode 100644 (file)
index 0000000..e14322e
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2018 Orange and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.transportpce.device.test;
+
+import io.fd.honeycomb.transportpce.device.tools.DefaultDeviceFactory;
+import io.fd.honeycomb.transportpce.device.tools.DefaultPmListFactory;
+import io.fd.honeycomb.transportpce.test.common.DataStoreContext;
+import io.fd.honeycomb.transportpce.test.common.DataStoreContextImpl;
+
+import java.io.File;
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.OrgOpenroadmDevice;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.pm.rev181019.CurrentPmList;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Converts XML Data operation file  to Configuration file.
+ *
+ * @author Martial COULIBALY ( mcoulibaly.ext@orange.com ) on behalf of Orange
+ */
+public class DeviceOperToConfig {
+    private static final Logger LOG = LoggerFactory.getLogger(DeviceOperToConfig.class);
+    private static final String DEVICE_OPER = "src/test/resources/oper-ROADMA.xml";
+    private static final String PM_LIST_OPER = "src/test/resources/oper-ROADMA-cpm.xml";
+    private static final String CONFIG_XSL = "src/main/resources/honeycomb-minimal-resources/config/device/config.xsl";
+    private static final String DEVICE_XSL = "src/main/resources/honeycomb-minimal-resources/config/device/OperToConfig.xsl";
+    private static final String NAMESPACE_TRIMER_XSL = "src/main/resources/honeycomb-minimal-resources/config/device/NamespaceTrimmer.xslt";
+
+
+    /**
+     * Convert data xml to config xml device.
+     *
+     * @return String result
+     */
+    public static String operToConfig() {
+        String result =null;
+        LOG.info("process to transform xml file ");
+        TransformerFactory factory = TransformerFactory.newInstance();
+        Source xslt = new StreamSource(new File(DEVICE_XSL));
+        Transformer transformer;
+        Source text;
+        StringWriter tmpwriter = new StringWriter();
+        StringReader reader;
+        try {
+            LOG.info("transforming xml data to config device ...");
+            transformer = factory.newTransformer(xslt);
+            text = new StreamSource(new File(DEVICE_OPER));
+            transformer.transform(text, new StreamResult(tmpwriter));
+            LOG.info("removing namespace ...");
+            xslt = new StreamSource(new File(NAMESPACE_TRIMER_XSL));
+            transformer = factory.newTransformer(xslt);
+            reader = new StringReader(tmpwriter.toString());
+            StringWriter device_config = new StringWriter();
+            text = new StreamSource(reader);
+            transformer.transform(text, new StreamResult(device_config));
+            //LOG.info("xml transformed : {}\n", device_config.toString());
+            result = device_config.toString();
+        } catch (TransformerException e) {
+            LOG.error("Transformer failed ");
+        }
+        return result;
+    }
+
+    public static String getDeviceFromXML(String xml) {
+        String config_result =null;
+        LOG.info("process to transform xml file to config data");
+        TransformerFactory factory = TransformerFactory.newInstance();
+        Source xslt = new StreamSource(new File(CONFIG_XSL));
+        Transformer transformer;
+        Source text;
+        StringWriter device_config = new StringWriter();
+        try {
+            LOG.info("transforming xml string to config device ...");
+            transformer = factory.newTransformer(xslt);
+            text = new StreamSource(new StringReader(xml));
+            transformer.transform(text, new StreamResult(device_config));
+            config_result = device_config.toString();
+            LOG.info(config_result);
+        } catch (TransformerException e) {
+            LOG.error("Transformer failed ");
+        }
+        return config_result;
+    }
+
+    public static void createDeviceFromString(String xml) throws NullPointerException {
+        OrgOpenroadmDevice result = null;
+        LOG.info("Parameterized string is : {}", xml);
+        DataStoreContext dataStoreContextUtil = new DataStoreContextImpl();
+        DefaultDeviceFactory defaultDeviceFactory = new DefaultDeviceFactory();
+        result = defaultDeviceFactory.createDefaultDevice(dataStoreContextUtil,xml);
+        if (result != null) {
+            LOG.info("result info : {}", result.getInfo().getNodeId());
+        } else {
+            LOG.error("failed !");
+        }
+
+    }
+
+    public static void createPmListFromFile() throws NullPointerException {
+        CurrentPmList result = null;
+        DataStoreContext dataStoreContextUtil = new DataStoreContextImpl();
+        DefaultPmListFactory defaultDeviceFactory = new DefaultPmListFactory();
+        result = defaultDeviceFactory.createDefaultPmList(dataStoreContextUtil,new File(PM_LIST_OPER));
+        if (result != null) {
+            LOG.info("result pm list size : {}", result.getCurrentPmEntry().size());
+        } else {
+            LOG.error("failed !");
+        }
+
+    }
+
+    public static void main(String[] args) {
+//        String xml = DeviceOperToConfig.getDeviceFromXML(DeviceOperToConfig.operToConfig());
+//        DeviceOperToConfig.createDeviceFromString(xml);
+        DeviceOperToConfig.createPmListFromFile();
+
+    }
+}
diff --git a/tests/honeynode221/honeynode-plugin-impl/src/test/java/io/fd/honeycomb/transportpce/device/test/DirectoryWatchTest.java b/tests/honeynode221/honeynode-plugin-impl/src/test/java/io/fd/honeycomb/transportpce/device/test/DirectoryWatchTest.java
new file mode 100644 (file)
index 0000000..0c02003
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2018 Orange and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.transportpce.device.test;
+
+import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
+import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
+import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.WatchEvent;
+import java.nio.file.WatchKey;
+import java.nio.file.WatchService;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Martial COULIBALY ( mcoulibaly.ext@orange.com ) on behalf of Orange
+ */
+public class DirectoryWatchTest {
+    private static final Logger LOG = LoggerFactory.getLogger(DirectoryWatchTest.class);
+    private static final String DATA_JSON = "/var/lib/honeycomb/persist/config/data.json";
+
+    public static void main(String[] args) {
+        File data = new File(DATA_JSON);
+        String parent = data.getParent();
+        LOG.info("data.json directory : {}",parent);
+        try {
+            WatchService watcher = FileSystems.getDefault().newWatchService();
+            Path dir = Paths.get(data.getParent());
+            dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
+            LOG.info("Watch Service registered for dir: {}", dir.getFileName());
+            while (true) {
+                WatchKey key;
+                try {
+                    key = watcher.take();
+                } catch (InterruptedException ex) {
+                    return;
+                }
+                for (WatchEvent<?> event : key.pollEvents()) {
+                    WatchEvent.Kind<?> kind = event.kind();
+                    @SuppressWarnings("unchecked")
+                    WatchEvent<Path> ev = (WatchEvent<Path>) event;
+                    Path fileName = ev.context();
+                    if (kind == ENTRY_MODIFY && fileName.toString().equals("data.json")) {
+                        LOG.info("My source file has changed ...");
+                        /**
+                         * merge honeycomb-config datastore to  device oper
+                         */
+                    }
+                }
+                boolean valid = key.reset();
+                if (!valid) {
+                    LOG.error("Key has been unregisterede");
+                    break;
+                }
+            }
+        } catch (IOException ex) {
+            LOG.error("WatchService Error",ex);
+        }
+    }
+
+}
diff --git a/tests/honeynode221/honeynode-plugin-impl/src/test/java/io/fd/honeycomb/transportpce/device/test/RestAPICallsTest.java b/tests/honeynode221/honeynode-plugin-impl/src/test/java/io/fd/honeycomb/transportpce/device/test/RestAPICallsTest.java
new file mode 100644 (file)
index 0000000..8ad450b
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2018 Orange and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.transportpce.device.test;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.Collection;
+
+import org.junit.Assert;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
+import org.junit.runners.Parameterized;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Martial COULIBALY ( mcoulibaly.ext@orange.com ) on behalf of Orange
+ */
+@RunWith(Parameterized.class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class RestAPICallsTest {
+    private static final String CONFIG_URI="http://localhost:8183/restconf/config/org-openroadm-device:org-openroadm-device";
+    private final String user = "admin";
+    private final String pass = "admin";
+    private String encodeUserPass;
+    private String uri;
+    private String input;
+    private static final Logger LOG = LoggerFactory.getLogger(RestAPICallsTest.class);
+
+    public RestAPICallsTest(String uriRest, String inputXml) {
+        uri = uriRest;
+        input = inputXml;
+        String usernameAndPassword = this.user+":"+this.pass;
+        try {
+            byte[] encodeBytes = Base64.getEncoder().encode(usernameAndPassword.getBytes());
+            this.encodeUserPass = new String(encodeBytes, "UTF-8");
+            LOG.info("encode : {}",encodeUserPass);
+        } catch (UnsupportedEncodingException e) {
+            LOG.error("encode usernameAndPassword failed !");
+        }
+    }
+
+    @Parameterized.Parameters
+    public static Collection<Object[]> stringXML() {
+        return Arrays.asList(new Object[][]{
+                {CONFIG_URI,DeviceOperToConfig.operToConfig()}
+        });
+    }
+
+    /**
+     *send PUT request via REST API.
+     *
+     * @param uri request url
+     * @return String response
+     * @throws IOException
+     */
+    @Test
+    public void test1Put() throws IOException {
+        URL url = new URL(uri);
+        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+        conn.setDoOutput(true);
+        conn.setRequestMethod("PUT");
+        conn.setRequestProperty ("Authorization", "Basic " + encodeUserPass);
+        conn.setRequestProperty("Content-Type", "application/xml");
+        LOG.info("input xml : {}",input);
+        if (input != null) {
+            OutputStream os = conn.getOutputStream();
+            os.write(input.getBytes());
+            os.flush();
+            Assert.assertEquals(HttpURLConnection.HTTP_CREATED,conn.getResponseCode());
+            conn.disconnect();
+        } else {
+            LOG.error("input xml gets is null !");
+        }
+        LOG.info("Test Succeed");
+    }
+
+    /**
+     * send GET request via REST API.
+     *
+     * @param uri request url
+     * @return String response
+     * @throws IOException
+     */
+    @Test
+    public void test2Get() throws IOException {
+        URL url = new URL(uri);
+        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+        conn.setRequestProperty ("Authorization", "Basic " + encodeUserPass);
+        conn.setRequestMethod("GET");
+        conn.setRequestProperty("Accept", "application/json");
+        Assert.assertEquals(HttpURLConnection.HTTP_OK,conn.getResponseCode());
+//        Assert.assertThat(result, CoreMatchers.containsString("org-openroadm-device"));
+        conn.disconnect();
+        LOG.info("Test Succeed");
+    }
+
+    /**
+     *send DELETE request via REST API.
+     *
+     * @param uri request url
+     * @return String response
+     * @throws IOException
+     */
+    @Test
+    public void test3Delete() throws IOException {
+        URL url = new URL(uri);
+        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+        conn.setDoOutput(true);
+        conn.setRequestMethod("DELETE");
+        conn.setRequestProperty ("Authorization", "Basic " + encodeUserPass);
+        Assert.assertEquals(HttpURLConnection.HTTP_OK,conn.getResponseCode());
+        conn.disconnect();
+    }
+}
\ No newline at end of file
diff --git a/tests/honeynode221/log/honeycomb/honeycomb.log b/tests/honeynode221/log/honeycomb/honeycomb.log
new file mode 100644 (file)
index 0000000..7ad36b9
--- /dev/null
@@ -0,0 +1,903 @@
+2019-05-20 16:18:33.915 CEST [main] INFO  io.fd.honeycomb.infra.distro.Main - Starting honeycomb
+2019-05-20 16:18:34.220 CEST [main] INFO  i.f.h.i.d.a.ActiveModuleProvider - Reading active modules configuration for distribution
+2019-05-20 16:18:34.248 CEST [main] INFO  i.f.h.t.device.DeviceModule - Initializing Device Module
+2019-05-20 16:18:34.259 CEST [main] INFO  i.f.h.t.d.c.DeviceConfigurationModule - Initializing Device Readers Module
+2019-05-20 16:18:34.262 CEST [main] INFO  i.f.h.t.d.c.PmConfigurationModule - Initializing Pm Readers Module
+2019-05-20 16:18:34.264 CEST [main] INFO  i.f.h.t.device.DeviceModule - Device Module intitailized !
+2019-05-20 16:18:34.264 CEST [main] INFO  i.f.h.t.d.c.NetconfConfigurationModule - Initializing Netconf Readers Module
+2019-05-20 16:18:34.266 CEST [main] INFO  i.f.h.t.device.DeviceModule - Netconf Module intitailized !
+2019-05-20 16:18:34.268 CEST [main] INFO  i.f.h.i.d.s.YangBindingProviderModule - Configuring YangBindingProviderModule
+2019-05-20 16:18:34.269 CEST [main] INFO  i.f.h.t.device.DeviceRpcModule - Initializing Device Rpcs Module
+2019-05-20 16:18:34.289 CEST [main] INFO  i.f.h.t.d.DeviceNotificationModule - Initializing Device Notification Module
+2019-05-20 16:18:34.292 CEST [main] INFO  i.f.h.t.device.DeviceWriterModule - Initializing Device Writers Module
+2019-05-20 16:18:34.302 CEST [main] INFO  i.f.h.n.n.NetconfReadersModule - Initializing NETCONF Northbound readers
+2019-05-20 16:18:34.305 CEST [main] INFO  i.f.h.n.netconf.NetconfModule - Starting NETCONF Northbound
+2019-05-20 16:18:34.434 CEST [main] INFO  i.f.h.t.device.DeviceReaderModule - Initializing Device, PM and Netconf Readers Module
+2019-05-20 16:18:34.625 CEST [main] INFO  i.f.h.i.d.a.ActiveModuleProvider - Reading active modules configuration for distribution
+2019-05-20 16:18:34.654 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: ModuleInfoBackedCtxProvider{writerFactories=io.fd.honeycomb.infra.distro.schema.YangModulesProvider$YangModules@447a020}
+2019-05-20 16:18:35.190 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.schema.SchemaServiceProvider@4c36250e
+2019-05-20 16:18:35.913 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataTreeProvider$ContextDataTreeProvider@6cc558c6
+2019-05-20 16:18:35.934 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.PersistingDataTreeProvider$ContextPersistingDataTreeProvider@63f259c3
+2019-05-20 16:18:35.934 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.context.ModifiableDTMgrProvider@3db972d2
+2019-05-20 16:18:35.935 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.schema.SerializerProvider@158f4cfe
+2019-05-20 16:18:36.211 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataTreeProvider$ConfigDataTreeProvider@1e7ab390
+2019-05-20 16:18:36.211 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.PersistingDataTreeProvider$ConfigPersistingDataTreeProvider@77774571
+2019-05-20 16:18:36.212 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataStoreProvider@62010f5c
+2019-05-20 16:18:36.223 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataStoreProvider@132e0cc
+2019-05-20 16:18:36.224 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.InmemoryDOMDataBrokerProvider@4745e9c
+2019-05-20 16:18:36.233 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.transportpce.device.DeviceBindingDataBrokerProvider@715b886f
+2019-05-20 16:18:36.236 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.config.WriterRegistryProvider@4228bf58
+2019-05-20 16:18:36.278 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.context.HoneycombContextDOMDataBrokerProvider@26ceffa8
+2019-05-20 16:18:36.279 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.BindingDataBrokerProvider@4bc33720
+2019-05-20 16:18:36.279 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.ModifiableDTDelegProvider@67064bdc
+2019-05-20 16:18:36.280 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataStoreProvider@7c8c9a05
+2019-05-20 16:18:36.280 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataStoreProvider@5c2375a9
+2019-05-20 16:18:36.280 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.InmemoryDOMDataBrokerProvider@1b7a52dd
+2019-05-20 16:18:36.280 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.BindingDataBrokerProvider@5ad5be4a
+2019-05-20 16:18:36.280 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfMonitoringReaderFactoryProvider@737d100a
+2019-05-20 16:18:36.281 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfNotificationsReaderFactoryProvider@3af7d855
+2019-05-20 16:18:42.454 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.oper.ReaderRegistryProvider@1768c0b3
+2019-05-20 16:18:42.458 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - writting xml file data to oper datastore
+2019-05-20 16:18:42.458 CEST [main] INFO  i.f.h.t.d.t.DefaultDeviceFactory - file 'oper-XPDRA.xml' exists at location : /home/gilles/git/01/transportpce/tests/honeynode221/honeynode-distribution/target/honeynode-distribution-1.18.01-hc/honeynode-distribution-1.18.01/config/device/oper-XPDRA.xml
+2019-05-20 16:18:42.569 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - result info : NodeIdType [_value=XPDR-A1]
+2019-05-20 16:18:42.569 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - Getting device info from xml file for device 'XPDR-A1'
+2019-05-20 16:18:42.646 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - WriteTransaction is ok, copy device info to oper datastore
+2019-05-20 16:18:43.468 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - device 'XPDR-A1' writed to oper datastore
+2019-05-20 16:18:43.468 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - writting netconf state to oper datastore
+2019-05-20 16:18:43.469 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - Loading models from directory.
+2019-05-20 16:18:43.469 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - folder '/home/gilles/git/01/transportpce/tests/honeynode221/honeynode-distribution/target/honeynode-distribution-1.18.01-hc/honeynode-distribution-1.18.01/config/yang' exists !
+2019-05-20 16:18:43.771 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - WriteTransaction is ok, copy device info to oper datastore
+2019-05-20 16:18:43.827 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - netconf state writed to oper datastore
+2019-05-20 16:18:43.827 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - writting netconf stream to oper datastore
+2019-05-20 16:18:43.827 CEST [main] INFO  i.f.h.t.d.t.DefaultNetconfFactory - file 'oper-XPDRA.xml' exists at location : /home/gilles/git/01/transportpce/tests/honeynode221/honeynode-distribution/target/honeynode-distribution-1.18.01-hc/honeynode-distribution-1.18.01/config/device/oper-XPDRA.xml
+2019-05-20 16:18:43.846 CEST [main] INFO  i.f.h.t.d.c.NetconfConfiguration - netconf streams result : Streams{getStream=[Stream{getName=StreamNameType [_value=OPENROADM], augmentations={}}], augmentations={}}
+2019-05-20 16:18:43.847 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - Netconf Data gets from xml file is present
+2019-05-20 16:18:43.848 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - WriteTransaction is ok
+2019-05-20 16:18:43.857 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - netconf stream writed to oper datastore
+2019-05-20 16:18:43.857 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - loading device configuration info from xml file...
+2019-05-20 16:18:43.857 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - process to transform xml file 
+2019-05-20 16:18:43.860 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - transforming xml data to config device ...
+2019-05-20 16:18:43.972 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - removing namespace ...
+2019-05-20 16:18:43.988 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - device info gets from xml file !
+2019-05-20 16:18:43.988 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - process to transform xml file to config data
+2019-05-20 16:18:43.989 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - transforming xml string to config device ...
+2019-05-20 16:18:43.997 CEST [main] INFO  i.f.h.t.d.t.DefaultDeviceFactory - device data config string is ok 
+2019-05-20 16:18:44.002 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - result info : NodeIdType [_value=XPDR-A1]
+2019-05-20 16:18:44.003 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - OrgOpenroadmDevice info gets : NodeIdType [_value=XPDR-A1]
+2019-05-20 16:18:44.003 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - WriteTransaction is ok, copy device info to config datastore
+2019-05-20 16:18:44.013 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - device writed to config datastore
+2019-05-20 16:18:44.014 CEST [main] INFO  i.f.h.t.device.read.PmReaderFactory - writting xml pm file data to oper datastore
+2019-05-20 16:18:44.014 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - onDataTreeChanged
+2019-05-20 16:18:44.014 CEST [main] INFO  i.f.h.t.d.t.DefaultPmListFactory - file with pm 'oper-XPDRA.xml' exists at location : /home/gilles/git/01/transportpce/tests/honeynode221/honeynode-distribution/target/honeynode-distribution-1.18.01-hc/honeynode-distribution-1.18.01/config/device/oper-XPDRA.xml
+2019-05-20 16:18:44.015 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - Received Device change(WRITE):
+ before=null 
+ after=OrgOpenroadmDevice{getCircuitPacks=[CircuitPacks{getCircuitPackMode=NORMAL, getCircuitPackName=1/0/3-PLUG-CLIENT, getCircuitPackProductCode=Client_P, getCircuitPackType=client_pluggable, getParentCircuitPack=ParentCircuitPack{getCircuitPackName=1/0, getCpSlotName=4, augmentations={}}, getPorts=[Ports{getAdministrativeState=InService, getPortName=C1, getPortQual=XpdrClient, getPortType=QSFP28, augmentations={}}], getShelf=1, getSlot=1, getSubSlot=1, augmentations={}}, CircuitPacks{getAdministrativeState=InService, getCircuitPackMode=inServiceMode, getCircuitPackName=1/0, getCircuitPackProductCode=baseXPDR, getCircuitPackType=Base_transponder_circuit_pack, getShelf=1, getSlot=1, augmentations={}}, CircuitPacks{getCircuitPackMode=NORMAL, getCircuitPackName=1/0/1-PLUG-CLIENT, getCircuitPackProductCode=Client_P, getCircuitPackType=client_pluggable, getParentCircuitPack=ParentCircuitPack{getCircuitPackName=1/0, getCpSlotName=2, augmentations={}}, getPorts=[Ports{getAdministrativeState=InService, getPortName=C1, getPortQual=XpdrClient, getPortType=QSFP28, augmentations={}}], getShelf=1, getSlot=1, getSubSlot=1, augmentations={}}, CircuitPacks{getCircuitPackMode=NORMAL, getCircuitPackName=1/0/1-PLUG-NET, getCircuitPackProductCode=Line_NW_P, getCircuitPackType=line_pluggable, getParentCircuitPack=ParentCircuitPack{getCircuitPackName=1/0, getCpSlotName=1, augmentations={}}, getPorts=[Ports{getAdministrativeState=InService, getPortName=1, getPortQual=XpdrNetwork, getPortType=CFP2, augmentations={}}], getShelf=1, getSlot=1, getSubSlot=1, augmentations={}}, CircuitPacks{getCircuitPackMode=NORMAL, getCircuitPackName=1/0/2-PLUG-NET, getCircuitPackProductCode=Line_NW_P, getCircuitPackType=line_pluggable, getParentCircuitPack=ParentCircuitPack{getCircuitPackName=1/0, getCpSlotName=3, augmentations={}}, getPorts=[Ports{getAdministrativeState=InService, getPortName=1, getPortQual=XpdrNetwork, getPortType=CFP2, augmentations={}}], getShelf=1, getSlot=1, getSubSlot=1, augmentations={}}], getInfo=Info{getClli=NodeC, getDefaultGateway=IpAddress [_ipv4Address=Ipv4Address [_value=1.2.3.4]], getGeoLocation=GeoLocation{getLatitude=1.0000, getLongitude=2.0000, augmentations={}}, getIpAddress=IpAddress [_ipv4Address=Ipv4Address [_value=1.2.3.4]], getNodeId=NodeIdType [_value=XPDR-A1], getNodeNumber=1, getNodeType=Xpdr, getPrefixLength=24, getTemplate=template_TRANSPONDER, augmentations={}}, getShelves=[Shelves{getAdministrativeState=InService, getDueDate=DateAndTime [_value=2017-02-24T15:56:10+00:00], getRack=XYZ, getShelfName=1, getShelfPosition=1, getShelfType=pizza, augmentations={}}], getUsers=Users{getUser=[User{getGroup=Sudo, getName=UsernameType [_value=openroadm], getPassword=PasswordType [_value=openroadm], augmentations={}}], augmentations={}}, augmentations={}}
+2019-05-20 16:18:44.025 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - processing change ...
+2019-05-20 16:18:44.025 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - WriteTransactions are ok, merge device info to datastores
+2019-05-20 16:18:44.031 CEST [main] INFO  i.f.h.t.d.c.PmConfiguration - result pm list size : 1
+2019-05-20 16:18:44.031 CEST [main] INFO  i.f.h.t.device.read.PmReaderFactory - Getting pm info from xml file for device 
+2019-05-20 16:18:44.032 CEST [main] INFO  i.f.h.t.device.read.PmReaderFactory - WriteTransaction is ok, copy currentPmList to oper datastore
+2019-05-20 16:18:44.033 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - device 'XPDR-A1' merged to device oper datastore
+2019-05-20 16:18:44.083 CEST [main] INFO  i.f.h.t.device.read.PmReaderFactory - currentPmList writed to oper datastore
+2019-05-20 16:18:44.090 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.oper.ReadableDTDelegProvider@121bacf4
+2019-05-20 16:18:44.093 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfBindingBrokerProvider@258cb16c
+2019-05-20 16:18:44.094 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfNotificationMapperProvider@2966695e
+2019-05-20 16:18:44.102 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.RpcRegistryBuilderProvider@1d8264c9
+2019-05-20 16:18:44.103 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.RpcRegistryProvider@59e182
+2019-05-20 16:18:44.104 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.HoneycombDOMRpcServiceProvider@138c53c7
+2019-05-20 16:18:44.105 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfMdsalMapperProvider@1eee885c
+2019-05-20 16:18:44.116 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfMonitoringServiceProvider@61ed43ae
+2019-05-20 16:18:44.128 CEST [main] INFO  o.o.n.i.o.NetconfSessionMonitoringService - Scheduling thread pool is present = false, update interval 0: /netconf-state/sessions won't be updated.
+2019-05-20 16:18:44.129 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfMonitoringMapperProvider@655936bd
+2019-05-20 16:18:44.150 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DOMNotificationServiceProvider@647407b4
+2019-05-20 16:18:44.162 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.HoneycombNotificationManagerProvider@b6b8632
+2019-05-20 16:18:44.165 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.HoneycombNotification2NetconfProvider@52b31599
+2019-05-20 16:18:44.172 CEST [main] INFO  i.f.h.n.n.HoneycombNotification2NetconfProvider - Exposing HONEYCOMB_NETCONF notification stream: honeycomb
+2019-05-20 16:18:44.172 CEST [pool-18-thread-3] INFO  i.f.h.t.d.n.DeviceNotificationProducer - Starting notification stream for OrgOpenroadmDevice
+2019-05-20 16:18:44.173 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NettyThreadGroupProvider@66df0533
+2019-05-20 16:18:44.174 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - onDataTreeChanged
+2019-05-20 16:18:44.174 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - transforming changes to notification...
+2019-05-20 16:18:44.174 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - Received Device change :
+WRITE
+2019-05-20 16:18:44.175 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - device operational datastore is created !
+2019-05-20 16:18:44.175 CEST [operational-DCL-0] WARN  i.f.h.t.d.n.DeviceNotificationProducer - edit List is empty !
+2019-05-20 16:18:44.175 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - Emitting notification : null
+2019-05-20 16:18:44.175 CEST [operational-DCL-0] WARN  i.f.h.t.d.n.DeviceNotificationProducer - Failed to emit notification
+2019-05-20 16:18:44.208 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfServerDispatcherProvider@519910b2
+2019-05-20 16:18:44.212 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfTcpServerProvider@273b3afc
+2019-05-20 16:18:44.213 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfSshServerProvider@444dac3f
+2019-05-20 16:18:44.213 CEST [main] INFO  i.f.h.n.n.NetconfSshServerProvider - Starting NETCONF SSH
+2019-05-20 16:18:44.273 CEST [main] WARN  io.netty.bootstrap.ServerBootstrap - Unknown channel option 'SO_BACKLOG' for channel '[id: 0x17b553fd]'
+2019-05-20 16:18:44.545 CEST [main] INFO  io.fd.honeycomb.infra.distro.Main - Initializing configuration
+2019-05-20 16:18:44.545 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.context.PersistedContextInitializerProvider@226ddb69
+2019-05-20 16:18:44.547 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.PersistedConfigInitializerProvider@5f666412
+2019-05-20 16:18:44.547 CEST [main] INFO  i.f.h.i.d.d.PersistedConfigInitializerProvider - RestoringInitializer ...
+2019-05-20 16:18:44.547 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.initializer.ModifiableDTDelegInitProvider@1ce6c617
+2019-05-20 16:18:44.548 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.HoneycombDOMDataBrokerProvider@2d1e3187
+2019-05-20 16:18:44.548 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.BindingDataBrokerProvider@26308d2a
+2019-05-20 16:18:44.548 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.context.RealtimeMappingContextProvider@38f3ef54
+2019-05-20 16:18:44.549 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.initializer.InitializerRegistryAdapterProvider@f32397
+2019-05-20 16:18:44.549 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Config initialization started
+2019-05-20 16:18:44.549 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Persisted context restored successfully
+2019-05-20 16:18:44.550 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Configuration initialized successfully
+2019-05-20 16:18:44.550 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Persisted configuration restored successfully
+2019-05-20 16:18:44.550 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Honeycomb initialized
+2019-05-20 16:18:44.550 CEST [main] INFO  io.fd.honeycomb.infra.distro.Main - Configuration initialized successfully
+2019-05-20 16:18:44.550 CEST [main] INFO  io.fd.honeycomb.infra.distro.Main - Honeycomb started successfully!
+2019-05-20 16:18:44.629 CEST [netconf-netty-0] INFO  i.f.h.n.n.NetconfSshServerProvider - Netconf SSH endpoint started successfully at /0.0.0.0:17840
+2019-05-20 16:19:32.923 CEST [main] INFO  io.fd.honeycomb.infra.distro.Main - Starting honeycomb
+2019-05-20 16:19:33.233 CEST [main] INFO  i.f.h.i.d.a.ActiveModuleProvider - Reading active modules configuration for distribution
+2019-05-20 16:19:33.261 CEST [main] INFO  i.f.h.t.device.DeviceModule - Initializing Device Module
+2019-05-20 16:19:33.272 CEST [main] INFO  i.f.h.t.d.c.DeviceConfigurationModule - Initializing Device Readers Module
+2019-05-20 16:19:33.275 CEST [main] INFO  i.f.h.t.d.c.PmConfigurationModule - Initializing Pm Readers Module
+2019-05-20 16:19:33.278 CEST [main] INFO  i.f.h.t.device.DeviceModule - Device Module intitailized !
+2019-05-20 16:19:33.278 CEST [main] INFO  i.f.h.t.d.c.NetconfConfigurationModule - Initializing Netconf Readers Module
+2019-05-20 16:19:33.280 CEST [main] INFO  i.f.h.t.device.DeviceModule - Netconf Module intitailized !
+2019-05-20 16:19:33.281 CEST [main] INFO  i.f.h.i.d.s.YangBindingProviderModule - Configuring YangBindingProviderModule
+2019-05-20 16:19:33.283 CEST [main] INFO  i.f.h.t.device.DeviceRpcModule - Initializing Device Rpcs Module
+2019-05-20 16:19:33.304 CEST [main] INFO  i.f.h.t.d.DeviceNotificationModule - Initializing Device Notification Module
+2019-05-20 16:19:33.306 CEST [main] INFO  i.f.h.t.device.DeviceWriterModule - Initializing Device Writers Module
+2019-05-20 16:19:33.316 CEST [main] INFO  i.f.h.n.n.NetconfReadersModule - Initializing NETCONF Northbound readers
+2019-05-20 16:19:33.319 CEST [main] INFO  i.f.h.n.netconf.NetconfModule - Starting NETCONF Northbound
+2019-05-20 16:19:33.450 CEST [main] INFO  i.f.h.t.device.DeviceReaderModule - Initializing Device, PM and Netconf Readers Module
+2019-05-20 16:19:33.647 CEST [main] INFO  i.f.h.i.d.a.ActiveModuleProvider - Reading active modules configuration for distribution
+2019-05-20 16:19:33.677 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: ModuleInfoBackedCtxProvider{writerFactories=io.fd.honeycomb.infra.distro.schema.YangModulesProvider$YangModules@447a020}
+2019-05-20 16:19:34.212 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.schema.SchemaServiceProvider@4c36250e
+2019-05-20 16:19:34.946 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataTreeProvider$ContextDataTreeProvider@6cc558c6
+2019-05-20 16:19:34.967 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.PersistingDataTreeProvider$ContextPersistingDataTreeProvider@63f259c3
+2019-05-20 16:19:34.967 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.context.ModifiableDTMgrProvider@3db972d2
+2019-05-20 16:19:34.968 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.schema.SerializerProvider@158f4cfe
+2019-05-20 16:19:35.255 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataTreeProvider$ConfigDataTreeProvider@77774571
+2019-05-20 16:19:35.255 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.PersistingDataTreeProvider$ConfigPersistingDataTreeProvider@6cd64ee8
+2019-05-20 16:19:35.256 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataStoreProvider@62010f5c
+2019-05-20 16:19:35.268 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataStoreProvider@132e0cc
+2019-05-20 16:19:35.268 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.InmemoryDOMDataBrokerProvider@75de29c0
+2019-05-20 16:19:35.277 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.transportpce.device.DeviceBindingDataBrokerProvider@1e253c9d
+2019-05-20 16:19:35.281 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.config.WriterRegistryProvider@20b9d5d5
+2019-05-20 16:19:35.322 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.context.HoneycombContextDOMDataBrokerProvider@26ceffa8
+2019-05-20 16:19:35.322 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.BindingDataBrokerProvider@67064bdc
+2019-05-20 16:19:35.322 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.ModifiableDTDelegProvider@18578491
+2019-05-20 16:19:35.323 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataStoreProvider@7c8c9a05
+2019-05-20 16:19:35.323 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataStoreProvider@5c2375a9
+2019-05-20 16:19:35.324 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.InmemoryDOMDataBrokerProvider@5ad5be4a
+2019-05-20 16:19:35.324 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.BindingDataBrokerProvider@737d100a
+2019-05-20 16:19:35.324 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfMonitoringReaderFactoryProvider@6535117e
+2019-05-20 16:19:35.324 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfNotificationsReaderFactoryProvider@f88bfbe
+2019-05-20 16:19:40.467 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.oper.ReaderRegistryProvider@287213ac
+2019-05-20 16:19:40.471 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - writting xml file data to oper datastore
+2019-05-20 16:19:40.471 CEST [main] INFO  i.f.h.t.d.t.DefaultDeviceFactory - file 'oper-XPDRA.xml' exists at location : /home/gilles/git/01/transportpce/tests/honeynode221/honeynode-distribution/target/honeynode-distribution-1.18.01-hc/honeynode-distribution-1.18.01/config/device/oper-XPDRA.xml
+2019-05-20 16:19:40.568 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - result info : NodeIdType [_value=XPDR-A1]
+2019-05-20 16:19:40.568 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - Getting device info from xml file for device 'XPDR-A1'
+2019-05-20 16:19:40.621 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - WriteTransaction is ok, copy device info to oper datastore
+2019-05-20 16:19:40.967 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - device 'XPDR-A1' writed to oper datastore
+2019-05-20 16:19:40.967 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - writting netconf state to oper datastore
+2019-05-20 16:19:40.967 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - Loading models from directory.
+2019-05-20 16:19:40.968 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - folder '/home/gilles/git/01/transportpce/tests/honeynode221/honeynode-distribution/target/honeynode-distribution-1.18.01-hc/honeynode-distribution-1.18.01/config/yang' exists !
+2019-05-20 16:19:41.211 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - WriteTransaction is ok, copy device info to oper datastore
+2019-05-20 16:19:41.271 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - netconf state writed to oper datastore
+2019-05-20 16:19:41.271 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - writting netconf stream to oper datastore
+2019-05-20 16:19:41.272 CEST [main] INFO  i.f.h.t.d.t.DefaultNetconfFactory - file 'oper-XPDRA.xml' exists at location : /home/gilles/git/01/transportpce/tests/honeynode221/honeynode-distribution/target/honeynode-distribution-1.18.01-hc/honeynode-distribution-1.18.01/config/device/oper-XPDRA.xml
+2019-05-20 16:19:41.299 CEST [main] INFO  i.f.h.t.d.c.NetconfConfiguration - netconf streams result : Streams{getStream=[Stream{getName=StreamNameType [_value=OPENROADM], augmentations={}}], augmentations={}}
+2019-05-20 16:19:41.302 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - Netconf Data gets from xml file is present
+2019-05-20 16:19:41.303 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - WriteTransaction is ok
+2019-05-20 16:19:41.313 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - netconf stream writed to oper datastore
+2019-05-20 16:19:41.313 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - loading device configuration info from xml file...
+2019-05-20 16:19:41.313 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - process to transform xml file 
+2019-05-20 16:19:41.316 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - transforming xml data to config device ...
+2019-05-20 16:19:41.435 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - removing namespace ...
+2019-05-20 16:19:41.451 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - device info gets from xml file !
+2019-05-20 16:19:41.452 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - process to transform xml file to config data
+2019-05-20 16:19:41.452 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - transforming xml string to config device ...
+2019-05-20 16:19:41.462 CEST [main] INFO  i.f.h.t.d.t.DefaultDeviceFactory - device data config string is ok 
+2019-05-20 16:19:41.467 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - result info : NodeIdType [_value=XPDR-A1]
+2019-05-20 16:19:41.467 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - OrgOpenroadmDevice info gets : NodeIdType [_value=XPDR-A1]
+2019-05-20 16:19:41.467 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - WriteTransaction is ok, copy device info to config datastore
+2019-05-20 16:19:41.477 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - device writed to config datastore
+2019-05-20 16:19:41.477 CEST [main] INFO  i.f.h.t.device.read.PmReaderFactory - writting xml pm file data to oper datastore
+2019-05-20 16:19:41.477 CEST [main] INFO  i.f.h.t.d.t.DefaultPmListFactory - file with pm 'oper-XPDRA.xml' exists at location : /home/gilles/git/01/transportpce/tests/honeynode221/honeynode-distribution/target/honeynode-distribution-1.18.01-hc/honeynode-distribution-1.18.01/config/device/oper-XPDRA.xml
+2019-05-20 16:19:41.478 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - onDataTreeChanged
+2019-05-20 16:19:41.480 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - Received Device change(WRITE):
+ before=null 
+ after=OrgOpenroadmDevice{getCircuitPacks=[CircuitPacks{getCircuitPackMode=NORMAL, getCircuitPackName=1/0/3-PLUG-CLIENT, getCircuitPackProductCode=Client_P, getCircuitPackType=client_pluggable, getParentCircuitPack=ParentCircuitPack{getCircuitPackName=1/0, getCpSlotName=4, augmentations={}}, getPorts=[Ports{getAdministrativeState=InService, getPortName=C1, getPortQual=XpdrClient, getPortType=QSFP28, augmentations={}}], getShelf=1, getSlot=1, getSubSlot=1, augmentations={}}, CircuitPacks{getAdministrativeState=InService, getCircuitPackMode=inServiceMode, getCircuitPackName=1/0, getCircuitPackProductCode=baseXPDR, getCircuitPackType=Base_transponder_circuit_pack, getShelf=1, getSlot=1, augmentations={}}, CircuitPacks{getCircuitPackMode=NORMAL, getCircuitPackName=1/0/1-PLUG-CLIENT, getCircuitPackProductCode=Client_P, getCircuitPackType=client_pluggable, getParentCircuitPack=ParentCircuitPack{getCircuitPackName=1/0, getCpSlotName=2, augmentations={}}, getPorts=[Ports{getAdministrativeState=InService, getPortName=C1, getPortQual=XpdrClient, getPortType=QSFP28, augmentations={}}], getShelf=1, getSlot=1, getSubSlot=1, augmentations={}}, CircuitPacks{getCircuitPackMode=NORMAL, getCircuitPackName=1/0/1-PLUG-NET, getCircuitPackProductCode=Line_NW_P, getCircuitPackType=line_pluggable, getParentCircuitPack=ParentCircuitPack{getCircuitPackName=1/0, getCpSlotName=1, augmentations={}}, getPorts=[Ports{getAdministrativeState=InService, getPortName=1, getPortQual=XpdrNetwork, getPortType=CFP2, augmentations={}}], getShelf=1, getSlot=1, getSubSlot=1, augmentations={}}, CircuitPacks{getCircuitPackMode=NORMAL, getCircuitPackName=1/0/2-PLUG-NET, getCircuitPackProductCode=Line_NW_P, getCircuitPackType=line_pluggable, getParentCircuitPack=ParentCircuitPack{getCircuitPackName=1/0, getCpSlotName=3, augmentations={}}, getPorts=[Ports{getAdministrativeState=InService, getPortName=1, getPortQual=XpdrNetwork, getPortType=CFP2, augmentations={}}], getShelf=1, getSlot=1, getSubSlot=1, augmentations={}}], getInfo=Info{getClli=NodeC, getDefaultGateway=IpAddress [_ipv4Address=Ipv4Address [_value=1.2.3.4]], getGeoLocation=GeoLocation{getLatitude=1.0000, getLongitude=2.0000, augmentations={}}, getIpAddress=IpAddress [_ipv4Address=Ipv4Address [_value=1.2.3.4]], getNodeId=NodeIdType [_value=XPDR-A1], getNodeNumber=1, getNodeType=Xpdr, getPrefixLength=24, getTemplate=template_TRANSPONDER, augmentations={}}, getShelves=[Shelves{getAdministrativeState=InService, getDueDate=DateAndTime [_value=2017-02-24T15:56:10+00:00], getRack=XYZ, getShelfName=1, getShelfPosition=1, getShelfType=pizza, augmentations={}}], getUsers=Users{getUser=[User{getGroup=Sudo, getName=UsernameType [_value=openroadm], getPassword=PasswordType [_value=openroadm], augmentations={}}], augmentations={}}, augmentations={}}
+2019-05-20 16:19:41.491 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - processing change ...
+2019-05-20 16:19:41.491 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - WriteTransactions are ok, merge device info to datastores
+2019-05-20 16:19:41.495 CEST [main] INFO  i.f.h.t.d.c.PmConfiguration - result pm list size : 1
+2019-05-20 16:19:41.495 CEST [main] INFO  i.f.h.t.device.read.PmReaderFactory - Getting pm info from xml file for device 
+2019-05-20 16:19:41.495 CEST [main] INFO  i.f.h.t.device.read.PmReaderFactory - WriteTransaction is ok, copy currentPmList to oper datastore
+2019-05-20 16:19:41.500 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - device 'XPDR-A1' merged to device oper datastore
+2019-05-20 16:19:41.533 CEST [main] INFO  i.f.h.t.device.read.PmReaderFactory - currentPmList writed to oper datastore
+2019-05-20 16:19:41.542 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.oper.ReadableDTDelegProvider@2954dc9e
+2019-05-20 16:19:41.545 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfBindingBrokerProvider@52b44e58
+2019-05-20 16:19:41.547 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfNotificationMapperProvider@21ae26b0
+2019-05-20 16:19:41.555 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.RpcRegistryBuilderProvider@300f2857
+2019-05-20 16:19:41.556 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.RpcRegistryProvider@5f1495c6
+2019-05-20 16:19:41.557 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.HoneycombDOMRpcServiceProvider@4b0d7cb5
+2019-05-20 16:19:41.558 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfMdsalMapperProvider@dda90c0
+2019-05-20 16:19:41.570 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfMonitoringServiceProvider@71993eba
+2019-05-20 16:19:41.583 CEST [main] INFO  o.o.n.i.o.NetconfSessionMonitoringService - Scheduling thread pool is present = false, update interval 0: /netconf-state/sessions won't be updated.
+2019-05-20 16:19:41.584 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfMonitoringMapperProvider@2298e5d2
+2019-05-20 16:19:41.607 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DOMNotificationServiceProvider@2596ae35
+2019-05-20 16:19:41.620 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.HoneycombNotificationManagerProvider@6a7488a0
+2019-05-20 16:19:41.627 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.HoneycombNotification2NetconfProvider@b6b8632
+2019-05-20 16:19:41.634 CEST [main] INFO  i.f.h.n.n.HoneycombNotification2NetconfProvider - Exposing HONEYCOMB_NETCONF notification stream: honeycomb
+2019-05-20 16:19:41.634 CEST [pool-18-thread-3] INFO  i.f.h.t.d.n.DeviceNotificationProducer - Starting notification stream for OrgOpenroadmDevice
+2019-05-20 16:19:41.635 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NettyThreadGroupProvider@4bfe0b18
+2019-05-20 16:19:41.637 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - onDataTreeChanged
+2019-05-20 16:19:41.637 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - transforming changes to notification...
+2019-05-20 16:19:41.637 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - Received Device change :
+WRITE
+2019-05-20 16:19:41.638 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - device operational datastore is created !
+2019-05-20 16:19:41.638 CEST [operational-DCL-0] WARN  i.f.h.t.d.n.DeviceNotificationProducer - edit List is empty !
+2019-05-20 16:19:41.638 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - Emitting notification : null
+2019-05-20 16:19:41.638 CEST [operational-DCL-0] WARN  i.f.h.t.d.n.DeviceNotificationProducer - Failed to emit notification
+2019-05-20 16:19:41.701 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfServerDispatcherProvider@4b74fb68
+2019-05-20 16:19:41.707 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfTcpServerProvider@4f251b32
+2019-05-20 16:19:41.709 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfSshServerProvider@52565dea
+2019-05-20 16:19:41.709 CEST [main] INFO  i.f.h.n.n.NetconfSshServerProvider - Starting NETCONF SSH
+2019-05-20 16:19:41.797 CEST [main] WARN  io.netty.bootstrap.ServerBootstrap - Unknown channel option 'SO_BACKLOG' for channel '[id: 0xf039ef03]'
+2019-05-20 16:19:42.113 CEST [main] INFO  io.fd.honeycomb.infra.distro.Main - Initializing configuration
+2019-05-20 16:19:42.113 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.context.PersistedContextInitializerProvider@150658c8
+2019-05-20 16:19:42.115 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.PersistedConfigInitializerProvider@5dadf7d9
+2019-05-20 16:19:42.115 CEST [main] INFO  i.f.h.i.d.d.PersistedConfigInitializerProvider - RestoringInitializer ...
+2019-05-20 16:19:42.115 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.initializer.ModifiableDTDelegInitProvider@5a1f3003
+2019-05-20 16:19:42.116 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.HoneycombDOMDataBrokerProvider@649b0336
+2019-05-20 16:19:42.116 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.BindingDataBrokerProvider@3e666559
+2019-05-20 16:19:42.116 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.context.RealtimeMappingContextProvider@461e3e5
+2019-05-20 16:19:42.117 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.initializer.InitializerRegistryAdapterProvider@6179761f
+2019-05-20 16:19:42.117 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Config initialization started
+2019-05-20 16:19:42.117 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Persisted context restored successfully
+2019-05-20 16:19:42.118 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Configuration initialized successfully
+2019-05-20 16:19:42.118 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Persisted configuration restored successfully
+2019-05-20 16:19:42.118 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Honeycomb initialized
+2019-05-20 16:19:42.118 CEST [main] INFO  io.fd.honeycomb.infra.distro.Main - Configuration initialized successfully
+2019-05-20 16:19:42.118 CEST [main] INFO  io.fd.honeycomb.infra.distro.Main - Honeycomb started successfully!
+2019-05-20 16:19:42.208 CEST [netconf-netty-0] INFO  i.f.h.n.n.NetconfSshServerProvider - Netconf SSH endpoint started successfully at /0.0.0.0:17841
+2019-05-20 16:22:00.815 CEST [Thread-5] INFO  i.f.h.impl.ShutdownHandlerImpl - Closing component notification-to-mdsal-writer
+2019-05-20 16:22:00.816 CEST [Thread-5] INFO  i.f.h.impl.ShutdownHandlerImpl - Closing component netconf-notification-service-factory
+2019-05-20 16:22:03.327 CEST [main] INFO  io.fd.honeycomb.infra.distro.Main - Starting honeycomb
+2019-05-20 16:22:03.626 CEST [main] INFO  i.f.h.i.d.a.ActiveModuleProvider - Reading active modules configuration for distribution
+2019-05-20 16:22:03.654 CEST [main] INFO  i.f.h.t.device.DeviceModule - Initializing Device Module
+2019-05-20 16:22:03.664 CEST [main] INFO  i.f.h.t.d.c.DeviceConfigurationModule - Initializing Device Readers Module
+2019-05-20 16:22:03.667 CEST [main] INFO  i.f.h.t.d.c.PmConfigurationModule - Initializing Pm Readers Module
+2019-05-20 16:22:03.670 CEST [main] INFO  i.f.h.t.device.DeviceModule - Device Module intitailized !
+2019-05-20 16:22:03.670 CEST [main] INFO  i.f.h.t.d.c.NetconfConfigurationModule - Initializing Netconf Readers Module
+2019-05-20 16:22:03.672 CEST [main] INFO  i.f.h.t.device.DeviceModule - Netconf Module intitailized !
+2019-05-20 16:22:03.673 CEST [main] INFO  i.f.h.i.d.s.YangBindingProviderModule - Configuring YangBindingProviderModule
+2019-05-20 16:22:03.675 CEST [main] INFO  i.f.h.t.device.DeviceRpcModule - Initializing Device Rpcs Module
+2019-05-20 16:22:03.695 CEST [main] INFO  i.f.h.t.d.DeviceNotificationModule - Initializing Device Notification Module
+2019-05-20 16:22:03.697 CEST [main] INFO  i.f.h.t.device.DeviceWriterModule - Initializing Device Writers Module
+2019-05-20 16:22:03.707 CEST [main] INFO  i.f.h.n.n.NetconfReadersModule - Initializing NETCONF Northbound readers
+2019-05-20 16:22:03.710 CEST [main] INFO  i.f.h.n.netconf.NetconfModule - Starting NETCONF Northbound
+2019-05-20 16:22:03.835 CEST [main] INFO  i.f.h.t.device.DeviceReaderModule - Initializing Device, PM and Netconf Readers Module
+2019-05-20 16:22:04.025 CEST [main] INFO  i.f.h.i.d.a.ActiveModuleProvider - Reading active modules configuration for distribution
+2019-05-20 16:22:04.055 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: ModuleInfoBackedCtxProvider{writerFactories=io.fd.honeycomb.infra.distro.schema.YangModulesProvider$YangModules@447a020}
+2019-05-20 16:22:04.610 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.schema.SchemaServiceProvider@4c36250e
+2019-05-20 16:22:05.378 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataTreeProvider$ContextDataTreeProvider@6cc558c6
+2019-05-20 16:22:05.400 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.PersistingDataTreeProvider$ContextPersistingDataTreeProvider@63f259c3
+2019-05-20 16:22:05.401 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.context.ModifiableDTMgrProvider@3db972d2
+2019-05-20 16:22:05.401 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.schema.SerializerProvider@158f4cfe
+2019-05-20 16:22:05.705 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataTreeProvider$ConfigDataTreeProvider@77774571
+2019-05-20 16:22:05.705 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.PersistingDataTreeProvider$ConfigPersistingDataTreeProvider@6cd64ee8
+2019-05-20 16:22:05.706 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataStoreProvider@62010f5c
+2019-05-20 16:22:05.717 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataStoreProvider@132e0cc
+2019-05-20 16:22:05.718 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.InmemoryDOMDataBrokerProvider@75de29c0
+2019-05-20 16:22:05.727 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.transportpce.device.DeviceBindingDataBrokerProvider@1e253c9d
+2019-05-20 16:22:05.730 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.config.WriterRegistryProvider@20b9d5d5
+2019-05-20 16:22:05.771 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.context.HoneycombContextDOMDataBrokerProvider@26ceffa8
+2019-05-20 16:22:05.771 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.BindingDataBrokerProvider@67064bdc
+2019-05-20 16:22:05.771 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.ModifiableDTDelegProvider@18578491
+2019-05-20 16:22:05.772 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataStoreProvider@7c8c9a05
+2019-05-20 16:22:05.773 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataStoreProvider@5c2375a9
+2019-05-20 16:22:05.773 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.InmemoryDOMDataBrokerProvider@5ad5be4a
+2019-05-20 16:22:05.773 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.BindingDataBrokerProvider@737d100a
+2019-05-20 16:22:05.773 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfMonitoringReaderFactoryProvider@6535117e
+2019-05-20 16:22:05.773 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfNotificationsReaderFactoryProvider@f88bfbe
+2019-05-20 16:22:10.983 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.oper.ReaderRegistryProvider@380d3099
+2019-05-20 16:22:10.988 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - writting xml file data to oper datastore
+2019-05-20 16:22:10.988 CEST [main] INFO  i.f.h.t.d.t.DefaultDeviceFactory - file 'oper-XPDRA.xml' exists at location : /home/gilles/git/01/transportpce/tests/honeynode221/honeynode-distribution/target/honeynode-distribution-1.18.01-hc/honeynode-distribution-1.18.01/config/device/oper-XPDRA.xml
+2019-05-20 16:22:11.085 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - result info : NodeIdType [_value=XPDR-A1]
+2019-05-20 16:22:11.085 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - Getting device info from xml file for device 'XPDR-A1'
+2019-05-20 16:22:11.138 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - WriteTransaction is ok, copy device info to oper datastore
+2019-05-20 16:22:11.524 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - device 'XPDR-A1' writed to oper datastore
+2019-05-20 16:22:11.524 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - writting netconf state to oper datastore
+2019-05-20 16:22:11.525 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - Loading models from directory.
+2019-05-20 16:22:11.525 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - folder '/home/gilles/git/01/transportpce/tests/honeynode221/honeynode-distribution/target/honeynode-distribution-1.18.01-hc/honeynode-distribution-1.18.01/config/yang' exists !
+2019-05-20 16:22:11.739 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - WriteTransaction is ok, copy device info to oper datastore
+2019-05-20 16:22:11.794 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - netconf state writed to oper datastore
+2019-05-20 16:22:11.794 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - writting netconf stream to oper datastore
+2019-05-20 16:22:11.795 CEST [main] INFO  i.f.h.t.d.t.DefaultNetconfFactory - file 'oper-XPDRA.xml' exists at location : /home/gilles/git/01/transportpce/tests/honeynode221/honeynode-distribution/target/honeynode-distribution-1.18.01-hc/honeynode-distribution-1.18.01/config/device/oper-XPDRA.xml
+2019-05-20 16:22:11.823 CEST [main] INFO  i.f.h.t.d.c.NetconfConfiguration - netconf streams result : Streams{getStream=[Stream{getName=StreamNameType [_value=OPENROADM], augmentations={}}], augmentations={}}
+2019-05-20 16:22:11.825 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - Netconf Data gets from xml file is present
+2019-05-20 16:22:11.826 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - WriteTransaction is ok
+2019-05-20 16:22:11.835 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - netconf stream writed to oper datastore
+2019-05-20 16:22:11.835 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - loading device configuration info from xml file...
+2019-05-20 16:22:11.835 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - process to transform xml file 
+2019-05-20 16:22:11.838 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - transforming xml data to config device ...
+2019-05-20 16:22:11.957 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - removing namespace ...
+2019-05-20 16:22:11.974 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - device info gets from xml file !
+2019-05-20 16:22:11.974 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - process to transform xml file to config data
+2019-05-20 16:22:11.975 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - transforming xml string to config device ...
+2019-05-20 16:22:11.984 CEST [main] INFO  i.f.h.t.d.t.DefaultDeviceFactory - device data config string is ok 
+2019-05-20 16:22:11.990 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - result info : NodeIdType [_value=XPDR-A1]
+2019-05-20 16:22:11.990 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - OrgOpenroadmDevice info gets : NodeIdType [_value=XPDR-A1]
+2019-05-20 16:22:11.990 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - WriteTransaction is ok, copy device info to config datastore
+2019-05-20 16:22:12.000 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - device writed to config datastore
+2019-05-20 16:22:12.001 CEST [main] INFO  i.f.h.t.device.read.PmReaderFactory - writting xml pm file data to oper datastore
+2019-05-20 16:22:12.001 CEST [main] INFO  i.f.h.t.d.t.DefaultPmListFactory - file with pm 'oper-XPDRA.xml' exists at location : /home/gilles/git/01/transportpce/tests/honeynode221/honeynode-distribution/target/honeynode-distribution-1.18.01-hc/honeynode-distribution-1.18.01/config/device/oper-XPDRA.xml
+2019-05-20 16:22:12.001 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - onDataTreeChanged
+2019-05-20 16:22:12.002 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - Received Device change(WRITE):
+ before=null 
+ after=OrgOpenroadmDevice{getCircuitPacks=[CircuitPacks{getCircuitPackMode=NORMAL, getCircuitPackName=1/0/3-PLUG-CLIENT, getCircuitPackProductCode=Client_P, getCircuitPackType=client_pluggable, getParentCircuitPack=ParentCircuitPack{getCircuitPackName=1/0, getCpSlotName=4, augmentations={}}, getPorts=[Ports{getAdministrativeState=InService, getPortName=C1, getPortQual=XpdrClient, getPortType=QSFP28, augmentations={}}], getShelf=1, getSlot=1, getSubSlot=1, augmentations={}}, CircuitPacks{getAdministrativeState=InService, getCircuitPackMode=inServiceMode, getCircuitPackName=1/0, getCircuitPackProductCode=baseXPDR, getCircuitPackType=Base_transponder_circuit_pack, getShelf=1, getSlot=1, augmentations={}}, CircuitPacks{getCircuitPackMode=NORMAL, getCircuitPackName=1/0/1-PLUG-CLIENT, getCircuitPackProductCode=Client_P, getCircuitPackType=client_pluggable, getParentCircuitPack=ParentCircuitPack{getCircuitPackName=1/0, getCpSlotName=2, augmentations={}}, getPorts=[Ports{getAdministrativeState=InService, getPortName=C1, getPortQual=XpdrClient, getPortType=QSFP28, augmentations={}}], getShelf=1, getSlot=1, getSubSlot=1, augmentations={}}, CircuitPacks{getCircuitPackMode=NORMAL, getCircuitPackName=1/0/1-PLUG-NET, getCircuitPackProductCode=Line_NW_P, getCircuitPackType=line_pluggable, getParentCircuitPack=ParentCircuitPack{getCircuitPackName=1/0, getCpSlotName=1, augmentations={}}, getPorts=[Ports{getAdministrativeState=InService, getPortName=1, getPortQual=XpdrNetwork, getPortType=CFP2, augmentations={}}], getShelf=1, getSlot=1, getSubSlot=1, augmentations={}}, CircuitPacks{getCircuitPackMode=NORMAL, getCircuitPackName=1/0/2-PLUG-NET, getCircuitPackProductCode=Line_NW_P, getCircuitPackType=line_pluggable, getParentCircuitPack=ParentCircuitPack{getCircuitPackName=1/0, getCpSlotName=3, augmentations={}}, getPorts=[Ports{getAdministrativeState=InService, getPortName=1, getPortQual=XpdrNetwork, getPortType=CFP2, augmentations={}}], getShelf=1, getSlot=1, getSubSlot=1, augmentations={}}], getInfo=Info{getClli=NodeC, getDefaultGateway=IpAddress [_ipv4Address=Ipv4Address [_value=1.2.3.4]], getGeoLocation=GeoLocation{getLatitude=1.0000, getLongitude=2.0000, augmentations={}}, getIpAddress=IpAddress [_ipv4Address=Ipv4Address [_value=1.2.3.4]], getNodeId=NodeIdType [_value=XPDR-A1], getNodeNumber=1, getNodeType=Xpdr, getPrefixLength=24, getTemplate=template_TRANSPONDER, augmentations={}}, getShelves=[Shelves{getAdministrativeState=InService, getDueDate=DateAndTime [_value=2017-02-24T15:56:10+00:00], getRack=XYZ, getShelfName=1, getShelfPosition=1, getShelfType=pizza, augmentations={}}], getUsers=Users{getUser=[User{getGroup=Sudo, getName=UsernameType [_value=openroadm], getPassword=PasswordType [_value=openroadm], augmentations={}}], augmentations={}}, augmentations={}}
+2019-05-20 16:22:12.013 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - processing change ...
+2019-05-20 16:22:12.013 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - WriteTransactions are ok, merge device info to datastores
+2019-05-20 16:22:12.021 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - device 'XPDR-A1' merged to device oper datastore
+2019-05-20 16:22:12.023 CEST [main] INFO  i.f.h.t.d.c.PmConfiguration - result pm list size : 1
+2019-05-20 16:22:12.023 CEST [main] INFO  i.f.h.t.device.read.PmReaderFactory - Getting pm info from xml file for device 
+2019-05-20 16:22:12.024 CEST [main] INFO  i.f.h.t.device.read.PmReaderFactory - WriteTransaction is ok, copy currentPmList to oper datastore
+2019-05-20 16:22:12.056 CEST [main] INFO  i.f.h.t.device.read.PmReaderFactory - currentPmList writed to oper datastore
+2019-05-20 16:22:12.063 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.oper.ReadableDTDelegProvider@58e13c25
+2019-05-20 16:22:12.066 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfBindingBrokerProvider@1538ca32
+2019-05-20 16:22:12.067 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfNotificationMapperProvider@40fc9cce
+2019-05-20 16:22:12.075 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.RpcRegistryBuilderProvider@4b0d7cb5
+2019-05-20 16:22:12.076 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.RpcRegistryProvider@2066f0d3
+2019-05-20 16:22:12.077 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.HoneycombDOMRpcServiceProvider@dda90c0
+2019-05-20 16:22:12.078 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfMdsalMapperProvider@1db078d9
+2019-05-20 16:22:12.089 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfMonitoringServiceProvider@4341ce99
+2019-05-20 16:22:12.101 CEST [main] INFO  o.o.n.i.o.NetconfSessionMonitoringService - Scheduling thread pool is present = false, update interval 0: /netconf-state/sessions won't be updated.
+2019-05-20 16:22:12.102 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfMonitoringMapperProvider@335755a0
+2019-05-20 16:22:12.152 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DOMNotificationServiceProvider@6efd96c7
+2019-05-20 16:22:12.165 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.HoneycombNotificationManagerProvider@56c9fb47
+2019-05-20 16:22:12.170 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.HoneycombNotification2NetconfProvider@694396a
+2019-05-20 16:22:12.176 CEST [main] INFO  i.f.h.n.n.HoneycombNotification2NetconfProvider - Exposing HONEYCOMB_NETCONF notification stream: honeycomb
+2019-05-20 16:22:12.176 CEST [pool-18-thread-3] INFO  i.f.h.t.d.n.DeviceNotificationProducer - Starting notification stream for OrgOpenroadmDevice
+2019-05-20 16:22:12.176 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NettyThreadGroupProvider@5a25183b
+2019-05-20 16:22:12.186 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - onDataTreeChanged
+2019-05-20 16:22:12.186 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - transforming changes to notification...
+2019-05-20 16:22:12.186 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - Received Device change :
+WRITE
+2019-05-20 16:22:12.188 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - device operational datastore is created !
+2019-05-20 16:22:12.188 CEST [operational-DCL-0] WARN  i.f.h.t.d.n.DeviceNotificationProducer - edit List is empty !
+2019-05-20 16:22:12.188 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - Emitting notification : null
+2019-05-20 16:22:12.188 CEST [operational-DCL-0] WARN  i.f.h.t.d.n.DeviceNotificationProducer - Failed to emit notification
+2019-05-20 16:22:12.212 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfServerDispatcherProvider@25becefb
+2019-05-20 16:22:12.216 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfTcpServerProvider@2720786f
+2019-05-20 16:22:12.217 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfSshServerProvider@7c4d896a
+2019-05-20 16:22:12.217 CEST [main] INFO  i.f.h.n.n.NetconfSshServerProvider - Starting NETCONF SSH
+2019-05-20 16:22:12.293 CEST [main] WARN  io.netty.bootstrap.ServerBootstrap - Unknown channel option 'SO_BACKLOG' for channel '[id: 0xb727ebc7]'
+2019-05-20 16:22:12.585 CEST [main] INFO  io.fd.honeycomb.infra.distro.Main - Initializing configuration
+2019-05-20 16:22:12.586 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.context.PersistedContextInitializerProvider@2f8a57c2
+2019-05-20 16:22:12.588 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.PersistedConfigInitializerProvider@4727acf9
+2019-05-20 16:22:12.588 CEST [main] INFO  i.f.h.i.d.d.PersistedConfigInitializerProvider - RestoringInitializer ...
+2019-05-20 16:22:12.588 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.initializer.ModifiableDTDelegInitProvider@9201335
+2019-05-20 16:22:12.589 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.HoneycombDOMDataBrokerProvider@684968be
+2019-05-20 16:22:12.589 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.BindingDataBrokerProvider@7c49fbd8
+2019-05-20 16:22:12.589 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.context.RealtimeMappingContextProvider@7a4a91f8
+2019-05-20 16:22:12.590 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.initializer.InitializerRegistryAdapterProvider@249199a7
+2019-05-20 16:22:12.590 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Config initialization started
+2019-05-20 16:22:12.590 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Persisted context restored successfully
+2019-05-20 16:22:12.591 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Configuration initialized successfully
+2019-05-20 16:22:12.591 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Persisted configuration restored successfully
+2019-05-20 16:22:12.591 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Honeycomb initialized
+2019-05-20 16:22:12.591 CEST [main] INFO  io.fd.honeycomb.infra.distro.Main - Configuration initialized successfully
+2019-05-20 16:22:12.591 CEST [main] INFO  io.fd.honeycomb.infra.distro.Main - Honeycomb started successfully!
+2019-05-20 16:22:12.693 CEST [netconf-netty-0] INFO  i.f.h.n.n.NetconfSshServerProvider - Netconf SSH endpoint started successfully at /0.0.0.0:17840
+2019-05-20 16:25:09.142 CEST [Thread-5] INFO  i.f.h.impl.ShutdownHandlerImpl - Closing component notification-to-mdsal-writer
+2019-05-20 16:25:09.144 CEST [Thread-5] INFO  i.f.h.impl.ShutdownHandlerImpl - Closing component netconf-notification-service-factory
+2019-05-20 16:26:16.144 CEST [main] INFO  io.fd.honeycomb.infra.distro.Main - Starting honeycomb
+2019-05-20 16:26:16.451 CEST [main] INFO  i.f.h.i.d.a.ActiveModuleProvider - Reading active modules configuration for distribution
+2019-05-20 16:26:16.479 CEST [main] INFO  i.f.h.t.device.DeviceModule - Initializing Device Module
+2019-05-20 16:26:16.489 CEST [main] INFO  i.f.h.t.d.c.DeviceConfigurationModule - Initializing Device Readers Module
+2019-05-20 16:26:16.492 CEST [main] INFO  i.f.h.t.d.c.PmConfigurationModule - Initializing Pm Readers Module
+2019-05-20 16:26:16.495 CEST [main] INFO  i.f.h.t.device.DeviceModule - Device Module intitailized !
+2019-05-20 16:26:16.495 CEST [main] INFO  i.f.h.t.d.c.NetconfConfigurationModule - Initializing Netconf Readers Module
+2019-05-20 16:26:16.497 CEST [main] INFO  i.f.h.t.device.DeviceModule - Netconf Module intitailized !
+2019-05-20 16:26:16.498 CEST [main] INFO  i.f.h.i.d.s.YangBindingProviderModule - Configuring YangBindingProviderModule
+2019-05-20 16:26:16.500 CEST [main] INFO  i.f.h.t.device.DeviceRpcModule - Initializing Device Rpcs Module
+2019-05-20 16:26:16.520 CEST [main] INFO  i.f.h.t.d.DeviceNotificationModule - Initializing Device Notification Module
+2019-05-20 16:26:16.522 CEST [main] INFO  i.f.h.t.device.DeviceWriterModule - Initializing Device Writers Module
+2019-05-20 16:26:16.532 CEST [main] INFO  i.f.h.n.n.NetconfReadersModule - Initializing NETCONF Northbound readers
+2019-05-20 16:26:16.536 CEST [main] INFO  i.f.h.n.netconf.NetconfModule - Starting NETCONF Northbound
+2019-05-20 16:26:16.665 CEST [main] INFO  i.f.h.t.device.DeviceReaderModule - Initializing Device, PM and Netconf Readers Module
+2019-05-20 16:26:16.862 CEST [main] INFO  i.f.h.i.d.a.ActiveModuleProvider - Reading active modules configuration for distribution
+2019-05-20 16:26:16.891 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: ModuleInfoBackedCtxProvider{writerFactories=io.fd.honeycomb.infra.distro.schema.YangModulesProvider$YangModules@447a020}
+2019-05-20 16:26:17.423 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.schema.SchemaServiceProvider@4c36250e
+2019-05-20 16:26:18.169 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataTreeProvider$ContextDataTreeProvider@6cc558c6
+2019-05-20 16:26:18.191 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.PersistingDataTreeProvider$ContextPersistingDataTreeProvider@63f259c3
+2019-05-20 16:26:18.191 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.context.ModifiableDTMgrProvider@3db972d2
+2019-05-20 16:26:18.192 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.schema.SerializerProvider@158f4cfe
+2019-05-20 16:26:18.471 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataTreeProvider$ConfigDataTreeProvider@77774571
+2019-05-20 16:26:18.472 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.PersistingDataTreeProvider$ConfigPersistingDataTreeProvider@6cd64ee8
+2019-05-20 16:26:18.473 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataStoreProvider@62010f5c
+2019-05-20 16:26:18.484 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataStoreProvider@132e0cc
+2019-05-20 16:26:18.484 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.InmemoryDOMDataBrokerProvider@75de29c0
+2019-05-20 16:26:18.493 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.transportpce.device.DeviceBindingDataBrokerProvider@1e253c9d
+2019-05-20 16:26:18.497 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.config.WriterRegistryProvider@20b9d5d5
+2019-05-20 16:26:18.538 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.context.HoneycombContextDOMDataBrokerProvider@26ceffa8
+2019-05-20 16:26:18.539 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.BindingDataBrokerProvider@67064bdc
+2019-05-20 16:26:18.539 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.ModifiableDTDelegProvider@18578491
+2019-05-20 16:26:18.540 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataStoreProvider@7c8c9a05
+2019-05-20 16:26:18.540 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataStoreProvider@5c2375a9
+2019-05-20 16:26:18.540 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.InmemoryDOMDataBrokerProvider@5ad5be4a
+2019-05-20 16:26:18.540 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.BindingDataBrokerProvider@737d100a
+2019-05-20 16:26:18.540 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfMonitoringReaderFactoryProvider@6535117e
+2019-05-20 16:26:18.541 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfNotificationsReaderFactoryProvider@f88bfbe
+2019-05-20 16:26:24.204 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.oper.ReaderRegistryProvider@287213ac
+2019-05-20 16:26:24.208 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - writting xml file data to oper datastore
+2019-05-20 16:26:24.208 CEST [main] INFO  i.f.h.t.d.t.DefaultDeviceFactory - file 'oper-XPDRA.xml' exists at location : /home/gilles/git/01/transportpce/tests/honeynode221/honeynode-distribution/target/honeynode-distribution-1.18.01-hc/honeynode-distribution-1.18.01/config/device/oper-XPDRA.xml
+2019-05-20 16:26:24.298 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - result info : NodeIdType [_value=XPDR-A1]
+2019-05-20 16:26:24.299 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - Getting device info from xml file for device 'XPDR-A1'
+2019-05-20 16:26:24.349 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - WriteTransaction is ok, copy device info to oper datastore
+2019-05-20 16:26:24.892 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - device 'XPDR-A1' writed to oper datastore
+2019-05-20 16:26:24.892 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - writting netconf state to oper datastore
+2019-05-20 16:26:24.892 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - Loading models from directory.
+2019-05-20 16:26:24.892 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - folder '/home/gilles/git/01/transportpce/tests/honeynode221/honeynode-distribution/target/honeynode-distribution-1.18.01-hc/honeynode-distribution-1.18.01/config/yang' exists !
+2019-05-20 16:26:25.102 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - WriteTransaction is ok, copy device info to oper datastore
+2019-05-20 16:26:25.148 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - netconf state writed to oper datastore
+2019-05-20 16:26:25.148 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - writting netconf stream to oper datastore
+2019-05-20 16:26:25.148 CEST [main] INFO  i.f.h.t.d.t.DefaultNetconfFactory - file 'oper-XPDRA.xml' exists at location : /home/gilles/git/01/transportpce/tests/honeynode221/honeynode-distribution/target/honeynode-distribution-1.18.01-hc/honeynode-distribution-1.18.01/config/device/oper-XPDRA.xml
+2019-05-20 16:26:25.166 CEST [main] INFO  i.f.h.t.d.c.NetconfConfiguration - netconf streams result : Streams{getStream=[Stream{getName=StreamNameType [_value=OPENROADM], augmentations={}}], augmentations={}}
+2019-05-20 16:26:25.167 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - Netconf Data gets from xml file is present
+2019-05-20 16:26:25.168 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - WriteTransaction is ok
+2019-05-20 16:26:25.177 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - netconf stream writed to oper datastore
+2019-05-20 16:26:25.177 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - loading device configuration info from xml file...
+2019-05-20 16:26:25.177 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - process to transform xml file 
+2019-05-20 16:26:25.179 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - transforming xml data to config device ...
+2019-05-20 16:26:25.292 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - removing namespace ...
+2019-05-20 16:26:25.309 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - device info gets from xml file !
+2019-05-20 16:26:25.309 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - process to transform xml file to config data
+2019-05-20 16:26:25.310 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - transforming xml string to config device ...
+2019-05-20 16:26:25.318 CEST [main] INFO  i.f.h.t.d.t.DefaultDeviceFactory - device data config string is ok 
+2019-05-20 16:26:25.324 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - result info : NodeIdType [_value=XPDR-A1]
+2019-05-20 16:26:25.324 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - OrgOpenroadmDevice info gets : NodeIdType [_value=XPDR-A1]
+2019-05-20 16:26:25.324 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - WriteTransaction is ok, copy device info to config datastore
+2019-05-20 16:26:25.333 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - device writed to config datastore
+2019-05-20 16:26:25.334 CEST [main] INFO  i.f.h.t.device.read.PmReaderFactory - writting xml pm file data to oper datastore
+2019-05-20 16:26:25.334 CEST [main] INFO  i.f.h.t.d.t.DefaultPmListFactory - file with pm 'oper-XPDRA.xml' exists at location : /home/gilles/git/01/transportpce/tests/honeynode221/honeynode-distribution/target/honeynode-distribution-1.18.01-hc/honeynode-distribution-1.18.01/config/device/oper-XPDRA.xml
+2019-05-20 16:26:25.334 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - onDataTreeChanged
+2019-05-20 16:26:25.335 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - Received Device change(WRITE):
+ before=null 
+ after=OrgOpenroadmDevice{getCircuitPacks=[CircuitPacks{getAdministrativeState=InService, getCircuitPackMode=inServiceMode, getCircuitPackName=1/0, getCircuitPackProductCode=baseXPDR, getCircuitPackType=Base_transponder_circuit_pack, getShelf=1, getSlot=1, augmentations={}}, CircuitPacks{getCircuitPackMode=NORMAL, getCircuitPackName=1/0/1-PLUG-CLIENT, getCircuitPackProductCode=Client_P, getCircuitPackType=client_pluggable, getParentCircuitPack=ParentCircuitPack{getCircuitPackName=1/0, getCpSlotName=2, augmentations={}}, getPorts=[Ports{getAdministrativeState=InService, getPortName=C1, getPortQual=XpdrClient, getPortType=QSFP28, augmentations={}}], getShelf=1, getSlot=1, getSubSlot=1, augmentations={}}, CircuitPacks{getCircuitPackMode=NORMAL, getCircuitPackName=1/0/2-PLUG-CLIENT, getCircuitPackProductCode=Client_P, getCircuitPackType=client_pluggable, getParentCircuitPack=ParentCircuitPack{getCircuitPackName=1/0, getCpSlotName=4, augmentations={}}, getPorts=[Ports{getAdministrativeState=InService, getPortName=C1, getPortQual=XpdrClient, getPortType=QSFP28, augmentations={}}], getShelf=1, getSlot=1, getSubSlot=1, augmentations={}}, CircuitPacks{getCircuitPackMode=NORMAL, getCircuitPackName=1/0/1-PLUG-NET, getCircuitPackProductCode=Line_NW_P, getCircuitPackType=line_pluggable, getParentCircuitPack=ParentCircuitPack{getCircuitPackName=1/0, getCpSlotName=1, augmentations={}}, getPorts=[Ports{getAdministrativeState=InService, getPortName=1, getPortQual=XpdrNetwork, getPortType=CFP2, augmentations={}}], getShelf=1, getSlot=1, getSubSlot=1, augmentations={}}, CircuitPacks{getCircuitPackMode=NORMAL, getCircuitPackName=1/0/2-PLUG-NET, getCircuitPackProductCode=Line_NW_P, getCircuitPackType=line_pluggable, getParentCircuitPack=ParentCircuitPack{getCircuitPackName=1/0, getCpSlotName=3, augmentations={}}, getPorts=[Ports{getAdministrativeState=InService, getPortName=1, getPortQual=XpdrNetwork, getPortType=CFP2, augmentations={}}], getShelf=1, getSlot=1, getSubSlot=1, augmentations={}}], getInfo=Info{getClli=NodeC, getDefaultGateway=IpAddress [_ipv4Address=Ipv4Address [_value=1.2.3.4]], getGeoLocation=GeoLocation{getLatitude=1.0000, getLongitude=2.0000, augmentations={}}, getIpAddress=IpAddress [_ipv4Address=Ipv4Address [_value=1.2.3.4]], getNodeId=NodeIdType [_value=XPDR-A1], getNodeNumber=1, getNodeType=Xpdr, getPrefixLength=24, getTemplate=template_TRANSPONDER, augmentations={}}, getShelves=[Shelves{getAdministrativeState=InService, getDueDate=DateAndTime [_value=2017-02-24T15:56:10+00:00], getRack=XYZ, getShelfName=1, getShelfPosition=1, getShelfType=pizza, augmentations={}}], getUsers=Users{getUser=[User{getGroup=Sudo, getName=UsernameType [_value=openroadm], getPassword=PasswordType [_value=openroadm], augmentations={}}], augmentations={}}, augmentations={}}
+2019-05-20 16:26:25.343 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - processing change ...
+2019-05-20 16:26:25.343 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - WriteTransactions are ok, merge device info to datastores
+2019-05-20 16:26:25.350 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - device 'XPDR-A1' merged to device oper datastore
+2019-05-20 16:26:25.355 CEST [main] INFO  i.f.h.t.d.c.PmConfiguration - result pm list size : 1
+2019-05-20 16:26:25.355 CEST [main] INFO  i.f.h.t.device.read.PmReaderFactory - Getting pm info from xml file for device 
+2019-05-20 16:26:25.356 CEST [main] INFO  i.f.h.t.device.read.PmReaderFactory - WriteTransaction is ok, copy currentPmList to oper datastore
+2019-05-20 16:26:25.387 CEST [main] INFO  i.f.h.t.device.read.PmReaderFactory - currentPmList writed to oper datastore
+2019-05-20 16:26:25.394 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.oper.ReadableDTDelegProvider@6354fb91
+2019-05-20 16:26:25.396 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfBindingBrokerProvider@78493c50
+2019-05-20 16:26:25.398 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfNotificationMapperProvider@121bacf4
+2019-05-20 16:26:25.406 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.RpcRegistryBuilderProvider@583ae407
+2019-05-20 16:26:25.407 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.RpcRegistryProvider@3782d1e6
+2019-05-20 16:26:25.407 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.HoneycombDOMRpcServiceProvider@ebfe707
+2019-05-20 16:26:25.408 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfMdsalMapperProvider@12bbf99e
+2019-05-20 16:26:25.419 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfMonitoringServiceProvider@2b7af38e
+2019-05-20 16:26:25.431 CEST [main] INFO  o.o.n.i.o.NetconfSessionMonitoringService - Scheduling thread pool is present = false, update interval 0: /netconf-state/sessions won't be updated.
+2019-05-20 16:26:25.431 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfMonitoringMapperProvider@18456783
+2019-05-20 16:26:25.452 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DOMNotificationServiceProvider@7506e95a
+2019-05-20 16:26:25.464 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.HoneycombNotificationManagerProvider@41d72593
+2019-05-20 16:26:25.482 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.HoneycombNotification2NetconfProvider@56c9fb47
+2019-05-20 16:26:25.491 CEST [main] INFO  i.f.h.n.n.HoneycombNotification2NetconfProvider - Exposing HONEYCOMB_NETCONF notification stream: honeycomb
+2019-05-20 16:26:25.491 CEST [pool-18-thread-3] INFO  i.f.h.t.d.n.DeviceNotificationProducer - Starting notification stream for OrgOpenroadmDevice
+2019-05-20 16:26:25.492 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NettyThreadGroupProvider@4bddc770
+2019-05-20 16:26:25.493 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - onDataTreeChanged
+2019-05-20 16:26:25.493 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - transforming changes to notification...
+2019-05-20 16:26:25.493 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - Received Device change :
+WRITE
+2019-05-20 16:26:25.494 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - device operational datastore is created !
+2019-05-20 16:26:25.494 CEST [operational-DCL-0] WARN  i.f.h.t.d.n.DeviceNotificationProducer - edit List is empty !
+2019-05-20 16:26:25.494 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - Emitting notification : null
+2019-05-20 16:26:25.494 CEST [operational-DCL-0] WARN  i.f.h.t.d.n.DeviceNotificationProducer - Failed to emit notification
+2019-05-20 16:26:25.517 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfServerDispatcherProvider@5b0c28d0
+2019-05-20 16:26:25.522 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfTcpServerProvider@354ec60
+2019-05-20 16:26:25.523 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfSshServerProvider@3c1d5349
+2019-05-20 16:26:25.523 CEST [main] INFO  i.f.h.n.n.NetconfSshServerProvider - Starting NETCONF SSH
+2019-05-20 16:26:25.582 CEST [main] WARN  io.netty.bootstrap.ServerBootstrap - Unknown channel option 'SO_BACKLOG' for channel '[id: 0x21015074]'
+2019-05-20 16:26:25.875 CEST [main] INFO  io.fd.honeycomb.infra.distro.Main - Initializing configuration
+2019-05-20 16:26:25.876 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.context.PersistedContextInitializerProvider@7499df3a
+2019-05-20 16:26:25.877 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.PersistedConfigInitializerProvider@1eb9713
+2019-05-20 16:26:25.877 CEST [main] INFO  i.f.h.i.d.d.PersistedConfigInitializerProvider - RestoringInitializer ...
+2019-05-20 16:26:25.877 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.initializer.ModifiableDTDelegInitProvider@3a949bec
+2019-05-20 16:26:25.878 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.HoneycombDOMDataBrokerProvider@3eeee97f
+2019-05-20 16:26:25.878 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.BindingDataBrokerProvider@14415802
+2019-05-20 16:26:25.878 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.context.RealtimeMappingContextProvider@1c1b9f36
+2019-05-20 16:26:25.879 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.initializer.InitializerRegistryAdapterProvider@7a8a2cd8
+2019-05-20 16:26:25.879 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Config initialization started
+2019-05-20 16:26:25.879 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Persisted context restored successfully
+2019-05-20 16:26:25.880 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Configuration initialized successfully
+2019-05-20 16:26:25.880 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Persisted configuration restored successfully
+2019-05-20 16:26:25.880 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Honeycomb initialized
+2019-05-20 16:26:25.880 CEST [main] INFO  io.fd.honeycomb.infra.distro.Main - Configuration initialized successfully
+2019-05-20 16:26:25.880 CEST [main] INFO  io.fd.honeycomb.infra.distro.Main - Honeycomb started successfully!
+2019-05-20 16:26:25.962 CEST [netconf-netty-0] INFO  i.f.h.n.n.NetconfSshServerProvider - Netconf SSH endpoint started successfully at /0.0.0.0:17840
+2019-05-20 16:27:18.230 CEST [Thread-5] INFO  i.f.h.impl.ShutdownHandlerImpl - Closing component notification-to-mdsal-writer
+2019-05-20 16:27:18.232 CEST [Thread-5] INFO  i.f.h.impl.ShutdownHandlerImpl - Closing component netconf-notification-service-factory
+2019-05-20 16:28:04.541 CEST [main] INFO  io.fd.honeycomb.infra.distro.Main - Starting honeycomb
+2019-05-20 16:28:04.851 CEST [main] INFO  i.f.h.i.d.a.ActiveModuleProvider - Reading active modules configuration for distribution
+2019-05-20 16:28:04.880 CEST [main] INFO  i.f.h.t.device.DeviceModule - Initializing Device Module
+2019-05-20 16:28:04.892 CEST [main] INFO  i.f.h.t.d.c.DeviceConfigurationModule - Initializing Device Readers Module
+2019-05-20 16:28:04.895 CEST [main] INFO  i.f.h.t.d.c.PmConfigurationModule - Initializing Pm Readers Module
+2019-05-20 16:28:04.897 CEST [main] INFO  i.f.h.t.device.DeviceModule - Device Module intitailized !
+2019-05-20 16:28:04.897 CEST [main] INFO  i.f.h.t.d.c.NetconfConfigurationModule - Initializing Netconf Readers Module
+2019-05-20 16:28:04.899 CEST [main] INFO  i.f.h.t.device.DeviceModule - Netconf Module intitailized !
+2019-05-20 16:28:04.901 CEST [main] INFO  i.f.h.i.d.s.YangBindingProviderModule - Configuring YangBindingProviderModule
+2019-05-20 16:28:04.902 CEST [main] INFO  i.f.h.t.device.DeviceRpcModule - Initializing Device Rpcs Module
+2019-05-20 16:28:04.923 CEST [main] INFO  i.f.h.t.d.DeviceNotificationModule - Initializing Device Notification Module
+2019-05-20 16:28:04.926 CEST [main] INFO  i.f.h.t.device.DeviceWriterModule - Initializing Device Writers Module
+2019-05-20 16:28:04.936 CEST [main] INFO  i.f.h.n.n.NetconfReadersModule - Initializing NETCONF Northbound readers
+2019-05-20 16:28:04.939 CEST [main] INFO  i.f.h.n.netconf.NetconfModule - Starting NETCONF Northbound
+2019-05-20 16:28:05.071 CEST [main] INFO  i.f.h.t.device.DeviceReaderModule - Initializing Device, PM and Netconf Readers Module
+2019-05-20 16:28:05.266 CEST [main] INFO  i.f.h.i.d.a.ActiveModuleProvider - Reading active modules configuration for distribution
+2019-05-20 16:28:05.296 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: ModuleInfoBackedCtxProvider{writerFactories=io.fd.honeycomb.infra.distro.schema.YangModulesProvider$YangModules@447a020}
+2019-05-20 16:28:05.832 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.schema.SchemaServiceProvider@4c36250e
+2019-05-20 16:28:06.617 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataTreeProvider$ContextDataTreeProvider@6cc558c6
+2019-05-20 16:28:06.639 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.PersistingDataTreeProvider$ContextPersistingDataTreeProvider@63f259c3
+2019-05-20 16:28:06.640 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.context.ModifiableDTMgrProvider@3db972d2
+2019-05-20 16:28:06.640 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.schema.SerializerProvider@158f4cfe
+2019-05-20 16:28:06.923 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataTreeProvider$ConfigDataTreeProvider@77774571
+2019-05-20 16:28:06.924 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.PersistingDataTreeProvider$ConfigPersistingDataTreeProvider@6cd64ee8
+2019-05-20 16:28:06.925 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataStoreProvider@62010f5c
+2019-05-20 16:28:06.935 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataStoreProvider@132e0cc
+2019-05-20 16:28:06.936 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.InmemoryDOMDataBrokerProvider@75de29c0
+2019-05-20 16:28:06.945 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.transportpce.device.DeviceBindingDataBrokerProvider@1e253c9d
+2019-05-20 16:28:06.949 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.config.WriterRegistryProvider@20b9d5d5
+2019-05-20 16:28:06.991 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.context.HoneycombContextDOMDataBrokerProvider@26ceffa8
+2019-05-20 16:28:06.992 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.BindingDataBrokerProvider@67064bdc
+2019-05-20 16:28:06.992 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.ModifiableDTDelegProvider@18578491
+2019-05-20 16:28:06.993 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataStoreProvider@7c8c9a05
+2019-05-20 16:28:06.994 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataStoreProvider@5c2375a9
+2019-05-20 16:28:06.994 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.InmemoryDOMDataBrokerProvider@5ad5be4a
+2019-05-20 16:28:06.994 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.BindingDataBrokerProvider@737d100a
+2019-05-20 16:28:06.994 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfMonitoringReaderFactoryProvider@6535117e
+2019-05-20 16:28:06.994 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfNotificationsReaderFactoryProvider@f88bfbe
+2019-05-20 16:28:12.118 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.oper.ReaderRegistryProvider@380d3099
+2019-05-20 16:28:12.123 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - writting xml file data to oper datastore
+2019-05-20 16:28:12.123 CEST [main] INFO  i.f.h.t.d.t.DefaultDeviceFactory - file 'oper-ROADMA.xml' exists at location : /home/gilles/git/01/transportpce/tests/honeynode221/honeynode-distribution/target/honeynode-distribution-1.18.01-hc/honeynode-distribution-1.18.01/config/device/oper-ROADMA.xml
+2019-05-20 16:28:12.237 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - result info : NodeIdType [_value=ROADM-A1]
+2019-05-20 16:28:12.238 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - Getting device info from xml file for device 'ROADM-A1'
+2019-05-20 16:28:12.504 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - WriteTransaction is ok, copy device info to oper datastore
+2019-05-20 16:28:12.911 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - device 'ROADM-A1' writed to oper datastore
+2019-05-20 16:28:12.911 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - writting netconf state to oper datastore
+2019-05-20 16:28:12.912 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - Loading models from directory.
+2019-05-20 16:28:12.912 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - folder '/home/gilles/git/01/transportpce/tests/honeynode221/honeynode-distribution/target/honeynode-distribution-1.18.01-hc/honeynode-distribution-1.18.01/config/yang' exists !
+2019-05-20 16:28:13.126 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - WriteTransaction is ok, copy device info to oper datastore
+2019-05-20 16:28:13.175 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - netconf state writed to oper datastore
+2019-05-20 16:28:13.175 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - writting netconf stream to oper datastore
+2019-05-20 16:28:13.175 CEST [main] INFO  i.f.h.t.d.t.DefaultNetconfFactory - file 'oper-ROADMA.xml' exists at location : /home/gilles/git/01/transportpce/tests/honeynode221/honeynode-distribution/target/honeynode-distribution-1.18.01-hc/honeynode-distribution-1.18.01/config/device/oper-ROADMA.xml
+2019-05-20 16:28:13.200 CEST [main] INFO  i.f.h.t.d.c.NetconfConfiguration - netconf streams result : Streams{getStream=[Stream{getName=StreamNameType [_value=OPENROADM], augmentations={}}], augmentations={}}
+2019-05-20 16:28:13.201 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - Netconf Data gets from xml file is present
+2019-05-20 16:28:13.203 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - WriteTransaction is ok
+2019-05-20 16:28:13.212 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - netconf stream writed to oper datastore
+2019-05-20 16:28:13.212 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - loading device configuration info from xml file...
+2019-05-20 16:28:13.212 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - process to transform xml file 
+2019-05-20 16:28:13.215 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - transforming xml data to config device ...
+2019-05-20 16:28:13.360 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - removing namespace ...
+2019-05-20 16:28:13.387 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - device info gets from xml file !
+2019-05-20 16:28:13.387 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - process to transform xml file to config data
+2019-05-20 16:28:13.388 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - transforming xml string to config device ...
+2019-05-20 16:28:13.400 CEST [main] INFO  i.f.h.t.d.t.DefaultDeviceFactory - device data config string is ok 
+2019-05-20 16:28:13.410 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - result info : NodeIdType [_value=ROADM-A1]
+2019-05-20 16:28:13.410 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - OrgOpenroadmDevice info gets : NodeIdType [_value=ROADM-A1]
+2019-05-20 16:28:13.410 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - WriteTransaction is ok, copy device info to config datastore
+2019-05-20 16:28:13.425 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - device writed to config datastore
+2019-05-20 16:28:13.426 CEST [main] INFO  i.f.h.t.device.read.PmReaderFactory - writting xml pm file data to oper datastore
+2019-05-20 16:28:13.426 CEST [main] INFO  i.f.h.t.d.t.DefaultPmListFactory - file with pm 'oper-ROADMA.xml' exists at location : /home/gilles/git/01/transportpce/tests/honeynode221/honeynode-distribution/target/honeynode-distribution-1.18.01-hc/honeynode-distribution-1.18.01/config/device/oper-ROADMA.xml
+2019-05-20 16:28:13.427 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - onDataTreeChanged
+2019-05-20 16:28:13.428 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - Received Device change(WRITE):
+ before=null 
+ after=OrgOpenroadmDevice{getCircuitPacks=[CircuitPacks{getAdministrativeState=InService, getCircuitPackMode=inServiceMode, getCircuitPackName=5/0, getCircuitPackProductCode=SRGRx, getCircuitPackType=ADDDROP, getEquipmentState=ReservedForFacilityAvailable, getPorts=[Ports{getAdministrativeState=InService, getLogicalConnectionPoint=SRG3-CP-TXRX, getPortName=AD-DEG1, getPortQual=RoadmInternal, getPortType=Edge, augmentations={}}, Ports{getAdministrativeState=InService, getCircuitId=SRG1, getLogicalConnectionPoint=SRG3-PP1, getPortName=C1, getPortQual=RoadmExternal, getPortType=Client, augmentations={}}, Ports{getAdministrativeState=InService, getCircuitId=SRG1, getLogicalConnectionPoint=SRG3-PP2, getPortName=C2, getPortQual=RoadmExternal, getPortType=Client, augmentations={}}, Ports{getAdministrativeState=InService, getLogicalConnectionPoint=SRG3-CP-TXRX, getPortName=AD-DEG2, getPortQual=RoadmInternal, getPortType=Edge, augmentations={}}, Ports{getAdministrativeState=InService, getCircuitId=SRG1, getLogicalConnectionPoint=SRG3-PP3, getPortName=C3, getPortQual=RoadmExternal, getPortType=Client, augmentations={}}, Ports{getAdministrativeState=InService, getCircuitId=SRG1, getLogicalConnectionPoint=SRG3-PP4, getPortName=C4, getPortQual=RoadmExternal, getPortType=Client, augmentations={}}], getShelf=1, getSlot=2, augmentations={}}, CircuitPacks{getAdministrativeState=InService, getCircuitPackMode=inServiceMode, getCircuitPackName=2/0, getCircuitPackProductCode=DegE, getCircuitPackType=WSSDEG, getEquipmentState=NotReservedAvailable, getPorts=[Ports{getAdministrativeState=InService, getCircuitId=1, getLogicalConnectionPoint=DEG2-TTP-TXRX, getPortName=L1, getPortQual=RoadmExternal, getPortType=LINE, augmentations={}}, Ports{getAdministrativeState=InService, getCircuitId=1, getLogicalConnectionPoint=DEG2-CTP-TXRX, getPortName=C1, getPortQual=RoadmInternal, getPortType=Client, augmentations={}}, Ports{getAdministrativeState=InService, getCircuitId=1, getLogicalConnectionPoint=DEG2-CTP-TXRX, getPortName=C2, getPortQual=RoadmInternal, getPortType=Client, augmentations={}}, Ports{getAdministrativeState=InService, getCircuitId=1, getLogicalConnectionPoint=DEG2-CTP-TXRX, getPortName=C3, getPortQual=RoadmInternal, getPortType=Client, augmentations={}}, Ports{getAdministrativeState=InService, getCircuitId=1, getLogicalConnectionPoint=DEG2-CTP-TXRX, getPortName=C4, getPortQual=RoadmInternal, getPortType=Client, augmentations={}}], getShelf=1, getSlot=1, augmentations={}}, CircuitPacks{getAdministrativeState=InService, getCircuitPackMode=inServiceMode, getCircuitPackName=1/0, getCircuitPackProductCode=DegW, getCircuitPackType=WSSDEG, getEquipmentState=NotReservedAvailable, getPorts=[Ports{getAdministrativeState=InService, getCircuitId=1, getLogicalConnectionPoint=DEG1-TTP-TXRX, getPortName=L1, getPortQual=RoadmExternal, getPortType=LINE, augmentations={}}, Ports{getAdministrativeState=InService, getCircuitId=1, getLogicalConnectionPoint=DEG1-CTP-TXRX, getPortName=C1, getPortQual=RoadmInternal, getPortType=Client, augmentations={}}, Ports{getAdministrativeState=InService, getCircuitId=1, getLogicalConnectionPoint=DEG1-CTP-TXRX, getPortName=C2, getPortQual=RoadmInternal, getPortType=Client, augmentations={}}, Ports{getAdministrativeState=InService, getCircuitId=1, getLogicalConnectionPoint=DEG1-CTP-TXRX, getPortName=C3, getPortQual=RoadmInternal, getPortType=Client, augmentations={}}, Ports{getAdministrativeState=InService, getCircuitId=1, getLogicalConnectionPoint=DEG1-CTP-TXRX, getPortName=C4, getPortQual=RoadmInternal, getPortType=Client, augmentations={}}], getShelf=1, getSlot=1, augmentations={}}, CircuitPacks{getAdministrativeState=InService, getCircuitPackMode=NORMAL, getCircuitPackName=2/0/OSC-PLUG, getCircuitPackType=port, getEquipmentState=NotReservedAvailable, getParentCircuitPack=ParentCircuitPack{getCircuitPackName=2/0, getCpSlotName=OSC-SLOT, augmentations={}}, getPorts=[Ports{getAdministrativeState=InService, getPortName=OSC-PORT, getPortQual=RoadmInternal, getPortType=1GEX, augmentations={}}], getShelf=2, getSlot=0, getSubSlot=0, augmentations={}}, CircuitPacks{getAdministrativeState=InService, getCircuitPackMode=inServiceMode, getCircuitPackName=3/0, getCircuitPackProductCode=SRGRx, getCircuitPackType=ADDDROP, getEquipmentState=ReservedForFacilityAvailable, getPorts=[Ports{getAdministrativeState=InService, getLogicalConnectionPoint=SRG1-CP-TXRX, getPortName=AD-DEG1, getPortQual=RoadmInternal, getPortType=Edge, augmentations={}}, Ports{getAdministrativeState=InService, getCircuitId=SRG1, getLogicalConnectionPoint=SRG1-PP1, getPortName=C1, getPortQual=RoadmExternal, getPortType=Client, augmentations={}}, Ports{getAdministrativeState=InService, getCircuitId=SRG1, getLogicalConnectionPoint=SRG1-PP2, getPortName=C2, getPortQual=RoadmExternal, getPortType=Client, augmentations={}}, Ports{getAdministrativeState=InService, getLogicalConnectionPoint=SRG1-CP-TXRX, getPortName=AD-DEG2, getPortQual=RoadmInternal, getPortType=Edge, augmentations={}}, Ports{getAdministrativeState=InService, getCircuitId=SRG1, getLogicalConnectionPoint=SRG1-PP3, getPortName=C3, getPortQual=RoadmExternal, getPortType=Client, augmentations={}}, Ports{getAdministrativeState=InService, getCircuitId=SRG1, getLogicalConnectionPoint=SRG1-PP4, getPortName=C4, getPortQual=RoadmExternal, getPortType=Client, augmentations={}}], getShelf=1, getSlot=2, augmentations={}}, CircuitPacks{getAdministrativeState=InService, getCircuitPackMode=inServiceMode, getCircuitPackName=2/0/ETH-PLUG, getCircuitPackProductCode=Eth, getCircuitPackType=port, getEquipmentState=NotReservedAvailable, getParentCircuitPack=ParentCircuitPack{getCircuitPackName=2/0, getCpSlotName=ETH-PLUG, augmentations={}}, getPorts=[Ports{getAdministrativeState=InService, getPortName=ETH-PLUG, getPortQual=RoadmInternal, getPortType=1GEX, augmentations={}}], getShelf=1, getSlot=1, getSubSlot=0, augmentations={}}], getDegree=[Degree{getCircuitPacks=[CircuitPacks{getCircuitPackName=2/0/ETH-PLUG, getIndex=1, augmentations={}}], getConnectionPorts=[ConnectionPorts{getCircuitPackName=2/0, getIndex=1, getPortName=L1, augmentations={}}], getDegreeNumber=2, augmentations={}}, Degree{getCircuitPacks=[CircuitPacks{getCircuitPackName=1/0/ETH-PLUG, getIndex=1, augmentations={}}], getConnectionPorts=[ConnectionPorts{getCircuitPackName=1/0, getIndex=1, getPortName=L1, augmentations={}}], getDegreeNumber=1, augmentations={}}], getInfo=Info{getClli=NodeA, getDefaultGateway=IpAddress [_ipv4Address=Ipv4Address [_value=127.0.0.20]], getGeoLocation=GeoLocation{getLatitude=1.0000, getLongitude=2.0000, augmentations={}}, getIpAddress=IpAddress [_ipv4Address=Ipv4Address [_value=127.0.0.11]], getNodeId=NodeIdType [_value=ROADM-A1], getNodeNumber=2, getNodeType=Rdm, getPrefixLength=28, getTemplate=template_1, augmentations={}}, getInterface=[Interface{getAdministrativeState=InService, getName=1GE-interface-2, getSupportingCircuitPackName=2/0/ETH-PLUG, getSupportingPort=ETH-PLUG, getType=class org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev170626.EthernetCsmacd, augmentations={interface org.opendaylight.yang.gen.v1.http.org.openroadm.ethernet.interfaces.rev181019.Interface1=Interface1{getEthernet=Ethernet{getAutoNegotiation=Enabled, getDuplex=Full, getMtu=1800, getSpeed=1000, augmentations={}}}}}, Interface{getAdministrativeState=InService, getName=OTS-DEG2-TTP-TXRX, getSupportingCircuitPackName=2/0, getSupportingPort=L1, getType=class org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev170626.OpticalTransport, augmentations={interface org.opendaylight.yang.gen.v1.http.org.openroadm.optical.transport.interfaces.rev181019.Interface1=Interface1{getOts=Ots{getFiberType=Smf, getIngressSpanLossAgingMargin=RatioDB [_value=0, _UNITS=dB], getSpanLossReceive=RatioDB [_value=15, _UNITS=dB], getSpanLossTransmit=RatioDB [_value=6, _UNITS=dB], augmentations={}}}}}, Interface{getAdministrativeState=InService, getCircuitId=TBD, getDescription=TBD, getName=OMS-DEG2-TTP-TXRX, getSupportingCircuitPackName=2/0, getSupportingInterface=OTS-DEG2-TTP-TXRX, getSupportingPort=L1, getType=class org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev170626.OpenROADMOpticalMultiplex, augmentations={}}], getProtocols=Protocols{augmentations={interface org.opendaylight.yang.gen.v1.http.org.openroadm.lldp.rev181019.Protocols1=Protocols1{getLldp=Lldp{getGlobalConfig=GlobalConfig{getAdminStatus=Enable, getMsgTxHoldMultiplier=4, getMsgTxInterval=20, augmentations={}}, getPortConfig=[PortConfig{getAdminStatus=Txandrx, getIfName=1GE-interface-2, augmentations={}}], augmentations={}}}}}, getSharedRiskGroup=[SharedRiskGroup{getCircuitPacks=[CircuitPacks{getCircuitPackName=3/0, getIndex=1, augmentations={}}], getSrgNumber=1, augmentations={}}, SharedRiskGroup{getCircuitPacks=[CircuitPacks{getCircuitPackName=5/0, getIndex=1, augmentations={}}], getSrgNumber=3, augmentations={}}], getUsers=Users{getUser=[User{getGroup=Sudo, getName=UsernameType [_value=openroadm], getPassword=PasswordType [_value=openroadm], augmentations={}}], augmentations={}}, augmentations={}}
+2019-05-20 16:28:13.441 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - processing change ...
+2019-05-20 16:28:13.441 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - WriteTransactions are ok, merge device info to datastores
+2019-05-20 16:28:13.451 CEST [main] INFO  i.f.h.t.d.c.PmConfiguration - result pm list size : 1
+2019-05-20 16:28:13.452 CEST [main] INFO  i.f.h.t.device.read.PmReaderFactory - Getting pm info from xml file for device 
+2019-05-20 16:28:13.452 CEST [main] INFO  i.f.h.t.device.read.PmReaderFactory - WriteTransaction is ok, copy currentPmList to oper datastore
+2019-05-20 16:28:13.456 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - device 'ROADM-A1' merged to device oper datastore
+2019-05-20 16:28:13.487 CEST [main] INFO  i.f.h.t.device.read.PmReaderFactory - currentPmList writed to oper datastore
+2019-05-20 16:28:13.494 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.oper.ReadableDTDelegProvider@3fe900b0
+2019-05-20 16:28:13.497 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfBindingBrokerProvider@44e0a1ce
+2019-05-20 16:28:13.498 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfNotificationMapperProvider@5058da5a
+2019-05-20 16:28:13.506 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.RpcRegistryBuilderProvider@172d9bb2
+2019-05-20 16:28:13.507 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.RpcRegistryProvider@485ca712
+2019-05-20 16:28:13.508 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.HoneycombDOMRpcServiceProvider@23277696
+2019-05-20 16:28:13.509 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfMdsalMapperProvider@3f7fbfba
+2019-05-20 16:28:13.520 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfMonitoringServiceProvider@2596ae35
+2019-05-20 16:28:13.533 CEST [main] INFO  o.o.n.i.o.NetconfSessionMonitoringService - Scheduling thread pool is present = false, update interval 0: /netconf-state/sessions won't be updated.
+2019-05-20 16:28:13.533 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfMonitoringMapperProvider@255a1fdb
+2019-05-20 16:28:13.553 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DOMNotificationServiceProvider@19f7107e
+2019-05-20 16:28:13.565 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.HoneycombNotificationManagerProvider@336e1bcf
+2019-05-20 16:28:13.569 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.HoneycombNotification2NetconfProvider@4054397
+2019-05-20 16:28:13.575 CEST [main] INFO  i.f.h.n.n.HoneycombNotification2NetconfProvider - Exposing HONEYCOMB_NETCONF notification stream: honeycomb
+2019-05-20 16:28:13.575 CEST [pool-18-thread-3] INFO  i.f.h.t.d.n.DeviceNotificationProducer - Starting notification stream for OrgOpenroadmDevice
+2019-05-20 16:28:13.575 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NettyThreadGroupProvider@26d6399e
+2019-05-20 16:28:13.577 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - onDataTreeChanged
+2019-05-20 16:28:13.577 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - transforming changes to notification...
+2019-05-20 16:28:13.577 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - Received Device change :
+WRITE
+2019-05-20 16:28:13.578 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - device operational datastore is created !
+2019-05-20 16:28:13.578 CEST [operational-DCL-0] WARN  i.f.h.t.d.n.DeviceNotificationProducer - edit List is empty !
+2019-05-20 16:28:13.578 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - Emitting notification : null
+2019-05-20 16:28:13.578 CEST [operational-DCL-0] WARN  i.f.h.t.d.n.DeviceNotificationProducer - Failed to emit notification
+2019-05-20 16:28:13.605 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfServerDispatcherProvider@f2d9eb
+2019-05-20 16:28:13.609 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfTcpServerProvider@70b95f05
+2019-05-20 16:28:13.610 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfSshServerProvider@1ad13538
+2019-05-20 16:28:13.610 CEST [main] INFO  i.f.h.n.n.NetconfSshServerProvider - Starting NETCONF SSH
+2019-05-20 16:28:13.671 CEST [main] WARN  io.netty.bootstrap.ServerBootstrap - Unknown channel option 'SO_BACKLOG' for channel '[id: 0x6f6e448c]'
+2019-05-20 16:28:13.949 CEST [main] INFO  io.fd.honeycomb.infra.distro.Main - Initializing configuration
+2019-05-20 16:28:13.949 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.context.PersistedContextInitializerProvider@720574a4
+2019-05-20 16:28:13.951 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.PersistedConfigInitializerProvider@2348e36
+2019-05-20 16:28:13.951 CEST [main] INFO  i.f.h.i.d.d.PersistedConfigInitializerProvider - RestoringInitializer ...
+2019-05-20 16:28:13.951 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.initializer.ModifiableDTDelegInitProvider@5c6d1a38
+2019-05-20 16:28:13.951 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.HoneycombDOMDataBrokerProvider@27c5fba0
+2019-05-20 16:28:13.952 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.BindingDataBrokerProvider@de3b06a
+2019-05-20 16:28:13.952 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.context.RealtimeMappingContextProvider@205d8cfa
+2019-05-20 16:28:13.952 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.initializer.InitializerRegistryAdapterProvider@698ba673
+2019-05-20 16:28:13.953 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Config initialization started
+2019-05-20 16:28:13.953 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Persisted context restored successfully
+2019-05-20 16:28:13.954 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Configuration initialized successfully
+2019-05-20 16:28:13.954 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Persisted configuration restored successfully
+2019-05-20 16:28:13.954 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Honeycomb initialized
+2019-05-20 16:28:13.954 CEST [main] INFO  io.fd.honeycomb.infra.distro.Main - Configuration initialized successfully
+2019-05-20 16:28:13.954 CEST [main] INFO  io.fd.honeycomb.infra.distro.Main - Honeycomb started successfully!
+2019-05-20 16:28:14.046 CEST [netconf-netty-0] INFO  i.f.h.n.n.NetconfSshServerProvider - Netconf SSH endpoint started successfully at /0.0.0.0:17841
+2019-05-20 16:33:25.548 CEST [main] INFO  io.fd.honeycomb.infra.distro.Main - Starting honeycomb
+2019-05-20 16:33:25.854 CEST [main] INFO  i.f.h.i.d.a.ActiveModuleProvider - Reading active modules configuration for distribution
+2019-05-20 16:33:25.883 CEST [main] INFO  i.f.h.t.device.DeviceModule - Initializing Device Module
+2019-05-20 16:33:25.893 CEST [main] INFO  i.f.h.t.d.c.DeviceConfigurationModule - Initializing Device Readers Module
+2019-05-20 16:33:25.896 CEST [main] INFO  i.f.h.t.d.c.PmConfigurationModule - Initializing Pm Readers Module
+2019-05-20 16:33:25.899 CEST [main] INFO  i.f.h.t.device.DeviceModule - Device Module intitailized !
+2019-05-20 16:33:25.899 CEST [main] INFO  i.f.h.t.d.c.NetconfConfigurationModule - Initializing Netconf Readers Module
+2019-05-20 16:33:25.901 CEST [main] INFO  i.f.h.t.device.DeviceModule - Netconf Module intitailized !
+2019-05-20 16:33:25.902 CEST [main] INFO  i.f.h.i.d.s.YangBindingProviderModule - Configuring YangBindingProviderModule
+2019-05-20 16:33:25.904 CEST [main] INFO  i.f.h.t.device.DeviceRpcModule - Initializing Device Rpcs Module
+2019-05-20 16:33:25.924 CEST [main] INFO  i.f.h.t.d.DeviceNotificationModule - Initializing Device Notification Module
+2019-05-20 16:33:25.927 CEST [main] INFO  i.f.h.t.device.DeviceWriterModule - Initializing Device Writers Module
+2019-05-20 16:33:25.937 CEST [main] INFO  i.f.h.n.n.NetconfReadersModule - Initializing NETCONF Northbound readers
+2019-05-20 16:33:25.940 CEST [main] INFO  i.f.h.n.netconf.NetconfModule - Starting NETCONF Northbound
+2019-05-20 16:33:26.070 CEST [main] INFO  i.f.h.t.device.DeviceReaderModule - Initializing Device, PM and Netconf Readers Module
+2019-05-20 16:33:26.263 CEST [main] INFO  i.f.h.i.d.a.ActiveModuleProvider - Reading active modules configuration for distribution
+2019-05-20 16:33:26.292 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: ModuleInfoBackedCtxProvider{writerFactories=io.fd.honeycomb.infra.distro.schema.YangModulesProvider$YangModules@447a020}
+2019-05-20 16:33:26.834 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.schema.SchemaServiceProvider@4c36250e
+2019-05-20 16:33:27.595 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataTreeProvider$ContextDataTreeProvider@6cc558c6
+2019-05-20 16:33:27.617 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.PersistingDataTreeProvider$ContextPersistingDataTreeProvider@63f259c3
+2019-05-20 16:33:27.617 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.context.ModifiableDTMgrProvider@3db972d2
+2019-05-20 16:33:27.618 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.schema.SerializerProvider@158f4cfe
+2019-05-20 16:33:27.896 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataTreeProvider$ConfigDataTreeProvider@77774571
+2019-05-20 16:33:27.897 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.PersistingDataTreeProvider$ConfigPersistingDataTreeProvider@6cd64ee8
+2019-05-20 16:33:27.898 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataStoreProvider@62010f5c
+2019-05-20 16:33:27.909 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataStoreProvider@132e0cc
+2019-05-20 16:33:27.909 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.InmemoryDOMDataBrokerProvider@75de29c0
+2019-05-20 16:33:27.918 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.transportpce.device.DeviceBindingDataBrokerProvider@1e253c9d
+2019-05-20 16:33:27.922 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.config.WriterRegistryProvider@20b9d5d5
+2019-05-20 16:33:27.962 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.context.HoneycombContextDOMDataBrokerProvider@26ceffa8
+2019-05-20 16:33:27.963 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.BindingDataBrokerProvider@67064bdc
+2019-05-20 16:33:27.963 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.ModifiableDTDelegProvider@18578491
+2019-05-20 16:33:27.964 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataStoreProvider@7c8c9a05
+2019-05-20 16:33:27.964 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataStoreProvider@5c2375a9
+2019-05-20 16:33:27.965 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.InmemoryDOMDataBrokerProvider@5ad5be4a
+2019-05-20 16:33:27.965 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.BindingDataBrokerProvider@737d100a
+2019-05-20 16:33:27.965 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfMonitoringReaderFactoryProvider@6535117e
+2019-05-20 16:33:27.965 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfNotificationsReaderFactoryProvider@f88bfbe
+2019-05-20 16:33:33.544 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.oper.ReaderRegistryProvider@380d3099
+2019-05-20 16:33:33.548 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - writting xml file data to oper datastore
+2019-05-20 16:33:33.548 CEST [main] INFO  i.f.h.t.d.t.DefaultDeviceFactory - file 'oper-ROADMC.xml' exists at location : /home/gilles/git/01/transportpce/tests/honeynode221/honeynode-distribution/target/honeynode-distribution-1.18.01-hc/honeynode-distribution-1.18.01/config/device/oper-ROADMC.xml
+2019-05-20 16:33:33.652 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - result info : NodeIdType [_value=ROADM-C1]
+2019-05-20 16:33:33.652 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - Getting device info from xml file for device 'ROADM-C1'
+2019-05-20 16:33:33.704 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - WriteTransaction is ok, copy device info to oper datastore
+2019-05-20 16:33:34.301 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - device 'ROADM-C1' writed to oper datastore
+2019-05-20 16:33:34.301 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - writting netconf state to oper datastore
+2019-05-20 16:33:34.301 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - Loading models from directory.
+2019-05-20 16:33:34.301 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - folder '/home/gilles/git/01/transportpce/tests/honeynode221/honeynode-distribution/target/honeynode-distribution-1.18.01-hc/honeynode-distribution-1.18.01/config/yang' exists !
+2019-05-20 16:33:34.509 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - WriteTransaction is ok, copy device info to oper datastore
+2019-05-20 16:33:34.555 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - netconf state writed to oper datastore
+2019-05-20 16:33:34.556 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - writting netconf stream to oper datastore
+2019-05-20 16:33:34.556 CEST [main] INFO  i.f.h.t.d.t.DefaultNetconfFactory - file 'oper-ROADMC.xml' exists at location : /home/gilles/git/01/transportpce/tests/honeynode221/honeynode-distribution/target/honeynode-distribution-1.18.01-hc/honeynode-distribution-1.18.01/config/device/oper-ROADMC.xml
+2019-05-20 16:33:34.577 CEST [main] INFO  i.f.h.t.d.c.NetconfConfiguration - netconf streams result : Streams{getStream=[Stream{getName=StreamNameType [_value=OPENROADM], augmentations={}}], augmentations={}}
+2019-05-20 16:33:34.579 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - Netconf Data gets from xml file is present
+2019-05-20 16:33:34.580 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - WriteTransaction is ok
+2019-05-20 16:33:34.588 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - netconf stream writed to oper datastore
+2019-05-20 16:33:34.588 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - loading device configuration info from xml file...
+2019-05-20 16:33:34.588 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - process to transform xml file 
+2019-05-20 16:33:34.591 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - transforming xml data to config device ...
+2019-05-20 16:33:34.707 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - removing namespace ...
+2019-05-20 16:33:34.729 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - device info gets from xml file !
+2019-05-20 16:33:34.729 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - process to transform xml file to config data
+2019-05-20 16:33:34.730 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - transforming xml string to config device ...
+2019-05-20 16:33:34.739 CEST [main] INFO  i.f.h.t.d.t.DefaultDeviceFactory - device data config string is ok 
+2019-05-20 16:33:34.747 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - result info : NodeIdType [_value=ROADM-C1]
+2019-05-20 16:33:34.747 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - OrgOpenroadmDevice info gets : NodeIdType [_value=ROADM-C1]
+2019-05-20 16:33:34.747 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - WriteTransaction is ok, copy device info to config datastore
+2019-05-20 16:33:34.759 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - device writed to config datastore
+2019-05-20 16:33:34.760 CEST [main] INFO  i.f.h.t.device.read.PmReaderFactory - writting xml pm file data to oper datastore
+2019-05-20 16:33:34.760 CEST [main] INFO  i.f.h.t.d.t.DefaultPmListFactory - file with pm 'oper-ROADMC.xml' exists at location : /home/gilles/git/01/transportpce/tests/honeynode221/honeynode-distribution/target/honeynode-distribution-1.18.01-hc/honeynode-distribution-1.18.01/config/device/oper-ROADMC.xml
+2019-05-20 16:33:34.760 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - onDataTreeChanged
+2019-05-20 16:33:34.762 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - Received Device change(WRITE):
+ before=null 
+ after=OrgOpenroadmDevice{getCircuitPacks=[CircuitPacks{getAdministrativeState=InService, getCircuitPackMode=NORMAL, getCircuitPackName=1/0/OSC-PLUG, getCircuitPackType=port, getEquipmentState=NotReservedAvailable, getParentCircuitPack=ParentCircuitPack{getCircuitPackName=1/0, getCpSlotName=OSC-SLOT, augmentations={}}, getPorts=[Ports{getAdministrativeState=InService, getPortName=OSC-PORT, getPortQual=RoadmInternal, getPortType=1GEX, augmentations={}}], getShelf=2, getSlot=0, getSubSlot=0, augmentations={}}, CircuitPacks{getAdministrativeState=InService, getCircuitPackMode=inServiceMode, getCircuitPackName=1/0/ETH-PLUG, getCircuitPackProductCode=Eth, getCircuitPackType=port, getEquipmentState=NotReservedAvailable, getParentCircuitPack=ParentCircuitPack{getCircuitPackName=1/0, getCpSlotName=ETH-PLUG, augmentations={}}, getPorts=[Ports{getAdministrativeState=InService, getPortName=ETH-PLUG, getPortQual=RoadmInternal, getPortType=1GEX, augmentations={}}], getShelf=1, getSlot=1, getSubSlot=0, augmentations={}}, CircuitPacks{getAdministrativeState=InService, getCircuitPackMode=inServiceMode, getCircuitPackName=1/0, getCircuitPackProductCode=DegW, getCircuitPackType=WSSDEG, getEquipmentState=NotReservedAvailable, getPorts=[Ports{getAdministrativeState=InService, getCircuitId=1, getLogicalConnectionPoint=DEG1-TTP-TXRX, getPortName=L1, getPortQual=RoadmExternal, getPortType=LINE, augmentations={}}, Ports{getAdministrativeState=InService, getCircuitId=1, getLogicalConnectionPoint=DEG1-CTP-TXRX, getPortName=C1, getPortQual=RoadmInternal, getPortType=Client, augmentations={}}, Ports{getAdministrativeState=InService, getCircuitId=1, getLogicalConnectionPoint=DEG1-CTP-TXRX, getPortName=C2, getPortQual=RoadmInternal, getPortType=Client, augmentations={}}, Ports{getAdministrativeState=InService, getCircuitId=1, getLogicalConnectionPoint=DEG1-CTP-TXRX, getPortName=C3, getPortQual=RoadmInternal, getPortType=Client, augmentations={}}, Ports{getAdministrativeState=InService, getCircuitId=1, getLogicalConnectionPoint=DEG1-CTP-TXRX, getPortName=C4, getPortQual=RoadmInternal, getPortType=Client, augmentations={}}], getShelf=1, getSlot=1, augmentations={}}, CircuitPacks{getAdministrativeState=InService, getCircuitPackMode=inServiceMode, getCircuitPackName=3/0, getCircuitPackProductCode=SRGRx, getCircuitPackType=ADDDROP, getEquipmentState=ReservedForFacilityAvailable, getPorts=[Ports{getAdministrativeState=InService, getLogicalConnectionPoint=SRG1-CP-TXRX, getPortName=AD-DEG1, getPortQual=RoadmInternal, getPortType=Edge, augmentations={}}, Ports{getAdministrativeState=InService, getCircuitId=SRG1, getLogicalConnectionPoint=SRG1-PP1, getPortName=C1, getPortQual=RoadmExternal, getPortType=Client, augmentations={}}, Ports{getAdministrativeState=InService, getCircuitId=SRG1, getLogicalConnectionPoint=SRG1-PP2, getPortName=C2, getPortQual=RoadmExternal, getPortType=Client, augmentations={}}, Ports{getAdministrativeState=InService, getLogicalConnectionPoint=SRG1-CP-TXRX, getPortName=AD-DEG2, getPortQual=RoadmInternal, getPortType=Edge, augmentations={}}, Ports{getAdministrativeState=InService, getCircuitId=SRG1, getLogicalConnectionPoint=SRG1-PP3, getPortName=C3, getPortQual=RoadmExternal, getPortType=Client, augmentations={}}, Ports{getAdministrativeState=InService, getCircuitId=SRG1, getLogicalConnectionPoint=SRG1-PP4, getPortName=C4, getPortQual=RoadmExternal, getPortType=Client, augmentations={}}], getShelf=1, getSlot=2, augmentations={}}], getDegree=[Degree{getCircuitPacks=[CircuitPacks{getCircuitPackName=1/0/ETH-PLUG, getIndex=1, augmentations={}}], getConnectionPorts=[ConnectionPorts{getCircuitPackName=1/0, getIndex=1, getPortName=L1, augmentations={}}], getDegreeNumber=1, augmentations={}}], getInfo=Info{getClli=NodeC, getDefaultGateway=IpAddress [_ipv4Address=Ipv4Address [_value=127.0.0.20]], getGeoLocation=GeoLocation{getLatitude=1.0000, getLongitude=2.0000, augmentations={}}, getIpAddress=IpAddress [_ipv4Address=Ipv4Address [_value=127.0.0.11]], getNodeId=NodeIdType [_value=ROADM-C1], getNodeNumber=4, getNodeType=Rdm, getPrefixLength=28, getTemplate=template_1, augmentations={}}, getInterface=[Interface{getAdministrativeState=InService, getCircuitId=TBD, getDescription=TBD, getName=OMS-DEG1-TTP-TXRX, getSupportingCircuitPackName=1/0, getSupportingInterface=OTS-DEG1-TTP-TXRX, getSupportingPort=L1, getType=class org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev170626.OpenROADMOpticalMultiplex, augmentations={}}, Interface{getAdministrativeState=InService, getName=1GE-interface-1, getSupportingCircuitPackName=1/0/ETH-PLUG, getSupportingPort=ETH-PLUG, getType=class org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev170626.EthernetCsmacd, augmentations={interface org.opendaylight.yang.gen.v1.http.org.openroadm.ethernet.interfaces.rev181019.Interface1=Interface1{getEthernet=Ethernet{getAutoNegotiation=Enabled, getDuplex=Full, getMtu=1800, getSpeed=1000, augmentations={}}}}}, Interface{getAdministrativeState=InService, getName=OTS-DEG1-TTP-TXRX, getSupportingCircuitPackName=1/0, getSupportingPort=L1, getType=class org.opendaylight.yang.gen.v1.http.org.openroadm.interfaces.rev170626.OpticalTransport, augmentations={interface org.opendaylight.yang.gen.v1.http.org.openroadm.optical.transport.interfaces.rev181019.Interface1=Interface1{getOts=Ots{getFiberType=Smf, getIngressSpanLossAgingMargin=RatioDB [_value=0, _UNITS=dB], getSpanLossReceive=RatioDB [_value=15, _UNITS=dB], getSpanLossTransmit=RatioDB [_value=6, _UNITS=dB], augmentations={}}}}}], getProtocols=Protocols{augmentations={interface org.opendaylight.yang.gen.v1.http.org.openroadm.lldp.rev181019.Protocols1=Protocols1{getLldp=Lldp{getGlobalConfig=GlobalConfig{getAdminStatus=Enable, getMsgTxHoldMultiplier=4, getMsgTxInterval=20, augmentations={}}, getPortConfig=[PortConfig{getAdminStatus=Txandrx, getIfName=1GE-interface-1, augmentations={}}], augmentations={}}}}}, getSharedRiskGroup=[SharedRiskGroup{getCircuitPacks=[CircuitPacks{getCircuitPackName=3/0, getIndex=1, augmentations={}}], getSrgNumber=1, augmentations={}}], getUsers=Users{getUser=[User{getGroup=Sudo, getName=UsernameType [_value=openroadm], getPassword=PasswordType [_value=openroadm], augmentations={}}], augmentations={}}, augmentations={}}
+2019-05-20 16:33:34.773 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - processing change ...
+2019-05-20 16:33:34.774 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - WriteTransactions are ok, merge device info to datastores
+2019-05-20 16:33:34.784 CEST [main] INFO  i.f.h.t.d.c.PmConfiguration - result pm list size : 1
+2019-05-20 16:33:34.784 CEST [main] INFO  i.f.h.t.device.read.PmReaderFactory - Getting pm info from xml file for device 
+2019-05-20 16:33:34.785 CEST [main] INFO  i.f.h.t.device.read.PmReaderFactory - WriteTransaction is ok, copy currentPmList to oper datastore
+2019-05-20 16:33:34.789 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - device 'ROADM-C1' merged to device oper datastore
+2019-05-20 16:33:34.816 CEST [main] INFO  i.f.h.t.device.read.PmReaderFactory - currentPmList writed to oper datastore
+2019-05-20 16:33:34.822 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.oper.ReadableDTDelegProvider@474e0ab4
+2019-05-20 16:33:34.824 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfBindingBrokerProvider@600c5acf
+2019-05-20 16:33:34.826 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfNotificationMapperProvider@56677422
+2019-05-20 16:33:34.833 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.RpcRegistryBuilderProvider@501c3ef6
+2019-05-20 16:33:34.834 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.RpcRegistryProvider@40ba320f
+2019-05-20 16:33:34.835 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.HoneycombDOMRpcServiceProvider@6981107f
+2019-05-20 16:33:34.836 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfMdsalMapperProvider@77f3e77a
+2019-05-20 16:33:34.863 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfMonitoringServiceProvider@34b1bc0f
+2019-05-20 16:33:34.876 CEST [main] INFO  o.o.n.i.o.NetconfSessionMonitoringService - Scheduling thread pool is present = false, update interval 0: /netconf-state/sessions won't be updated.
+2019-05-20 16:33:34.876 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfMonitoringMapperProvider@49b257f9
+2019-05-20 16:33:34.895 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DOMNotificationServiceProvider@21622e1
+2019-05-20 16:33:34.907 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.HoneycombNotificationManagerProvider@58ef7429
+2019-05-20 16:33:34.911 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.HoneycombNotification2NetconfProvider@541c9054
+2019-05-20 16:33:34.918 CEST [main] INFO  i.f.h.n.n.HoneycombNotification2NetconfProvider - Exposing HONEYCOMB_NETCONF notification stream: honeycomb
+2019-05-20 16:33:34.918 CEST [pool-18-thread-3] INFO  i.f.h.t.d.n.DeviceNotificationProducer - Starting notification stream for OrgOpenroadmDevice
+2019-05-20 16:33:34.918 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NettyThreadGroupProvider@34f8cee0
+2019-05-20 16:33:34.920 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - onDataTreeChanged
+2019-05-20 16:33:34.920 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - transforming changes to notification...
+2019-05-20 16:33:34.920 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - Received Device change :
+WRITE
+2019-05-20 16:33:34.921 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - device operational datastore is created !
+2019-05-20 16:33:34.921 CEST [operational-DCL-0] WARN  i.f.h.t.d.n.DeviceNotificationProducer - edit List is empty !
+2019-05-20 16:33:34.921 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - Emitting notification : null
+2019-05-20 16:33:34.921 CEST [operational-DCL-0] WARN  i.f.h.t.d.n.DeviceNotificationProducer - Failed to emit notification
+2019-05-20 16:33:34.948 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfServerDispatcherProvider@5555eb81
+2019-05-20 16:33:34.954 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfTcpServerProvider@169d11c5
+2019-05-20 16:33:34.955 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfSshServerProvider@1894b733
+2019-05-20 16:33:34.955 CEST [main] INFO  i.f.h.n.n.NetconfSshServerProvider - Starting NETCONF SSH
+2019-05-20 16:33:35.020 CEST [main] WARN  io.netty.bootstrap.ServerBootstrap - Unknown channel option 'SO_BACKLOG' for channel '[id: 0x42478495]'
+2019-05-20 16:33:35.290 CEST [main] INFO  io.fd.honeycomb.infra.distro.Main - Initializing configuration
+2019-05-20 16:33:35.291 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.context.PersistedContextInitializerProvider@59d768de
+2019-05-20 16:33:35.292 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.PersistedConfigInitializerProvider@1bac51bd
+2019-05-20 16:33:35.292 CEST [main] INFO  i.f.h.i.d.d.PersistedConfigInitializerProvider - RestoringInitializer ...
+2019-05-20 16:33:35.293 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.initializer.ModifiableDTDelegInitProvider@6150e1c5
+2019-05-20 16:33:35.293 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.HoneycombDOMDataBrokerProvider@7ab8af34
+2019-05-20 16:33:35.293 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.BindingDataBrokerProvider@2fdd5baa
+2019-05-20 16:33:35.294 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.context.RealtimeMappingContextProvider@698ba673
+2019-05-20 16:33:35.294 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.initializer.InitializerRegistryAdapterProvider@7d5b1786
+2019-05-20 16:33:35.294 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Config initialization started
+2019-05-20 16:33:35.294 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Persisted context restored successfully
+2019-05-20 16:33:35.295 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Configuration initialized successfully
+2019-05-20 16:33:35.295 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Persisted configuration restored successfully
+2019-05-20 16:33:35.295 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Honeycomb initialized
+2019-05-20 16:33:35.295 CEST [main] INFO  io.fd.honeycomb.infra.distro.Main - Configuration initialized successfully
+2019-05-20 16:33:35.295 CEST [main] INFO  io.fd.honeycomb.infra.distro.Main - Honeycomb started successfully!
+2019-05-20 16:33:35.375 CEST [netconf-netty-0] INFO  i.f.h.n.n.NetconfSshServerProvider - Netconf SSH endpoint started successfully at /0.0.0.0:17843
+2019-05-20 16:34:57.288 CEST [main] INFO  io.fd.honeycomb.infra.distro.Main - Starting honeycomb
+2019-05-20 16:34:57.594 CEST [main] INFO  i.f.h.i.d.a.ActiveModuleProvider - Reading active modules configuration for distribution
+2019-05-20 16:34:57.622 CEST [main] INFO  i.f.h.t.device.DeviceModule - Initializing Device Module
+2019-05-20 16:34:57.633 CEST [main] INFO  i.f.h.t.d.c.DeviceConfigurationModule - Initializing Device Readers Module
+2019-05-20 16:34:57.636 CEST [main] INFO  i.f.h.t.d.c.PmConfigurationModule - Initializing Pm Readers Module
+2019-05-20 16:34:57.638 CEST [main] INFO  i.f.h.t.device.DeviceModule - Device Module intitailized !
+2019-05-20 16:34:57.638 CEST [main] INFO  i.f.h.t.d.c.NetconfConfigurationModule - Initializing Netconf Readers Module
+2019-05-20 16:34:57.640 CEST [main] INFO  i.f.h.t.device.DeviceModule - Netconf Module intitailized !
+2019-05-20 16:34:57.642 CEST [main] INFO  i.f.h.i.d.s.YangBindingProviderModule - Configuring YangBindingProviderModule
+2019-05-20 16:34:57.643 CEST [main] INFO  i.f.h.t.device.DeviceRpcModule - Initializing Device Rpcs Module
+2019-05-20 16:34:57.664 CEST [main] INFO  i.f.h.t.d.DeviceNotificationModule - Initializing Device Notification Module
+2019-05-20 16:34:57.667 CEST [main] INFO  i.f.h.t.device.DeviceWriterModule - Initializing Device Writers Module
+2019-05-20 16:34:57.677 CEST [main] INFO  i.f.h.n.n.NetconfReadersModule - Initializing NETCONF Northbound readers
+2019-05-20 16:34:57.680 CEST [main] INFO  i.f.h.n.netconf.NetconfModule - Starting NETCONF Northbound
+2019-05-20 16:34:57.809 CEST [main] INFO  i.f.h.t.device.DeviceReaderModule - Initializing Device, PM and Netconf Readers Module
+2019-05-20 16:34:58.002 CEST [main] INFO  i.f.h.i.d.a.ActiveModuleProvider - Reading active modules configuration for distribution
+2019-05-20 16:34:58.031 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: ModuleInfoBackedCtxProvider{writerFactories=io.fd.honeycomb.infra.distro.schema.YangModulesProvider$YangModules@447a020}
+2019-05-20 16:34:58.565 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.schema.SchemaServiceProvider@4c36250e
+2019-05-20 16:34:59.273 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataTreeProvider$ContextDataTreeProvider@6cc558c6
+2019-05-20 16:34:59.294 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.PersistingDataTreeProvider$ContextPersistingDataTreeProvider@63f259c3
+2019-05-20 16:34:59.295 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.context.ModifiableDTMgrProvider@3db972d2
+2019-05-20 16:34:59.295 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.schema.SerializerProvider@158f4cfe
+2019-05-20 16:34:59.575 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataTreeProvider$ConfigDataTreeProvider@77774571
+2019-05-20 16:34:59.575 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.PersistingDataTreeProvider$ConfigPersistingDataTreeProvider@6cd64ee8
+2019-05-20 16:34:59.576 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataStoreProvider@62010f5c
+2019-05-20 16:34:59.588 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataStoreProvider@132e0cc
+2019-05-20 16:34:59.588 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.InmemoryDOMDataBrokerProvider@75de29c0
+2019-05-20 16:34:59.597 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.transportpce.device.DeviceBindingDataBrokerProvider@1e253c9d
+2019-05-20 16:34:59.600 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.config.WriterRegistryProvider@20b9d5d5
+2019-05-20 16:34:59.641 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.context.HoneycombContextDOMDataBrokerProvider@26ceffa8
+2019-05-20 16:34:59.642 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.BindingDataBrokerProvider@67064bdc
+2019-05-20 16:34:59.642 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.ModifiableDTDelegProvider@18578491
+2019-05-20 16:34:59.643 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataStoreProvider@7c8c9a05
+2019-05-20 16:34:59.643 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DataStoreProvider@5c2375a9
+2019-05-20 16:34:59.643 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.InmemoryDOMDataBrokerProvider@5ad5be4a
+2019-05-20 16:34:59.643 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.BindingDataBrokerProvider@737d100a
+2019-05-20 16:34:59.644 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfMonitoringReaderFactoryProvider@6535117e
+2019-05-20 16:34:59.644 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfNotificationsReaderFactoryProvider@f88bfbe
+2019-05-20 16:35:04.847 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.oper.ReaderRegistryProvider@380d3099
+2019-05-20 16:35:04.851 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - writting xml file data to oper datastore
+2019-05-20 16:35:04.851 CEST [main] INFO  i.f.h.t.d.t.DefaultDeviceFactory - file 'oper-XPDRC.xml' exists at location : /home/gilles/git/01/transportpce/tests/honeynode221/honeynode-distribution/target/honeynode-distribution-1.18.01-hc/honeynode-distribution-1.18.01/config/device/oper-XPDRC.xml
+2019-05-20 16:35:04.951 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - result info : NodeIdType [_value=XPDR-C1]
+2019-05-20 16:35:04.951 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - Getting device info from xml file for device 'XPDR-C1'
+2019-05-20 16:35:05.009 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - WriteTransaction is ok, copy device info to oper datastore
+2019-05-20 16:35:05.574 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - device 'XPDR-C1' writed to oper datastore
+2019-05-20 16:35:05.574 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - writting netconf state to oper datastore
+2019-05-20 16:35:05.574 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - Loading models from directory.
+2019-05-20 16:35:05.575 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - folder '/home/gilles/git/01/transportpce/tests/honeynode221/honeynode-distribution/target/honeynode-distribution-1.18.01-hc/honeynode-distribution-1.18.01/config/yang' exists !
+2019-05-20 16:35:05.788 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - WriteTransaction is ok, copy device info to oper datastore
+2019-05-20 16:35:05.833 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - netconf state writed to oper datastore
+2019-05-20 16:35:05.833 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - writting netconf stream to oper datastore
+2019-05-20 16:35:05.833 CEST [main] INFO  i.f.h.t.d.t.DefaultNetconfFactory - file 'oper-XPDRC.xml' exists at location : /home/gilles/git/01/transportpce/tests/honeynode221/honeynode-distribution/target/honeynode-distribution-1.18.01-hc/honeynode-distribution-1.18.01/config/device/oper-XPDRC.xml
+2019-05-20 16:35:05.851 CEST [main] INFO  i.f.h.t.d.c.NetconfConfiguration - netconf streams result : Streams{getStream=[Stream{getName=StreamNameType [_value=OPENROADM], augmentations={}}], augmentations={}}
+2019-05-20 16:35:05.853 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - Netconf Data gets from xml file is present
+2019-05-20 16:35:05.854 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - WriteTransaction is ok
+2019-05-20 16:35:05.862 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - netconf stream writed to oper datastore
+2019-05-20 16:35:05.862 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - loading device configuration info from xml file...
+2019-05-20 16:35:05.862 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - process to transform xml file 
+2019-05-20 16:35:05.865 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - transforming xml data to config device ...
+2019-05-20 16:35:05.975 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - removing namespace ...
+2019-05-20 16:35:05.992 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - device info gets from xml file !
+2019-05-20 16:35:05.992 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - process to transform xml file to config data
+2019-05-20 16:35:05.993 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - transforming xml string to config device ...
+2019-05-20 16:35:06.001 CEST [main] INFO  i.f.h.t.d.t.DefaultDeviceFactory - device data config string is ok 
+2019-05-20 16:35:06.007 CEST [main] INFO  i.f.h.t.d.c.DeviceConfiguration - result info : NodeIdType [_value=XPDR-C1]
+2019-05-20 16:35:06.007 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - OrgOpenroadmDevice info gets : NodeIdType [_value=XPDR-C1]
+2019-05-20 16:35:06.007 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - WriteTransaction is ok, copy device info to config datastore
+2019-05-20 16:35:06.017 CEST [main] INFO  i.f.h.t.d.read.DeviceReaderFactory - device writed to config datastore
+2019-05-20 16:35:06.017 CEST [main] INFO  i.f.h.t.device.read.PmReaderFactory - writting xml pm file data to oper datastore
+2019-05-20 16:35:06.017 CEST [main] INFO  i.f.h.t.d.t.DefaultPmListFactory - file with pm 'oper-XPDRC.xml' exists at location : /home/gilles/git/01/transportpce/tests/honeynode221/honeynode-distribution/target/honeynode-distribution-1.18.01-hc/honeynode-distribution-1.18.01/config/device/oper-XPDRC.xml
+2019-05-20 16:35:06.017 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - onDataTreeChanged
+2019-05-20 16:35:06.018 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - Received Device change(WRITE):
+ before=null 
+ after=OrgOpenroadmDevice{getCircuitPacks=[CircuitPacks{getAdministrativeState=InService, getCircuitPackMode=inServiceMode, getCircuitPackName=1/0, getCircuitPackProductCode=baseXPDR, getCircuitPackType=Base_transponder_circuit_pack, getShelf=1, getSlot=1, augmentations={}}, CircuitPacks{getCircuitPackMode=NORMAL, getCircuitPackName=1/0/1-PLUG-CLIENT, getCircuitPackProductCode=Client_P, getCircuitPackType=client_pluggable, getParentCircuitPack=ParentCircuitPack{getCircuitPackName=1/0, getCpSlotName=2, augmentations={}}, getPorts=[Ports{getAdministrativeState=InService, getPortName=C1, getPortQual=XpdrClient, getPortType=QSFP28, augmentations={}}], getShelf=1, getSlot=1, getSubSlot=1, augmentations={}}, CircuitPacks{getCircuitPackMode=NORMAL, getCircuitPackName=1/0/2-PLUG-CLIENT, getCircuitPackProductCode=Client_P, getCircuitPackType=client_pluggable, getParentCircuitPack=ParentCircuitPack{getCircuitPackName=1/0, getCpSlotName=4, augmentations={}}, getPorts=[Ports{getAdministrativeState=InService, getPortName=C1, getPortQual=XpdrClient, getPortType=QSFP28, augmentations={}}], getShelf=1, getSlot=1, getSubSlot=1, augmentations={}}, CircuitPacks{getCircuitPackMode=NORMAL, getCircuitPackName=1/0/1-PLUG-NET, getCircuitPackProductCode=Line_NW_P, getCircuitPackType=line_pluggable, getParentCircuitPack=ParentCircuitPack{getCircuitPackName=1/0, getCpSlotName=1, augmentations={}}, getPorts=[Ports{getAdministrativeState=InService, getPortName=1, getPortQual=XpdrNetwork, getPortType=CFP2, augmentations={}}], getShelf=1, getSlot=1, getSubSlot=1, augmentations={}}, CircuitPacks{getCircuitPackMode=NORMAL, getCircuitPackName=1/0/2-PLUG-NET, getCircuitPackProductCode=Line_NW_P, getCircuitPackType=line_pluggable, getParentCircuitPack=ParentCircuitPack{getCircuitPackName=1/0, getCpSlotName=3, augmentations={}}, getPorts=[Ports{getAdministrativeState=InService, getPortName=1, getPortQual=XpdrNetwork, getPortType=CFP2, augmentations={}}], getShelf=1, getSlot=1, getSubSlot=1, augmentations={}}], getInfo=Info{getClli=NodeC, getDefaultGateway=IpAddress [_ipv4Address=Ipv4Address [_value=1.2.3.4]], getGeoLocation=GeoLocation{getLatitude=1.0000, getLongitude=2.0000, augmentations={}}, getIpAddress=IpAddress [_ipv4Address=Ipv4Address [_value=1.2.3.4]], getNodeId=NodeIdType [_value=XPDR-C1], getNodeNumber=1, getNodeType=Xpdr, getPrefixLength=24, getTemplate=template_TRANSPONDER, augmentations={}}, getShelves=[Shelves{getAdministrativeState=InService, getDueDate=DateAndTime [_value=2017-02-24T15:56:10+00:00], getRack=XYZ, getShelfName=1, getShelfPosition=1, getShelfType=pizza, augmentations={}}], getUsers=Users{getUser=[User{getGroup=Sudo, getName=UsernameType [_value=openroadm], getPassword=PasswordType [_value=openroadm], augmentations={}}], augmentations={}}, augmentations={}}
+2019-05-20 16:35:06.026 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - processing change ...
+2019-05-20 16:35:06.026 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - WriteTransactions are ok, merge device info to datastores
+2019-05-20 16:35:06.033 CEST [config-DCL-0] INFO  i.f.h.t.d.w.DeviceChangeListener - device 'XPDR-C1' merged to device oper datastore
+2019-05-20 16:35:06.034 CEST [main] INFO  i.f.h.t.d.c.PmConfiguration - result pm list size : 1
+2019-05-20 16:35:06.034 CEST [main] INFO  i.f.h.t.device.read.PmReaderFactory - Getting pm info from xml file for device 
+2019-05-20 16:35:06.035 CEST [main] INFO  i.f.h.t.device.read.PmReaderFactory - WriteTransaction is ok, copy currentPmList to oper datastore
+2019-05-20 16:35:06.067 CEST [main] INFO  i.f.h.t.device.read.PmReaderFactory - currentPmList writed to oper datastore
+2019-05-20 16:35:06.074 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.oper.ReadableDTDelegProvider@571ae6d5
+2019-05-20 16:35:06.076 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfBindingBrokerProvider@59ef35de
+2019-05-20 16:35:06.078 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfNotificationMapperProvider@2eaafa39
+2019-05-20 16:35:06.087 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.RpcRegistryBuilderProvider@48e48923
+2019-05-20 16:35:06.087 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.RpcRegistryProvider@6c1f6481
+2019-05-20 16:35:06.088 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.HoneycombDOMRpcServiceProvider@2a428e3b
+2019-05-20 16:35:06.089 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfMdsalMapperProvider@4473d830
+2019-05-20 16:35:06.100 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfMonitoringServiceProvider@73e15280
+2019-05-20 16:35:06.131 CEST [main] INFO  o.o.n.i.o.NetconfSessionMonitoringService - Scheduling thread pool is present = false, update interval 0: /netconf-state/sessions won't be updated.
+2019-05-20 16:35:06.132 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfMonitoringMapperProvider@47a20fab
+2019-05-20 16:35:06.152 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.DOMNotificationServiceProvider@719edb69
+2019-05-20 16:35:06.166 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.HoneycombNotificationManagerProvider@71e21f48
+2019-05-20 16:35:06.170 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.HoneycombNotification2NetconfProvider@18f557ce
+2019-05-20 16:35:06.176 CEST [main] INFO  i.f.h.n.n.HoneycombNotification2NetconfProvider - Exposing HONEYCOMB_NETCONF notification stream: honeycomb
+2019-05-20 16:35:06.176 CEST [pool-18-thread-3] INFO  i.f.h.t.d.n.DeviceNotificationProducer - Starting notification stream for OrgOpenroadmDevice
+2019-05-20 16:35:06.176 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NettyThreadGroupProvider@53600a30
+2019-05-20 16:35:06.178 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - onDataTreeChanged
+2019-05-20 16:35:06.178 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - transforming changes to notification...
+2019-05-20 16:35:06.178 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - Received Device change :
+WRITE
+2019-05-20 16:35:06.179 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - device operational datastore is created !
+2019-05-20 16:35:06.179 CEST [operational-DCL-0] WARN  i.f.h.t.d.n.DeviceNotificationProducer - edit List is empty !
+2019-05-20 16:35:06.179 CEST [operational-DCL-0] INFO  i.f.h.t.d.n.DeviceNotificationProducer - Emitting notification : null
+2019-05-20 16:35:06.179 CEST [operational-DCL-0] WARN  i.f.h.t.d.n.DeviceNotificationProducer - Failed to emit notification
+2019-05-20 16:35:06.203 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfServerDispatcherProvider@3fd762bb
+2019-05-20 16:35:06.207 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfTcpServerProvider@2b6cd876
+2019-05-20 16:35:06.208 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.northbound.netconf.NetconfSshServerProvider@70207dcb
+2019-05-20 16:35:06.208 CEST [main] INFO  i.f.h.n.n.NetconfSshServerProvider - Starting NETCONF SSH
+2019-05-20 16:35:06.269 CEST [main] WARN  io.netty.bootstrap.ServerBootstrap - Unknown channel option 'SO_BACKLOG' for channel '[id: 0x85cde949]'
+2019-05-20 16:35:06.542 CEST [main] INFO  io.fd.honeycomb.infra.distro.Main - Initializing configuration
+2019-05-20 16:35:06.543 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.context.PersistedContextInitializerProvider@1eb9713
+2019-05-20 16:35:06.544 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.PersistedConfigInitializerProvider@514753f4
+2019-05-20 16:35:06.544 CEST [main] INFO  i.f.h.i.d.d.PersistedConfigInitializerProvider - RestoringInitializer ...
+2019-05-20 16:35:06.544 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.initializer.ModifiableDTDelegInitProvider@2f8a57c2
+2019-05-20 16:35:06.545 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.HoneycombDOMDataBrokerProvider@61d2ff30
+2019-05-20 16:35:06.545 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.BindingDataBrokerProvider@6c60a141
+2019-05-20 16:35:06.545 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.data.context.RealtimeMappingContextProvider@78626f16
+2019-05-20 16:35:06.546 CEST [main] INFO  i.f.h.binding.init.ProviderTrait - Providing: io.fd.honeycomb.infra.distro.initializer.InitializerRegistryAdapterProvider@3e666559
+2019-05-20 16:35:06.546 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Config initialization started
+2019-05-20 16:35:06.546 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Persisted context restored successfully
+2019-05-20 16:35:06.547 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Configuration initialized successfully
+2019-05-20 16:35:06.547 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Persisted configuration restored successfully
+2019-05-20 16:35:06.547 CEST [main] INFO  i.f.h.i.d.i.InitializerRegistryAdapter - Honeycomb initialized
+2019-05-20 16:35:06.547 CEST [main] INFO  io.fd.honeycomb.infra.distro.Main - Configuration initialized successfully
+2019-05-20 16:35:06.547 CEST [main] INFO  io.fd.honeycomb.infra.distro.Main - Honeycomb started successfully!
+2019-05-20 16:35:06.629 CEST [netconf-netty-0] INFO  i.f.h.n.n.NetconfSshServerProvider - Netconf SSH endpoint started successfully at /0.0.0.0:17844
+2019-05-20 16:39:00.502 CEST [Thread-5] INFO  i.f.h.impl.ShutdownHandlerImpl - Closing component notification-to-mdsal-writer
+2019-05-20 16:39:00.503 CEST [Thread-5] INFO  i.f.h.impl.ShutdownHandlerImpl - Closing component netconf-notification-service-factory
+2019-05-20 16:39:03.270 CEST [Thread-5] INFO  i.f.h.impl.ShutdownHandlerImpl - Closing component notification-to-mdsal-writer
+2019-05-20 16:39:03.271 CEST [Thread-5] INFO  i.f.h.impl.ShutdownHandlerImpl - Closing component netconf-notification-service-factory
+2019-05-20 16:39:04.292 CEST [Thread-5] INFO  i.f.h.impl.ShutdownHandlerImpl - Closing component notification-to-mdsal-writer
+2019-05-20 16:39:04.293 CEST [Thread-5] INFO  i.f.h.impl.ShutdownHandlerImpl - Closing component netconf-notification-service-factory
+2019-05-20 16:39:05.317 CEST [Thread-5] INFO  i.f.h.impl.ShutdownHandlerImpl - Closing component notification-to-mdsal-writer
+2019-05-20 16:39:05.319 CEST [Thread-5] INFO  i.f.h.impl.ShutdownHandlerImpl - Closing component netconf-notification-service-factory
diff --git a/tests/honeynode221/minimal-distribution-core/asciidoc/Readme.adoc b/tests/honeynode221/minimal-distribution-core/asciidoc/Readme.adoc
new file mode 100644 (file)
index 0000000..e8306c2
--- /dev/null
@@ -0,0 +1,3 @@
+= minimal-distribution-core
+
+Project contains core modules for minimal distribution
\ No newline at end of file
diff --git a/tests/honeynode221/minimal-distribution-core/pom.xml b/tests/honeynode221/minimal-distribution-core/pom.xml
new file mode 100644 (file)
index 0000000..f5bdf6a
--- /dev/null
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright (c) 2017 Cisco and/or its affiliates.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at:
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<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">
+    <parent>
+        <artifactId>impl-parent</artifactId>
+        <groupId>io.fd.honeycomb.common</groupId>
+        <version>1.18.01</version>
+        <relativePath/>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>io.fd.honeycomb.transportpce</groupId>
+    <artifactId>minimal-distribution-core</artifactId>
+    <version>1.18.01</version>
+    <name>${project.artifactId}</name>
+
+    <properties>
+        <commons-io.version>2.5</commons-io.version>
+        <osgi.core.version>5.0.0</osgi.core.version>
+        <!-- Core guice modules does not need any yang modules itself -->
+        <skip.module.list.generation>true</skip.module.list.generation>
+    </properties>
+
+    <dependencies>
+        <!-- TPCE dependencies -->
+        <dependency>
+            <groupId>io.fd.honeycomb.transportpce</groupId>
+            <artifactId>honeynode-plugin-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <!-- DI-->
+        <dependency>
+            <groupId>com.google.inject</groupId>
+            <artifactId>guice</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>net.jmob</groupId>
+            <artifactId>guice.conf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.inject.extensions</groupId>
+            <artifactId>guice-multibindings</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.fd.honeycomb</groupId>
+            <artifactId>binding-init</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <!-- ODL -->
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-data-impl</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-core-api</artifactId>
+        </dependency>
+
+
+        <!-- OSGI Even tough not running in OSGI, dependency needs to be here since some deprecated MD-SAL APIs rely on osgi core -->
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <version>${osgi.core.version}</version>
+        </dependency>
+
+        <!-- Northbound -->
+        <dependency>
+            <groupId>io.fd.honeycomb.northbound</groupId>
+            <artifactId>common</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <!-- HC -->
+        <dependency>
+            <groupId>io.fd.honeycomb</groupId>
+            <artifactId>cfg-init</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.fd.honeycomb</groupId>
+            <artifactId>notification-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.fd.honeycomb</groupId>
+            <artifactId>rpc-impl</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.fd.honeycomb</groupId>
+            <artifactId>data-impl</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.fd.honeycomb</groupId>
+            <artifactId>honeycomb-impl</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.fd.honeycomb</groupId>
+            <artifactId>notification-impl</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <!-- Utilities -->
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>${commons-io.version}</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/InitializationException.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/InitializationException.java
new file mode 100644 (file)
index 0000000..0ed530c
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro;
+
+/**
+ * Exception thrown when a failure occurs during HC initialization.
+ */
+public class InitializationException extends RuntimeException {
+
+    public InitializationException(final String s) {
+        super(s);
+    }
+
+    public InitializationException(final String s, final Throwable throwable) {
+        super(s, throwable);
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/activation/ActivationConfig.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/activation/ActivationConfig.java
new file mode 100644 (file)
index 0000000..ecda4ae
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.activation;
+
+import net.jmob.guice.conf.core.BindConfig;
+import net.jmob.guice.conf.core.InjectConfig;
+import net.jmob.guice.conf.core.Syntax;
+
+import java.util.Optional;
+
+@BindConfig(value = "activation", syntax = Syntax.JSON)
+public class ActivationConfig {
+
+    @InjectConfig("modules-resource-path")
+    public String modulesResourcePath;
+
+    @InjectConfig("yang-modules-index-path")
+    public String yangModulesIndexPath;
+
+    public String getModulesResourcePath() {
+        return Optional.ofNullable(modulesResourcePath).orElse("../modules/");
+    }
+
+    public String getYangModulesIndexPath() {
+        return Optional.ofNullable(yangModulesIndexPath).orElse("../yang-mapping/");
+    }
+
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/activation/ActivationModule.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/activation/ActivationModule.java
new file mode 100644 (file)
index 0000000..00f77a6
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.activation;
+
+import com.google.inject.AbstractModule;
+import net.jmob.guice.conf.core.ConfigurationModule;
+
+/**
+ * Module that provides set of modules activated by distribution and binds this set to be available
+ */
+public class ActivationModule extends AbstractModule {
+    @Override
+    protected void configure() {
+        install(ConfigurationModule.create());
+        requestInjection(ActivationConfig.class);
+        bind(ActiveModules.class).toProvider(ActiveModuleProvider.class).asEagerSingleton();
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/activation/ActiveModuleProvider.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/activation/ActiveModuleProvider.java
new file mode 100644 (file)
index 0000000..643af16
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.activation;
+
+import com.google.inject.Inject;
+import com.google.inject.Module;
+import com.google.inject.Provider;
+import io.fd.honeycomb.infra.distro.schema.ResourceLoader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Provides list of active modules for distribution
+ */
+public class ActiveModuleProvider implements Provider<ActiveModules>, ResourceLoader {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ActiveModuleProvider.class);
+
+    @Inject
+    private ActivationConfig config;
+
+    @Override
+    public ActiveModules get() {
+        return new ActiveModules(loadActiveModules(
+                aggregateResources(config.getModulesResourcePath())));
+    }
+
+    /**
+     * Provide unique set of active modules filtered from provided resources
+     */
+    static Set<Class<? extends Module>> loadActiveModules(@Nonnull final List<String> moduleNames) {
+        final ClassLoader classLoader = ActiveModuleProvider.class.getClassLoader();
+        LOG.info("Reading active modules configuration for distribution");
+
+        // process resources to resource modules
+        return moduleNames.stream()
+                .map(String::trim)
+                .filter(trimmedLine -> trimmedLine.length() != 0)
+                // filter out commented lines
+                .filter(nonEmptyLine -> !nonEmptyLine.startsWith("//"))
+                // filter duplicates
+                .distinct()
+                .map(validLine -> moduleNameToClass(validLine, classLoader))
+                // filters out classes that are not modules
+                .filter(ActiveModuleProvider::filterNonModules)
+                .collect(Collectors.toSet());
+    }
+
+    /**
+     * Aggregate all resources from provided relative path into a {@code List<String>}
+     */
+    public List<String> aggregateResources(final String relativePath) {
+        // must use universal approach of loading from folder/jar
+        // because of memory footprint benchmark
+        return new ArrayList<>(loadResourceContentsOnPath(relativePath));
+    }
+
+    private static boolean filterNonModules(final Class<?> clazz) {
+        final boolean isModule = Module.class.isAssignableFrom(clazz);
+        if (!isModule) {
+            LOG.warn("Class {} is provided in modules configuration, but is not a Module and will be ignored", clazz);
+        }
+        return isModule;
+    }
+
+    /**
+     * Loads class by provided name
+     */
+    private static Class<? extends Module> moduleNameToClass(final String name,
+                                                             final ClassLoader classLoader) {
+        try {
+            LOG.debug("Loading module class {}", name);
+            return (Class<? extends Module>) classLoader.loadClass(name);
+        } catch (ClassNotFoundException e) {
+            LOG.error("Unable to convert {} to class, make sure you've provided sources to classpath", name);
+            throw new IllegalStateException(
+                    "Unable to convert " + name + " to class, make sure you've provided sources to classpath", e);
+        }
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/activation/ActiveModules.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/activation/ActiveModules.java
new file mode 100644 (file)
index 0000000..601e9b6
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.activation;
+
+import com.google.inject.Module;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static java.lang.String.format;
+
+/**
+ * Provides static set of active activeModulesClasses
+ */
+public class ActiveModules {
+    private final Set<Class<? extends Module>> activeModulesClasses;
+
+    public ActiveModules(final Set<Class<? extends Module>> activeModulesClasses) {
+        this.activeModulesClasses = activeModulesClasses;
+    }
+
+    public Set<Class<? extends Module>> getActiveModulesClasses() {
+        return activeModulesClasses;
+    }
+
+    public Set<? extends Module> createModuleInstances() {
+        return activeModulesClasses.stream()
+                .map(moduleClass -> {
+                    try {
+                        return moduleClass.newInstance();
+                    } catch (InstantiationException | IllegalAccessException e) {
+                        throw new IllegalStateException(format("Unable to create instance of module %s", moduleClass),
+                                e);
+                    }
+                }).collect(Collectors.toSet());
+    }
+
+    @Override
+    public String toString() {
+        return "ActiveModules{" +
+                "activeModulesClasses=" + activeModulesClasses +
+                '}';
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/cfgattrs/CfgAttrsModule.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/cfgattrs/CfgAttrsModule.java
new file mode 100644 (file)
index 0000000..29e79a2
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.cfgattrs;
+
+import com.google.inject.AbstractModule;
+import net.jmob.guice.conf.core.ConfigurationModule;
+
+/**
+ * Load the configuration from json into HoneycombConfiguration and make it available.
+ */
+public class CfgAttrsModule extends AbstractModule {
+
+    @Override
+    protected void configure() {
+        install(ConfigurationModule.create());
+        // Inject non-dependency configuration
+        requestInjection(HoneycombConfiguration.class);
+    }
+
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/cfgattrs/HoneycombConfiguration.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/cfgattrs/HoneycombConfiguration.java
new file mode 100644 (file)
index 0000000..cfe1408
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.cfgattrs;
+
+import com.google.common.base.MoreObjects;
+import java.util.Optional;
+import net.jmob.guice.conf.core.BindConfig;
+import net.jmob.guice.conf.core.InjectConfig;
+import net.jmob.guice.conf.core.Syntax;
+
+/**
+ * This is the Java equivalent for honeyconb.json file. We use guice-config library to load all the config attributes
+ * into this class instance.
+ *
+ * The BindConfig annotation tells that honeycomb.json file should be looked up on classpath root.
+ */
+@BindConfig(value = "honeycomb", syntax = Syntax.JSON)
+public class HoneycombConfiguration {
+
+    @InjectConfig("persist-context")
+    public Optional<String> persistContext = Optional.of("true");
+    @InjectConfig("persisted-context-path")
+    public String peristContextPath;
+    @InjectConfig("persisted-context-restoration-type")
+    public String persistedContextRestorationType;
+    @InjectConfig("persist-config")
+    public Optional<String> persistConfig = Optional.of("true");
+    @InjectConfig("persisted-config-path")
+    public String peristConfigPath;
+    @InjectConfig("persisted-config-restoration-type")
+    public String persistedConfigRestorationType;
+    @InjectConfig("notification-service-queue-depth")
+    public int notificationServiceQueueDepth;
+
+    public boolean isConfigPersistenceEnabled() {
+        return persistConfig.isPresent() && Boolean.valueOf(persistConfig.get());
+    }
+
+    public boolean isContextPersistenceEnabled() {
+        return persistContext.isPresent() && Boolean.valueOf(persistContext.get());
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+            .add("peristContextPath", peristContextPath)
+            .add("persistedContextRestorationType", persistedContextRestorationType)
+            .add("peristConfigPath", peristConfigPath)
+            .add("persistedConfigRestorationType", persistedConfigRestorationType)
+            .add("notificationServiceQueueDepth", notificationServiceQueueDepth)
+            .toString();
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/BindingDataBrokerProvider.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/BindingDataBrokerProvider.java
new file mode 100644 (file)
index 0000000..a99235e
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.data;
+
+import com.google.inject.Inject;
+
+import io.fd.honeycomb.binding.init.ProviderTrait;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.impl.BindingDOMDataBrokerAdapter;
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+
+public final class BindingDataBrokerProvider extends ProviderTrait<DataBroker> {
+
+    @Inject
+    private DOMDataBroker domDataBroker;
+    @Inject
+    private BindingToNormalizedNodeCodec mappingService;
+
+    @Override
+    protected BindingDOMDataBrokerAdapter create() {
+        return new BindingDOMDataBrokerAdapter(domDataBroker, mappingService);
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/ConfigAndOperationalPipelineModule.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/ConfigAndOperationalPipelineModule.java
new file mode 100644 (file)
index 0000000..962f593
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2016, 2017 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.data;
+
+import com.google.inject.PrivateModule;
+import com.google.inject.Singleton;
+import com.google.inject.name.Names;
+
+import io.fd.honeycomb.data.ModifiableDataManager;
+import io.fd.honeycomb.data.ReadableDataManager;
+import io.fd.honeycomb.data.init.DataTreeInitializer;
+import io.fd.honeycomb.data.init.ShutdownHandler;
+import io.fd.honeycomb.impl.EmptyDomMountService;
+import io.fd.honeycomb.impl.ShutdownHandlerImpl;
+import io.fd.honeycomb.infra.distro.data.config.WriterRegistryProvider;
+import io.fd.honeycomb.infra.distro.data.oper.ReadableDTDelegProvider;
+import io.fd.honeycomb.infra.distro.data.oper.ReaderRegistryProvider;
+import io.fd.honeycomb.rpc.RpcRegistry;
+import io.fd.honeycomb.rpc.RpcRegistryBuilder;
+import io.fd.honeycomb.translate.read.registry.ReaderRegistry;
+import io.fd.honeycomb.translate.write.registry.WriterRegistry;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.opendaylight.controller.md.sal.dom.broker.impl.DOMNotificationRouter;
+import org.opendaylight.controller.sal.core.api.Broker;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
+
+public class ConfigAndOperationalPipelineModule extends PrivateModule {
+
+    public static final String HONEYCOMB_CONFIG_NONPERSIST = "honeycomb-config-nopersist";
+    public static final String HONEYCOMB_CONFIG = "honeycomb-config";
+
+    @Override
+    protected void configure() {
+        bind(ShutdownHandler.class).to(ShutdownHandlerImpl.class).in(Singleton.class);
+        expose(ShutdownHandler.class);
+
+        // Mount point service is required by notification service and restconf
+        bind(DOMMountPointService.class).to(EmptyDomMountService.class).in(Singleton.class);
+        expose(DOMMountPointService.class);
+
+        // Expose registries for plugin reader/writer factories
+        bind(WriterRegistry.class).toProvider(WriterRegistryProvider.class).in(Singleton.class);
+        expose(WriterRegistry.class);
+        bind(ReaderRegistry.class).toProvider(ReaderRegistryProvider.class).in(Singleton.class);
+        expose(ReaderRegistry.class);
+
+        // Non persisting data tree for config
+        bind(DataTree.class).annotatedWith(Names.named(HONEYCOMB_CONFIG_NONPERSIST))
+                .toProvider(DataTreeProvider.ConfigDataTreeProvider.class).in(Singleton.class);
+        expose(DataTree.class).annotatedWith(Names.named(HONEYCOMB_CONFIG_NONPERSIST));
+        // Persisting data tree wrapper for config
+        bind(DataTree.class).annotatedWith(Names.named(HONEYCOMB_CONFIG))
+                .toProvider(PersistingDataTreeProvider.ConfigPersistingDataTreeProvider.class).in(Singleton.class);
+        expose(DataTree.class).annotatedWith(Names.named(HONEYCOMB_CONFIG));
+
+        // Config Data Tree manager working on top of config data tree + writer registry
+        bind(ModifiableDataManager.class).toProvider(ModifiableDTDelegProvider.class).in(Singleton.class);
+        // Operational Data Tree manager working on top of reader registry
+        bind(ReadableDataManager.class).toProvider(ReadableDTDelegProvider.class).in(Singleton.class);
+        expose(ReadableDataManager.class);
+
+        // DOMDataBroker wrapper on top of data tree managers
+        HoneycombDOMDataBrokerProvider domBrokerProvider = new HoneycombDOMDataBrokerProvider();
+        bind(DOMDataBroker.class).annotatedWith(Names.named(HONEYCOMB_CONFIG)).toProvider(domBrokerProvider).in(Singleton.class);
+        expose(DOMDataBroker.class).annotatedWith(Names.named(HONEYCOMB_CONFIG));
+
+        // BA version of data broker
+        bind(DataBroker.class).annotatedWith(Names.named(HONEYCOMB_CONFIG)).toProvider(HoneycombBindingDataBrokerProvider.class)
+                .in(Singleton.class);
+        expose(DataBroker.class).annotatedWith(Names.named(HONEYCOMB_CONFIG));
+
+        // Create initializer to init persisted config data
+        bind(DataTreeInitializer.class).annotatedWith(Names.named(HONEYCOMB_CONFIG))
+                .toProvider(PersistedConfigInitializerProvider.class)
+                .in(Singleton.class);
+        expose(DataTreeInitializer.class).annotatedWith(Names.named(HONEYCOMB_CONFIG));
+
+        configureNotifications();
+        configureRpcs();
+    }
+
+    private void configureNotifications() {
+        // Create notification service
+        bind(DOMNotificationRouter.class).toProvider(DOMNotificationServiceProvider.class).in(Singleton.class);
+        expose(DOMNotificationRouter.class);
+        // Wrap notification service, data broker and schema service in a Broker MD-SAL API
+        bind(Broker.class).toProvider(HoneycombDOMBrokerProvider.class).in(Singleton.class);
+        expose(Broker.class);
+    }
+
+    private void configureRpcs() {
+        // Create rpc service
+        bind(DOMRpcService.class).toProvider(HoneycombDOMRpcServiceProvider.class).in(Singleton.class);
+        expose(DOMRpcService.class);
+
+        bind(RpcRegistryBuilder.class).toProvider(RpcRegistryBuilderProvider.class).in(Singleton.class);
+        expose(RpcRegistryBuilder.class);
+
+        bind(RpcRegistry.class).toProvider(RpcRegistryProvider.class).in(Singleton.class);
+        expose(RpcRegistry.class);
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/DOMNotificationServiceProvider.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/DOMNotificationServiceProvider.java
new file mode 100644 (file)
index 0000000..4c419a8
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.data;
+
+import com.google.inject.Inject;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration;
+import org.opendaylight.controller.md.sal.dom.broker.impl.DOMNotificationRouter;
+
+public final class DOMNotificationServiceProvider extends ProviderTrait<DOMNotificationRouter> {
+
+    @Inject
+    private HoneycombConfiguration cfg;
+
+    @Override
+    protected DOMNotificationRouter create() {
+        return DOMNotificationRouter.create(cfg.notificationServiceQueueDepth);
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/DataStoreProvider.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/DataStoreProvider.java
new file mode 100644 (file)
index 0000000..82b1ed3
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.data;
+
+import com.google.inject.Inject;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
+import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStoreFactory;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+
+public final class DataStoreProvider extends ProviderTrait<InMemoryDOMDataStore> {
+
+    @Inject
+    private SchemaService schemaService;
+    private String name;
+    private LogicalDatastoreType type;
+
+    public DataStoreProvider(final String name,
+                             final LogicalDatastoreType type) {
+        this.name = name;
+        this.type = type;
+    }
+
+    @Override
+    protected InMemoryDOMDataStore create() {
+        return InMemoryDOMDataStoreFactory.create(name, type, schemaService, false, null);
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/DataTreeProvider.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/DataTreeProvider.java
new file mode 100644 (file)
index 0000000..039a0ad
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.data;
+
+import com.google.inject.Inject;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.TipProducingDataTree;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.TreeType;
+import org.opendaylight.yangtools.yang.data.impl.schema.tree.InMemoryDataTreeFactory;
+
+public abstract class DataTreeProvider extends ProviderTrait<DataTree> {
+
+    @Inject
+    private SchemaService schemaService;
+    @Inject
+    private HoneycombConfiguration config;
+
+    @Override
+    public TipProducingDataTree create() {
+        TipProducingDataTree delegate = InMemoryDataTreeFactory.getInstance().create(getType());
+        delegate.setSchemaContext(schemaService.getGlobalContext());
+        return delegate;
+    }
+
+    public abstract TreeType getType();
+
+    public static class ConfigDataTreeProvider extends DataTreeProvider {
+        @Override
+        public TreeType getType() {
+            return TreeType.CONFIGURATION;
+        }
+
+    }
+
+    public static class ContextDataTreeProvider extends DataTreeProvider {
+        @Override
+        public TreeType getType() {
+            return TreeType.OPERATIONAL;
+        }
+
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/HoneycombBindingDataBrokerProvider.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/HoneycombBindingDataBrokerProvider.java
new file mode 100644 (file)
index 0000000..bbcd409
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.data;
+
+import static io.fd.honeycomb.infra.distro.data.ConfigAndOperationalPipelineModule.HONEYCOMB_CONFIG;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.impl.BindingDOMDataBrokerAdapter;
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+
+/**
+ * Provides binding adapter for {@link io.fd.honeycomb.data.impl.DataBroker}.
+ */
+final class HoneycombBindingDataBrokerProvider extends ProviderTrait<DataBroker> {
+
+    @Inject
+    @Named(HONEYCOMB_CONFIG)
+    private DOMDataBroker domDataBroker;
+    @Inject
+    private BindingToNormalizedNodeCodec mappingService;
+
+    @Override
+    protected BindingDOMDataBrokerAdapter create() {
+
+        return new BindingDOMDataBrokerAdapter(domDataBroker, mappingService);
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/HoneycombDOMBrokerProvider.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/HoneycombDOMBrokerProvider.java
new file mode 100644 (file)
index 0000000..7507686
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016, 2017 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.data;
+
+import static io.fd.honeycomb.infra.distro.data.ConfigAndOperationalPipelineModule.HONEYCOMB_CONFIG;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import io.fd.honeycomb.impl.NorthboundFacadeHoneycombDOMBroker;
+
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.opendaylight.controller.md.sal.dom.broker.impl.DOMNotificationRouter;
+import org.opendaylight.controller.sal.core.api.Broker;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+
+final class HoneycombDOMBrokerProvider extends ProviderTrait<Broker> {
+
+    @Inject
+    @Named(HONEYCOMB_CONFIG)
+    private DOMDataBroker domDataBroker;
+    @Inject
+    private SchemaService schemaService;
+    @Inject
+    private DOMNotificationRouter domNotificationService;
+    @Inject
+    private DOMRpcService domRpcService;
+    @Inject
+    private DOMMountPointService domMountPointService;
+
+    @Override
+    protected NorthboundFacadeHoneycombDOMBroker create() {
+        return new NorthboundFacadeHoneycombDOMBroker(domDataBroker, schemaService, domNotificationService,
+            domRpcService, domMountPointService);
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/HoneycombDOMDataBrokerProvider.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/HoneycombDOMDataBrokerProvider.java
new file mode 100644 (file)
index 0000000..ca94350
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.data;
+
+import com.google.inject.Inject;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import io.fd.honeycomb.data.ModifiableDataManager;
+import io.fd.honeycomb.data.ReadableDataManager;
+import io.fd.honeycomb.data.impl.DataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+
+public final class HoneycombDOMDataBrokerProvider extends ProviderTrait<DOMDataBroker> {
+
+    @Inject
+    private ModifiableDataManager modDataManager;
+    @Inject(optional = true)
+    private ReadableDataManager readDataManager;
+
+    @Override
+    protected DataBroker create() {
+        return readDataManager != null
+                ? DataBroker.create(modDataManager, readDataManager)
+                : DataBroker.create(modDataManager);
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/HoneycombDOMRpcServiceProvider.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/HoneycombDOMRpcServiceProvider.java
new file mode 100644 (file)
index 0000000..324d636
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.data;
+
+import com.google.inject.Inject;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import io.fd.honeycomb.rpc.HoneycombDOMRpcService;
+import io.fd.honeycomb.rpc.RpcRegistry;
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+
+public final class HoneycombDOMRpcServiceProvider extends ProviderTrait<DOMRpcService> {
+
+    @Inject
+    private BindingToNormalizedNodeCodec serializer;
+
+    @Inject
+    private RpcRegistry rpcRegistry;
+
+    @Override
+    protected DOMRpcService create() {
+        return new HoneycombDOMRpcService(serializer, rpcRegistry);
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/HoneycombNotificationManagerProvider.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/HoneycombNotificationManagerProvider.java
new file mode 100644 (file)
index 0000000..b318038
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.data;
+
+import com.google.common.collect.Lists;
+import com.google.inject.Inject;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import io.fd.honeycomb.notification.ManagedNotificationProducer;
+import io.fd.honeycomb.notification.NotificationCollector;
+import io.fd.honeycomb.notification.impl.HoneycombNotificationCollector;
+import io.fd.honeycomb.notification.impl.NotificationProducerRegistry;
+import io.fd.honeycomb.notification.impl.NotificationProducerTracker;
+import java.util.HashSet;
+import java.util.Set;
+import org.opendaylight.controller.md.sal.binding.impl.BindingDOMNotificationPublishServiceAdapter;
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.controller.md.sal.dom.broker.impl.DOMNotificationRouter;
+
+public final class HoneycombNotificationManagerProvider extends ProviderTrait<NotificationCollector> {
+
+    @Inject
+    private DOMNotificationRouter notificationRouter;
+    @Inject(optional = true)
+    private Set<ManagedNotificationProducer> notificationProducers = new HashSet<>();
+    @Inject
+    private BindingToNormalizedNodeCodec codec;
+
+    @Override
+    protected HoneycombNotificationCollector create() {
+        // Create the registry to keep track of what'OPERATIONAL registered
+        NotificationProducerRegistry notificationProducerRegistry =
+                new NotificationProducerRegistry(Lists.newArrayList(notificationProducers));
+
+        // Create BA version of notification service (implementation is free from ODL)
+        BindingDOMNotificationPublishServiceAdapter bindingDOMNotificationPublishServiceAdapter =
+                new BindingDOMNotificationPublishServiceAdapter(codec, notificationRouter);
+
+        // Create Collector on top of BA notification service and registry
+        HoneycombNotificationCollector honeycombNotificationCollector =
+                new HoneycombNotificationCollector(bindingDOMNotificationPublishServiceAdapter,
+                        notificationProducerRegistry);
+
+        // Create tracker, responsible for starting and stopping registered notification producers whenever necessary
+        NotificationProducerTracker notificationProducerTracker =
+                new NotificationProducerTracker(notificationProducerRegistry, honeycombNotificationCollector,
+                        notificationRouter);
+
+        // DOMNotificationService is already provided by DOMBroker injected into RESTCONF, however RESTCONF
+        // only supports data-change notification, nothing else. So currently (Beryllium-SR2) honeycomb notifications
+        // won't be available over RESTCONF.
+
+        return honeycombNotificationCollector;
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/InmemoryDOMDataBrokerProvider.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/InmemoryDOMDataBrokerProvider.java
new file mode 100644 (file)
index 0000000..8e003c2
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.data;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+
+import io.fd.honeycomb.binding.init.ProviderTrait;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitDeadlockException;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.broker.impl.SerializedDOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
+import org.opendaylight.controller.sal.core.spi.data.DOMStore;
+import org.opendaylight.yangtools.util.concurrent.DeadlockDetectingListeningExecutorService;
+import org.opendaylight.yangtools.util.concurrent.SpecialExecutors;
+
+public final class InmemoryDOMDataBrokerProvider extends ProviderTrait<DOMDataBroker> {
+
+    public static final String CONFIG = "config";
+    public static final String OPERATIONAL = "operational";
+
+    @Inject
+    @Named(InmemoryDOMDataBrokerProvider.CONFIG)
+    private InMemoryDOMDataStore cfgDataStore;
+    @Inject
+    @Named(InmemoryDOMDataBrokerProvider.OPERATIONAL)
+    private InMemoryDOMDataStore operDataStore;
+
+    @Override
+    protected SerializedDOMDataBroker create() {
+        // This Databroker is dedicated for netconf metadata, not expected to be under heavy load
+        ExecutorService listenableFutureExecutor =
+                SpecialExecutors.newBlockingBoundedCachedThreadPool(1, 100, "commits");
+        ExecutorService commitExecutor = SpecialExecutors.newBoundedSingleThreadExecutor(100, "WriteTxCommit");
+        // TODO HONEYCOMB-164 try to provide more lightweight implementation of DataBroker
+
+        Map<LogicalDatastoreType, DOMStore> map = new LinkedHashMap<>();
+        map.put(LogicalDatastoreType.CONFIGURATION, cfgDataStore);
+        map.put(LogicalDatastoreType.OPERATIONAL, operDataStore);
+
+        return new SerializedDOMDataBroker(map, new DeadlockDetectingListeningExecutorService(commitExecutor,
+                TransactionCommitDeadlockException.DEADLOCK_EXCEPTION_SUPPLIER, listenableFutureExecutor));
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/ModifiableDTDelegProvider.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/ModifiableDTDelegProvider.java
new file mode 100644 (file)
index 0000000..b2ed417
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.data;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import io.fd.honeycomb.data.ModifiableDataManager;
+import io.fd.honeycomb.data.impl.ModifiableDataTreeDelegator;
+import io.fd.honeycomb.infra.distro.data.context.ContextPipelineModule;
+import io.fd.honeycomb.translate.write.registry.WriterRegistry;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
+
+public final class ModifiableDTDelegProvider extends ProviderTrait<ModifiableDataManager> {
+
+    @Inject
+    private BindingToNormalizedNodeCodec serializer;
+    @Inject
+    private SchemaService schemaService;
+    @Inject
+    @Named(ConfigAndOperationalPipelineModule.HONEYCOMB_CONFIG)
+    private DataTree dataTree;
+    @Inject
+    private WriterRegistry registry;
+    @Inject
+    @Named(ContextPipelineModule.HONEYCOMB_CONTEXT)
+    private DataBroker contextBroker;
+
+    @Override
+    protected ModifiableDataTreeDelegator create() {
+        return new ModifiableDataTreeDelegator(serializer, dataTree, schemaService.getGlobalContext(),
+            registry, contextBroker);
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/PersistedConfigInitializerProvider.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/PersistedConfigInitializerProvider.java
new file mode 100644 (file)
index 0000000..caa5199
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.data;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import io.fd.honeycomb.data.init.RestoringInitializer;
+import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration;
+
+import java.nio.file.Paths;
+
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+final class PersistedConfigInitializerProvider extends ProviderTrait<RestoringInitializer> {
+    private static final Logger LOG = LoggerFactory.getLogger(PersistedConfigInitializerProvider.class);
+
+    @Inject
+    private SchemaService schemaService;
+    @Inject
+    protected HoneycombConfiguration cfgAttributes;
+    @Inject
+//    @Named(ConfigAndOperationalPipelineModule.HONEYCOMB_CONFIG)
+    //mofified to be able to restore config to device config datastore
+    @Named("device-databroker")
+    private DOMDataBroker domDataBroker;
+
+    @Override
+    public RestoringInitializer create() {
+        LOG.info("RestoringInitializer ...");
+        return new RestoringInitializer(schemaService, Paths.get(cfgAttributes.peristConfigPath), domDataBroker,
+                RestoringInitializer.RestorationType.valueOf(cfgAttributes.persistedConfigRestorationType),
+                LogicalDatastoreType.CONFIGURATION);
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/PersistingDataTreeProvider.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/PersistingDataTreeProvider.java
new file mode 100644 (file)
index 0000000..95c07cf
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.data;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import io.fd.honeycomb.data.impl.PersistingDataTreeAdapter;
+import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration;
+import io.fd.honeycomb.infra.distro.data.context.ContextPipelineModule;
+
+import java.nio.file.Paths;
+
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.TreeType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class PersistingDataTreeProvider extends ProviderTrait<DataTree> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(PersistingDataTreeProvider.class);
+
+    @Inject
+    private SchemaService schemaService;
+    @Inject
+    protected HoneycombConfiguration config;
+
+    @Override
+    public DataTree create() {
+        return isEnabled()
+                ? new PersistingDataTreeAdapter(getDelegate(), schemaService, Paths.get(getPath()))
+                : getDelegate();
+    }
+
+    public abstract String getPath();
+
+    public abstract TreeType getType();
+
+    public abstract DataTree getDelegate();
+
+    protected abstract boolean isEnabled();
+
+    public static final class ConfigPersistingDataTreeProvider extends PersistingDataTreeProvider {
+
+        @Inject
+        @Named(ConfigAndOperationalPipelineModule.HONEYCOMB_CONFIG_NONPERSIST)
+        private DataTree delegate;
+
+        @Override
+        public String getPath() {
+            return config.peristConfigPath;
+        }
+
+        @Override
+        public TreeType getType() {
+            return TreeType.CONFIGURATION;
+        }
+
+        @Override
+        public DataTree getDelegate() {
+            return delegate;
+        }
+
+        @Override
+        protected boolean isEnabled() {
+            return config.isConfigPersistenceEnabled();
+        }
+    }
+
+    public static final class ContextPersistingDataTreeProvider extends PersistingDataTreeProvider {
+
+        @Inject
+        @Named(ContextPipelineModule.HONEYCOMB_CONTEXT_NOPERSIST)
+        private DataTree delegate;
+
+        @Override
+        public String getPath() {
+            return config.peristContextPath;
+        }
+
+        @Override
+        public TreeType getType() {
+            return TreeType.OPERATIONAL;
+        }
+
+        @Override
+        public DataTree getDelegate() {
+            return delegate;
+        }
+
+        @Override
+        protected boolean isEnabled() {
+            return config.isContextPersistenceEnabled();
+        }
+
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/RpcRegistryBuilderProvider.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/RpcRegistryBuilderProvider.java
new file mode 100644 (file)
index 0000000..3184363
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.data;
+
+import com.google.inject.Inject;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import io.fd.honeycomb.rpc.RpcRegistryBuilder;
+import io.fd.honeycomb.rpc.RpcService;
+import java.util.HashSet;
+import java.util.Set;
+
+public final class RpcRegistryBuilderProvider extends ProviderTrait<RpcRegistryBuilder> {
+
+    @Inject(optional = true)
+    private Set<RpcService> rpcServices = new HashSet<>();
+
+    @Override
+    protected RpcRegistryBuilder create() {
+        final RpcRegistryBuilder builder = new RpcRegistryBuilder();
+        rpcServices.stream()
+                .forEach(service -> builder.addService(service));
+        return builder;
+    }
+
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/RpcRegistryProvider.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/RpcRegistryProvider.java
new file mode 100644 (file)
index 0000000..fd6499b
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.data;
+
+import com.google.inject.Inject;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import io.fd.honeycomb.rpc.RpcRegistry;
+import io.fd.honeycomb.rpc.RpcRegistryBuilder;
+
+public final class RpcRegistryProvider extends ProviderTrait<RpcRegistry> {
+
+    @Inject
+    private RpcRegistryBuilder builder;
+
+    @Override
+    protected RpcRegistry create() {
+        return builder.build();
+    }
+
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/config/WriterRegistryProvider.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/config/WriterRegistryProvider.java
new file mode 100644 (file)
index 0000000..fa37d10
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.data.config;
+
+import com.google.inject.Inject;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import io.fd.honeycomb.translate.impl.write.registry.FlatWriterRegistryBuilder;
+import io.fd.honeycomb.translate.util.YangDAG;
+import io.fd.honeycomb.translate.write.WriterFactory;
+import io.fd.honeycomb.translate.write.registry.WriterRegistry;
+import java.util.HashSet;
+import java.util.Set;
+
+public final class WriterRegistryProvider extends ProviderTrait<WriterRegistry> {
+
+    @Inject(optional = true)
+    private Set<WriterFactory> writerFactories = new HashSet<>();
+
+    @Override
+    protected WriterRegistry create() {
+        final FlatWriterRegistryBuilder builder = new FlatWriterRegistryBuilder(new YangDAG());
+        writerFactories
+                .stream()
+                .forEach(it -> it.init(builder));
+        return builder.build();
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/context/ContextPipelineModule.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/context/ContextPipelineModule.java
new file mode 100644 (file)
index 0000000..b004efd
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.data.context;
+
+import com.google.inject.PrivateModule;
+import com.google.inject.Singleton;
+import com.google.inject.name.Names;
+import io.fd.honeycomb.data.ModifiableDataManager;
+import io.fd.honeycomb.data.init.DataTreeInitializer;
+import io.fd.honeycomb.infra.distro.data.BindingDataBrokerProvider;
+import io.fd.honeycomb.infra.distro.data.DataTreeProvider;
+import io.fd.honeycomb.infra.distro.data.PersistingDataTreeProvider;
+import io.fd.honeycomb.translate.MappingContext;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
+
+public class ContextPipelineModule extends PrivateModule {
+
+    public static final String HONEYCOMB_CONTEXT_NOPERSIST = "honeycomb-context-nopersist";
+    public static final String HONEYCOMB_CONTEXT = "honeycomb-context";
+
+    @Override
+    protected void configure() {
+        // Non persisting data tree for context
+        DataTreeProvider.ContextDataTreeProvider noPersistDataTreeProvider =
+                new DataTreeProvider.ContextDataTreeProvider();
+        bind(DataTree.class).annotatedWith(Names.named(HONEYCOMB_CONTEXT_NOPERSIST))
+                .toProvider(noPersistDataTreeProvider).in(Singleton.class);
+        expose(DataTree.class).annotatedWith(Names.named(HONEYCOMB_CONTEXT_NOPERSIST));
+        // Persisting data tree wrapper for context
+        PersistingDataTreeProvider.ContextPersistingDataTreeProvider dataTreeProvider =
+                new PersistingDataTreeProvider.ContextPersistingDataTreeProvider();
+        bind(DataTree.class).toProvider(dataTreeProvider).in(Singleton.class);
+
+        // Data Tree manager (without any delegation) on top of context data tree
+        bind(ModifiableDataManager.class).toProvider(ModifiableDTMgrProvider.class).in(Singleton.class);
+
+        // DOMDataBroker interface on top of data tree manager
+        HoneycombContextDOMDataBrokerProvider domBrokerProvider = new HoneycombContextDOMDataBrokerProvider();
+        bind(DOMDataBroker.class).toProvider(domBrokerProvider).in(Singleton.class);
+
+        // BA version of data broker for context
+        bind(DataBroker.class).annotatedWith(Names.named(HONEYCOMB_CONTEXT)).toProvider(BindingDataBrokerProvider.class)
+                .in(Singleton.class);
+        expose(DataBroker.class).annotatedWith(Names.named(HONEYCOMB_CONTEXT));
+
+        // Create initializer to init persisted config data
+        bind(DataTreeInitializer.class).annotatedWith(Names.named(HONEYCOMB_CONTEXT))
+                .toProvider(PersistedContextInitializerProvider.class)
+                .in(Singleton.class);
+        expose(DataTreeInitializer.class).annotatedWith(Names.named(HONEYCOMB_CONTEXT));
+
+        // Mapping context is just a small adapter on top of BA data broker to simplify CRUD of context data
+        bind(MappingContext.class).annotatedWith(Names.named(HONEYCOMB_CONTEXT))
+                .toProvider(RealtimeMappingContextProvider.class).in(Singleton.class);
+        expose(MappingContext.class).annotatedWith(Names.named(HONEYCOMB_CONTEXT));
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/context/HoneycombContextDOMDataBrokerProvider.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/context/HoneycombContextDOMDataBrokerProvider.java
new file mode 100644 (file)
index 0000000..4c3965f
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.data.context;
+
+import com.google.inject.Inject;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import io.fd.honeycomb.data.ModifiableDataManager;
+import io.fd.honeycomb.data.impl.DataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+
+public final class HoneycombContextDOMDataBrokerProvider extends ProviderTrait<DOMDataBroker> {
+
+    @Inject
+    private ModifiableDataManager modDataManager;
+
+    @Override
+    public DataBroker create() {
+        return DataBroker.create(modDataManager);
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/context/ModifiableDTMgrProvider.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/context/ModifiableDTMgrProvider.java
new file mode 100644 (file)
index 0000000..c703e95
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.data.context;
+
+import com.google.inject.Inject;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import io.fd.honeycomb.data.ModifiableDataManager;
+import io.fd.honeycomb.data.impl.ModifiableDataTreeManager;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
+
+public final class ModifiableDTMgrProvider extends ProviderTrait<ModifiableDataManager> {
+
+    @Inject
+    private DataTree dataTree;
+
+    @Override
+    public ModifiableDataTreeManager create() {
+        return new ModifiableDataTreeManager(dataTree);
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/context/PersistedContextInitializerProvider.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/context/PersistedContextInitializerProvider.java
new file mode 100644 (file)
index 0000000..6d256d8
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.data.context;
+
+import com.google.inject.Inject;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import io.fd.honeycomb.data.init.RestoringInitializer;
+import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration;
+import java.nio.file.Paths;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+
+final class PersistedContextInitializerProvider extends ProviderTrait<RestoringInitializer> {
+
+    @Inject
+    private SchemaService schemaService;
+    @Inject
+    protected HoneycombConfiguration cfgAttributes;
+    // injects data broker from within context of private module
+    @Inject
+    private DOMDataBroker domDataBroker;
+
+    @Override
+    public RestoringInitializer create() {
+        return new RestoringInitializer(schemaService, Paths.get(cfgAttributes.peristContextPath), domDataBroker,
+                RestoringInitializer.RestorationType.valueOf(cfgAttributes.persistedContextRestorationType),
+                LogicalDatastoreType.OPERATIONAL);
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/context/RealtimeMappingContextProvider.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/context/RealtimeMappingContextProvider.java
new file mode 100644 (file)
index 0000000..3f39ce1
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.data.context;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import io.fd.honeycomb.translate.MappingContext;
+import io.fd.honeycomb.translate.util.RealtimeMappingContext;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+
+public final class RealtimeMappingContextProvider extends ProviderTrait<MappingContext> {
+
+    @Inject
+    @Named(ContextPipelineModule.HONEYCOMB_CONTEXT)
+    private DataBroker contextDataBroker;
+
+    @Override
+    public RealtimeMappingContext create() {
+        return new RealtimeMappingContext(contextDataBroker);
+    }
+
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/oper/ReadableDTDelegProvider.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/oper/ReadableDTDelegProvider.java
new file mode 100644 (file)
index 0000000..cdd3596
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.data.oper;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import io.fd.honeycomb.data.ReadableDataManager;
+import io.fd.honeycomb.data.impl.ReadableDataTreeDelegator;
+import io.fd.honeycomb.infra.distro.data.context.ContextPipelineModule;
+import io.fd.honeycomb.translate.read.registry.ReaderRegistry;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+
+public final class ReadableDTDelegProvider extends ProviderTrait<ReadableDataManager> {
+
+    @Inject
+    private BindingToNormalizedNodeCodec serializer;
+    @Inject
+    private SchemaService schemaService;
+    @Inject
+    private ReaderRegistry registry;
+    @Inject
+    @Named(ContextPipelineModule.HONEYCOMB_CONTEXT)
+    private DataBroker contextBroker;
+
+    @Override
+    protected ReadableDataTreeDelegator create() {
+        return new ReadableDataTreeDelegator(serializer, schemaService.getGlobalContext(),
+                registry, contextBroker);
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/oper/ReaderRegistryProvider.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/data/oper/ReaderRegistryProvider.java
new file mode 100644 (file)
index 0000000..8e0b776
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.data.oper;
+
+import com.google.inject.Inject;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import io.fd.honeycomb.translate.impl.read.registry.CompositeReaderRegistryBuilder;
+import io.fd.honeycomb.translate.read.ReaderFactory;
+import io.fd.honeycomb.translate.read.registry.ReaderRegistry;
+import io.fd.honeycomb.translate.util.YangDAG;
+import java.util.HashSet;
+import java.util.Set;
+
+public final class ReaderRegistryProvider extends ProviderTrait<ReaderRegistry> {
+
+    @Inject(optional = true)
+    private Set<ReaderFactory> readerFactories = new HashSet<>();
+
+    @Override
+    protected ReaderRegistry create() {
+        final CompositeReaderRegistryBuilder builder = new CompositeReaderRegistryBuilder(new YangDAG());
+        readerFactories.stream()
+            .forEach(it -> it.init(builder));
+        return builder.build();
+    }
+
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/initializer/DeviceChangeListener.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/initializer/DeviceChangeListener.java
new file mode 100644 (file)
index 0000000..a2543f3
--- /dev/null
@@ -0,0 +1,426 @@
+/*
+ * Copyright (c) 2018 Orange and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fd.honeycomb.infra.distro.initializer;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.circuit.pack.Ports;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.circuit.pack.PortsBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.circuit.packs.CircuitPacks;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.circuit.packs.CircuitPacksKey;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.interfaces.grp.Interface;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.interfaces.grp.InterfaceKey;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.OrgOpenroadmDevice;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.OrgOpenroadmDeviceBuilder;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.org.openroadm.device.RoadmConnections;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.org.openroadm.device.RoadmConnectionsKey;
+import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.port.InterfacesBuilder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Martial COULIBALY ( mcoulibaly.ext@orange.com ) on behalf of Orange
+ */
+final class DeviceChangeListener implements DataTreeChangeListener<OrgOpenroadmDevice> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(DeviceChangeListener.class);
+    private final DataBroker honeyCombDB;
+    private final DataBroker dataBroker;
+
+    public DeviceChangeListener(DataBroker deviceDataBroker, DataBroker honeycombDB) {
+        this.dataBroker = deviceDataBroker;
+        this.honeyCombDB = honeycombDB;
+        Preconditions.checkArgument(this.dataBroker != null, "Device datastore is null");
+        Preconditions.checkArgument(this.honeyCombDB != null, "HC datastore is null");
+    }
+
+    @Override
+    public void onDataTreeChanged(Collection<DataTreeModification<OrgOpenroadmDevice>> changes) {
+        LOG.info("onDataTreeChanged");
+        for (DataTreeModification<OrgOpenroadmDevice> change : changes) {
+            final DataObjectModification<OrgOpenroadmDevice> rootNode = change.getRootNode();
+            final DataTreeIdentifier<OrgOpenroadmDevice> rootPath = change.getRootPath();
+            if (rootNode != null ) {
+                final OrgOpenroadmDevice dataBefore = rootNode.getDataBefore();
+                final OrgOpenroadmDevice dataAfter = rootNode.getDataAfter();
+                LOG.info("Received Device change({}):\n before={} \n after={}", rootNode.getModificationType(), dataBefore,
+                        dataAfter);
+                Collection<DataObjectModification<? extends DataObject>> modifiedChildren = rootNode.getModifiedChildren();
+                switch (rootNode.getModificationType()) {
+                    case SUBTREE_MODIFIED:
+                        if (!modifiedChildren.isEmpty()) {
+                            Iterator<DataObjectModification<? extends DataObject>> iterator = modifiedChildren.iterator();
+                            while (iterator.hasNext()) {
+                                DataObjectModification<? extends DataObject> modified = iterator.next();
+                                LOG.info("modified = \ndataType : {}\nid : {}\nmodifiedType : {}\noldData : {}\nnewData : {} \n",
+                                        modified.getDataType(), modified.getIdentifier(),modified.getModificationType(),
+                                        modified.getDataBefore(), modified.getDataAfter());
+                                switch (modified.getModificationType()) {
+                                  case SUBTREE_MODIFIED:
+                                  case WRITE :
+                                      processChange(rootPath.getRootIdentifier(), modified, dataAfter);
+                                      updateCircuitPackInterface(rootPath.getRootIdentifier(), modified, dataAfter,
+                                              false);
+                                      break;
+                                  case DELETE:
+                                      updateCircuitPackInterface(rootPath.getRootIdentifier(), modified, dataBefore,
+                                              true);
+                                      deleteContainer(rootPath, modified);
+                                      break;
+                                  default:
+                                      break;
+                               }
+                            }
+                        }
+                        //processChange(rootPath.getRootIdentifier(), dataAfter);
+                        break;
+                    case WRITE :
+                        processChange(rootPath.getRootIdentifier(), null, dataAfter);
+                        break;
+                    case DELETE:
+                        deleteChange(rootPath.getRootIdentifier(),dataBefore);
+                        break;
+                    default:
+                        break;
+                }
+            } else {
+                LOG.error("rootNode is null !");
+            }
+        }
+    }
+
+    /**
+     * Delete change from device
+     * oper datastore.
+     *
+     * @param id container identifier
+     */
+    private void deleteContainer(DataTreeIdentifier<OrgOpenroadmDevice> rootPath,
+            DataObjectModification<? extends DataObject> modified) {
+        final String ROADM_CONNECTIONS = "interface org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206"
+                + ".org.openroadm.device.container.org.openroadm.device.RoadmConnections";
+        final String INTERFACE_GRP = "interface org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206"
+                + ".interfaces.grp.Interface";
+        Class<? extends DataObject> type = modified.getDataType();
+        PathArgument path = modified.getIdentifier();
+        LOG.info("deleting container type '{}' with id '{}' ...", type.toString(), path);
+        String key = extractKey(path.toString());
+        if ( key != null) {
+            InstanceIdentifier<?> iid = null;
+            switch (type.toString()) {
+                case ROADM_CONNECTIONS:
+                    LOG.info("roadm-connections ...");
+                    iid = rootPath.getRootIdentifier().child(RoadmConnections.class,
+                        new RoadmConnectionsKey(key));
+                    break;
+                case INTERFACE_GRP:
+                    LOG.info("interface ....");
+                    iid = rootPath.getRootIdentifier().child(Interface.class,
+                            new InterfaceKey(key));
+                default:
+                    break;
+            }
+            LOG.info("iid : {}", iid);
+            WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
+            WriteTransaction writeHCTx = this.honeyCombDB.newWriteOnlyTransaction();
+            if (writeTx != null && writeHCTx != null) {
+                LOG.info("WriteTransaction is ok, delete container device from device oper datastore");
+                try {
+                    LOG.info("deleting container element from device oper DS ...");
+                    writeTx.delete(LogicalDatastoreType.OPERATIONAL, iid);
+                    Future<Void> future = writeTx.submit();
+                    future.get();
+                    LOG.info("container element '{}' deleted from device oper datastore", iid);
+//                    LOG.info("deleting from HC config DS ...");
+//                    OrgOpenroadmDevice readDevice = readDeviceConfigData(rootPath.getRootIdentifier());
+//                    if (readDevice != null) {
+//                        writeHCTx.put(LogicalDatastoreType.CONFIGURATION, rootPath.getRootIdentifier(), readDevice);
+//                        future = writeHCTx.submit();
+//                        future.get();
+//                        LOG.info("device config DS '{}' updated to HC config DS", rootPath.getRootIdentifier());
+//                    } else {
+//                        LOG.error("failed to get device info from config datastore !");
+//                    }
+                } catch (InterruptedException | ExecutionException e) {
+                    LOG.error("Failed to process WriteTransactions",e);
+                }
+            } else {
+                LOG.error("WriteTransaction object is null");
+            }
+        } else {
+            LOG.error("extract key is null");
+        }
+    }
+
+
+
+    private String extractKey(String path) {
+        LOG.info("getting key from pathArgument ...");
+        String result = null;
+        if (path != null && path.length() > 2) {
+            result = path.substring(path.lastIndexOf("=") + 1, path.length()-2);
+            LOG.info("result : {}", result);
+        } else {
+            LOG.error("String pathArgument is not compliant !!");
+        }
+        return result;
+    }
+
+    /**
+     * Delete change from Honeycomb
+     * config datastore.
+     *
+     * @param id OrgOpenroadmDevice identifier
+     * @param dataBefore OrgOpenroadmDevice before delete action
+     */
+    private void deleteChange(final InstanceIdentifier<OrgOpenroadmDevice> id, final OrgOpenroadmDevice dataBefore) {
+        LOG.info("deleting change ...");
+        WriteTransaction writeHCTx = this.honeyCombDB.newWriteOnlyTransaction();
+        if (writeHCTx != null) {
+            LOG.info("WriteTransaction is ok, delete device info from HC config datastore");
+            if(dataBefore != null) {
+                String deviceId = dataBefore.getInfo().getNodeId().getValue();
+                try {
+                    writeHCTx.delete(LogicalDatastoreType.CONFIGURATION, id);
+                    Future<Void> future = writeHCTx.submit();
+                    future.get();
+                    LOG.info("device '{}' deleted from HC config  datastore", deviceId);
+                } catch (InterruptedException | ExecutionException e) {
+                    LOG.error("Failed to delete Element '{}' from datastore", deviceId);
+                }
+            } else {
+                LOG.error("OrgOpenroadmDevice is null");
+            }
+        } else {
+            LOG.error("WriteTransaction object is null");
+        }
+
+    }
+
+    /**
+     * Merge change to Honeycomb
+     * config datastore and device
+     * config datastore.
+     *
+     * @param id OrgOpenroadmDevice identifier
+     * @param dataAfter OrgOpenroadmDevice to be merged
+     */
+    private void processChange(final InstanceIdentifier<OrgOpenroadmDevice> id,
+            DataObjectModification<? extends DataObject> modified, final OrgOpenroadmDevice dataAfter) {
+        LOG.info("processing change ...");
+        WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
+        WriteTransaction writeHCTx = this.honeyCombDB.newWriteOnlyTransaction();
+        if (writeTx != null && writeHCTx != null) {
+            LOG.info("WriteTransactions are ok, merge device info to datastores");
+            if(dataAfter != null) {
+                String deviceId = dataAfter.getInfo().getNodeId().getValue();
+                writeTx.merge(LogicalDatastoreType.OPERATIONAL, id, dataAfter);
+                Future<Void> future = writeTx.submit();
+                try {
+                    future.get();
+                    LOG.info("device '{}' merged to device oper datastore", deviceId);
+//                    OrgOpenroadmDevice readDevice = readDeviceConfigData(id);
+//                    if (readDevice != null) {
+//                        writeHCTx.put(LogicalDatastoreType.CONFIGURATION, id, readDevice);
+//                        future = writeHCTx.submit();
+//                        future.get();
+//                        LOG.info("device '{}' merged to HC config datastore", deviceId);
+//                    } else {
+//                        LOG.error("failed to get device info from config datastore !");
+//                    }
+                } catch (InterruptedException | ExecutionException e) {
+                    LOG.error("Failed to merge Element '{}' to datastores", deviceId);
+                }
+            } else {
+                LOG.error("device is null");
+            }
+        } else {
+            LOG.error("WriteTransaction object is null");
+        }
+    }
+
+    /**
+     *Update Interface info on
+     *Ports list in CircuitPacks.
+     *
+     * @param id device InstanceIdentifier
+     * @param modified DataObjectModification
+     * @param deviceData OrgOpenroadmDevice
+     * @param delete if yes delete interface from circuitpacks else adding interface
+     */
+    private void updateCircuitPackInterface(final InstanceIdentifier<OrgOpenroadmDevice> id,
+            DataObjectModification<? extends DataObject> modified, final OrgOpenroadmDevice deviceData,
+            boolean delete) {
+        LOG.info("Updating circuit packs interface ...");
+        final String INTERFACE_GRP = "interface org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206"
+                + ".interfaces.grp.Interface";
+        InstanceIdentifier<CircuitPacks> iid = null;
+        if (modified != null) {
+            Class<? extends DataObject> type = modified.getDataType();
+            LOG.info("getting container type '{}' ...", type.toString());
+            if (type != null) {
+                if (type.toString().compareTo(INTERFACE_GRP) == 0) {
+                    LOG.warn("interface update ! ");
+                    Interface data = null;
+                    if (delete) {
+                        data = (Interface) modified.getDataBefore();
+                    } else {
+                        data = (Interface) modified.getDataAfter();
+                    }
+                    LOG.info("Interface data gets : {}", data.toString());
+                    if (data!= null) {
+                        String circuitPackName = data.getSupportingCircuitPackName();
+                        String port = data.getSupportingPort().toString();
+                        String interfaceName = data.getName();
+                        if (circuitPackName != null && port != null && interfaceName != null) {
+                            iid = id.child(CircuitPacks.class,
+                                    new CircuitPacksKey(circuitPackName));
+                            OrgOpenroadmDeviceBuilder builder = new OrgOpenroadmDeviceBuilder(deviceData);
+                            List<CircuitPacks> list = builder.getCircuitPacks();
+                            LOG.info("Getting circuit packs ...");
+                            for (CircuitPacks circuitPacks : list) {
+                                if (circuitPacks.getCircuitPackName().compareTo(circuitPackName) == 0) {
+                                    LOG.info("circuitpack found");
+                                    List<Ports> portList = circuitPacks.getPorts();
+                                    LOG.info("Getting ports for circuit pack '{}' ...", circuitPackName);
+                                    for (Ports ports : portList) {
+                                        if (ports.getPortName().compareTo(port) == 0 ) {
+                                            LOG.info("port found");
+                                            PortsBuilder newPorts = new PortsBuilder(ports);
+                                            List<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019
+                                            .port.Interfaces> value;
+                                            if (!delete) {
+                                                LOG.info("adding interface info to port '{}'", port);
+                                                value = new ArrayList<org.opendaylight.yang.gen.v1.http.org.openroadm
+                                                        .device.rev181019.port.Interfaces>();
+                                                value.add(new InterfacesBuilder().setInterfaceName(interfaceName)
+                                                        .build());
+                                            } else {
+                                                LOG.info("removing interface info from port '{}'", port);
+                                                value = newPorts.getInterfaces();
+                                                if (value != null) {
+                                                    LOG.info("Getting interfaces list ...");
+                                                    for (org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019
+                                                            .port.Interfaces tmp : value) {
+                                                        if( tmp != null
+                                                                && tmp.getInterfaceName().compareTo(interfaceName) == 0) {
+                                                            LOG.info("Interfaces with name '{}' gets",interfaceName);
+                                                            value.remove(tmp);
+                                                            break;
+                                                        }
+                                                    }
+                                                } else {
+                                                    LOG.error("Interfaces list is null");
+                                                    value = new ArrayList<org.opendaylight.yang.gen.v1.http.org.openroadm
+                                                            .device.rev181019.port.Interfaces>();
+                                                }
+                                            }
+                                            newPorts.setInterfaces(value);
+                                            portList.remove(ports);
+                                            portList.add(newPorts.build());
+                                            LOG.info("port list updated !");
+                                            update(circuitPacks, iid);
+                                            break;
+                                        }
+                                    }
+                                    break;
+                                }
+                            }
+                        } else {
+                            LOG.error("SupportingCircuitPackName / SupportingPort / Interfcae Name are/is null !");
+                        }
+                    }
+                } else {
+                    LOG.warn("not an interface update ! ");
+                }
+            }
+        } else {
+            LOG.error("DataObjectModification is null");
+        }
+    }
+
+    /**
+     * Update circuitPacks information
+     * in device oper datastore.
+     *
+     * @param circuitPacks CircuitPacks data
+     * @param iid CircuitPacks InstanceIdentifier
+     * @param id OrgOpenroadmDevice InstanceIdentifier
+     * @param deviceData OrgOpenroadmDevice data
+     */
+    private void update(CircuitPacks circuitPacks, final InstanceIdentifier<CircuitPacks> iid) {
+        LOG.info("updating oper Datastore with iid : {}", iid);
+        WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
+        WriteTransaction writeHCTx = this.honeyCombDB.newWriteOnlyTransaction();
+        if (writeTx != null && writeHCTx != null) {
+            LOG.info("WriteTransaction is ok, update container circuitpacks from device oper datastore");
+            try {
+                LOG.info("updating container circuitpacks from device oper DS ...");
+                writeTx.merge(LogicalDatastoreType.OPERATIONAL, iid,circuitPacks);
+                Future<Void> future = writeTx.submit();
+                future.get();
+                LOG.info("container circuitpacks '{}' merged to device oper datastore", iid);
+            } catch (InterruptedException | ExecutionException e) {
+                LOG.error("Failed to process WriteTransactions",e);
+            }
+        } else {
+            LOG.error("WriteTransaction object is null");
+        }
+    }
+
+    private OrgOpenroadmDevice readDeviceConfigData(final InstanceIdentifier<OrgOpenroadmDevice> id) {
+        OrgOpenroadmDevice result = null;
+        LOG.info("reading device configuartion datastore ...");
+        ReadTransaction readTx = this.dataBroker.newReadOnlyTransaction();
+        if (readTx != null) {
+            LOG.info("ReadTransaction is ok");
+            try {
+                LOG.info("reading device from device config DS ...");
+                Optional<OrgOpenroadmDevice> device = readTx.read(LogicalDatastoreType.CONFIGURATION, id).get();
+                if (device.isPresent()) {
+                    result = device.get();
+                    LOG.info("device gets from device config datastore");
+                }
+            } catch (InterruptedException | ExecutionException e) {
+                LOG.error("Failed to process ReadTransaction",e);
+            }
+        } else {
+            LOG.error("WriteTransaction object is null");
+        }
+        return result;
+
+    }
+
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/initializer/InitializerPipelineModule.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/initializer/InitializerPipelineModule.java
new file mode 100644 (file)
index 0000000..0ddcf2e
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.initializer;
+
+import com.google.inject.PrivateModule;
+import com.google.inject.Singleton;
+import com.google.inject.name.Names;
+import io.fd.honeycomb.data.ModifiableDataManager;
+import io.fd.honeycomb.data.init.InitializerRegistry;
+import io.fd.honeycomb.infra.distro.data.BindingDataBrokerProvider;
+import io.fd.honeycomb.infra.distro.data.HoneycombDOMDataBrokerProvider;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+
+public final class InitializerPipelineModule extends PrivateModule {
+
+    public static final String HONEYCOMB_INITIALIZER = "honeycomb-initializer";
+
+    @Override
+    protected void configure() {
+        // Create data tree manager on top of non-persisting config data tree
+        bind(ModifiableDataManager.class).toProvider(ModifiableDTDelegInitProvider.class).in(Singleton.class);
+        // Wrap as DOMDataBroker
+        bind(DOMDataBroker.class).toProvider(HoneycombDOMDataBrokerProvider.class).in(Singleton.class);
+        // Wrap as BA data broker
+        bind(DataBroker.class).annotatedWith(Names.named(HONEYCOMB_INITIALIZER))
+                .toProvider(BindingDataBrokerProvider.class).in(Singleton.class);
+        expose(DataBroker.class).annotatedWith(Names.named(HONEYCOMB_INITIALIZER));
+
+        // Create initializer registry so that plugins can provide their initializers
+        bind(InitializerRegistry.class).annotatedWith(Names.named(HONEYCOMB_INITIALIZER))
+                .toProvider(InitializerRegistryAdapterProvider.class).in(Singleton.class);
+        expose(InitializerRegistry.class).annotatedWith(Names.named(HONEYCOMB_INITIALIZER));
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/initializer/InitializerRegistryAdapter.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/initializer/InitializerRegistryAdapter.java
new file mode 100644 (file)
index 0000000..23b0d1f
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.initializer;
+
+import io.fd.honeycomb.data.init.DataTreeInitializer;
+import io.fd.honeycomb.data.init.InitializerRegistry;
+import io.fd.honeycomb.translate.MappingContext;
+import io.fd.honeycomb.translate.ModificationCache;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.registry.InitRegistry;
+
+import javax.annotation.Nonnull;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+final class InitializerRegistryAdapter implements InitializerRegistry {
+
+    private static final Logger LOG = LoggerFactory.getLogger(InitializerRegistryAdapter.class);
+
+    private final DataTreeInitializer configInitializer;
+    private final DataTreeInitializer contextInitializer;
+    private final InitRegistry initRegistry;
+    private final DataBroker dataBroker;
+    private final MappingContext realtimeMappingContext;
+
+    InitializerRegistryAdapter(final DataTreeInitializer configInitializer,
+                               final DataTreeInitializer contextInitializer,
+                               final InitRegistry initRegistry,
+                               final DataBroker noopConfigDataBroker,
+                               final MappingContext realtimeMappingContext) {
+        this.configInitializer = configInitializer;
+        this.contextInitializer = contextInitializer;
+        this.initRegistry = initRegistry;
+        this.dataBroker = noopConfigDataBroker;
+        this.realtimeMappingContext = realtimeMappingContext;
+    }
+
+    @Override
+    public void initialize() throws DataTreeInitializer.InitializeException {
+        LOG.info("Config initialization started");
+        try {
+            // Initialize contexts first so that other initializers can find any relevant mapping before initializing
+            // configuration to what is already in VPP
+            contextInitializer.initialize();
+            LOG.info("Persisted context restored successfully");
+            // Initialize all registered initializers
+            initRegistry.initAll(dataBroker, new InitReadContext(realtimeMappingContext));
+            LOG.info("Configuration initialized successfully");
+            // Initialize stored configuration on top
+            configInitializer.initialize();
+            LOG.info("Persisted configuration restored successfully");
+        } catch (Exception e) {
+            LOG.warn("Failed to initialize config", e);
+        }
+
+        LOG.info("Honeycomb initialized");
+    }
+
+    private static final class InitReadContext implements ReadContext {
+
+        private final ModificationCache modificationCache;
+        private final MappingContext realtimeMappingContext;
+
+        InitReadContext(final MappingContext realtimeMappingContext) {
+            modificationCache = new ModificationCache();
+            this.realtimeMappingContext = realtimeMappingContext;
+        }
+
+        @Nonnull
+        @Override
+        public ModificationCache getModificationCache() {
+            return modificationCache;
+        }
+
+        @Nonnull
+        @Override
+        public MappingContext getMappingContext() {
+            return realtimeMappingContext;
+        }
+
+        @Override
+        public void close() {
+            modificationCache.close();
+        }
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/initializer/InitializerRegistryAdapterProvider.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/initializer/InitializerRegistryAdapterProvider.java
new file mode 100644 (file)
index 0000000..8d0782f
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.initializer;
+
+import static io.fd.honeycomb.infra.distro.data.ConfigAndOperationalPipelineModule.HONEYCOMB_CONFIG;
+import static io.fd.honeycomb.infra.distro.data.context.ContextPipelineModule.HONEYCOMB_CONTEXT;
+import static io.fd.honeycomb.infra.distro.initializer.InitializerPipelineModule.HONEYCOMB_INITIALIZER;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import io.fd.honeycomb.data.init.DataTreeInitializer;
+import io.fd.honeycomb.data.init.InitializerRegistry;
+import io.fd.honeycomb.translate.MappingContext;
+import io.fd.honeycomb.translate.read.registry.ReaderRegistry;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+
+public final class InitializerRegistryAdapterProvider extends ProviderTrait<InitializerRegistry> {
+
+    @Inject
+    @Named(HONEYCOMB_CONTEXT)
+    private DataTreeInitializer contextInitializer;
+    @Inject
+    @Named(HONEYCOMB_CONFIG)
+    private DataTreeInitializer configInitializer;
+    @Inject
+    private ReaderRegistry initRegistry;
+    @Inject
+    @Named(HONEYCOMB_INITIALIZER)
+    private DataBroker noopConfigDataBroker;
+    @Inject
+    @Named(HONEYCOMB_CONTEXT)
+    private MappingContext realtimeMappingContext;
+
+    @Override
+    protected InitializerRegistryAdapter create() {
+        return new InitializerRegistryAdapter(configInitializer, contextInitializer, initRegistry,
+                noopConfigDataBroker, realtimeMappingContext);
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/initializer/ModifiableDTDelegInitProvider.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/initializer/ModifiableDTDelegInitProvider.java
new file mode 100644 (file)
index 0000000..42c6838
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.initializer;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import io.fd.honeycomb.data.ModifiableDataManager;
+import io.fd.honeycomb.data.impl.ModifiableDataTreeDelegator;
+import io.fd.honeycomb.infra.distro.data.ConfigAndOperationalPipelineModule;
+import io.fd.honeycomb.infra.distro.data.context.ContextPipelineModule;
+import io.fd.honeycomb.translate.util.write.NoopWriterRegistry;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
+
+public final class ModifiableDTDelegInitProvider extends ProviderTrait<ModifiableDataManager> {
+
+    @Inject
+    private BindingToNormalizedNodeCodec serializer;
+    @Inject
+    @Named(ConfigAndOperationalPipelineModule.HONEYCOMB_CONFIG_NONPERSIST)
+    //solve writing in ./persist/config/data.json
+    private DataTree dataTree;
+    @Inject
+    @Named(ContextPipelineModule.HONEYCOMB_CONTEXT)
+    private DataBroker contextBroker;
+    @Inject
+    private SchemaService schemaService;
+
+    @Override
+    public ModifiableDataTreeDelegator create() {
+        return new ModifiableDataTreeDelegator(serializer, dataTree, schemaService.getGlobalContext(),
+                new NoopWriterRegistry(), contextBroker);
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/schema/ModuleInfoBackedCtxProvider.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/schema/ModuleInfoBackedCtxProvider.java
new file mode 100644 (file)
index 0000000..01b03c4
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.schema;
+
+import static io.fd.honeycomb.infra.distro.schema.YangModulesProvider.YangModules;
+
+import com.google.common.base.MoreObjects;
+import com.google.inject.Inject;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import java.util.stream.Collectors;
+import org.opendaylight.mdsal.binding.generator.impl.ModuleInfoBackedContext;
+import org.opendaylight.yangtools.yang.binding.YangModelBindingProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class ModuleInfoBackedCtxProvider extends ProviderTrait<ModuleInfoBackedContext> {
+    private static final Logger LOG = LoggerFactory.getLogger(ModuleInfoBackedCtxProvider.class);
+
+    // optional in sense that list of modules inside can be empty if none was found
+    @Inject
+    private YangModules moduleInfos;
+
+    @Override
+    protected ModuleInfoBackedContext create() {
+        ModuleInfoBackedContext create = ModuleInfoBackedContext.create();
+        create.addModuleInfos(moduleInfos.getYangBindings().stream()
+                .map(YangModelBindingProvider::getModuleInfo)
+                .collect(Collectors.toList()));
+        LOG.debug("ModuleInfoBackedContext created from {}", moduleInfos);
+        return create;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this).add("writerFactories", moduleInfos).toString();
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/schema/ResourceLoader.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/schema/ResourceLoader.java
new file mode 100644 (file)
index 0000000..88428e8
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.schema;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static java.lang.String.format;
+
+import com.google.common.base.Charsets;
+import com.google.common.base.Strings;
+import com.google.common.io.Resources;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.stream.Collectors;
+import org.apache.commons.io.IOUtils;
+
+/**
+ * Allows loading content of X amount of files from filesystem or archive
+ */
+public interface ResourceLoader {
+
+    default Set<String> loadResourceContentsOnPath(final String path) {
+        final URL folderUrl = getClass().getClassLoader().getResource(path);
+        checkState(folderUrl != null, "Resources %s not found", path);
+
+        if (ResourceLoaderIml.urlToUri(folderUrl).getScheme().equals("jar")) {
+            return ResourceLoaderIml.readFromJar(path, folderUrl);
+        } else {
+            return ResourceLoaderIml.readFromFolder(folderUrl);
+        }
+
+    }
+
+    final class ResourceLoaderIml {
+
+        private static Set<String> readFromFolder(final URL folderUrl) {
+            final File folder = new File(folderUrl.getPath());
+            final File[] files = checkNotNull(folder.listFiles(), "No files present on path %s", folderUrl);
+            return Arrays.stream(files)
+                    .map(ResourceLoaderIml::fileToUrl)
+                    .map(ResourceLoaderIml::urlToContentString)
+                    .flatMap(content -> Arrays.stream(content.split(System.lineSeparator())))
+                    .filter(ResourceLoaderIml::filterNonEmpty)
+                    .collect(Collectors.toSet());
+        }
+
+        private static Set<String> readFromJar(final String path, final URL url) {
+            final String uriString = urlToUri(url).toString();
+            final String fileReference = extractJarFilePath(uriString);
+            try (JarFile jar = new JarFile(new File(fileReference))) {
+                return Collections.list(jar.entries())
+                        .stream()
+                        .filter(jarEntry -> jarEntry.getName().contains(path))
+                        .map(jarEntry -> getJarEntryStream(jar, jarEntry))
+                        .map(ResourceLoaderIml::readJarEntryStream)
+                        .flatMap(content -> Arrays.stream(content.split(System.lineSeparator())))
+                        .filter(ResourceLoaderIml::filterNonEmpty)
+                        .collect(Collectors.toSet());
+            } catch (IOException e) {
+                throw new IllegalStateException(e);
+            }
+        }
+
+        private static String extractJarFilePath(final String uriString) {
+            return uriString.substring(0, uriString.indexOf("!")).replace("jar:file:", "");
+        }
+
+        private static boolean filterNonEmpty(final String line) {
+            return !Strings.isNullOrEmpty(line.trim());
+        }
+
+        private static String readJarEntryStream(final InputStream inputStream) {
+            try {
+                final String value = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
+                IOUtils.closeQuietly(inputStream);
+                return value;
+            } catch (IOException e) {
+                throw new IllegalStateException(e);
+            }
+        }
+
+        private static InputStream getJarEntryStream(final JarFile jar, final JarEntry jarEntry) {
+            try {
+                return jar.getInputStream(jarEntry);
+            } catch (IOException e) {
+                throw new IllegalStateException(format("Unable to get stream for entry %s | jar %s", jar, jarEntry), e);
+            }
+        }
+
+        private static URI urlToUri(final URL url) {
+            try {
+                return url.toURI();
+            } catch (URISyntaxException e) {
+                throw new IllegalStateException(format("Unable to convert URL %s to URI", url), e);
+            }
+        }
+
+        private static String urlToContentString(final URL url) {
+            try {
+                return Resources.toString(url, Charsets.UTF_8);
+            } catch (IOException e) {
+                throw new IllegalArgumentException("Unable to read resource from: " + url, e);
+            }
+        }
+
+        private static URL fileToUrl(final File file) {
+            try {
+                return file.toURI().toURL();
+            } catch (MalformedURLException e) {
+                throw new IllegalStateException(e);
+            }
+        }
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/schema/SchemaModule.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/schema/SchemaModule.java
new file mode 100644 (file)
index 0000000..7e6b89d
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.schema;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Singleton;
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.mdsal.binding.generator.impl.ModuleInfoBackedContext;
+
+public class SchemaModule extends AbstractModule {
+
+    @Override
+    protected void configure() {
+        bind(ModuleInfoBackedContext.class).toProvider(ModuleInfoBackedCtxProvider.class).in(Singleton.class);
+        bind(SchemaService.class).toProvider(SchemaServiceProvider.class).in(Singleton.class);
+        bind(BindingToNormalizedNodeCodec.class).toProvider(SerializerProvider.class).in(Singleton.class);
+    }
+
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/schema/SchemaServiceProvider.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/schema/SchemaServiceProvider.java
new file mode 100644 (file)
index 0000000..4ed3698
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.schema;
+
+import com.google.inject.Inject;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.mdsal.binding.generator.impl.ModuleInfoBackedContext;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
+
+public final class SchemaServiceProvider extends ProviderTrait<SchemaService> {
+
+    @Inject
+    private ModuleInfoBackedContext mibCtx;
+
+    @Override
+    public StaticSchemaService create() {
+        return new StaticSchemaService(mibCtx.getSchemaContext());
+    }
+
+    /**
+     * Static schema context provider service.
+     */
+    private static final class StaticSchemaService implements SchemaService {
+        private final SchemaContext schemaContext;
+
+        StaticSchemaService(SchemaContext schemaContext) {
+            this.schemaContext = schemaContext;
+        }
+
+        @Override
+        public void addModule(final Module module) {
+            throw new UnsupportedOperationException("Static service");
+        }
+
+        @Override
+        public void removeModule(final Module module) {
+            throw new UnsupportedOperationException("Static service");
+        }
+
+        @Override
+        public SchemaContext getSessionContext() {
+            return schemaContext;
+        }
+
+        @Override
+        public SchemaContext getGlobalContext() {
+            return schemaContext;
+        }
+
+        @Override
+        public ListenerRegistration<SchemaContextListener> registerSchemaContextListener(
+                final SchemaContextListener listener) {
+            listener.onGlobalContextUpdated(schemaContext);
+            return new ListenerRegistration<SchemaContextListener>() {
+                @Override
+                public void close() {}
+
+                @Override
+                public SchemaContextListener getInstance() {
+                    return listener;
+                }
+
+            };
+        }
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/schema/SerializerProvider.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/schema/SerializerProvider.java
new file mode 100644 (file)
index 0000000..dbd08a4
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.schema;
+
+import com.google.inject.Inject;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import javassist.ClassPool;
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.mdsal.binding.generator.impl.ModuleInfoBackedContext;
+import org.opendaylight.mdsal.binding.generator.util.BindingRuntimeContext;
+import org.opendaylight.mdsal.binding.generator.util.JavassistUtils;
+import org.opendaylight.yangtools.binding.data.codec.gen.impl.DataObjectSerializerGenerator;
+import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator;
+import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
+
+public class SerializerProvider extends ProviderTrait<BindingToNormalizedNodeCodec> {
+
+    @Inject
+    private ModuleInfoBackedContext mibCtx;
+
+    @Override
+    protected BindingToNormalizedNodeCodec create() {
+        final DataObjectSerializerGenerator serializerGenerator =
+            StreamWriterGenerator.create(JavassistUtils.forClassPool(ClassPool.getDefault()));
+        BindingNormalizedNodeCodecRegistry codecRegistry = new BindingNormalizedNodeCodecRegistry(serializerGenerator);
+        BindingRuntimeContext ctx = BindingRuntimeContext.create(mibCtx, mibCtx.getSchemaContext());
+        codecRegistry.onBindingRuntimeContextUpdated(ctx);
+        BindingToNormalizedNodeCodec codec = new BindingToNormalizedNodeCodec(mibCtx, codecRegistry);
+        codec.onGlobalContextUpdated(mibCtx.getSchemaContext());
+        return codec;
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/schema/YangBindingProviderModule.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/schema/YangBindingProviderModule.java
new file mode 100644 (file)
index 0000000..d43485f
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.schema;
+
+import com.google.inject.AbstractModule;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class YangBindingProviderModule extends AbstractModule {
+    private static final Logger LOG = LoggerFactory.getLogger(YangBindingProviderModule.class);
+
+    @Override
+    protected void configure() {
+        LOG.info("Configuring YangBindingProviderModule");
+        bind(YangModulesProvider.YangModules.class).toProvider(YangModulesProvider.class).asEagerSingleton();
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/schema/YangModuleMappingIndex.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/schema/YangModuleMappingIndex.java
new file mode 100644 (file)
index 0000000..a483cfd
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.schema;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.LinkedListMultimap;
+import com.google.common.collect.Multimap;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.stream.Stream;
+import javax.annotation.Nonnull;
+
+/**
+ * Index from guice module to yang module providers
+ */
+class YangModuleMappingIndex implements ResourceLoader {
+
+    private static final String G_MODULE_TOKEN = "GUICE_MODULE:";
+    private static final String KEY_VALUE_SEPARATOR = "|";
+    private static final String Y_MODULE_TOKEN = "YANG_MODULES:";
+    private static final String Y_MODULE_SEPARATOR = ",";
+
+    /**
+     * key - module class name
+     * value  - yang module provider
+     */
+    private final Multimap<String, String> index;
+
+    YangModuleMappingIndex(final String indexPath) {
+        this.index = LinkedListMultimap.create();
+        loadResourceContentsOnPath(indexPath)
+                .forEach(line -> {
+                    final String moduleName = parseModuleName(line);
+                    parseYangModules(line).forEach(yModuleProvider -> index.put(moduleName, yModuleProvider));
+                });
+    }
+
+    Set<String> getByModuleName(@Nonnull final String moduleName) {
+        return ImmutableSet.copyOf(index.get(moduleName));
+    }
+
+    int applicationModulesCount() {
+        return index.keySet().size();
+    }
+
+    private static String parseModuleName(final String rawLine) {
+        return rawLine.substring(rawLine.indexOf(G_MODULE_TOKEN) + G_MODULE_TOKEN.length(),
+                rawLine.indexOf(KEY_VALUE_SEPARATOR));
+    }
+
+    private static Stream<String> parseYangModules(final String rawLine) {
+        return Arrays.stream(rawLine.substring(rawLine.indexOf(Y_MODULE_TOKEN) + Y_MODULE_TOKEN.length())
+                .split(Y_MODULE_SEPARATOR));
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/schema/YangModulesProvider.java b/tests/honeynode221/minimal-distribution-core/src/main/java/io/fd/honeycomb/infra/distro/schema/YangModulesProvider.java
new file mode 100644 (file)
index 0000000..5acc1ea
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro.schema;
+
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import io.fd.honeycomb.infra.distro.activation.ActivationConfig;
+import io.fd.honeycomb.infra.distro.activation.ActiveModules;
+import org.opendaylight.yangtools.yang.binding.YangModelBindingProvider;
+
+import javax.annotation.Nonnull;
+import java.util.Collection;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static java.lang.String.format;
+
+/**
+ * Loads active yang modules
+ * Relying on generate yang-module-index
+ */
+public class YangModulesProvider implements Provider<YangModulesProvider.YangModules> {
+
+    @Inject
+    private ActiveModules activeModules;
+
+    @Inject
+    private ActivationConfig config;
+
+    @Override
+    public YangModules get() {
+        // no need to bind this, pretty big map and its needed just here
+        final YangModuleMappingIndex index = new YangModuleMappingIndex(config.getYangModulesIndexPath());
+
+        return new YangModules(activeModules.getActiveModulesClasses().stream()
+                .map(Class::getName)
+                .map(index::getByModuleName)
+                .flatMap(Collection::stream)
+                .map(YangModulesProvider::loadClass)
+                .map(aClass -> (Class<? extends YangModelBindingProvider>) aClass)
+                .collect(Collectors.toSet()));
+    }
+
+    static class YangModules {
+        private final Set<Class<? extends YangModelBindingProvider>> yangBindings;
+
+        YangModules(final Set<Class<? extends YangModelBindingProvider>> yangBindings) {
+            this.yangBindings = yangBindings;
+        }
+
+        Set<YangModelBindingProvider> getYangBindings() {
+            return yangBindings.stream()
+                    .map(providerClass -> {
+                        try {
+                            return providerClass.newInstance();
+                        } catch (InstantiationException | IllegalAccessException e) {
+                            throw new IllegalStateException(format("Unable to create instance of %s", providerClass),
+                                    e);
+                        }
+                    }).collect(Collectors.toSet());
+        }
+    }
+
+    private static Class<?> loadClass(@Nonnull final String className) {
+        try {
+            return Class.forName(className);
+        } catch (ClassNotFoundException e) {
+            throw new IllegalArgumentException("Unable to load class: " + className, e);
+        }
+    }
+}
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/resources/honeycomb-minimal-resources/cert/honeycomb-keystore b/tests/honeynode221/minimal-distribution-core/src/main/resources/honeycomb-minimal-resources/cert/honeycomb-keystore
new file mode 100644 (file)
index 0000000..27a2633
Binary files /dev/null and b/tests/honeynode221/minimal-distribution-core/src/main/resources/honeycomb-minimal-resources/cert/honeycomb-keystore differ
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/resources/honeycomb-minimal-resources/config/WEB-INF/web.xml b/tests/honeynode221/minimal-distribution-core/src/main/resources/honeycomb-minimal-resources/config/WEB-INF/web.xml
new file mode 100644 (file)
index 0000000..6cf4871
--- /dev/null
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+  ~ Copyright (c) 2016 Cisco and/or its affiliates.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at:
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<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>JAXRSRestconf</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.netconf.sal.rest.impl.RestconfApplication</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+
+    <servlet-mapping>
+        <servlet-name>JAXRSRestconf</servlet-name>
+        <url-pattern>/*</url-pattern>
+    </servlet-mapping>
+    <filter>
+        <filter-name>cross-origin-restconf</filter-name>
+        <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
+        <init-param>
+            <param-name>allowedOrigins</param-name>
+            <param-value>*</param-value>
+        </init-param>
+        <init-param>
+            <param-name>allowedMethods</param-name>
+            <param-value>GET,POST,OPTIONS,DELETE,PUT,HEAD</param-value>
+        </init-param>
+        <init-param>
+            <param-name>allowedHeaders</param-name>
+            <param-value>origin, content-type, accept, authorization</param-value>
+        </init-param>
+        <init-param>
+            <param-name>exposedHeaders</param-name>
+            <param-value>location</param-value>
+        </init-param>
+    </filter>
+    <filter-mapping>
+        <filter-name>cross-origin-restconf</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-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>
+    </security-constraint>
+
+</web-app>
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/resources/honeycomb-minimal-resources/config/activation.json b/tests/honeynode221/minimal-distribution-core/src/main/resources/honeycomb-minimal-resources/config/activation.json
new file mode 100644 (file)
index 0000000..8dd1687
--- /dev/null
@@ -0,0 +1,4 @@
+{
+  "modules-resource-path": "../modules/",
+  "yang-modules-index-path": "../yang-mapping/"
+}
\ No newline at end of file
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/resources/honeycomb-minimal-resources/config/honeycomb.json b/tests/honeynode221/minimal-distribution-core/src/main/resources/honeycomb-minimal-resources/config/honeycomb.json
new file mode 100644 (file)
index 0000000..4d5c201
--- /dev/null
@@ -0,0 +1,11 @@
+{
+  "persist-context": "true",
+  "persisted-context-path" : "./persist/17832/context/data.json",
+  "persisted-context-restoration-type": "Merge",
+  "persist-config": "true",
+  "persisted-config-path" : "./persist/17832/config/data.json",
+  "persisted-config-restoration-type": "Merge",
+  "notification-service-queue-depth": 1,
+  "netconf-initial-config-xml" : "device/oper-ROADMA.xml",
+  "netconf-initial-pm-xml" : "device/oper-ROADMA-cpm.xml"
+}
\ No newline at end of file
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/resources/honeycomb-minimal-resources/config/logback.xml b/tests/honeynode221/minimal-distribution-core/src/main/resources/honeycomb-minimal-resources/config/logback.xml
new file mode 100644 (file)
index 0000000..800d761
--- /dev/null
@@ -0,0 +1,32 @@
+ <configuration scan="true">
+
+  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+    <encoder>
+      <pattern>%date{"yyyy-MM-dd HH:mm:ss.SSS z"} [%thread] %-5level %logger{36} - %msg%n</pattern>
+    </encoder>
+  </appender>
+  <appender name="honeycomb.log" class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>./log/honeycomb/honeycomb.log</file>
+
+    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+      <fileNamePattern>./log/honeycomb/logs/honeycomb.%d.log.zip</fileNamePattern>
+      <maxHistory>1</maxHistory>
+    </rollingPolicy>
+
+    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>10MB</maxFileSize>
+    </triggeringPolicy>
+
+    <encoder>
+      <pattern>%date{"yyyy-MM-dd HH:mm:ss.SSS z"} [%thread] %-5level %logger{35} - %msg%n</pattern>
+    </encoder>
+  </appender>
+
+  <root level="warn">
+    <appender-ref ref="STDOUT" />
+    <appender-ref ref="honeycomb.log" />
+  </root>
+
+  <logger name="org.opendaylight" level="INFO"/>
+  <logger name="io.fd" level="INFO"/>
+</configuration>
diff --git a/tests/honeynode221/minimal-distribution-core/src/main/resources/honeycomb-minimal-resources/honeycomb-tpce b/tests/honeynode221/minimal-distribution-core/src/main/resources/honeycomb-minimal-resources/honeycomb-tpce
new file mode 100755 (executable)
index 0000000..ec622d7
--- /dev/null
@@ -0,0 +1,35 @@
+#!/bin/sh -
+STATUS=100
+
+if [ "$#" -ge 2 ]
+then
+    PORT=$1
+    CONFIG=$2
+    if [ -e $CONFIG ]
+    then
+        cp $CONFIG $(dirname $0)/config/device/
+        filename=$(basename -- "$CONFIG")
+        echo "changing netconf port with $PORT in netconf.json file ..."
+        sed -i "/netconf-ssh-binding-port/c\  \"netconf-ssh-binding-port\" : "$PORT"," $(dirname $0)/config/netconf.json
+        echo "changing persist-context and persist-config to false in honeycomb.json file ..."
+        sed -i "/persist-context/c\  \"persist-context\" : \"false\"," $(dirname $0)/config/honeycomb.json
+        sed -i "/persist-config/c\  \"persist-config\" : \"false\"," $(dirname $0)/config/honeycomb.json
+        echo "changing netconf-initial-config-xml location with $CONFIG in honeycomb.json file ..."
+        sed -i "/netconf-initial-config-xml/c\  \"netconf-initial-config-xml\" : \"device/$filename\"," $(dirname $0)/config/honeycomb.json
+         while [ $STATUS -eq 100 ]
+         do
+           java -Xms512m -Xmn512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -jar $(dirname $0)/honeynode-distribution-1.18.01.jar
+           STATUS=$?
+           echo "Honeycomb exited with status: $STATUS"
+           if [ $STATUS -eq 100 ]
+           then
+             echo "Restarting..."
+           fi
+         done
+    else
+        echo "initial config file doesn't exist !"
+    fi
+else 
+    echo "honeycomb-tpce port initial-config-xml (option)pm-list-xml"
+    echo "Eg : honeycomb-tpce 17832 sample-config-ROADM.xml pm-list.xml"
+fi
diff --git a/tests/honeynode221/minimal-distribution/asciidoc/Readme.adoc b/tests/honeynode221/minimal-distribution/asciidoc/Readme.adoc
new file mode 100644 (file)
index 0000000..1da86ca
--- /dev/null
@@ -0,0 +1,3 @@
+= minimal-distribution
+
+Overview of minimal-distribution
\ No newline at end of file
diff --git a/tests/honeynode221/minimal-distribution/pom.xml b/tests/honeynode221/minimal-distribution/pom.xml
new file mode 100644 (file)
index 0000000..c382fa0
--- /dev/null
@@ -0,0 +1,153 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2015 Cisco and/or its affiliates.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at:
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<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">
+    <parent>
+        <groupId>io.fd.honeycomb.common</groupId>
+        <artifactId>minimal-distribution-parent</artifactId>
+        <version>1.18.01</version>
+        <relativePath/>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>io.fd.honeycomb.transportpce</groupId>
+    <artifactId>minimal-distribution</artifactId>
+    <name>${project.artifactId}</name>
+    <version>1.18.01</version>
+
+    <properties>
+        <main.class>io.fd.honeycomb.infra.distro.Main</main.class>
+        <distribution.modules>
+            io.fd.honeycomb.infra.distro.schema.YangBindingProviderModule,
+            io.fd.honeycomb.infra.distro.schema.SchemaModule,
+            io.fd.honeycomb.infra.distro.data.ConfigAndOperationalPipelineModule,
+            io.fd.honeycomb.infra.distro.data.context.ContextPipelineModule,
+            io.fd.honeycomb.infra.distro.initializer.InitializerPipelineModule,
+            io.fd.honeycomb.northbound.CredentialsModule,
+            io.fd.honeycomb.northbound.netconf.NetconfModule,
+            io.fd.honeycomb.northbound.netconf.NetconfReadersModule,
+            //io.fd.honeycomb.northbound.restconf.RestconfModule,
+            io.fd.honeycomb.infra.distro.cfgattrs.CfgAttrsModule,
+            // io.fd.honeycomb.infra.bgp.BgpModule,
+            // io.fd.honeycomb.infra.bgp.BgpReadersModule,
+            // io.fd.honeycomb.infra.bgp.BgpWritersModule,
+            // io.fd.honeycomb.northbound.bgp.extension.EvpnModule,
+            // io.fd.honeycomb.northbound.bgp.extension.InetModule,
+            // io.fd.honeycomb.northbound.bgp.extension.L3VpnV4Module,
+            // io.fd.honeycomb.northbound.bgp.extension.L3VpnV6Module,
+            // io.fd.honeycomb.northbound.bgp.extension.LabeledUnicastModule,
+            // io.fd.honeycomb.northbound.bgp.extension.LinkstateModule,
+            // io.fd.honeycomb.footprint.FootprintModule
+        </distribution.modules>
+    </properties>
+
+    <dependencies>
+        <!-- DI-->
+        <dependency>
+            <groupId>com.google.inject</groupId>
+            <artifactId>guice</artifactId>
+        </dependency>
+
+        <!-- TPCE Distribution core -->
+        <dependency>
+            <groupId>io.fd.honeycomb.transportpce</groupId>
+            <artifactId>minimal-distribution-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.fd.honeycomb.transportpce</groupId>
+            <artifactId>restconf</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.fd.honeycomb.transportpce</groupId>
+            <artifactId>netconf</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <!-- Northbound interfaces -->
+        <dependency>
+            <groupId>io.fd.honeycomb.northbound</groupId>
+            <artifactId>common</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <!-- <dependency>
+            <groupId>io.fd.honeycomb.northbound</groupId>
+            <artifactId>restconf</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.fd.honeycomb.northbound</groupId>
+            <artifactId>netconf</artifactId>
+            <version>${project.version}</version>
+        </dependency>-->
+        <dependency>
+            <groupId>io.fd.honeycomb.northbound</groupId>
+            <artifactId>bgp</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <!-- Bgp extension modules -->
+        <dependency>
+            <groupId>io.fd.honeycomb.northbound.bgp</groupId>
+            <artifactId>extension-common</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>io.fd.honeycomb.northbound.bgp</groupId>
+            <artifactId>evpn</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>io.fd.honeycomb.northbound.bgp</groupId>
+            <artifactId>inet</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>io.fd.honeycomb.northbound.bgp</groupId>
+            <artifactId>l3-vpn-v4</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>io.fd.honeycomb.northbound.bgp</groupId>
+            <artifactId>l3-vpn-v6</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>io.fd.honeycomb.northbound.bgp</groupId>
+            <artifactId>linkstate</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>io.fd.honeycomb.northbound.bgp</groupId>
+            <artifactId>labeled-unicast</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <!-- Footprint api -->
+        <dependency>
+            <groupId>io.fd.honeycomb.footprint</groupId>
+            <artifactId>impl</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/tests/honeynode221/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/Main.java b/tests/honeynode221/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/Main.java
new file mode 100644 (file)
index 0000000..5082604
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro;
+
+import static com.google.inject.Guice.createInjector;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.ConfigurationException;
+import com.google.inject.CreationException;
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.Module;
+import com.google.inject.ProvisionException;
+import com.google.inject.name.Names;
+
+import io.fd.honeycomb.data.init.DataTreeInitializer;
+import io.fd.honeycomb.data.init.InitializerRegistry;
+import io.fd.honeycomb.infra.distro.activation.ActivationModule;
+import io.fd.honeycomb.infra.distro.activation.ActiveModules;
+import io.fd.honeycomb.infra.distro.initializer.InitializerPipelineModule;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class Main {
+
+    private static final Logger LOG = LoggerFactory.getLogger(Main.class);
+
+    private Main() {
+    }
+
+    public static void main(String[] args) {
+        init(new ActivationModule());
+    }
+
+    /**
+     * Initialize the Honeycomb with provided modules
+     */
+    public static Injector init(final ActivationModule activationModule) {
+        try {
+            LOG.info("Starting honeycomb");
+            // creating child injector does not work in this case, so just create injector, and does not store ref
+            // to it, or its active modules instance
+            Injector injector = createInjector(ImmutableSet.<Module>builder()
+                    .add(activationModule)
+                    .addAll(createInjector(activationModule).getInstance(ActiveModules.class).createModuleInstances())
+                    .build());
+
+            // Log all bindings
+            injector.getAllBindings().entrySet().stream()
+                    .forEach(e -> LOG.trace("Component available under: {} is {}", e.getKey(), e.getValue()));
+
+            try {
+                LOG.info("Initializing configuration");
+                injector.getInstance(Key.get(InitializerRegistry.class,
+                        Names.named(InitializerPipelineModule.HONEYCOMB_INITIALIZER))).initialize();
+                LOG.info("Configuration initialized successfully");
+            } catch (DataTreeInitializer.InitializeException e) {
+                LOG.error("Unable to initialize configuration", e);
+            }
+
+
+            LOG.info("Honeycomb started successfully!");
+            return injector;
+        } catch (CreationException | ProvisionException | ConfigurationException e) {
+            LOG.error("Failed to initialize Honeycomb components", e);
+            throw e;
+        } catch (RuntimeException e) {
+            LOG.error("Unexpected initialization failure", e);
+            throw e;
+        } finally {
+            // Trigger gc to force collect initial garbage + dedicated classloader
+            System.gc();
+        }
+    }
+
+}
diff --git a/tests/honeynode221/netconf-netty-util/.gitignore b/tests/honeynode221/netconf-netty-util/.gitignore
new file mode 100644 (file)
index 0000000..eacf31a
--- /dev/null
@@ -0,0 +1 @@
+/target-ide/
diff --git a/tests/honeynode221/netconf-netty-util/pom.xml b/tests/honeynode221/netconf-netty-util/pom.xml
new file mode 100644 (file)
index 0000000..983f5a6
--- /dev/null
@@ -0,0 +1,141 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+  ~
+  ~ This program and the accompanying materials are made available under the
+  ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+  ~ and is available at http://www.eclipse.org/legal/epl-v10.html
+  -->
+<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>
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>bundle-parent</artifactId>
+    <version>2.0.5</version>
+    <relativePath/>
+  </parent>
+
+  <groupId>org.opendaylight.netconf</groupId>
+  <artifactId>netconf-netty-util</artifactId>
+  <packaging>bundle</packaging>
+  <version>1.3.1</version>
+  <name>${project.artifactId}</name>
+
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>org.opendaylight.netconf</groupId>
+        <artifactId>netconf-artifacts</artifactId>
+        <version>${project.version}</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.opendaylight.yangtools</groupId>
+        <artifactId>yangtools-artifacts</artifactId>
+        <version>1.2.1</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+      <!--<dependency>
+        <groupId>openexi</groupId>
+        <artifactId>nagasena</artifactId>
+        <version>0000.0002.0062.0</version>
+      </dependency>
+      <dependency>
+        <groupId>openexi</groupId>
+        <artifactId>nagasena-rta</artifactId>
+        <version>0000.0002.0062.0</version>
+      </dependency>-->
+      <dependency>
+        <groupId>com.siemens.ct.exi</groupId>
+        <artifactId>exificient</artifactId>
+        <version>1.0.1</version>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+
+  <dependencies>
+    <!-- compile dependencies -->
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>netconf-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>netconf-mapping-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>netconf-util</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.netty</groupId>
+      <artifactId>netty-handler</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sshd</groupId>
+      <artifactId>sshd-core</artifactId>
+      <version>0.14.0</version>
+    </dependency>
+    <!--<dependency>
+      <groupId>openexi</groupId>
+      <artifactId>nagasena</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>openexi</groupId>
+      <artifactId>nagasena-rta</artifactId>
+    </dependency>-->
+    <dependency>
+      <groupId>com.siemens.ct.exi</groupId>
+      <artifactId>exificient</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>xmlunit</groupId>
+      <artifactId>xmlunit</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>mockito-configuration</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.aaa</groupId>
+      <artifactId>aaa-encrypt-service</artifactId>
+      <version>0.6.1</version>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>test-jar</goal>
+            </goals>
+            <phase>package</phase>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+        <configuration>
+          <propertyExpansion>checkstyle.violationSeverity=error</propertyExpansion>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+</project>
diff --git a/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/AbstractChannelInitializer.java b/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/AbstractChannelInitializer.java
new file mode 100644 (file)
index 0000000..c967e8f
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * 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.netconf.nettyutil;
+
+import io.netty.channel.Channel;
+import io.netty.util.concurrent.Promise;
+import org.opendaylight.netconf.api.NetconfSession;
+import org.opendaylight.netconf.nettyutil.handler.FramingMechanismHandlerFactory;
+import org.opendaylight.netconf.nettyutil.handler.NetconfEOMAggregator;
+import org.opendaylight.netconf.nettyutil.handler.NetconfHelloMessageToXMLEncoder;
+import org.opendaylight.netconf.nettyutil.handler.NetconfXMLToHelloMessageDecoder;
+import org.opendaylight.netconf.util.messages.FramingMechanism;
+
+public abstract class AbstractChannelInitializer<S extends NetconfSession> {
+
+    public static final String NETCONF_MESSAGE_DECODER = "netconfMessageDecoder";
+    public static final String NETCONF_MESSAGE_AGGREGATOR = "aggregator";
+    public static final String NETCONF_MESSAGE_ENCODER = "netconfMessageEncoder";
+    public static final String NETCONF_MESSAGE_FRAME_ENCODER = "frameEncoder";
+    public static final String NETCONF_SESSION_NEGOTIATOR = "negotiator";
+
+    public void initialize(Channel ch, Promise<S> promise) {
+        ch.pipeline().addLast(NETCONF_MESSAGE_AGGREGATOR, new NetconfEOMAggregator());
+        initializeMessageDecoder(ch);
+        ch.pipeline().addLast(NETCONF_MESSAGE_FRAME_ENCODER,
+                FramingMechanismHandlerFactory.createHandler(FramingMechanism.EOM));
+        initializeMessageEncoder(ch);
+
+        initializeSessionNegotiator(ch, promise);
+    }
+
+    protected void initializeMessageEncoder(Channel ch) {
+        // Special encoding handler for hello message to include additional header if available,
+        // it is thrown away after successful negotiation
+        ch.pipeline().addLast(NETCONF_MESSAGE_ENCODER, new NetconfHelloMessageToXMLEncoder());
+    }
+
+    protected void initializeMessageDecoder(Channel ch) {
+        // Special decoding handler for hello message to parse additional header if available,
+        // it is thrown away after successful negotiation
+        ch.pipeline().addLast(NETCONF_MESSAGE_DECODER, new NetconfXMLToHelloMessageDecoder());
+    }
+
+    /**
+     * Insert session negotiator into the pipeline. It must be inserted after message decoder
+     * identified by {@link AbstractChannelInitializer#NETCONF_MESSAGE_DECODER}, (or any other custom decoder processor)
+     */
+    protected abstract void initializeSessionNegotiator(Channel ch, Promise<S> promise);
+
+}
diff --git a/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/AbstractNetconfSession.java b/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/AbstractNetconfSession.java
new file mode 100644 (file)
index 0000000..49f7b7e
--- /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.netconf.nettyutil;
+
+import com.siemens.ct.exi.core.exceptions.EXIException;
+import com.siemens.ct.exi.core.exceptions.UnsupportedOption;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.DefaultChannelPromise;
+import io.netty.handler.codec.ByteToMessageDecoder;
+import io.netty.handler.codec.MessageToByteEncoder;
+import io.netty.util.concurrent.Future;
+import io.netty.util.concurrent.FutureListener;
+import java.io.IOException;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.netconf.api.NetconfExiSession;
+import org.opendaylight.netconf.api.NetconfMessage;
+import org.opendaylight.netconf.api.NetconfSession;
+import org.opendaylight.netconf.api.NetconfSessionListener;
+import org.opendaylight.netconf.api.NetconfTerminationReason;
+import org.opendaylight.netconf.nettyutil.handler.NetconfEXICodec;
+import org.opendaylight.netconf.nettyutil.handler.NetconfEXIToMessageDecoder;
+import org.opendaylight.netconf.nettyutil.handler.NetconfMessageToEXIEncoder;
+import org.opendaylight.netconf.nettyutil.handler.exi.EXIParameters;
+import org.opendaylight.protocol.framework.AbstractProtocolSession;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class AbstractNetconfSession<S extends NetconfSession,L extends NetconfSessionListener<S>>
+        extends AbstractProtocolSession<NetconfMessage> implements NetconfSession, NetconfExiSession {
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractNetconfSession.class);
+    private final L sessionListener;
+    private final long sessionId;
+    private boolean up = false;
+
+    private ChannelHandler delayedEncoder;
+
+    private final Channel channel;
+
+    protected AbstractNetconfSession(final L sessionListener, final Channel channel, final long sessionId) {
+        this.sessionListener = sessionListener;
+        this.channel = channel;
+        this.sessionId = sessionId;
+        LOG.debug("Session {} created", sessionId);
+    }
+
+    protected abstract S thisInstance();
+
+    @Override
+    public void close() {
+        channel.close();
+        up = false;
+        sessionListener.onSessionTerminated(thisInstance(), new NetconfTerminationReason("Session closed"));
+    }
+
+    @Override
+    protected void handleMessage(final NetconfMessage netconfMessage) {
+        LOG.debug("handling incoming message");
+        sessionListener.onMessage(thisInstance(), netconfMessage);
+    }
+
+    @Override
+    public ChannelFuture sendMessage(final NetconfMessage netconfMessage) {
+        // From: https://github.com/netty/netty/issues/3887
+        // Netty can provide "ordering" in the following situations:
+        // 1. You are doing all writes from the EventLoop thread; OR
+        // 2. You are doing no writes from the EventLoop thread (i.e. all writes are being done in other thread(s)).
+        //
+        // Restconf writes to a netconf mountpoint execute multiple messages
+        // and one of these was executed from a restconf thread thus breaking ordering so
+        // we need to execute all messages from an EventLoop thread.
+        final DefaultChannelPromise proxyFuture = new DefaultChannelPromise(channel);
+        channel.eventLoop().execute(new Runnable() {
+            @Override
+            public void run() {
+                final ChannelFuture future = channel.writeAndFlush(netconfMessage);
+                future.addListener(new FutureListener<Void>() {
+                    @Override
+                    public void operationComplete(Future<Void> future) throws Exception {
+                        if (future.isSuccess()) {
+                            proxyFuture.setSuccess();
+                        } else {
+                            proxyFuture.setFailure(future.cause());
+                        }
+                    }
+                });
+                if (delayedEncoder != null) {
+                    replaceMessageEncoder(delayedEncoder);
+                    delayedEncoder = null;
+                }
+            }
+        });
+
+        return proxyFuture;
+    }
+
+    @Override
+    protected void endOfInput() {
+        LOG.debug("Session {} end of input detected while session was in state {}", toString(), isUp() ? "up"
+                : "initialized");
+        if (isUp()) {
+            this.sessionListener.onSessionDown(thisInstance(),
+                    new IOException("End of input detected. Close the session."));
+        }
+    }
+
+    @Override
+    protected void sessionUp() {
+        LOG.debug("Session {} up", toString());
+        sessionListener.onSessionUp(thisInstance());
+        this.up = true;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuffer sb = new StringBuffer(getClass().getSimpleName() + "{");
+        sb.append("sessionId=").append(sessionId);
+        sb.append(", channel=").append(channel);
+        sb.append('}');
+        return sb.toString();
+    }
+
+    protected final void replaceMessageDecoder(final ChannelHandler handler) {
+        replaceChannelHandler(AbstractChannelInitializer.NETCONF_MESSAGE_DECODER, handler);
+    }
+
+    protected final void replaceMessageEncoder(final ChannelHandler handler) {
+        replaceChannelHandler(AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER, handler);
+    }
+
+    protected final void replaceMessageEncoderAfterNextMessage(final ChannelHandler handler) {
+        this.delayedEncoder = handler;
+    }
+
+    protected final void replaceChannelHandler(final String handlerName, final ChannelHandler handler) {
+        channel.pipeline().replace(handlerName, handlerName, handler);
+    }
+
+    @Override
+    public final void startExiCommunication(final NetconfMessage startExiMessage) {
+        final EXIParameters exiParams;
+        try {
+            exiParams = EXIParameters.fromXmlElement(XmlElement.fromDomDocument(startExiMessage.getDocument()));
+        } catch (final UnsupportedOption e) {
+            LOG.warn("Unable to parse EXI parameters from {} on session {}", startExiMessage, this, e);
+            throw new IllegalArgumentException("Cannot parse options", e);
+        }
+
+        final NetconfEXICodec exiCodec = NetconfEXICodec.forParameters(exiParams);
+        final NetconfMessageToEXIEncoder exiEncoder = NetconfMessageToEXIEncoder.create(exiCodec);
+        final NetconfEXIToMessageDecoder exiDecoder;
+        try {
+            exiDecoder = NetconfEXIToMessageDecoder.create(exiCodec);
+        } catch (EXIException e) {
+            LOG.warn("Failed to instantiate EXI decodeer for {} on session {}", exiCodec, this, e);
+            throw new IllegalStateException("Cannot instantiate encoder for options", e);
+        }
+
+        addExiHandlers(exiDecoder, exiEncoder);
+        LOG.debug("Session {} EXI handlers added to pipeline", this);
+    }
+
+    /**
+     * Add a set encoder/decoder tuple into the channel pipeline as appropriate.
+     *
+     * @param decoder EXI decoder
+     * @param encoder EXI encoder
+     */
+    protected abstract void addExiHandlers(ByteToMessageDecoder decoder, MessageToByteEncoder<NetconfMessage> encoder);
+
+    public final boolean isUp() {
+        return up;
+    }
+
+    public final long getSessionId() {
+        return sessionId;
+    }
+}
diff --git a/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/AbstractNetconfSessionNegotiator.java b/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/AbstractNetconfSessionNegotiator.java
new file mode 100644 (file)
index 0000000..2f30023
--- /dev/null
@@ -0,0 +1,275 @@
+/*
+ * 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.netconf.nettyutil;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.handler.ssl.SslHandler;
+import io.netty.util.Timeout;
+import io.netty.util.Timer;
+import io.netty.util.TimerTask;
+import io.netty.util.concurrent.Future;
+import io.netty.util.concurrent.GenericFutureListener;
+import io.netty.util.concurrent.Promise;
+import java.util.concurrent.TimeUnit;
+import org.opendaylight.netconf.api.NetconfDocumentedException;
+import org.opendaylight.netconf.api.NetconfMessage;
+import org.opendaylight.netconf.api.NetconfSessionListener;
+import org.opendaylight.netconf.api.NetconfSessionPreferences;
+import org.opendaylight.netconf.api.messages.NetconfHelloMessage;
+import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
+import org.opendaylight.netconf.nettyutil.handler.FramingMechanismHandlerFactory;
+import org.opendaylight.netconf.nettyutil.handler.NetconfChunkAggregator;
+import org.opendaylight.netconf.nettyutil.handler.NetconfMessageToXMLEncoder;
+import org.opendaylight.netconf.nettyutil.handler.NetconfXMLToHelloMessageDecoder;
+import org.opendaylight.netconf.nettyutil.handler.NetconfXMLToMessageDecoder;
+import org.opendaylight.netconf.util.messages.FramingMechanism;
+import org.opendaylight.protocol.framework.AbstractSessionNegotiator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+
+public abstract class AbstractNetconfSessionNegotiator<P extends NetconfSessionPreferences,
+        S extends AbstractNetconfSession<S, L>, L extends NetconfSessionListener<S>>
+    extends AbstractSessionNegotiator<NetconfHelloMessage, S> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractNetconfSessionNegotiator.class);
+
+    public static final String NAME_OF_EXCEPTION_HANDLER = "lastExceptionHandler";
+
+    protected final P sessionPreferences;
+
+    private final L sessionListener;
+    private Timeout timeout;
+
+    /**
+     * Possible states for Finite State Machine.
+     */
+    protected enum State {
+        IDLE, OPEN_WAIT, FAILED, ESTABLISHED
+    }
+
+    private State state = State.IDLE;
+    private final Promise<S> promise;
+    private final Timer timer;
+    private final long connectionTimeoutMillis;
+
+    protected AbstractNetconfSessionNegotiator(final P sessionPreferences, final Promise<S> promise,
+                                               final Channel channel, final Timer timer,
+                                               final L sessionListener, final long connectionTimeoutMillis) {
+        super(promise, channel);
+        this.sessionPreferences = sessionPreferences;
+        this.promise = promise;
+        this.timer = timer;
+        this.sessionListener = sessionListener;
+        this.connectionTimeoutMillis = connectionTimeoutMillis;
+    }
+
+    @Override
+    protected final void startNegotiation() {
+        final Optional<SslHandler> sslHandler = getSslHandler(channel);
+        if (sslHandler.isPresent()) {
+            Future<Channel> future = sslHandler.get().handshakeFuture();
+            future.addListener(new GenericFutureListener<Future<? super Channel>>() {
+                @Override
+                public void operationComplete(final Future<? super Channel> future) {
+                    Preconditions.checkState(future.isSuccess(), "Ssl handshake was not successful");
+                    LOG.debug("Ssl handshake complete");
+                    start();
+                }
+            });
+        } else {
+            start();
+        }
+    }
+
+    private static Optional<SslHandler> getSslHandler(final Channel channel) {
+        final SslHandler sslHandler = channel.pipeline().get(SslHandler.class);
+        return sslHandler == null ? Optional.<SslHandler>absent() : Optional.of(sslHandler);
+    }
+
+    public P getSessionPreferences() {
+        return sessionPreferences;
+    }
+
+    private void start() {
+        final NetconfHelloMessage helloMessage = this.sessionPreferences.getHelloMessage();
+        LOG.debug("Session negotiation started with hello message {} on channel {}", helloMessage, channel);
+
+        channel.pipeline().addLast(NAME_OF_EXCEPTION_HANDLER, new ExceptionHandlingInboundChannelHandler());
+
+        sendMessage(helloMessage);
+
+        replaceHelloMessageOutboundHandler();
+        changeState(State.OPEN_WAIT);
+
+        timeout = this.timer.newTimeout(new TimerTask() {
+            @Override
+            public void run(final Timeout timeout) {
+                synchronized (this) {
+                    if (state != State.ESTABLISHED) {
+
+                        LOG.debug("Connection timeout after {}, session is in state {}", timeout, state);
+
+                        // Do not fail negotiation if promise is done or canceled
+                        // It would result in setting result of the promise second time and that throws exception
+                        if (isPromiseFinished() == false) {
+                            LOG.warn("Netconf session was not established after {}", connectionTimeoutMillis);
+                            changeState(State.FAILED);
+
+                            channel.close().addListener(new GenericFutureListener<ChannelFuture>() {
+                                @Override
+                                public void operationComplete(final ChannelFuture future) throws Exception {
+                                    if (future.isSuccess()) {
+                                        LOG.debug("Channel {} closed: success", future.channel());
+                                    } else {
+                                        LOG.warn("Channel {} closed: fail", future.channel());
+                                    }
+                                }
+                            });
+                        }
+                    } else if (channel.isOpen()) {
+                        channel.pipeline().remove(NAME_OF_EXCEPTION_HANDLER);
+                    }
+                }
+            }
+
+            private boolean isPromiseFinished() {
+                return promise.isDone() || promise.isCancelled();
+            }
+
+        }, connectionTimeoutMillis, TimeUnit.MILLISECONDS);
+    }
+
+    private void cancelTimeout() {
+        if (timeout != null) {
+            timeout.cancel();
+        }
+    }
+
+    protected final S getSessionForHelloMessage(final NetconfHelloMessage netconfMessage)
+            throws NetconfDocumentedException {
+        Preconditions.checkNotNull(netconfMessage, "netconfMessage");
+
+        final Document doc = netconfMessage.getDocument();
+
+        if (shouldUseChunkFraming(doc)) {
+            insertChunkFramingToPipeline();
+        }
+
+        changeState(State.ESTABLISHED);
+        return getSession(sessionListener, channel, netconfMessage);
+    }
+
+    /**
+     * Insert chunk framing handlers into the pipeline.
+     */
+    private void insertChunkFramingToPipeline() {
+        replaceChannelHandler(channel, AbstractChannelInitializer.NETCONF_MESSAGE_FRAME_ENCODER,
+                FramingMechanismHandlerFactory.createHandler(FramingMechanism.CHUNK));
+        replaceChannelHandler(channel, AbstractChannelInitializer.NETCONF_MESSAGE_AGGREGATOR,
+                new NetconfChunkAggregator());
+    }
+
+    private boolean shouldUseChunkFraming(final Document doc) {
+        return containsBase11Capability(doc)
+                && containsBase11Capability(sessionPreferences.getHelloMessage().getDocument());
+    }
+
+    /**
+     * Remove special inbound handler for hello message. Insert regular netconf xml message (en|de)coders.
+     *
+     * <p>
+     * Inbound hello message handler should be kept until negotiation is successful
+     * It caches any non-hello messages while negotiation is still in progress
+     */
+    protected final void replaceHelloMessageInboundHandler(final S session) {
+        ChannelHandler helloMessageHandler = replaceChannelHandler(channel,
+                AbstractChannelInitializer.NETCONF_MESSAGE_DECODER, new NetconfXMLToMessageDecoder());
+
+        Preconditions.checkState(helloMessageHandler instanceof NetconfXMLToHelloMessageDecoder,
+                "Pipeline handlers misplaced on session: %s, pipeline: %s", session, channel.pipeline());
+        Iterable<NetconfMessage> netconfMessagesFromNegotiation =
+                ((NetconfXMLToHelloMessageDecoder) helloMessageHandler).getPostHelloNetconfMessages();
+
+        // Process messages received during negotiation
+        // The hello message handler does not have to be synchronized,
+        // since it is always call from the same thread by netty.
+        // It means, we are now using the thread now
+        for (NetconfMessage message : netconfMessagesFromNegotiation) {
+            session.handleMessage(message);
+        }
+    }
+
+    /**
+     * Remove special outbound handler for hello message. Insert regular netconf xml message (en|de)coders.
+     */
+    private void replaceHelloMessageOutboundHandler() {
+        replaceChannelHandler(channel, AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER,
+                new NetconfMessageToXMLEncoder());
+    }
+
+    private static ChannelHandler replaceChannelHandler(final Channel channel, final String handlerKey,
+                                                        final ChannelHandler decoder) {
+        return channel.pipeline().replace(handlerKey, handlerKey, decoder);
+    }
+
+    protected abstract S getSession(L sessionListener, Channel channel, NetconfHelloMessage message)
+            throws NetconfDocumentedException;
+
+    private synchronized void changeState(final State newState) {
+        LOG.debug("Changing state from : {} to : {} for channel: {}", state, newState, channel);
+        Preconditions.checkState(isStateChangePermitted(state, newState),
+                "Cannot change state from %s to %s for chanel %s", state, newState, channel);
+        this.state = newState;
+    }
+
+    private static boolean containsBase11Capability(final Document doc) {
+        final NodeList nList = doc.getElementsByTagName(XmlNetconfConstants.CAPABILITY);
+        for (int i = 0; i < nList.getLength(); i++) {
+            if (nList.item(i).getTextContent().contains(XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_1)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static boolean isStateChangePermitted(final State state, final State newState) {
+        if (state == State.IDLE && newState == State.OPEN_WAIT) {
+            return true;
+        }
+        if (state == State.OPEN_WAIT && newState == State.ESTABLISHED) {
+            return true;
+        }
+        if (state == State.OPEN_WAIT && newState == State.FAILED) {
+            return true;
+        }
+        LOG.debug("Transition from {} to {} is not allowed", state, newState);
+        return false;
+    }
+
+    /**
+     * Handler to catch exceptions in pipeline during negotiation.
+     */
+    private final class ExceptionHandlingInboundChannelHandler extends ChannelInboundHandlerAdapter {
+        @Override
+        public void exceptionCaught(final ChannelHandlerContext ctx, final Throwable cause) {
+            LOG.warn("An exception occurred during negotiation with {}", channel.remoteAddress(), cause);
+            cancelTimeout();
+            negotiationFailed(cause);
+            changeState(State.FAILED);
+        }
+    }
+}
diff --git a/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/BufferedWriter.java b/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/BufferedWriter.java
new file mode 100644 (file)
index 0000000..7f3dd38
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2015 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.netconf.nettyutil.handler;
+
+import com.google.common.base.Preconditions;
+import java.io.IOException;
+import java.io.Writer;
+import javax.annotation.concurrent.NotThreadSafe;
+
+/**
+ * Custom BufferedWriter optimized for netconf pipeline implemented instead of default BufferedWriter provided by jdk.
+ *
+ * <p>
+ * The line separator instance field in java.io.BufferedWriter is
+ * assigned using AccessController and takes considerable amount of time especially
+ * if lots of BufferedWriters are created in the system.
+ *
+ * <p>
+ * This implementation should only be used if newLine method is not required
+ * such as netconf message to XML encoders.
+ * Methods in this implementation are not synchronized.
+ */
+@NotThreadSafe
+public final class BufferedWriter extends Writer {
+
+    private static final int DEFAULT_CHAR_BUFFER_SIZE = 8192;
+
+    private final Writer writer;
+    private final char[] buffer;
+    private final int bufferSize;
+
+    private int nextChar = 0;
+
+    public BufferedWriter(final Writer writer) {
+        this(writer, DEFAULT_CHAR_BUFFER_SIZE);
+    }
+
+    public BufferedWriter(final Writer writer, final int bufferSize) {
+        super(writer);
+        Preconditions.checkArgument(bufferSize > 0, "Buffer size <= 0");
+        this.writer = writer;
+        this.buffer = new char[bufferSize];
+        this.bufferSize = bufferSize;
+    }
+
+    private void flushBuffer() throws IOException {
+        if (nextChar == 0) {
+            return;
+        }
+        writer.write(buffer, 0, nextChar);
+        nextChar = 0;
+    }
+
+    @Override
+    public void write(final int character) throws IOException {
+        if (nextChar >= bufferSize) {
+            flushBuffer();
+        }
+        buffer[nextChar++] = (char) character;
+    }
+
+    @Override
+    public void write(final char[] buffer, final int offset, final int length) throws IOException {
+        if ((offset < 0) || (offset > buffer.length)
+                || (length < 0) || ((offset + length) > buffer.length) || ((offset + length) < 0)) {
+            throw new IndexOutOfBoundsException(
+                    String.format("Buffer size: %d, Offset: %d, Length: %d", buffer.length, offset, length));
+        } else if (length == 0) {
+            return;
+        }
+
+        if (length >= bufferSize) {
+            flushBuffer();
+            writer.write(buffer, offset, length);
+            return;
+        }
+
+        int bufferOffset = offset;
+        final int t = offset + length;
+        while (bufferOffset < t) {
+            final int d = Math.min(bufferSize - nextChar, t - bufferOffset);
+            System.arraycopy(buffer, bufferOffset, this.buffer, nextChar, d);
+            bufferOffset += d;
+            nextChar += d;
+            if (nextChar >= bufferSize) {
+                flushBuffer();
+            }
+        }
+    }
+
+    @Override
+    public void write(final String string, final int offset, final int length) throws IOException {
+        int bufferOffset = offset;
+        final int t = offset + length;
+        while (bufferOffset < t) {
+            final int d = Math.min(bufferSize - nextChar, t - bufferOffset);
+            string.getChars(bufferOffset, bufferOffset + d, buffer, nextChar);
+            bufferOffset += d;
+            nextChar += d;
+            if (nextChar >= bufferSize) {
+                flushBuffer();
+            }
+        }
+    }
+
+    @Override
+    public void flush() throws IOException {
+        flushBuffer();
+        writer.flush();
+    }
+
+    @Override
+    public void close() throws IOException {
+        try {
+            flushBuffer();
+        } finally {
+            writer.close();
+        }
+    }
+}
diff --git a/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/ChunkedFramingMechanismEncoder.java b/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/ChunkedFramingMechanismEncoder.java
new file mode 100644 (file)
index 0000000..1d7a3cd
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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.netconf.nettyutil.handler;
+
+import com.google.common.base.Preconditions;
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.MessageToByteEncoder;
+import java.nio.charset.StandardCharsets;
+import org.opendaylight.netconf.util.messages.NetconfMessageConstants;
+
+public class ChunkedFramingMechanismEncoder extends MessageToByteEncoder<ByteBuf> {
+    public static final int DEFAULT_CHUNK_SIZE = 8192;
+    public static final int MIN_CHUNK_SIZE = 128;
+    public static final int MAX_CHUNK_SIZE = 16 * 1024 * 1024;
+
+    private final int chunkSize;
+
+    public ChunkedFramingMechanismEncoder() {
+        this(DEFAULT_CHUNK_SIZE);
+    }
+
+    public ChunkedFramingMechanismEncoder(final int chunkSize) {
+        Preconditions.checkArgument(chunkSize >= MIN_CHUNK_SIZE && chunkSize <= MAX_CHUNK_SIZE,
+                "Unsupported chunk size %s", chunkSize);
+        this.chunkSize = chunkSize;
+    }
+
+    public final int getChunkSize() {
+        return chunkSize;
+    }
+
+    @Override
+    protected void encode(final ChannelHandlerContext ctx, final ByteBuf msg, final ByteBuf out)  {
+        do {
+            final int xfer = Math.min(chunkSize, msg.readableBytes());
+
+            out.writeBytes(NetconfMessageConstants.START_OF_CHUNK);
+            out.writeBytes(String.valueOf(xfer).getBytes(StandardCharsets.US_ASCII));
+            out.writeByte('\n');
+
+            out.writeBytes(msg, xfer);
+        } while (msg.isReadable());
+
+        out.writeBytes(NetconfMessageConstants.END_OF_CHUNK);
+    }
+}
diff --git a/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/EOMFramingMechanismEncoder.java b/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/EOMFramingMechanismEncoder.java
new file mode 100644 (file)
index 0000000..fdb0aae
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * 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.netconf.nettyutil.handler;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.MessageToByteEncoder;
+import org.opendaylight.netconf.util.messages.NetconfMessageConstants;
+
+public class EOMFramingMechanismEncoder extends MessageToByteEncoder<ByteBuf> {
+    @Override
+    protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) {
+        out.writeBytes(msg);
+        out.writeBytes(NetconfMessageConstants.END_OF_MESSAGE);
+    }
+}
diff --git a/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/FramingMechanismHandlerFactory.java b/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/FramingMechanismHandlerFactory.java
new file mode 100644 (file)
index 0000000..b233ff9
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * 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.netconf.nettyutil.handler;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.handler.codec.MessageToByteEncoder;
+import org.opendaylight.netconf.util.messages.FramingMechanism;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class FramingMechanismHandlerFactory {
+
+    private static final Logger LOG = LoggerFactory.getLogger(FramingMechanismHandlerFactory.class);
+
+    private FramingMechanismHandlerFactory() {
+        // not called - private constructor for utility class
+    }
+
+    public static MessageToByteEncoder<ByteBuf> createHandler(FramingMechanism framingMechanism) {
+        LOG.debug("{} framing mechanism was selected.", framingMechanism);
+        if (framingMechanism == FramingMechanism.EOM) {
+            return new EOMFramingMechanismEncoder();
+        } else {
+            return new ChunkedFramingMechanismEncoder();
+        }
+    }
+}
diff --git a/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/NetconfChunkAggregator.java b/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/NetconfChunkAggregator.java
new file mode 100644 (file)
index 0000000..144b4f5
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * 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.netconf.nettyutil.handler;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.CompositeByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.ByteToMessageDecoder;
+import java.util.List;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NetconfChunkAggregator extends ByteToMessageDecoder {
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfChunkAggregator.class);
+    private static final String GOT_PARAM_WHILE_WAITING_FOR_PARAM = "Got byte {} while waiting for {}";
+    private static final String GOT_PARAM_WHILE_WAITING_FOR_PARAM_PARAM = "Got byte {} while waiting for {}-{}";
+    public static final int DEFAULT_MAXIMUM_CHUNK_SIZE = 16 * 1024 * 1024;
+
+    private enum State {
+        HEADER_ONE, // \n
+        HEADER_TWO, // #
+        HEADER_LENGTH_FIRST, // [1-9]
+        HEADER_LENGTH_OTHER, // [0-9]*\n
+        DATA,
+        FOOTER_ONE, // \n
+        FOOTER_TWO, // #
+        FOOTER_THREE, // #
+        FOOTER_FOUR, // \n
+    }
+
+    private final int maxChunkSize = DEFAULT_MAXIMUM_CHUNK_SIZE;
+    private State state = State.HEADER_ONE;
+    private long chunkSize;
+    private CompositeByteBuf chunk;
+
+    private static void checkNewLine(final byte byteToCheck, final String errorMessage) {
+        if (byteToCheck != '\n') {
+            LOG.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM, byteToCheck, (byte)'\n');
+            throw new IllegalStateException(errorMessage);
+        }
+    }
+
+    private static void checkHash(final byte byteToCheck, final String errorMessage) {
+        if (byteToCheck != '#') {
+            LOG.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM, byteToCheck, (byte)'#');
+            throw new IllegalStateException(errorMessage);
+        }
+    }
+
+    private void checkChunkSize() {
+        if (chunkSize > maxChunkSize) {
+            LOG.debug("Parsed chunk size {}, maximum allowed is {}", chunkSize, maxChunkSize);
+            throw new IllegalStateException("Maximum chunk size exceeded");
+        }
+    }
+
+    @Override
+    protected void decode(final ChannelHandlerContext ctx,
+                          final ByteBuf in, final List<Object> out) throws IllegalStateException {
+        while (in.isReadable()) {
+            switch (state) {
+                case HEADER_ONE:
+                {
+                    final byte b = in.readByte();
+                    checkNewLine(b, "Malformed chunk header encountered (byte 0)");
+                    state = State.HEADER_TWO;
+                    initChunk();
+                    break;
+                }
+                case HEADER_TWO:
+                {
+                    final byte b = in.readByte();
+                    checkHash(b, "Malformed chunk header encountered (byte 1)");
+                    state = State.HEADER_LENGTH_FIRST;
+                    break;
+                }
+                case HEADER_LENGTH_FIRST:
+                {
+                    final byte b = in.readByte();
+                    chunkSize = processHeaderLengthFirst(b);
+                    state = State.HEADER_LENGTH_OTHER;
+                    break;
+                }
+                case HEADER_LENGTH_OTHER:
+                {
+                    final byte b = in.readByte();
+                    if (b == '\n') {
+                        state = State.DATA;
+                        break;
+                    }
+                    if (b < '0' || b > '9') {
+                        LOG.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM_PARAM, b, (byte)'0', (byte)'9');
+                        throw new IllegalStateException("Invalid chunk size encountered");
+                    }
+                    chunkSize *= 10;
+                    chunkSize += b - '0';
+                    checkChunkSize();
+                    break;
+                }
+                case DATA:
+                    /*
+                     * FIXME: this gathers all data into one big chunk before passing
+                     *        it on. Make sure the pipeline can work with partial data
+                     *        and then change this piece to pass the data on as it
+                     *        comes through.
+                     */
+                    if (in.readableBytes() < chunkSize) {
+                        LOG.debug("Buffer has {} bytes, need {} to complete chunk", in.readableBytes(), chunkSize);
+                        in.discardReadBytes();
+                        return;
+                    }
+                    aggregateChunks(in.readBytes((int) chunkSize));
+                    state = State.FOOTER_ONE;
+                    break;
+                case FOOTER_ONE:
+                {
+                    final byte b = in.readByte();
+                    checkNewLine(b,"Malformed chunk footer encountered (byte 0)");
+                    state = State.FOOTER_TWO;
+                    chunkSize = 0;
+                    break;
+                }
+                case FOOTER_TWO:
+                {
+                    final byte b = in.readByte();
+                    checkHash(b,"Malformed chunk footer encountered (byte 1)");
+                    state = State.FOOTER_THREE;
+                    break;
+                }
+                case FOOTER_THREE:
+                {
+                    final byte b = in.readByte();
+                    // In this state, either header-of-new-chunk or message-end is expected
+                    // Depends on the next character
+                    extractNewChunkOrMessageEnd(b);
+                    break;
+                }
+                case FOOTER_FOUR:
+                {
+                    final byte b = in.readByte();
+                    checkNewLine(b,"Malformed chunk footer encountered (byte 3)");
+                    state = State.HEADER_ONE;
+                    out.add(chunk);
+                    chunk = null;
+                    break;
+                }
+                default :
+                {
+                    LOG.info("Unknown state.");
+                }
+            }
+        }
+
+        in.discardReadBytes();
+    }
+
+    private void extractNewChunkOrMessageEnd(final byte byteToCheck) {
+        if (isHeaderLengthFirst(byteToCheck)) {
+            // Extract header length#1 from new chunk
+            chunkSize = processHeaderLengthFirst(byteToCheck);
+            // Proceed with next chunk processing
+            state = State.HEADER_LENGTH_OTHER;
+        } else if (byteToCheck == '#') {
+            state = State.FOOTER_FOUR;
+        } else {
+            LOG.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM_PARAM, byteToCheck, (byte) '#', (byte) '1', (byte) '9');
+            throw new IllegalStateException("Malformed chunk footer encountered (byte 2)");
+        }
+    }
+
+    private void initChunk() {
+        chunk = Unpooled.compositeBuffer();
+    }
+
+    private void aggregateChunks(final ByteBuf newChunk) {
+        chunk.addComponent(chunk.numComponents(), newChunk);
+
+        // Update writer index, addComponent does not update it
+        chunk.writerIndex(chunk.writerIndex() + newChunk.readableBytes());
+    }
+
+    private static int processHeaderLengthFirst(final byte byteToCheck) {
+        if (!isHeaderLengthFirst(byteToCheck)) {
+            LOG.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM_PARAM, byteToCheck, (byte)'1', (byte)'9');
+            throw new IllegalStateException("Invalid chunk size encountered (byte 0)");
+        }
+
+        return byteToCheck - '0';
+    }
+
+    private static boolean isHeaderLengthFirst(final byte byteToCheck) {
+        return byteToCheck >= '1' && byteToCheck <= '9';
+    }
+}
diff --git a/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/NetconfEOMAggregator.java b/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/NetconfEOMAggregator.java
new file mode 100644 (file)
index 0000000..6c0f5a1
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * 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.netconf.nettyutil.handler;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.handler.codec.DelimiterBasedFrameDecoder;
+import org.opendaylight.netconf.util.messages.NetconfMessageConstants;
+
+public class NetconfEOMAggregator extends DelimiterBasedFrameDecoder {
+
+    public static final ByteBuf DELIMITER = Unpooled.wrappedBuffer(NetconfMessageConstants.END_OF_MESSAGE);
+
+    public NetconfEOMAggregator() {
+        super(Integer.MAX_VALUE, DELIMITER);
+    }
+}
diff --git a/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/NetconfEXICodec.java b/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/NetconfEXICodec.java
new file mode 100644 (file)
index 0000000..b8924bb
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2014, 2015 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.netconf.nettyutil.handler;
+
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.siemens.ct.exi.core.EXIFactory;
+import com.siemens.ct.exi.core.exceptions.EXIException;
+import com.siemens.ct.exi.main.api.sax.SAXEncoder;
+import com.siemens.ct.exi.main.api.sax.SAXFactory;
+import org.opendaylight.netconf.nettyutil.handler.exi.EXIParameters;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+
+public final class NetconfEXICodec {
+    /**
+     * OpenEXI does not allow us to directly prevent resolution of external entities. In order
+     * to prevent XXE attacks, we reuse a single no-op entity resolver.
+     */
+    private static final EntityResolver ENTITY_RESOLVER = (publicId, systemId) -> new InputSource();
+
+    /**
+     * Since we have a limited number of options we can have, instantiating a weak cache
+     * will allow us to reuse instances where possible.
+     */
+    private static final LoadingCache<EXIParameters, NetconfEXICodec> CODECS =
+            CacheBuilder.newBuilder().weakValues().build(new CacheLoader<EXIParameters, NetconfEXICodec>() {
+                @Override
+                public NetconfEXICodec load(final EXIParameters key) {
+                    return new NetconfEXICodec(key.getFactory());
+                }
+            });
+
+    private final SAXFactory exiFactory;
+
+    private NetconfEXICodec(final EXIFactory exiFactory) {
+        this.exiFactory = new SAXFactory(requireNonNull(exiFactory));
+    }
+
+    public static NetconfEXICodec forParameters(final EXIParameters parameters) {
+        return CODECS.getUnchecked(parameters);
+    }
+
+    XMLReader getReader() throws EXIException {
+        final XMLReader reader = exiFactory.createEXIReader();
+        reader.setEntityResolver(ENTITY_RESOLVER);
+        return reader;
+    }
+
+    SAXEncoder getWriter() throws EXIException {
+        final SAXEncoder writer = exiFactory.createEXIWriter();
+        return writer;
+    }
+}
diff --git a/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/NetconfEXIToMessageDecoder.java b/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/NetconfEXIToMessageDecoder.java
new file mode 100644 (file)
index 0000000..1ddacb8
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netconf.nettyutil.handler;
+
+import static java.util.Objects.requireNonNull;
+
+import com.siemens.ct.exi.core.exceptions.EXIException;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufInputStream;
+import io.netty.buffer.ByteBufUtil;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.ByteToMessageDecoder;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import javax.xml.transform.sax.TransformerHandler;
+import org.opendaylight.netconf.api.NetconfMessage;
+import org.opendaylight.yangtools.util.xml.UntrustedXML;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+
+public final class NetconfEXIToMessageDecoder extends ByteToMessageDecoder {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfEXIToMessageDecoder.class);
+    private static final SAXTransformerFactory FACTORY;
+
+    static {
+        final TransformerFactory f = SAXTransformerFactory.newInstance();
+        if (!f.getFeature(SAXTransformerFactory.FEATURE)) {
+            throw new TransformerFactoryConfigurationError(
+                    String.format("Factory %s is not a SAXTransformerFactory", f));
+        }
+
+        FACTORY = (SAXTransformerFactory)f;
+    }
+
+    /**
+     * This class is not marked as shared, so it can be attached to only a single channel,
+     * which means that {@link #decode(ChannelHandlerContext, ByteBuf, List)}
+     * cannot be invoked concurrently. Hence we can reuse the reader.
+     */
+    private final XMLReader reader;
+    private final DocumentBuilder documentBuilder;
+
+    private NetconfEXIToMessageDecoder(final XMLReader reader) {
+        this.reader = requireNonNull(reader);
+        this.documentBuilder = UntrustedXML.newDocumentBuilder();
+    }
+
+    public static NetconfEXIToMessageDecoder create(final NetconfEXICodec codec) throws EXIException {
+        return new NetconfEXIToMessageDecoder(codec.getReader());
+    }
+
+    @Override
+    protected void decode(final ChannelHandlerContext ctx, final ByteBuf in, final List<Object> out)
+            throws IOException, SAXException, TransformerConfigurationException {
+        /*
+         * Note that we could loop here and process all the messages, but we can't do that.
+         * The reason is <stop-exi> operation, which has the contract of immediately stopping
+         * the use of EXI, which means the next message needs to be decoded not by us, but rather
+         * by the XML decoder.
+         */
+
+        // If empty Byte buffer is passed to r.parse, EOFException is thrown
+        if (!in.isReadable()) {
+            LOG.debug("No more content in incoming buffer.");
+            return;
+        }
+
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Received to decode: {}", ByteBufUtil.hexDump(in));
+        }
+
+        final TransformerHandler handler = FACTORY.newTransformerHandler();
+        reader.setContentHandler(handler);
+
+        final DOMResult domResult = new DOMResult(documentBuilder.newDocument());
+        handler.setResult(domResult);
+
+        try (InputStream is = new ByteBufInputStream(in)) {
+            // Performs internal reset before doing anything
+            reader.parse(new InputSource(is));
+        }
+
+        out.add(new NetconfMessage((Document) domResult.getNode()));
+    }
+}
diff --git a/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/NetconfHelloMessageToXMLEncoder.java b/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/NetconfHelloMessageToXMLEncoder.java
new file mode 100644 (file)
index 0000000..fac1b2b
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netconf.nettyutil.handler;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandlerContext;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import javax.xml.transform.TransformerException;
+import org.opendaylight.netconf.api.NetconfMessage;
+import org.opendaylight.netconf.api.messages.NetconfHelloMessage;
+import org.opendaylight.netconf.api.messages.NetconfHelloMessageAdditionalHeader;
+
+/**
+ * Customized NetconfMessageToXMLEncoder that serializes additional header with
+ * session metadata along with
+ * {@link NetconfHelloMessage}
+ * . Used by netconf clients to send information about the user, ip address,
+ * protocol etc.
+ *
+ * <p>
+ * Hello message with header example:
+ *
+ * <p>
+ *
+ * <pre>
+ * {@code
+ * [tomas;10.0.0.0/10000;tcp;1000;1000;;/home/tomas;;]
+ * < hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+ * < capabilities>
+ * < capability>urn:ietf:params:netconf:base:1.0< /capability>
+ * < /capabilities>
+ * < /hello>
+ * }
+ * </pre>
+ */
+public final class NetconfHelloMessageToXMLEncoder extends NetconfMessageToXMLEncoder {
+    @Override
+    @VisibleForTesting
+    public void encode(ChannelHandlerContext ctx, NetconfMessage msg, ByteBuf out)
+            throws IOException, TransformerException {
+        Preconditions.checkState(msg instanceof NetconfHelloMessage, "Netconf message of type %s expected, was %s",
+                NetconfHelloMessage.class, msg.getClass());
+        Optional<NetconfHelloMessageAdditionalHeader> headerOptional = ((NetconfHelloMessage) msg)
+                .getAdditionalHeader();
+
+        // If additional header present, serialize it along with netconf hello message
+        if (headerOptional.isPresent()) {
+            out.writeBytes(headerOptional.get().toFormattedString().getBytes(StandardCharsets.UTF_8));
+        }
+
+        super.encode(ctx, msg, out);
+    }
+}
diff --git a/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/NetconfMessageToEXIEncoder.java b/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/NetconfMessageToEXIEncoder.java
new file mode 100644 (file)
index 0000000..932613c
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netconf.nettyutil.handler;
+
+import static java.util.Objects.requireNonNull;
+
+import com.siemens.ct.exi.core.exceptions.EXIException;
+import com.siemens.ct.exi.main.api.sax.SAXEncoder;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufOutputStream;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.MessageToByteEncoder;
+import java.io.IOException;
+import java.io.OutputStream;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.sax.SAXResult;
+import org.opendaylight.netconf.api.NetconfMessage;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class NetconfMessageToEXIEncoder extends MessageToByteEncoder<NetconfMessage> {
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfMessageToEXIEncoder.class);
+    private final NetconfEXICodec codec;
+
+    private NetconfMessageToEXIEncoder(final NetconfEXICodec codec) {
+        this.codec = requireNonNull(codec);
+    }
+
+    public static NetconfMessageToEXIEncoder create(final NetconfEXICodec codec) {
+        return new NetconfMessageToEXIEncoder(codec);
+    }
+
+    @Override
+    protected void encode(final ChannelHandlerContext ctx, final NetconfMessage msg, final ByteBuf out)
+            throws IOException, TransformerException, EXIException {
+        LOG.trace("Sent to encode : {}", msg);
+
+        try (OutputStream os = new ByteBufOutputStream(out)) {
+            final SAXEncoder encoder = codec.getWriter();
+            encoder.setOutputStream(os);
+            final Transformer transformer = ThreadLocalTransformers.getDefaultTransformer();
+            transformer.transform(new DOMSource(msg.getDocument()), new SAXResult(encoder));
+        }
+    }
+}
diff --git a/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/NetconfMessageToXMLEncoder.java b/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/NetconfMessageToXMLEncoder.java
new file mode 100644 (file)
index 0000000..f033e0e
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netconf.nettyutil.handler;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Optional;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufOutputStream;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.MessageToByteEncoder;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.nio.charset.StandardCharsets;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import org.opendaylight.netconf.api.NetconfMessage;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Comment;
+
+public class NetconfMessageToXMLEncoder extends MessageToByteEncoder<NetconfMessage> {
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfMessageToXMLEncoder.class);
+
+    private final Optional<String> clientId;
+
+    public NetconfMessageToXMLEncoder() {
+        this(Optional.<String>absent());
+    }
+
+    public NetconfMessageToXMLEncoder(final Optional<String> clientId) {
+        this.clientId = clientId;
+    }
+
+    @Override
+    @VisibleForTesting
+    public void encode(final ChannelHandlerContext ctx, final NetconfMessage msg, final ByteBuf out)
+            throws IOException, TransformerException {
+        LOG.trace("Sent to encode : {}", msg);
+
+        if (clientId.isPresent()) {
+            Comment comment = msg.getDocument().createComment("clientId:" + clientId.get());
+            msg.getDocument().appendChild(comment);
+        }
+
+        try (OutputStream os = new ByteBufOutputStream(out)) {
+            // Wrap OutputStreamWriter with BufferedWriter as suggested in javadoc for OutputStreamWriter
+
+            // Using custom BufferedWriter that does not provide newLine method as performance improvement
+            // see javadoc for BufferedWriter
+            StreamResult result =
+                    new StreamResult(new BufferedWriter(new OutputStreamWriter(os, StandardCharsets.UTF_8)));
+            DOMSource source = new DOMSource(msg.getDocument());
+            ThreadLocalTransformers.getPrettyTransformer().transform(source, result);
+        }
+    }
+}
diff --git a/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/NetconfXMLToHelloMessageDecoder.java b/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/NetconfXMLToHelloMessageDecoder.java
new file mode 100644 (file)
index 0000000..5d69d40
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netconf.nettyutil.handler;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufUtil;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.ByteToMessageDecoder;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.List;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
+import org.opendaylight.netconf.api.NetconfDocumentedException;
+import org.opendaylight.netconf.api.NetconfMessage;
+import org.opendaylight.netconf.api.messages.NetconfHelloMessage;
+import org.opendaylight.netconf.api.messages.NetconfHelloMessageAdditionalHeader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+/**
+ * Customized NetconfXMLToMessageDecoder that reads additional header with
+ * session metadata from
+ * {@link NetconfHelloMessage}*
+ * This handler should be replaced in pipeline by regular message handler as last step of negotiation.
+ * It serves as a message barrier and halts all non-hello netconf messages.
+ * Netconf messages after hello should be processed once the negotiation succeeded.
+ *
+ */
+public final class NetconfXMLToHelloMessageDecoder extends ByteToMessageDecoder {
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfXMLToHelloMessageDecoder.class);
+
+    private static final List<byte[]> POSSIBLE_ENDS = ImmutableList.of(
+            new byte[] { ']', '\n' },
+            new byte[] { ']', '\r', '\n' });
+    private static final List<byte[]> POSSIBLE_STARTS = ImmutableList.of(
+            new byte[] { '[' },
+            new byte[] { '\r', '\n', '[' },
+            new byte[] { '\n', '[' });
+
+    // State variables do not have to by synchronized
+    // Netty uses always the same (1) thread per pipeline
+    // We use instance of this per pipeline
+    private final List<NetconfMessage> nonHelloMessages = Lists.newArrayList();
+    private boolean helloReceived = false;
+
+    @Override
+    @VisibleForTesting
+    public void decode(final ChannelHandlerContext ctx, final ByteBuf in, final List<Object> out)
+            throws IOException, SAXException, NetconfDocumentedException {
+        if (in.readableBytes() == 0) {
+            LOG.debug("No more content in incoming buffer.");
+            return;
+        }
+
+        in.markReaderIndex();
+        try {
+            if (LOG.isTraceEnabled()) {
+                LOG.trace("Received to decode: {}", ByteBufUtil.hexDump(in));
+            }
+
+            byte[] bytes = new byte[in.readableBytes()];
+            in.readBytes(bytes);
+
+            logMessage(bytes);
+
+            // Extract bytes containing header with additional metadata
+            String additionalHeader = null;
+            if (startsWithAdditionalHeader(bytes)) {
+                // Auth information containing username, ip address... extracted for monitoring
+                int endOfAuthHeader = getAdditionalHeaderEndIndex(bytes);
+                if (endOfAuthHeader > -1) {
+                    byte[] additionalHeaderBytes = Arrays.copyOfRange(bytes, 0, endOfAuthHeader);
+                    additionalHeader = additionalHeaderToString(additionalHeaderBytes);
+                    bytes = Arrays.copyOfRange(bytes, endOfAuthHeader, bytes.length);
+                }
+            }
+
+            Document doc = XmlUtil.readXmlToDocument(new ByteArrayInputStream(bytes));
+
+            final NetconfMessage message = getNetconfMessage(additionalHeader, doc);
+            if (message instanceof NetconfHelloMessage) {
+                Preconditions.checkState(helloReceived == false,
+                        "Multiple hello messages received, unexpected hello: %s", message);
+                out.add(message);
+                helloReceived = true;
+            // Non hello message, suspend the message and insert into cache
+            } else {
+                Preconditions.checkState(helloReceived, "Hello message not received, instead received: %s", message);
+                LOG.debug("Netconf message received during negotiation, caching {}", message);
+                nonHelloMessages.add(message);
+            }
+        } finally {
+            in.discardReadBytes();
+        }
+    }
+
+    private static NetconfMessage getNetconfMessage(final String additionalHeader, final Document doc)
+            throws NetconfDocumentedException {
+        NetconfMessage msg = new NetconfMessage(doc);
+        if (NetconfHelloMessage.isHelloMessage(msg)) {
+            if (additionalHeader != null) {
+                return new NetconfHelloMessage(doc, NetconfHelloMessageAdditionalHeader.fromString(additionalHeader));
+            } else {
+                return new NetconfHelloMessage(doc);
+            }
+        }
+
+        return msg;
+    }
+
+    private static int getAdditionalHeaderEndIndex(final byte[] bytes) {
+        for (byte[] possibleEnd : POSSIBLE_ENDS) {
+            int idx = findByteSequence(bytes, possibleEnd);
+
+            if (idx != -1) {
+                return idx + possibleEnd.length;
+            }
+        }
+
+        return -1;
+    }
+
+    private static int findByteSequence(final byte[] bytes, final byte[] sequence) {
+        if (bytes.length < sequence.length) {
+            throw new IllegalArgumentException("Sequence to be found is longer than the given byte array.");
+        }
+        if (bytes.length == sequence.length) {
+            if (Arrays.equals(bytes, sequence)) {
+                return 0;
+            } else {
+                return -1;
+            }
+        }
+        int index = 0;
+        for (int i = 0; i < bytes.length; i++) {
+            if (bytes[i] == sequence[index]) {
+                index++;
+                if (index == sequence.length) {
+                    return i - index + 1;
+                }
+            } else {
+                index = 0;
+            }
+        }
+        return -1;
+    }
+
+    private static void logMessage(final byte[] bytes) {
+        if (LOG.isDebugEnabled()) {
+            String string = StandardCharsets.UTF_8.decode(ByteBuffer.wrap(bytes)).toString();
+            LOG.debug("Parsing message \n{}", string);
+        }
+    }
+
+    private static boolean startsWithAdditionalHeader(final byte[] bytes) {
+        for (byte[] possibleStart : POSSIBLE_STARTS) {
+            int index = 0;
+            for (byte b : possibleStart) {
+                if (bytes[index++] != b) {
+                    break;
+                }
+
+                if (index == possibleStart.length) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    private static String additionalHeaderToString(final byte[] bytes) {
+        return StandardCharsets.UTF_8.decode(ByteBuffer.wrap(bytes)).toString();
+    }
+
+    /**
+     * Get netconf messages received during negotiation.
+     *
+     * @return Collection of NetconfMessages that were not hello, but were received during negotiation.
+     */
+    public Iterable<NetconfMessage> getPostHelloNetconfMessages() {
+        return nonHelloMessages;
+    }
+}
diff --git a/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/NetconfXMLToMessageDecoder.java b/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/NetconfXMLToMessageDecoder.java
new file mode 100644 (file)
index 0000000..60a8dd1
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netconf.nettyutil.handler;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufInputStream;
+import io.netty.buffer.ByteBufUtil;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.ByteToMessageDecoder;
+import java.io.IOException;
+import java.util.List;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
+import org.opendaylight.netconf.api.FailedNetconfMessage;
+import org.opendaylight.netconf.api.NetconfMessage;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+public final class NetconfXMLToMessageDecoder extends ByteToMessageDecoder {
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfXMLToMessageDecoder.class);
+
+    @Override
+    public void decode(final ChannelHandlerContext ctx, final ByteBuf in,
+                       final List<Object> out) throws IOException, SAXException {
+        if (in.isReadable()) {
+            if (LOG.isTraceEnabled()) {
+                LOG.trace("Received to decode: {}", ByteBufUtil.hexDump(in));
+            }
+
+            /* According to the XML 1.0 specifications, when there is an XML declaration
+             * at the beginning of an XML document, it is invalid to have
+             * white spaces before that declaration (reminder: a XML declaration looks like:
+             * <?xml version="1.0" encoding="UTF-8"?>). In contrast, when there is no XML declaration,
+             * it is valid to have white spaces at the beginning of the document.
+             *
+             * When they send a NETCONF message, several NETCONF servers start with a new line (either
+             * LF or CRLF), presumably to improve readability in interactive sessions with a human being.
+             * Some NETCONF servers send an XML declaration, some others do not.
+             *
+             * If a server starts a NETCONF message with white spaces and follows with an XML
+             * declaration, XmlUtil.readXmlToDocument() will fail because this is invalid XML.
+             * But in the spirit of the "NETCONF over SSH" RFC 4742 and to improve interoperability, we want
+             * to accept those messages.
+             *
+             * To do this, the following code strips the leading bytes before the start of the XML messages.
+             */
+
+            // Skip all leading whitespaces by moving the reader index to the first non whitespace character
+            while (in.isReadable()) {
+                if (!isWhitespace(in.readByte())) {
+                    // return reader index to the first non whitespace character
+                    in.readerIndex(in.readerIndex() - 1);
+                    break;
+                }
+            }
+
+            // Warn about leading whitespaces
+            if (in.readerIndex() != 0 && LOG.isWarnEnabled()) {
+                final byte[] strippedBytes = new byte[in.readerIndex()];
+                in.getBytes(0, strippedBytes, 0, in.readerIndex());
+                LOG.warn("XML message with unwanted leading bytes detected. Discarded the {} leading byte(s): '{}'",
+                        in.readerIndex(), ByteBufUtil.hexDump(Unpooled.wrappedBuffer(strippedBytes)));
+            }
+        }
+        if (in.isReadable()) {
+            NetconfMessage msg;
+
+            try {
+                msg = new NetconfMessage(XmlUtil.readXmlToDocument(new ByteBufInputStream(in)));
+            } catch (SAXParseException exception) {
+                LOG.error("Failed to parse received message", exception);
+                msg = new FailedNetconfMessage(exception);
+            }
+
+            out.add(msg);
+        } else {
+            LOG.debug("No more content in incoming buffer.");
+        }
+    }
+
+    /**
+     * Check whether a byte is whitespace/control character. Considered whitespace characters: <br/>
+     * SPACE, \t, \n, \v, \r, \f
+     *
+     * @param byteToCheck byte to check
+     * @return true if the byte is a whitespace/control character
+     */
+    private static boolean isWhitespace(final byte byteToCheck) {
+        return byteToCheck <= 0x0d && byteToCheck >= 0x09 || byteToCheck == 0x20;
+    }
+}
diff --git a/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/ThreadLocalTransformers.java b/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/ThreadLocalTransformers.java
new file mode 100644 (file)
index 0000000..35146e1
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netconf.nettyutil.handler;
+
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+
+/**
+ * Utility class for cached thread-local transformers. This class exists mostly for use by handlers.
+ */
+final class ThreadLocalTransformers {
+    private static final TransformerFactory FACTORY = TransformerFactory.newInstance();
+
+    private static final ThreadLocal<Transformer> DEFAULT_TRANSFORMER = new ThreadLocal<Transformer>() {
+        @Override
+        protected Transformer initialValue() {
+            return createTransformer();
+        }
+
+        @Override
+        public void set(final Transformer value) {
+            throw new UnsupportedOperationException();
+        }
+    };
+
+    private static final ThreadLocal<Transformer> PRETTY_TRANSFORMER = new ThreadLocal<Transformer>() {
+        @Override
+        protected Transformer initialValue() {
+            final Transformer ret = createTransformer();
+            ret.setOutputProperty(OutputKeys.INDENT, "yes");
+            ret.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
+            return ret;
+        }
+
+        @Override
+        public void set(final Transformer value) {
+            throw new UnsupportedOperationException();
+        }
+    };
+
+    private ThreadLocalTransformers() {
+        throw new UnsupportedOperationException("Utility class");
+    }
+
+    /**
+     * Get the transformer with default configuration.
+     *
+     * @return A transformer with default configuration based on the default implementation.
+     */
+    static Transformer getDefaultTransformer() {
+        return DEFAULT_TRANSFORMER.get();
+    }
+
+    /**
+     * Get the transformer with default configuration, but with automatic indentation
+     * and the XML declaration removed.
+     *
+     * @return A transformer with human-friendly configuration.
+     */
+    static Transformer getPrettyTransformer() {
+        return PRETTY_TRANSFORMER.get();
+    }
+
+    private static Transformer createTransformer() {
+        try {
+            return FACTORY.newTransformer();
+        } catch (TransformerConfigurationException | TransformerFactoryConfigurationError e) {
+            throw new IllegalStateException("Unexpected error while instantiating a Transformer", e);
+        }
+    }
+}
diff --git a/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/exi/EXIParameters.java b/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/exi/EXIParameters.java
new file mode 100644 (file)
index 0000000..9eb32eb
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * 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.netconf.nettyutil.handler.exi;
+
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.siemens.ct.exi.core.CodingMode;
+import com.siemens.ct.exi.core.EXIFactory;
+import com.siemens.ct.exi.core.EncodingOptions;
+import com.siemens.ct.exi.core.FidelityOptions;
+import com.siemens.ct.exi.core.exceptions.UnsupportedOption;
+import com.siemens.ct.exi.core.helpers.DefaultEXIFactory;
+import java.util.Objects;
+import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+public final class EXIParameters {
+    private static final Logger LOG = LoggerFactory.getLogger(EXIParameters.class);
+
+    static final String EXI_PARAMETER_ALIGNMENT = "alignment";
+    private static final String EXI_PARAMETER_BYTE_ALIGNED = "byte-aligned";
+    private static final String EXI_PARAMETER_BIT_PACKED = "bit-packed";
+    private static final String EXI_PARAMETER_COMPRESSED = "compressed";
+    private static final String EXI_PARAMETER_PRE_COMPRESSION = "pre-compression";
+
+    static final String EXI_PARAMETER_FIDELITY = "fidelity";
+    private static final String EXI_FIDELITY_DTD = "dtd";
+    private static final String EXI_FIDELITY_LEXICAL_VALUES = "lexical-values";
+    private static final String EXI_FIDELITY_COMMENTS = "comments";
+    private static final String EXI_FIDELITY_PIS = "pis";
+    private static final String EXI_FIDELITY_PREFIXES = "prefixes";
+
+    private static final EncodingOptions ENCODING_OPTIONS;
+
+    static {
+        final EncodingOptions opts = EncodingOptions.createDefault();
+        try {
+            opts.setOption(EncodingOptions.RETAIN_ENTITY_REFERENCE);
+            opts.setOption(EncodingOptions.INCLUDE_OPTIONS);
+
+            /**
+             * NETCONF is XML environment, so the use of EXI cookie is not really needed. Adding it
+             * decreases efficiency of encoding by adding human-readable 4 bytes "EXI$" to the head
+             * of the stream. This is really useful, so let's output it now.
+             */
+            opts.setOption(EncodingOptions.INCLUDE_COOKIE);
+        } catch (final UnsupportedOption e) {
+            throw new ExceptionInInitializerError(e);
+        }
+
+        ENCODING_OPTIONS = opts;
+    }
+
+    private final FidelityOptions fidelityOptions;
+    private final CodingMode codingMode;
+
+    public EXIParameters(final CodingMode codingMode, final FidelityOptions fidelityOptions) {
+        this.fidelityOptions = requireNonNull(fidelityOptions);
+        this.codingMode = requireNonNull(codingMode);
+    }
+
+    @VisibleForTesting
+    public static EXIParameters empty() {
+        return new EXIParameters(CodingMode.BIT_PACKED, FidelityOptions.createDefault());
+    }
+
+    public static EXIParameters fromXmlElement(final XmlElement root) throws UnsupportedOption {
+        final CodingMode coding;
+        final NodeList alignmentElements = root.getElementsByTagName(EXI_PARAMETER_ALIGNMENT);
+        if (alignmentElements.getLength() > 0) {
+            final Element alignmentElement = (Element) alignmentElements.item(0);
+            final String alignmentTextContent = alignmentElement.getTextContent().trim();
+
+            switch (alignmentTextContent) {
+                case EXI_PARAMETER_BYTE_ALIGNED:
+                    coding = CodingMode.BYTE_PACKED;
+                    break;
+                case EXI_PARAMETER_COMPRESSED:
+                    coding = CodingMode.COMPRESSION;
+                    break;
+                case EXI_PARAMETER_PRE_COMPRESSION:
+                    coding = CodingMode.PRE_COMPRESSION;
+                    break;
+                case EXI_PARAMETER_BIT_PACKED:
+                    coding = CodingMode.BIT_PACKED;
+                    break;
+                default:
+                    LOG.warn("Unexpected value in alignmentTextContent: {} , using default value",
+                            alignmentTextContent);
+                    coding = CodingMode.BIT_PACKED;
+                    break;
+            }
+        } else {
+            coding = CodingMode.BIT_PACKED;
+        }
+
+        final FidelityOptions fidelity = FidelityOptions.createDefault();
+        final NodeList fidelityElements = root.getElementsByTagName(EXI_PARAMETER_FIDELITY);
+        if (fidelityElements.getLength() > 0) {
+            final Element fidelityElement = (Element) fidelityElements.item(0);
+
+            fidelity.setFidelity(FidelityOptions.FEATURE_DTD,
+                fidelityElement.getElementsByTagName(EXI_FIDELITY_DTD).getLength() > 0);
+            fidelity.setFidelity(FidelityOptions.FEATURE_LEXICAL_VALUE,
+                fidelityElement.getElementsByTagName(EXI_FIDELITY_LEXICAL_VALUES).getLength() > 0);
+            fidelity.setFidelity(FidelityOptions.FEATURE_COMMENT,
+                fidelityElement.getElementsByTagName(EXI_FIDELITY_COMMENTS).getLength() > 0);
+            fidelity.setFidelity(FidelityOptions.FEATURE_PI,
+                fidelityElement.getElementsByTagName(EXI_FIDELITY_PIS).getLength() > 0);
+            fidelity.setFidelity(FidelityOptions.FEATURE_PREFIX,
+                fidelityElement.getElementsByTagName(EXI_FIDELITY_PREFIXES).getLength() > 0);
+        }
+
+        return new EXIParameters(coding, fidelity);
+    }
+
+    public EXIFactory getFactory() {
+        final EXIFactory factory = DefaultEXIFactory.newInstance();
+        factory.setCodingMode(codingMode);
+        factory.setEncodingOptions(ENCODING_OPTIONS);
+        factory.setFidelityOptions(fidelityOptions);
+        return factory;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(fidelityOptions, codingMode);
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof EXIParameters)) {
+            return false;
+        }
+        final EXIParameters other = (EXIParameters) obj;
+        return (codingMode == other.codingMode) && fidelityOptions.equals(other.fidelityOptions);
+    }
+
+    String getAlignment() {
+        switch (codingMode) {
+            case BIT_PACKED:
+                return EXI_PARAMETER_BIT_PACKED;
+            case BYTE_PACKED:
+                return EXI_PARAMETER_BYTE_ALIGNED;
+            case COMPRESSION:
+                return EXI_PARAMETER_COMPRESSED;
+            case PRE_COMPRESSION:
+                return EXI_PARAMETER_PRE_COMPRESSION;
+            default:
+                throw new IllegalStateException("Unhandled coding mode " + codingMode);
+        }
+    }
+
+    private String fidelityString(final String feature, final String string) {
+        return fidelityOptions.isFidelityEnabled(feature) ? string : null;
+    }
+
+    String getPreserveComments() {
+        return fidelityString(FidelityOptions.FEATURE_COMMENT, EXI_FIDELITY_COMMENTS);
+    }
+
+    String getPreserveDTD() {
+        return fidelityString(FidelityOptions.FEATURE_DTD, EXI_FIDELITY_DTD);
+    }
+
+    String getPreserveLexicalValues() {
+        return fidelityString(FidelityOptions.FEATURE_LEXICAL_VALUE, EXI_FIDELITY_LEXICAL_VALUES);
+    }
+
+    String getPreservePIs() {
+        return fidelityString(FidelityOptions.FEATURE_PI, EXI_FIDELITY_PIS);
+    }
+
+    String getPreservePrefixes() {
+        return fidelityString(FidelityOptions.FEATURE_PREFIX, EXI_FIDELITY_PREFIXES);
+    }
+}
\ No newline at end of file
diff --git a/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/exi/NetconfStartExiMessage.java b/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/exi/NetconfStartExiMessage.java
new file mode 100644 (file)
index 0000000..c87dc98
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * 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.netconf.nettyutil.handler.exi;
+
+import com.google.common.annotations.VisibleForTesting;
+import java.util.ArrayList;
+import java.util.List;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
+import org.opendaylight.netconf.api.NetconfMessage;
+import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Start-exi netconf message.
+ */
+public final class NetconfStartExiMessage extends NetconfMessage {
+    @VisibleForTesting
+    public static final String START_EXI = "start-exi";
+
+
+    private NetconfStartExiMessage(final Document doc) {
+        super(doc);
+    }
+
+    public static NetconfStartExiMessage create(final EXIParameters exiOptions, final String messageId) {
+        final Document doc = XmlUtil.newDocument();
+        final Element rpcElement = doc.createElementNS(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0,
+                XmlNetconfConstants.RPC_KEY);
+        rpcElement.setAttributeNS(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0,
+                XmlNetconfConstants.MESSAGE_ID, messageId);
+
+        // TODO draft http://tools.ietf.org/html/draft-varga-netconf-exi-capability-02#section-3.5.1 has no namespace
+        // for start-exi element in xml
+        final Element startExiElement = doc.createElementNS(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_EXI_1_0,
+                START_EXI);
+
+        addAlignment(exiOptions, doc, startExiElement);
+        addFidelity(exiOptions, doc, startExiElement);
+
+        rpcElement.appendChild(startExiElement);
+
+        doc.appendChild(rpcElement);
+        return new NetconfStartExiMessage(doc);
+    }
+
+    private static void addFidelity(final EXIParameters exiOptions, final Document doc, final Element startExiElement) {
+        final List<Element> fidelityElements = new ArrayList<>(5);
+        createFidelityElement(doc, fidelityElements, exiOptions.getPreserveComments());
+        createFidelityElement(doc, fidelityElements, exiOptions.getPreserveDTD());
+        createFidelityElement(doc, fidelityElements, exiOptions.getPreserveLexicalValues());
+        createFidelityElement(doc, fidelityElements, exiOptions.getPreservePIs());
+        createFidelityElement(doc, fidelityElements, exiOptions.getPreservePrefixes());
+
+        if (!fidelityElements.isEmpty()) {
+            final Element fidelityElement = doc.createElementNS(
+                    XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_EXI_1_0, EXIParameters.EXI_PARAMETER_FIDELITY);
+            for (final Element element : fidelityElements) {
+                fidelityElement.appendChild(element);
+            }
+            startExiElement.appendChild(fidelityElement);
+        }
+    }
+
+    private static void addAlignment(final EXIParameters exiOptions, final Document doc,
+                                     final Element startExiElement) {
+        final Element alignmentElement = doc.createElementNS(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_EXI_1_0,
+            EXIParameters.EXI_PARAMETER_ALIGNMENT);
+
+        alignmentElement.setTextContent(exiOptions.getAlignment());
+        startExiElement.appendChild(alignmentElement);
+    }
+
+    private static void createFidelityElement(final Document doc, final List<Element> elements,
+                                              final String fidelity) {
+        if (fidelity != null) {
+            elements.add(doc.createElementNS(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_EXI_1_0, fidelity));
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/ssh/authentication/AuthenticationHandler.java b/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/ssh/authentication/AuthenticationHandler.java
new file mode 100644 (file)
index 0000000..aed4334
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * 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.netconf.nettyutil.handler.ssh.authentication;
+
+import java.io.IOException;
+import org.apache.sshd.ClientSession;
+
+/**
+ * Class providing authentication facility to SSH handler.
+ */
+public abstract class AuthenticationHandler {
+
+    public abstract String getUsername();
+
+    public abstract org.apache.sshd.client.future.AuthFuture authenticate(ClientSession session)
+            throws IOException;
+}
diff --git a/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/ssh/authentication/LoginPassword.java b/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/ssh/authentication/LoginPassword.java
new file mode 100644 (file)
index 0000000..8281a79
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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.netconf.nettyutil.handler.ssh.authentication;
+
+import java.io.IOException;
+import org.apache.sshd.ClientSession;
+import org.apache.sshd.client.future.AuthFuture;
+import org.opendaylight.aaa.encrypt.AAAEncryptionService;
+
+/**
+ * Class Providing username/password authentication option to
+ * {@link org.opendaylight.netconf.nettyutil.handler.ssh.client.AsyncSshHandler}.
+ */
+public class LoginPassword extends AuthenticationHandler {
+    protected final String username;
+    protected final String password;
+    protected final AAAEncryptionService encryptionService;
+
+    public LoginPassword(String username, String password) {
+        this(username, password, null);
+    }
+
+    public LoginPassword(final String username, final String password, final AAAEncryptionService encryptionService) {
+        this.username = username;
+        this.password = password;
+        this.encryptionService = encryptionService;
+    }
+
+    @Override
+    public String getUsername() {
+        return username;
+    }
+
+    @Override
+    public AuthFuture authenticate(final ClientSession session) throws IOException {
+        if (encryptionService != null) {
+            String decryptedPassword = encryptionService.decrypt(password);
+            session.addPasswordIdentity(decryptedPassword);
+        } else {
+            session.addPasswordIdentity(password);
+        }
+        return session.auth();
+    }
+}
diff --git a/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/ssh/authentication/PublicKeyAuth.java b/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/ssh/authentication/PublicKeyAuth.java
new file mode 100644 (file)
index 0000000..420a216
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2017 Brocade Communication Systems 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.netconf.nettyutil.handler.ssh.authentication;
+
+import com.google.common.base.Strings;
+import java.io.IOException;
+import java.security.KeyPair;
+import org.apache.sshd.ClientSession;
+import org.apache.sshd.client.future.AuthFuture;
+import org.opendaylight.aaa.encrypt.AAAEncryptionService;
+import org.opendaylight.aaa.encrypt.PKIUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Represents Auth information for the public key based authentication for netconf.
+ */
+public class PublicKeyAuth extends LoginPassword {
+    private KeyPair keyPair = null;
+    private static final Logger LOG = LoggerFactory.getLogger(PublicKeyAuth.class);
+
+    public PublicKeyAuth(String username, String password, String keyPath,
+            String passPhrase, AAAEncryptionService encryptionService) {
+        super(username, password, encryptionService);
+        try {
+            boolean isKeyPathAbsent = Strings.isNullOrEmpty(keyPath);
+            passPhrase = Strings.isNullOrEmpty(passPhrase) ? "" : passPhrase;
+            if (!isKeyPathAbsent) {
+                this.keyPair = new PKIUtil().decodePrivateKey(keyPath, passPhrase);
+            } else {
+                LOG.info("Private key path not specified in the config file.");
+            }
+        } catch (IOException ioEx) {
+            LOG.warn("Not able to read the private key and passphrase for netconf client", ioEx);
+        }
+    }
+
+    @Override
+    public AuthFuture authenticate(final ClientSession session) throws IOException {
+        if (keyPair != null) {
+            session.addPublicKeyIdentity(keyPair);
+        }
+
+        return super.authenticate(session);
+    }
+}
diff --git a/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/ssh/client/AsyncSshHandler.java b/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/ssh/client/AsyncSshHandler.java
new file mode 100644 (file)
index 0000000..8f6e2ba
--- /dev/null
@@ -0,0 +1,309 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.nettyutil.handler.ssh.client;
+
+import com.google.common.base.Preconditions;
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelOutboundHandlerAdapter;
+import io.netty.channel.ChannelPromise;
+import io.netty.util.concurrent.Future;
+import io.netty.util.concurrent.GenericFutureListener;
+import java.io.IOException;
+import java.net.SocketAddress;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.sshd.ClientChannel;
+import org.apache.sshd.ClientSession;
+import org.apache.sshd.SshClient;
+import org.apache.sshd.client.future.AuthFuture;
+import org.apache.sshd.client.future.ConnectFuture;
+import org.apache.sshd.client.future.OpenFuture;
+import org.apache.sshd.common.future.CloseFuture;
+import org.apache.sshd.common.future.SshFutureListener;
+import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Netty SSH handler class. Acts as interface between Netty and SSH library.
+ */
+public class AsyncSshHandler extends ChannelOutboundHandlerAdapter {
+    private static final Logger LOG = LoggerFactory.getLogger(AsyncSshHandler.class);
+
+    public static final String SUBSYSTEM = "netconf";
+
+    public static final int SSH_DEFAULT_NIO_WORKERS = 8;
+    // Disable default timeouts from mina sshd
+    private static final long DEFAULT_TIMEOUT = -1L;
+
+    public static final SshClient DEFAULT_CLIENT;
+
+    static {
+        final Map<String, String> props = new HashMap<>();
+        props.put(SshClient.AUTH_TIMEOUT, Long.toString(DEFAULT_TIMEOUT));
+        props.put(SshClient.IDLE_TIMEOUT, Long.toString(DEFAULT_TIMEOUT));
+
+        final SshClient c = SshClient.setUpDefaultClient();
+
+        c.setProperties(props);
+        // TODO make configurable, or somehow reuse netty threadpool
+        c.setNioWorkers(SSH_DEFAULT_NIO_WORKERS);
+        c.start();
+        DEFAULT_CLIENT = c;
+    }
+
+    private final AuthenticationHandler authenticationHandler;
+    private final SshClient sshClient;
+    private Future<?> negotiationFuture;
+
+    private AsyncSshHandlerReader sshReadAsyncListener;
+    private AsyncSshHandlerWriter sshWriteAsyncHandler;
+
+    private ClientChannel channel;
+    private ClientSession session;
+    private ChannelPromise connectPromise;
+    private GenericFutureListener negotiationFutureListener;
+
+    public AsyncSshHandler(final AuthenticationHandler authenticationHandler, final SshClient sshClient,
+            final Future<?> negotiationFuture) throws IOException {
+        this(authenticationHandler, sshClient);
+        this.negotiationFuture = negotiationFuture;
+    }
+
+    /**
+     * Constructor of {@code AsyncSshHandler}.
+     *
+     * @param authenticationHandler authentication handler
+     * @param sshClient             started SshClient
+     * @throws IOException          if the I/O operation fails
+     */
+    public AsyncSshHandler(final AuthenticationHandler authenticationHandler,
+                           final SshClient sshClient) throws IOException {
+        this.authenticationHandler = Preconditions.checkNotNull(authenticationHandler);
+        this.sshClient = Preconditions.checkNotNull(sshClient);
+    }
+
+    public static AsyncSshHandler createForNetconfSubsystem(final AuthenticationHandler authenticationHandler)
+            throws IOException {
+        return new AsyncSshHandler(authenticationHandler, DEFAULT_CLIENT);
+    }
+
+    /**
+     * Create AsyncSshHandler for netconf subsystem. Negotiation future has to be set to success after successful
+     * netconf negotiation.
+     *
+     * @param authenticationHandler authentication handler
+     * @param negotiationFuture     negotiation future
+     * @return                      {@code AsyncSshHandler}
+     * @throws IOException          if the I/O operation fails
+     */
+    public static AsyncSshHandler createForNetconfSubsystem(final AuthenticationHandler authenticationHandler,
+            final Future<?> negotiationFuture) throws IOException {
+        return new AsyncSshHandler(authenticationHandler, DEFAULT_CLIENT, negotiationFuture);
+    }
+
+    private void startSsh(final ChannelHandlerContext ctx, final SocketAddress address) {
+        LOG.debug("Starting SSH to {} on channel: {}", address, ctx.channel());
+
+        final ConnectFuture sshConnectionFuture = sshClient.connect(authenticationHandler.getUsername(), address);
+        sshConnectionFuture.addListener(new SshFutureListener<ConnectFuture>() {
+            @Override
+            public void operationComplete(final ConnectFuture future) {
+                if (future.isConnected()) {
+                    handleSshSessionCreated(future, ctx);
+                } else {
+                    handleSshSetupFailure(ctx, future.getException());
+                }
+            }
+        });
+    }
+
+    private synchronized void handleSshSessionCreated(final ConnectFuture future, final ChannelHandlerContext ctx) {
+        try {
+            LOG.trace("SSH session created on channel: {}", ctx.channel());
+
+            session = future.getSession();
+            final AuthFuture authenticateFuture = authenticationHandler.authenticate(session);
+            authenticateFuture.addListener(new SshFutureListener<AuthFuture>() {
+                @Override
+                public void operationComplete(final AuthFuture future) {
+                    if (future.isSuccess()) {
+                        handleSshAuthenticated(session, ctx);
+                    } else {
+                        // Exception does not have to be set in the future, add simple exception in such case
+                        final Throwable exception = future.getException() == null
+                                ? new IllegalStateException("Authentication failed") : future.getException();
+                        handleSshSetupFailure(ctx, exception);
+                    }
+                }
+            });
+        } catch (final IOException e) {
+            handleSshSetupFailure(ctx, e);
+        }
+    }
+
+    private synchronized void handleSshAuthenticated(final ClientSession session, final ChannelHandlerContext ctx) {
+        try {
+            LOG.debug("SSH session authenticated on channel: {}, server version: {}", ctx.channel(),
+                    session.getServerVersion());
+
+            channel = session.createSubsystemChannel(SUBSYSTEM);
+            channel.setStreaming(ClientChannel.Streaming.Async);
+            channel.open().addListener(new SshFutureListener<OpenFuture>() {
+                @Override
+                public void operationComplete(final OpenFuture future) {
+                    if (future.isOpened()) {
+                        handleSshChanelOpened(ctx);
+                    } else {
+                        handleSshSetupFailure(ctx, future.getException());
+                    }
+                }
+            });
+
+
+        } catch (final IOException e) {
+            handleSshSetupFailure(ctx, e);
+        }
+    }
+
+    private synchronized void handleSshChanelOpened(final ChannelHandlerContext ctx) {
+        LOG.trace("SSH subsystem channel opened successfully on channel: {}", ctx.channel());
+
+        if (negotiationFuture == null) {
+            connectPromise.setSuccess();
+        }
+
+        // TODO we should also read from error stream and at least log from that
+
+        sshReadAsyncListener = new AsyncSshHandlerReader(new AutoCloseable() {
+            @Override
+            public void close() throws Exception {
+                AsyncSshHandler.this.disconnect(ctx, ctx.newPromise());
+            }
+        }, new AsyncSshHandlerReader.ReadMsgHandler() {
+            @Override
+            public void onMessageRead(final ByteBuf msg) {
+                ctx.fireChannelRead(msg);
+            }
+        }, channel.toString(), channel.getAsyncOut());
+
+        // if readAsyncListener receives immediate close,
+        // it will close this handler and closing this handler sets channel variable to null
+        if (channel != null) {
+            sshWriteAsyncHandler = new AsyncSshHandlerWriter(channel.getAsyncIn());
+            ctx.fireChannelActive();
+        }
+    }
+
+    private synchronized void handleSshSetupFailure(final ChannelHandlerContext ctx, final Throwable error) {
+        LOG.warn("Unable to setup SSH connection on channel: {}", ctx.channel(), error);
+
+        // If the promise is not yet done, we have failed with initial connect and set connectPromise to failure
+        if (!connectPromise.isDone()) {
+            connectPromise.setFailure(error);
+        }
+
+        disconnect(ctx, ctx.newPromise());
+    }
+
+    @Override
+    public synchronized void write(final ChannelHandlerContext ctx, final Object msg, final ChannelPromise promise) {
+        sshWriteAsyncHandler.write(ctx, msg, promise);
+    }
+
+    @Override
+    public synchronized void connect(final ChannelHandlerContext ctx, final SocketAddress remoteAddress,
+                                     final SocketAddress localAddress, final ChannelPromise promise) throws Exception {
+        LOG.debug("SSH session connecting on channel {}. promise: {} ", ctx.channel(), connectPromise);
+        this.connectPromise = promise;
+
+        if (negotiationFuture != null) {
+
+            negotiationFutureListener = new GenericFutureListener<Future<?>>() {
+                @Override
+                public void operationComplete(final Future<?> future) {
+                    if (future.isSuccess()) {
+                        connectPromise.setSuccess();
+                    }
+                }
+            };
+            //complete connection promise with netconf negotiation future
+            negotiationFuture.addListener(negotiationFutureListener);
+        }
+        startSsh(ctx, remoteAddress);
+    }
+
+    @Override
+    public void close(final ChannelHandlerContext ctx, final ChannelPromise promise) throws Exception {
+        disconnect(ctx, promise);
+    }
+
+    @SuppressWarnings("checkstyle:IllegalCatch")
+    @Override
+    public synchronized void disconnect(final ChannelHandlerContext ctx, final ChannelPromise promise) {
+        LOG.trace("Closing SSH session on channel: {} with connect promise in state: {}",
+                ctx.channel(),connectPromise);
+
+        // If we have already succeeded and the session was dropped after,
+        // we need to fire inactive to notify reconnect logic
+        if (connectPromise.isSuccess()) {
+            ctx.fireChannelInactive();
+        }
+
+        if (sshWriteAsyncHandler != null) {
+            sshWriteAsyncHandler.close();
+        }
+
+        if (sshReadAsyncListener != null) {
+            sshReadAsyncListener.close();
+        }
+
+        //If connection promise is not already set, it means negotiation failed
+        //we must set connection promise to failure
+        if (!connectPromise.isDone()) {
+            connectPromise.setFailure(new IllegalStateException("Negotiation failed"));
+        }
+
+        //Remove listener from negotiation future, we don't want notifications
+        //from negotiation anymore
+        if (negotiationFuture != null) {
+            negotiationFuture.removeListener(negotiationFutureListener);
+        }
+
+        if (session != null && !session.isClosed() && !session.isClosing()) {
+            session.close(false).addListener(new SshFutureListener<CloseFuture>() {
+                @Override
+                public void operationComplete(final CloseFuture future) {
+                    if (future.isClosed() == false) {
+                        session.close(true);
+                    }
+                    session = null;
+                }
+            });
+        }
+
+        // Super disconnect is necessary in this case since we are using NioSocketChannel and it needs
+        // to cleanup its resources e.g. Socket that it tries to open in its constructor
+        // (https://bugs.opendaylight.org/show_bug.cgi?id=2430)
+        // TODO better solution would be to implement custom ChannelFactory + Channel
+        // that will use mina SSH lib internally: port this to custom channel implementation
+        try {
+            // Disconnect has to be closed after inactive channel event was fired, because it interferes with it
+            super.disconnect(ctx, ctx.newPromise());
+        } catch (final Exception e) {
+            LOG.warn("Unable to cleanup all resources for channel: {}. Ignoring.", ctx.channel(), e);
+        }
+
+        channel = null;
+        promise.setSuccess();
+        LOG.debug("SSH session closed on channel: {}", ctx.channel());
+    }
+
+}
diff --git a/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/ssh/client/AsyncSshHandlerReader.java b/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/ssh/client/AsyncSshHandlerReader.java
new file mode 100644 (file)
index 0000000..c79b713
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.nettyutil.handler.ssh.client;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.apache.sshd.common.future.SshFutureListener;
+import org.apache.sshd.common.io.IoInputStream;
+import org.apache.sshd.common.io.IoReadFuture;
+import org.apache.sshd.common.util.Buffer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Listener on async input stream from SSH session.
+ * This listeners schedules reads in a loop until the session is closed or read fails.
+ */
+public final class AsyncSshHandlerReader implements SshFutureListener<IoReadFuture>, AutoCloseable {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AsyncSshHandlerReader.class);
+
+    private static final int BUFFER_SIZE = 2048;
+
+    private final AutoCloseable connectionClosedCallback;
+    private final ReadMsgHandler readHandler;
+
+    private final String channelId;
+    private IoInputStream asyncOut;
+    private Buffer buf;
+    private IoReadFuture currentReadFuture;
+
+    public AsyncSshHandlerReader(final AutoCloseable connectionClosedCallback, final ReadMsgHandler readHandler,
+                                 final String channelId, final IoInputStream asyncOut) {
+        this.connectionClosedCallback = connectionClosedCallback;
+        this.readHandler = readHandler;
+        this.channelId = channelId;
+        this.asyncOut = asyncOut;
+        buf = new Buffer(BUFFER_SIZE);
+        asyncOut.read(buf).addListener(this);
+    }
+
+    @Override
+    public synchronized void operationComplete(final IoReadFuture future) {
+        if (future.getException() != null) {
+
+            //if asyncout is already set to null by close method, do nothing
+            if (asyncOut == null) {
+                return;
+            }
+
+            if (asyncOut.isClosed() || asyncOut.isClosing()) {
+                // Ssh dropped
+                LOG.debug("Ssh session dropped on channel: {}", channelId, future.getException());
+            } else {
+                LOG.warn("Exception while reading from SSH remote on channel {}", channelId, future.getException());
+            }
+            invokeDisconnect();
+            return;
+        }
+
+        if (future.getRead() > 0) {
+            final ByteBuf msg = Unpooled.wrappedBuffer(buf.array(), 0, future.getRead());
+            if (LOG.isTraceEnabled()) {
+                LOG.trace("Reading message on channel: {}, message: {}",
+                        channelId, AsyncSshHandlerWriter.byteBufToString(msg));
+            }
+            readHandler.onMessageRead(msg);
+
+            // Schedule next read
+            buf = new Buffer(BUFFER_SIZE);
+            currentReadFuture = asyncOut.read(buf);
+            currentReadFuture.addListener(this);
+        }
+    }
+
+    @SuppressWarnings("checkstyle:IllegalCatch")
+    private void invokeDisconnect() {
+        try {
+            connectionClosedCallback.close();
+        } catch (final Exception e) {
+            // This should not happen
+            throw new IllegalStateException(e);
+        }
+    }
+
+    @Override
+    public synchronized void close() {
+        // Remove self as listener on close to prevent reading from closed input
+        if (currentReadFuture != null) {
+            currentReadFuture.removeListener(this);
+            currentReadFuture = null;
+        }
+
+        asyncOut = null;
+    }
+
+    public interface ReadMsgHandler {
+
+        void onMessageRead(ByteBuf msg);
+    }
+}
diff --git a/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/ssh/client/AsyncSshHandlerWriter.java b/tests/honeynode221/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/ssh/client/AsyncSshHandlerWriter.java
new file mode 100644 (file)
index 0000000..d116b99
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netconf.nettyutil.handler.ssh.client;
+
+import com.google.common.base.Preconditions;
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelPromise;
+import java.nio.charset.StandardCharsets;
+import java.util.Deque;
+import java.util.LinkedList;
+import java.util.Queue;
+import org.apache.sshd.common.future.SshFutureListener;
+import org.apache.sshd.common.io.IoOutputStream;
+import org.apache.sshd.common.io.IoWriteFuture;
+import org.apache.sshd.common.io.WritePendingException;
+import org.apache.sshd.common.util.Buffer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Async Ssh writer. Takes messages(byte arrays) and sends them encrypted to remote server.
+ * Also handles pending writes by caching requests until pending state is over.
+ */
+public final class AsyncSshHandlerWriter implements AutoCloseable {
+
+    private static final Logger LOG = LoggerFactory
+            .getLogger(AsyncSshHandlerWriter.class);
+
+    // public static final int MAX_PENDING_WRITES = 1000;
+    // TODO implement Limiting mechanism for pending writes
+    // But there is a possible issue with limiting:
+    // 1. What to do when queue is full ? Immediate Fail for every request ?
+    // 2. At this level we might be dealing with Chunks of messages(not whole messages)
+    // and unexpected behavior might occur when we send/queue 1 chunk and fail the other chunks
+
+    private final Object asyncInLock = new Object();
+    private volatile IoOutputStream asyncIn;
+
+    // Order has to be preserved for queued writes
+    private final Deque<PendingWriteRequest> pending = new LinkedList<>();
+
+    public AsyncSshHandlerWriter(final IoOutputStream asyncIn) {
+        this.asyncIn = asyncIn;
+    }
+
+    public void write(final ChannelHandlerContext ctx,
+            final Object msg, final ChannelPromise promise) {
+        if (asyncIn == null) {
+            promise.setFailure(new IllegalStateException("Channel closed"));
+            return;
+        }
+        // synchronized block due to deadlock that happens on ssh window resize
+        // writes and pending writes would lock the underlyinch channel session
+        // window resize write would try to write the message on an already locked channelSession
+        // while the pending write was in progress from the write callback
+        synchronized (asyncInLock) {
+            // TODO check for isClosed, isClosing might be performed by mina SSH internally and is not required here
+            // If we are closed/closing, set immediate fail
+            if (asyncIn.isClosed() || asyncIn.isClosing()) {
+                promise.setFailure(new IllegalStateException("Channel closed"));
+            } else {
+                final ByteBuf byteBufMsg = (ByteBuf) msg;
+                if (pending.isEmpty() == false) {
+                    queueRequest(ctx, byteBufMsg, promise);
+                    return;
+                }
+
+                writeWithPendingDetection(ctx, promise, byteBufMsg, false);
+            }
+        }
+    }
+
+    //sending message with pending
+    //if resending message not succesfull, then attribute wasPending is true
+    private void writeWithPendingDetection(final ChannelHandlerContext ctx, final ChannelPromise promise,
+                                           final ByteBuf byteBufMsg, final boolean wasPending) {
+        try {
+
+            if (LOG.isTraceEnabled()) {
+                LOG.trace("Writing request on channel: {}, message: {}", ctx.channel(), byteBufToString(byteBufMsg));
+            }
+            asyncIn.write(toBuffer(byteBufMsg)).addListener(new SshFutureListener<IoWriteFuture>() {
+
+                @Override
+                public void operationComplete(final IoWriteFuture future) {
+                    // synchronized block due to deadlock that happens on ssh window resize
+                    // writes and pending writes would lock the underlyinch channel session
+                    // window resize write would try to write the message on an already locked channelSession,
+                    // while the pending write was in progress from the write callback
+                    synchronized (asyncInLock) {
+                        if (LOG.isTraceEnabled()) {
+                            LOG.trace(
+                                "Ssh write request finished on channel: {} with result: {}: and ex:{}, message: {}",
+                                ctx.channel(), future.isWritten(), future.getException(), byteBufToString(byteBufMsg));
+                        }
+
+                        // Notify success or failure
+                        if (future.isWritten()) {
+                            promise.setSuccess();
+                        } else {
+                            LOG.warn("Ssh write request failed on channel: {} for message: {}", ctx.channel(),
+                                    byteBufToString(byteBufMsg), future.getException());
+                            promise.setFailure(future.getException());
+                        }
+
+                        // Not needed anymore, release
+                        byteBufMsg.release();
+
+                        //rescheduling message from queue after successfully sent
+                        if (wasPending) {
+                            byteBufMsg.resetReaderIndex();
+                            pending.remove();
+                        }
+                    }
+
+                    // Check pending queue and schedule next
+                    // At this time we are guaranteed that we are not in pending state anymore
+                    // so the next request should succeed
+                    writePendingIfAny();
+                }
+            });
+
+        } catch (final WritePendingException e) {
+
+            if (wasPending == false) {
+                queueRequest(ctx, byteBufMsg, promise);
+            }
+        }
+    }
+
+    private void writePendingIfAny() {
+        synchronized (asyncInLock) {
+            if (pending.peek() == null) {
+                return;
+            }
+
+            final PendingWriteRequest pendingWrite = pending.peek();
+            final ByteBuf msg = pendingWrite.msg;
+            if (LOG.isTraceEnabled()) {
+                LOG.trace("Writing pending request on channel: {}, message: {}",
+                        pendingWrite.ctx.channel(), byteBufToString(msg));
+            }
+
+            writeWithPendingDetection(pendingWrite.ctx, pendingWrite.promise, msg, true);
+        }
+    }
+
+    public static String byteBufToString(final ByteBuf msg) {
+        final String s = msg.toString(StandardCharsets.UTF_8);
+        msg.resetReaderIndex();
+        return s;
+    }
+
+    private void queueRequest(final ChannelHandlerContext ctx, final ByteBuf msg, final ChannelPromise promise) {
+//        try {
+        LOG.debug("Write pending on channel: {}, queueing, current queue size: {}", ctx.channel(), pending.size());
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Queueing request due to pending: {}", byteBufToString(msg));
+        }
+        new PendingWriteRequest(ctx, msg, promise).pend(pending);
+//        } catch (final Exception ex) {
+//            LOG.warn("Unable to queue write request on channel: {}. Setting fail for the request: {}",
+//                    ctx.channel(), ex, byteBufToString(msg));
+//            msg.release();
+//            promise.setFailure(ex);
+//        }
+    }
+
+    @Override
+    public void close() {
+        asyncIn = null;
+    }
+
+    private static Buffer toBuffer(final ByteBuf msg) {
+        // TODO Buffer vs ByteBuf translate, Can we handle that better ?
+        msg.resetReaderIndex();
+        final byte[] temp = new byte[msg.readableBytes()];
+        msg.readBytes(temp, 0, msg.readableBytes());
+        return new Buffer(temp);
+    }
+
+    private static final class PendingWriteRequest {
+        private final ChannelHandlerContext ctx;
+        private final ByteBuf msg;
+        private final ChannelPromise promise;
+
+        PendingWriteRequest(final ChannelHandlerContext ctx, final ByteBuf msg, final ChannelPromise promise) {
+            this.ctx = ctx;
+            // Reset reader index, last write (failed) attempt moved index to the end
+            msg.resetReaderIndex();
+            this.msg = msg;
+            this.promise = promise;
+        }
+
+        public void pend(final Queue<PendingWriteRequest> pending) {
+            // Preconditions.checkState(pending.size() < MAX_PENDING_WRITES,
+            // "Too much pending writes(%s) on channel: %s, remote window is not getting read or is too small",
+            // pending.size(), ctx.channel());
+            Preconditions.checkState(pending.offer(this),
+                "Cannot pend another request write (pending count: %s) on channel: %s", pending.size(), ctx.channel());
+        }
+    }
+}
diff --git a/tests/honeynode221/netconf/asciidoc/Readme.adoc b/tests/honeynode221/netconf/asciidoc/Readme.adoc
new file mode 100644 (file)
index 0000000..525b0b4
--- /dev/null
@@ -0,0 +1,3 @@
+= netconf
+
+Provides binding support to start NETCONF SSH/TCP
\ No newline at end of file
diff --git a/tests/honeynode221/netconf/pom.xml b/tests/honeynode221/netconf/pom.xml
new file mode 100644 (file)
index 0000000..f8924ed
--- /dev/null
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright (c) 2017 Cisco and/or its affiliates.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at:
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<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">
+    <parent>
+        <artifactId>impl-parent</artifactId>
+        <groupId>io.fd.honeycomb.common</groupId>
+        <version>1.18.01</version>
+        <relativePath/>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>io.fd.honeycomb.transportpce</groupId>
+    <artifactId>netconf</artifactId>
+    <version>1.18.01</version>
+
+    <properties>
+        <yang.modules.whitelist>
+            ${project.basedir}/src/main/resources/honeycomb-minimal-resources/config/netconf-whitelist.xml
+        </yang.modules.whitelist>
+    </properties>
+
+    <dependencies>
+        <!-- TPCE dependencies  -->
+        <dependency>
+            <groupId>io.fd.honeycomb.transportpce</groupId>
+            <artifactId>honeynode-plugin-impl</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.fd.honeycomb.transportpce</groupId>
+            <artifactId>minimal-distribution-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <!-- DI-->
+        <dependency>
+            <groupId>com.google.inject</groupId>
+            <artifactId>guice</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>net.jmob</groupId>
+            <artifactId>guice.conf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.inject.extensions</groupId>
+            <artifactId>guice-multibindings</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.fd.honeycomb</groupId>
+            <artifactId>binding-init</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <!-- Northbound -->
+        <dependency>
+            <groupId>io.fd.honeycomb.northbound</groupId>
+            <artifactId>common</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <!-- ODL-Netconf -->
+        <dependency>
+            <groupId>org.opendaylight.netconf</groupId>
+            <artifactId>netconf-impl</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.netconf</groupId>
+            <artifactId>netconf-ssh</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.netconf</groupId>
+            <artifactId>mdsal-netconf-notification</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.netconf</groupId>
+            <artifactId>mdsal-netconf-monitoring</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.netconf</groupId>
+            <artifactId>mdsal-netconf-connector</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.netconf</groupId>
+            <artifactId>ietf-netconf-monitoring</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.netconf</groupId>
+            <artifactId>ietf-netconf-monitoring-extension</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>io.fd.honeycomb</groupId>
+            <artifactId>data-impl</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.fd.honeycomb</groupId>
+            <artifactId>honeycomb-impl</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.fd.honeycomb</groupId>
+            <artifactId>notification-impl</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git a/tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/HoneycombNotification2NetconfProvider.java b/tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/HoneycombNotification2NetconfProvider.java
new file mode 100644 (file)
index 0000000..26ecf3a
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.northbound.netconf;
+
+import com.google.inject.Inject;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import io.fd.honeycomb.northbound.NetconfConfiguration;
+import io.fd.honeycomb.notification.NotificationCollector;
+import io.fd.honeycomb.notification.impl.NotificationProducerRegistry;
+import io.fd.honeycomb.notification.impl.TranslationUtil;
+import java.util.List;
+import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
+import org.opendaylight.controller.md.sal.dom.api.DOMNotificationListener;
+import org.opendaylight.controller.md.sal.dom.broker.impl.DOMNotificationRouter;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.netconf.notifications.NetconfNotificationCollector;
+import org.opendaylight.netconf.notifications.NotificationPublisherRegistration;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.StreamBuilder;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class HoneycombNotification2NetconfProvider
+        extends ProviderTrait<HoneycombNotification2NetconfProvider.HoneycombNotification2Netconf> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(HoneycombNotification2NetconfProvider.class);
+
+    @Inject
+    private DOMNotificationRouter notificationRouter;
+    @Inject
+    private SchemaService schemaService;
+    @Inject
+    private NetconfConfiguration cfgAttributes;
+    @Inject
+    private NotificationCollector hcNotificationCollector;
+    @Inject
+    private NetconfNotificationCollector netconfNotificationCollector;
+
+    @Override
+    protected HoneycombNotification2Netconf create() {
+        final StreamNameType streamType = new StreamNameType(cfgAttributes.netconfNotificationStreamName.get());
+
+        // Register as HONEYCOMB_NETCONF notification publisher under configured name
+        final NotificationPublisherRegistration netconfNotifReg = netconfNotificationCollector
+                .registerNotificationPublisher(new StreamBuilder().setName(streamType).setReplaySupport(false)
+                        .setDescription(cfgAttributes.netconfNotificationStreamName.get()).build());
+
+        // Notification Translator, get notification from HC producers and put into HONEYCOMB_NETCONF notification collector
+        final DOMNotificationListener domNotificationListener =
+                new TranslatingNotificationListener(netconfNotifReg, streamType, schemaService);
+
+        // NotificationManager is used to provide list of available notifications (which are all of the notifications registered)
+        // TODO HONEYCOMB-165 make available notifications configurable here so that any number of notification streams for netconf
+        // can be configured on top of a single notification manager
+        LOG.debug("Current notifications to be exposed over HONEYCOMB_NETCONF: {}",
+                hcNotificationCollector.getNotificationTypes());
+        List<SchemaPath> currentNotificationSchemaPaths = hcNotificationCollector.getNotificationTypes().stream()
+                .map(notifType -> SchemaPath.create(true, NotificationProducerRegistry.getQName(notifType)))
+                .collect(Collectors.toList());
+
+        // Register as listener to HC'OPERATIONAL DOM notification service
+        // TODO HONEYCOMB-166 This should only be triggered when HONEYCOMB_NETCONF notifications are activated
+        // Because this way we actually start all notification producers
+        // final Collection<QName> notificationQNames =
+        ListenerRegistration<DOMNotificationListener> domNotifListenerReg = notificationRouter
+                .registerNotificationListener(domNotificationListener, currentNotificationSchemaPaths);
+
+        LOG.info("Exposing HONEYCOMB_NETCONF notification stream: {}", streamType.getValue());
+        return new HoneycombNotification2Netconf(domNotifListenerReg, netconfNotifReg);
+    }
+
+    public static final class HoneycombNotification2Netconf {
+        private final ListenerRegistration<DOMNotificationListener> domNotifListenerReg;
+        private final NotificationPublisherRegistration netconfNotifReg;
+
+        public HoneycombNotification2Netconf(final ListenerRegistration<DOMNotificationListener> domNotifListenerReg,
+                                             final NotificationPublisherRegistration netconfNotifReg) {
+            this.domNotifListenerReg = domNotifListenerReg;
+            this.netconfNotifReg = netconfNotifReg;
+        }
+
+        public ListenerRegistration<DOMNotificationListener> getDomNotifListenerReg() {
+            return domNotifListenerReg;
+        }
+
+        public NotificationPublisherRegistration getNetconfNotifReg() {
+            return netconfNotifReg;
+        }
+    }
+
+    private static final class TranslatingNotificationListener implements DOMNotificationListener {
+
+        private static final Logger LOG = LoggerFactory.getLogger(TranslatingNotificationListener.class);
+
+        private final NotificationPublisherRegistration netconfNotifReg;
+        private final StreamNameType streamType;
+        private final SchemaService schemaService;
+
+        TranslatingNotificationListener(final NotificationPublisherRegistration netconfNotifReg,
+                                               final StreamNameType streamType, final SchemaService schemaService) {
+            this.netconfNotifReg = netconfNotifReg;
+            this.streamType = streamType;
+            this.schemaService = schemaService;
+        }
+
+        @Override
+        public void onNotification(@Nonnull final DOMNotification notif) {
+            LOG.debug("Propagating notification: {} into HONEYCOMB_NETCONF", notif.getType());
+            netconfNotifReg.onNotification(streamType, TranslationUtil.notificationToXml(notif, schemaService.getGlobalContext()));
+        }
+    }
+}
diff --git a/tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfBindingBrokerProvider.java b/tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfBindingBrokerProvider.java
new file mode 100644 (file)
index 0000000..bafd4ea
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.northbound.netconf;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import io.fd.honeycomb.impl.FakeBindingAwareBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+
+public final class NetconfBindingBrokerProvider extends ProviderTrait<BindingAwareBroker> {
+
+    @Inject
+    @Named(NetconfModule.HONEYCOMB_NETCONF)
+    private DataBroker dataBroker;
+
+    @Override
+    protected FakeBindingAwareBroker create() {
+        return new FakeBindingAwareBroker(dataBroker);
+    }
+}
diff --git a/tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfConfigurationModule.java b/tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfConfigurationModule.java
new file mode 100644 (file)
index 0000000..aba254b
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.northbound.netconf;
+
+import com.google.inject.AbstractModule;
+import io.fd.honeycomb.northbound.NetconfConfiguration;
+import net.jmob.guice.conf.core.ConfigurationModule;
+
+public class NetconfConfigurationModule extends AbstractModule {
+    @Override
+    protected void configure() {
+        install(ConfigurationModule.create());
+        requireBinding(NetconfConfiguration.class);
+    }
+}
diff --git a/tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfMdsalMapperProvider.java b/tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfMdsalMapperProvider.java
new file mode 100644 (file)
index 0000000..cd2867f
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.northbound.netconf;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+
+import io.fd.honeycomb.binding.init.ProviderTrait;
+
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.mdsal.binding.generator.impl.ModuleInfoBackedContext;
+import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactory;
+import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactoryListener;
+import org.opendaylight.netconf.mdsal.connector.MdsalNetconfOperationServiceFactory;
+
+public final class NetconfMdsalMapperProvider extends ProviderTrait<NetconfOperationServiceFactory> {
+
+    @Inject
+    private SchemaService schemaService;
+    @Inject
+    private NetconfOperationServiceFactoryListener aggregator;
+    @Inject
+    private ModuleInfoBackedContext moduleInfoBackedContext;
+    @Inject
+//    @Named(HONEYCOMB_CONFIG)
+    //Modified in order to connect TPCE to device config datastore
+    @Named("device-databroker")
+    private DOMDataBroker domBroker;
+    @Inject
+    private NetconfOperationServiceFactoryListener netconfOperationServiceFactoryListener;
+    @Inject
+    private DOMRpcService rpcService;
+
+    @Override
+    protected MdsalNetconfOperationServiceFactory create() {
+        MdsalNetconfOperationServiceFactory mdsalNetconfOperationServiceFactory =
+                new MdsalNetconfOperationServiceFactory(schemaService, moduleInfoBackedContext, netconfOperationServiceFactoryListener, domBroker, rpcService);
+        return mdsalNetconfOperationServiceFactory;
+    }
+}
diff --git a/tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfModule.java b/tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfModule.java
new file mode 100644 (file)
index 0000000..5b522af
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.northbound.netconf;
+
+import com.google.inject.Singleton;
+import com.google.inject.binder.AnnotatedElementBuilder;
+import com.google.inject.name.Names;
+
+import io.fd.honeycomb.infra.distro.data.BindingDataBrokerProvider;
+import io.fd.honeycomb.infra.distro.data.DataStoreProvider;
+import io.fd.honeycomb.infra.distro.data.HoneycombNotificationManagerProvider;
+import io.fd.honeycomb.infra.distro.data.InmemoryDOMDataBrokerProvider;
+import io.fd.honeycomb.northbound.NetconfConfiguration;
+import io.fd.honeycomb.northbound.NorthboundPrivateModule;
+import io.fd.honeycomb.notification.NotificationCollector;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.util.HashedWheelTimer;
+import io.netty.util.Timer;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.netconf.api.NetconfServerDispatcher;
+import org.opendaylight.netconf.api.monitoring.NetconfMonitoringService;
+import org.opendaylight.netconf.impl.osgi.AggregatedNetconfOperationServiceFactory;
+import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactory;
+import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactoryListener;
+import org.opendaylight.netconf.notifications.NetconfNotificationCollector;
+import org.opendaylight.netconf.notifications.NetconfNotificationListener;
+import org.opendaylight.netconf.notifications.NetconfNotificationRegistry;
+import org.opendaylight.netconf.notifications.impl.NetconfNotificationManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NetconfModule extends NorthboundPrivateModule<NetconfConfiguration> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfModule.class);
+
+    public static final String HONEYCOMB_NETCONF = "honeycomb-netconf";
+    public static final String HONEYCOMB_NETCONF_MAPPER_AGGR = "netconf-mapper-aggregator";
+    public static final String HONEYCOMB_NETCONF_MAPPER_NOTIF = "netconf-mapper-notification";
+    public static final String HONEYCOMB_NETCONF_MAPPER_CORE = "netconf-mapper-honeycomb";
+    public static final String HONEYCOMB_NETCONF_MAPPER_OPER = "netconf-mapper-monitoring";
+
+    public NetconfModule() {
+        super(new NetconfConfigurationModule(), NetconfConfiguration.class);
+    }
+
+    @Override
+    protected void configure() {
+        if (!getConfiguration().isNetconfEnabled()) {
+            LOG.debug("Netconf disabled, skipping initialization");
+            return;
+        }
+        install(getConfigurationModule());
+        LOG.info("Starting NETCONF Northbound");
+        // Create inmemory data store for HONEYCOMB_NETCONF config metadata
+        bind(InMemoryDOMDataStore.class).annotatedWith(Names.named(InmemoryDOMDataBrokerProvider.CONFIG))
+                .toProvider(
+                        new DataStoreProvider(InmemoryDOMDataBrokerProvider.CONFIG, LogicalDatastoreType.CONFIGURATION))
+                .in(Singleton.class);
+
+        // Create inmemory data store for HONEYCOMB_NETCONF operational metadata
+        bind(InMemoryDOMDataStore.class).annotatedWith(Names.named(InmemoryDOMDataBrokerProvider.OPERATIONAL))
+                .toProvider(new DataStoreProvider(InmemoryDOMDataBrokerProvider.OPERATIONAL,
+                        LogicalDatastoreType.OPERATIONAL))
+                .in(Singleton.class);
+        // Wrap datastores as DOMDataBroker
+        bind(DOMDataBroker.class).toProvider(InmemoryDOMDataBrokerProvider.class).in(Singleton.class);
+
+        // Wrap DOMDataBroker as BA data broker
+        bind(DataBroker.class).annotatedWith(Names.named(HONEYCOMB_NETCONF)).toProvider(BindingDataBrokerProvider.class)
+                .in(Singleton.class);
+        expose(DataBroker.class).annotatedWith(Names.named(HONEYCOMB_NETCONF));
+
+        // Wrap BA data broker as BindingAwareBroker (requied by HONEYCOMB_NETCONF)
+        bind(BindingAwareBroker.class).annotatedWith(Names.named(HONEYCOMB_NETCONF))
+                .toProvider(NetconfBindingBrokerProvider.class).in(Singleton.class);
+
+        // Create netconf operation service factory aggregator to aggregate different services
+        AggregatedNetconfOperationServiceFactory factory = new AggregatedNetconfOperationServiceFactory();
+        bind(NetconfOperationServiceFactory.class).annotatedWith(Names.named(HONEYCOMB_NETCONF_MAPPER_AGGR))
+                .toInstance(factory);
+        bind(NetconfOperationServiceFactoryListener.class).toInstance(factory);
+
+        // Create netconf notification manager
+        NetconfNotificationManager manager = new NetconfNotificationManager();
+        bind(NetconfNotificationCollector.class).toInstance(manager);
+        bind(NetconfNotificationRegistry.class).toInstance(manager);
+        bind(NetconfNotificationListener.class).toInstance(manager);
+
+        // Netconf notification service factory
+        bind(NetconfOperationServiceFactory.class).annotatedWith(Names.named(HONEYCOMB_NETCONF_MAPPER_NOTIF))
+                .toProvider(NetconfNotificationMapperProvider.class).asEagerSingleton();
+        expose(NetconfOperationServiceFactory.class).annotatedWith(Names.named(HONEYCOMB_NETCONF_MAPPER_NOTIF));
+
+        // Netconf core part - mapping between Honeycomb and Netconf
+        bind(NetconfOperationServiceFactory.class).annotatedWith(Names.named(HONEYCOMB_NETCONF_MAPPER_CORE))
+                .toProvider(NetconfMdsalMapperProvider.class).asEagerSingleton();
+        expose(NetconfOperationServiceFactory.class).annotatedWith(Names.named(HONEYCOMB_NETCONF_MAPPER_CORE));
+
+        // Netconf monitoring service factory
+        bind(NetconfMonitoringService.class).toProvider(NetconfMonitoringServiceProvider.class).in(Singleton.class);
+        bind(NetconfOperationServiceFactory.class).annotatedWith(Names.named(HONEYCOMB_NETCONF_MAPPER_OPER))
+                .toProvider(NetconfMonitoringMapperProvider.class).asEagerSingleton();
+        expose(NetconfOperationServiceFactory.class).annotatedWith(Names.named(HONEYCOMB_NETCONF_MAPPER_OPER));
+
+        // Create HC notification manager + HC2Netconf translator
+        bind(NotificationCollector.class).toProvider(HoneycombNotificationManagerProvider.class).in(Singleton.class);
+        bind(HoneycombNotification2NetconfProvider.HoneycombNotification2Netconf.class)
+                .toProvider(HoneycombNotification2NetconfProvider.class).asEagerSingleton();
+        expose(HoneycombNotification2NetconfProvider.HoneycombNotification2Netconf.class);
+
+        configureServer();
+    }
+
+    /**
+     * Provide HONEYCOMB_NETCONF TCP and SSH servers.
+     */
+    private AnnotatedElementBuilder configureServer() {
+        bind(NioEventLoopGroup.class).toProvider(NettyThreadGroupProvider.class).in(Singleton.class);
+        bind(Timer.class).toInstance(new HashedWheelTimer());
+        bind(NetconfServerDispatcher.class).toProvider(NetconfServerDispatcherProvider.class).in(Singleton.class);
+        bind(NetconfTcpServerProvider.NetconfTcpServer.class).toProvider(NetconfTcpServerProvider.class)
+                .asEagerSingleton();
+        expose(NetconfTcpServerProvider.NetconfTcpServer.class);
+        bind(NetconfSshServerProvider.NetconfSshServer.class).toProvider(NetconfSshServerProvider.class)
+                .asEagerSingleton();
+        return expose(NetconfSshServerProvider.NetconfSshServer.class);
+    }
+}
diff --git a/tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfMonitoringMapperProvider.java b/tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfMonitoringMapperProvider.java
new file mode 100644 (file)
index 0000000..e7b5edb
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.northbound.netconf;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import org.opendaylight.controller.config.yang.netconf.mdsal.monitoring.MdsalMonitoringMapperFactory;
+import org.opendaylight.controller.config.yang.netconf.mdsal.monitoring.MonitoringToMdsalWriter;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.netconf.api.monitoring.NetconfMonitoringService;
+import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactory;
+import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactoryListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class NetconfMonitoringMapperProvider extends ProviderTrait<NetconfOperationServiceFactory> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfMonitoringMapperProvider.class);
+
+    @Inject
+    @Named(NetconfModule.HONEYCOMB_NETCONF)
+    private DataBroker dataBroker;
+    @Inject
+    private NetconfOperationServiceFactoryListener aggregator;
+    @Inject
+    private NetconfMonitoringService monitoringService;
+
+    @Override
+    protected NetconfOperationServiceFactory create() {
+        LOG.trace("Initializing MonitoringToMdsalWriter");
+        final MonitoringToMdsalWriter writer = new MonitoringToMdsalWriter(monitoringService, dataBroker);
+        writer.start();
+
+        LOG.trace("Providing MdsalMonitoringMapperFactory");
+        return new MdsalMonitoringMapperFactory(aggregator, monitoringService, writer);
+    }
+}
diff --git a/tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfMonitoringReaderFactoryProvider.java b/tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfMonitoringReaderFactoryProvider.java
new file mode 100644 (file)
index 0000000..50e0e8a
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.northbound.netconf;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import io.fd.honeycomb.translate.read.ReaderFactory;
+import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder;
+import io.fd.honeycomb.translate.util.read.BindingBrokerReader;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfStateBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+
+public final class NetconfMonitoringReaderFactoryProvider extends ProviderTrait<ReaderFactory> {
+
+    @Inject
+    @Named(NetconfModule.HONEYCOMB_NETCONF)
+    private DataBroker netconfDataBroker;
+
+    @Override
+    protected NetconfMonitoringReaderFactory create() {
+        return new NetconfMonitoringReaderFactory(netconfDataBroker);
+    }
+
+    /**
+     * {@link io.fd.honeycomb.translate.read.ReaderFactory} initiating reader into NETCONF's dedicated data store.
+     * Making NETCONF operational data available over NETCONF/RESTCONF
+     */
+    private static final class NetconfMonitoringReaderFactory implements ReaderFactory {
+
+        private final DataBroker netconfMonitoringBindingBrokerDependency;
+
+        NetconfMonitoringReaderFactory(final DataBroker netconfMonitoringBindingBrokerDependency) {
+            this.netconfMonitoringBindingBrokerDependency = netconfMonitoringBindingBrokerDependency;
+        }
+
+        @Override
+        public void init(final ModifiableReaderRegistryBuilder registry) {
+            registry.add(new BindingBrokerReader<>(InstanceIdentifier.create(NetconfState.class),
+                    netconfMonitoringBindingBrokerDependency,
+                    LogicalDatastoreType.OPERATIONAL, NetconfStateBuilder.class));
+        }
+    }
+}
diff --git a/tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfMonitoringServiceProvider.java b/tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfMonitoringServiceProvider.java
new file mode 100644 (file)
index 0000000..1a99dd1
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.northbound.netconf;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import org.opendaylight.netconf.api.monitoring.NetconfMonitoringService;
+import org.opendaylight.netconf.impl.osgi.NetconfMonitoringServiceImpl;
+import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactory;
+
+
+public class NetconfMonitoringServiceProvider extends ProviderTrait<NetconfMonitoringService> {
+
+    @Inject
+    @Named(NetconfModule.HONEYCOMB_NETCONF_MAPPER_AGGR)
+    private NetconfOperationServiceFactory aggregator;
+
+    @Override
+    protected NetconfMonitoringServiceImpl create() {
+        return new NetconfMonitoringServiceImpl(aggregator);
+    }
+}
diff --git a/tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfNotificationMapperProvider.java b/tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfNotificationMapperProvider.java
new file mode 100644 (file)
index 0000000..e402f04
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.northbound.netconf;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import io.fd.honeycomb.data.init.ShutdownHandler;
+import org.opendaylight.controller.config.yang.netconf.mdsal.notification.CapabilityChangeNotificationProducer;
+import org.opendaylight.controller.config.yang.netconf.mdsal.notification.NotificationToMdsalWriter;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactory;
+import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactoryListener;
+import org.opendaylight.netconf.mdsal.notification.NetconfNotificationOperationServiceFactory;
+import org.opendaylight.netconf.notifications.NetconfNotificationCollector;
+import org.opendaylight.netconf.notifications.NetconfNotificationRegistry;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Capabilities;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class NetconfNotificationMapperProvider extends ProviderTrait<NetconfOperationServiceFactory> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfNotificationMapperProvider.class);
+
+    public static final InstanceIdentifier<Capabilities> capabilitiesIdentifier =
+            InstanceIdentifier.create(NetconfState.class).child(Capabilities.class).builder().build();
+    @Inject
+    private NetconfNotificationCollector notificationCollector;
+    @Inject
+    private NetconfNotificationRegistry notificationRegistry;
+    @Inject
+    @Named(NetconfModule.HONEYCOMB_NETCONF)
+    private BindingAwareBroker bindingAwareBroker;
+    @Inject
+    @Named(NetconfModule.HONEYCOMB_NETCONF)
+    private DataBroker dataBroker;
+    @Inject
+    private NetconfOperationServiceFactoryListener aggregator;
+    @Inject
+    private ShutdownHandler shutdownHandler;
+
+    @Override
+    protected NetconfNotificationOperationServiceFactory create() {
+        LOG.trace("Initializing NotificationToMdsalWriter");
+        final NotificationToMdsalWriter writer = new NotificationToMdsalWriter(notificationCollector, dataBroker);
+        writer.start();
+
+        LOG.trace("Initializing CapabilityChangeNotificationProducer");
+        final DataTreeChangeListener<Capabilities> publisher =
+            new CapabilityChangeNotificationProducer(notificationCollector, dataBroker);
+
+        LOG.trace("Providing NetconfNotificationOperationServiceFactory");
+        NetconfNotificationOperationServiceFactory netconfNotificationOperationServiceFactory =
+            new NetconfNotificationOperationServiceFactory(notificationRegistry, aggregator);
+
+        shutdownHandler.register("netconf-notification-service-factory", netconfNotificationOperationServiceFactory);
+        shutdownHandler.register("notification-to-mdsal-writer", writer);
+        return netconfNotificationOperationServiceFactory;
+    }
+}
diff --git a/tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfNotificationsReaderFactoryProvider.java b/tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfNotificationsReaderFactoryProvider.java
new file mode 100644 (file)
index 0000000..4ed682f
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.northbound.netconf;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import io.fd.honeycomb.translate.read.ReaderFactory;
+import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder;
+import io.fd.honeycomb.translate.util.read.BindingBrokerReader;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.Netconf;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.NetconfBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public final class NetconfNotificationsReaderFactoryProvider extends ProviderTrait<ReaderFactory> {
+
+    @Inject
+    @Named(NetconfModule.HONEYCOMB_NETCONF)
+    private DataBroker netconfDataBroker;
+
+    @Override
+    protected ReaderFactory create() {
+        return new NotificationReaderFactory(netconfDataBroker);
+    }
+
+    private static final class NotificationReaderFactory implements ReaderFactory {
+        private final DataBroker netconfDataBroker;
+
+        NotificationReaderFactory(final DataBroker netconfDataBroker) {
+            this.netconfDataBroker = netconfDataBroker;
+        }
+
+        @Override
+        public void init(@Nonnull final ModifiableReaderRegistryBuilder registry) {
+            registry.add(new BindingBrokerReader<>(InstanceIdentifier.create(Netconf.class), netconfDataBroker,
+                    LogicalDatastoreType.OPERATIONAL, NetconfBuilder.class));
+        }
+
+    }
+}
diff --git a/tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfReadersModule.java b/tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfReadersModule.java
new file mode 100644 (file)
index 0000000..377ce6e
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.northbound.netconf;
+
+import com.google.inject.Singleton;
+import com.google.inject.multibindings.Multibinder;
+import io.fd.honeycomb.northbound.NetconfConfiguration;
+import io.fd.honeycomb.northbound.NorthboundAbstractModule;
+import io.fd.honeycomb.translate.read.ReaderFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NetconfReadersModule extends NorthboundAbstractModule<NetconfConfiguration> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfReadersModule.class);
+
+    public NetconfReadersModule() {
+        super(new NetconfConfigurationModule(), NetconfConfiguration.class);
+    }
+
+    @Override
+    protected void configure() {
+        if (!getConfiguration().isNetconfEnabled()) {
+            LOG.debug("NETCONF Northbound disabled, skipping readers initialization");
+            return;
+        }
+        LOG.info("Initializing NETCONF Northbound readers");
+        // This should be part of NetconfModule, but that one is Private and Multibinders + private BASE_MODULES
+        // do not work together, that's why there's a dedicated module here
+        // https://github.com/google/guice/issues/906
+        final Multibinder<ReaderFactory> binder = Multibinder.newSetBinder(binder(), ReaderFactory.class);
+        binder.addBinding().toProvider(NetconfMonitoringReaderFactoryProvider.class).in(Singleton.class);
+        binder.addBinding().toProvider(NetconfNotificationsReaderFactoryProvider.class).in(Singleton.class);
+    }
+}
diff --git a/tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfServerDispatcherProvider.java b/tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfServerDispatcherProvider.java
new file mode 100644 (file)
index 0000000..b6c22bf
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.northbound.netconf;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.util.Timer;
+import java.util.concurrent.TimeUnit;
+import org.opendaylight.netconf.api.NetconfServerDispatcher;
+import org.opendaylight.netconf.api.monitoring.NetconfMonitoringService;
+import org.opendaylight.netconf.impl.NetconfServerDispatcherImpl;
+import org.opendaylight.netconf.impl.SessionIdProvider;
+import org.opendaylight.netconf.impl.osgi.AggregatedNetconfOperationServiceFactory;
+import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactory;
+
+public final class NetconfServerDispatcherProvider extends ProviderTrait<NetconfServerDispatcher> {
+    private static final long CONNECTION_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(20);
+
+    @Inject
+    @Named(NetconfModule.HONEYCOMB_NETCONF_MAPPER_AGGR)
+    private NetconfOperationServiceFactory aggregator;
+    @Inject
+    private NetconfMonitoringService monitoringService;
+    @Inject
+    private Timer timer;
+    @Inject
+    private NioEventLoopGroup nettyThreadgroup;
+
+    @Override
+    protected NetconfServerDispatcherImpl create() {
+        AggregatedNetconfOperationServiceFactory netconfOperationProvider =
+                new AggregatedNetconfOperationServiceFactory();
+        netconfOperationProvider.onAddNetconfOperationServiceFactory(aggregator);
+
+        NetconfServerSessionNegotiatorFactory serverNegotiatorFactory =
+                new NetconfServerSessionNegotiatorFactory(timer, netconfOperationProvider, new SessionIdProvider(),
+                        CONNECTION_TIMEOUT_MILLIS, monitoringService);
+        NetconfServerDispatcherImpl.ServerChannelInitializer serverChannelInitializer =
+                new NetconfServerDispatcherImpl.ServerChannelInitializer(serverNegotiatorFactory);
+
+        return new NetconfServerDispatcherImpl(serverChannelInitializer, nettyThreadgroup, nettyThreadgroup);
+    }
+
+    private static final class NetconfServerSessionNegotiatorFactory extends
+            org.opendaylight.netconf.impl.NetconfServerSessionNegotiatorFactory {
+
+        NetconfServerSessionNegotiatorFactory(final Timer timer,
+                                                     final AggregatedNetconfOperationServiceFactory netconfOperationProvider,
+                                                     final SessionIdProvider sessionIdProvider,
+                                                     final long connectionTimeoutMillis,
+                                                     final NetconfMonitoringService monitoringService) {
+            super(timer, netconfOperationProvider, sessionIdProvider, connectionTimeoutMillis, monitoringService,
+                    org.opendaylight.netconf.impl.NetconfServerSessionNegotiatorFactory.DEFAULT_BASE_CAPABILITIES);
+        }
+    }
+}
diff --git a/tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfSshServerProvider.java b/tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfSshServerProvider.java
new file mode 100644 (file)
index 0000000..02847d7
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.northbound.netconf;
+
+import com.google.common.net.InetAddresses;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import com.google.inject.Inject;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import io.fd.honeycomb.infra.distro.InitializationException;
+import io.fd.honeycomb.northbound.CredentialsConfiguration;
+import io.fd.honeycomb.northbound.NetconfConfiguration;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.local.LocalAddress;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.util.concurrent.GenericFutureListener;
+import io.netty.util.concurrent.GlobalEventExecutor;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import org.apache.sshd.server.keyprovider.PEMGeneratorHostKeyProvider;
+import org.opendaylight.netconf.api.NetconfServerDispatcher;
+import org.opendaylight.netconf.auth.AuthProvider;
+import org.opendaylight.netconf.ssh.SshProxyServer;
+import org.opendaylight.netconf.ssh.SshProxyServerConfigurationBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public final class NetconfSshServerProvider extends ProviderTrait<NetconfSshServerProvider.NetconfSshServer> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfSshServerProvider.class);
+
+    // Use RSA for ssh server, see https://git.opendaylight.org/gerrit/#/c/60138/
+    private static final String DEFAULT_PRIVATE_KEY_PATH = null; // disable private key serialization
+    private static final String DEFAULT_ALGORITHM = "RSA";
+    private static final int DEFAULT_KEY_SIZE = 4096;
+
+    @Inject
+    private NetconfServerDispatcher dispatcher;
+    @Inject
+    private NetconfConfiguration cfgAttributes;
+    @Inject
+    private NioEventLoopGroup nettyThreadgroup;
+    @Inject
+    private CredentialsConfiguration credentialsCfg;
+
+    private ScheduledExecutorService pool =
+            Executors.newScheduledThreadPool(1, new ThreadFactoryBuilder().setNameFormat("netconf-ssh-%d").build());
+
+    @Override
+    protected NetconfSshServer create() {
+        if (!cfgAttributes.isNetconfSshEnabled()) {
+            LOG.info("NETCONF SSH disabled, skipping initialization");
+            return null;
+        }
+        LOG.info("Starting NETCONF SSH");
+
+        // TODO(HONEYCOMB-414):  the logic below is very similar to
+        // org.opendaylight.netconf.ssh.NetconfNorthboundSshServer (introduced in Carbon), so consider reusing it
+        // (requires fixing hardcoded private key path).
+        final InetAddress sshBindingAddress = InetAddresses.forString(cfgAttributes.netconfSshBindingAddress.get());
+        final InetSocketAddress bindingAddress =
+                new InetSocketAddress(sshBindingAddress, cfgAttributes.netconfSshBindingPort.get());
+
+        LocalAddress localAddress = new LocalAddress(cfgAttributes.netconfSshBindingPort.toString());
+        ChannelFuture localServer = dispatcher.createLocalServer(localAddress);
+
+        final SshProxyServer sshProxyServer = new SshProxyServer(pool, nettyThreadgroup, GlobalEventExecutor.INSTANCE);
+
+        final SshProxyServerConfigurationBuilder sshConfigBuilder = new SshProxyServerConfigurationBuilder();
+        sshConfigBuilder.setBindingAddress(bindingAddress);
+        sshConfigBuilder.setLocalAddress(localAddress);
+        // Only simple authProvider checking ConfigAttributes, checking the config file
+        sshConfigBuilder.setAuthenticator(new SimplelAuthProvider(credentialsCfg));
+        sshConfigBuilder.setIdleTimeout(Integer.MAX_VALUE);
+        sshConfigBuilder.setKeyPairProvider(new PEMGeneratorHostKeyProvider(DEFAULT_PRIVATE_KEY_PATH,
+            DEFAULT_ALGORITHM, DEFAULT_KEY_SIZE));
+
+        localServer.addListener(new SshServerBinder(sshProxyServer, sshConfigBuilder, bindingAddress));
+
+        return new NetconfSshServer(localServer, sshProxyServer);
+    }
+
+    public static final class NetconfSshServer {
+        private ChannelFuture localServer;
+        private SshProxyServer sshProxyServer;
+
+        NetconfSshServer(final ChannelFuture localServer,
+                         final SshProxyServer sshProxyServer) {
+            this.localServer = localServer;
+            this.sshProxyServer = sshProxyServer;
+        }
+
+        public Object getLocalServer() {
+            return localServer;
+        }
+
+        public Object getSshProxyServer() {
+            return sshProxyServer;
+        }
+    }
+
+    private static final class SimplelAuthProvider implements AuthProvider {
+
+        private final CredentialsConfiguration cfgAttributes;
+
+        SimplelAuthProvider(final CredentialsConfiguration cfgAttributes) {
+            this.cfgAttributes = cfgAttributes;
+        }
+
+        @Override
+        public boolean authenticated(final String uname, final String passwd) {
+            return cfgAttributes.username.equals(uname) && cfgAttributes.password.equals(passwd);
+        }
+    }
+
+    private static final class SshServerBinder implements GenericFutureListener<ChannelFuture> {
+        private final SshProxyServer sshProxyServer;
+        private final SshProxyServerConfigurationBuilder sshConfigBuilder;
+        private final InetSocketAddress bindingAddress;
+
+        SshServerBinder(final SshProxyServer sshProxyServer,
+                        final SshProxyServerConfigurationBuilder sshConfigBuilder,
+                        final InetSocketAddress bindingAddress) {
+            this.sshProxyServer = sshProxyServer;
+            this.sshConfigBuilder = sshConfigBuilder;
+            this.bindingAddress = bindingAddress;
+        }
+
+        @Override
+        public void operationComplete(final ChannelFuture future) {
+            if (future.isDone() && !future.isCancelled()) {
+                try {
+                    sshProxyServer.bind(sshConfigBuilder.createSshProxyServerConfiguration());
+                    LOG.info("Netconf SSH endpoint started successfully at {}", bindingAddress);
+                } catch (final IOException e) {
+                    throw new InitializationException("Unable to start SSH netconf server", e);
+                }
+
+            } else {
+                LOG.warn("Unable to start SSH netconf server at {}", bindingAddress, future.cause());
+                throw new InitializationException("Unable to start SSH netconf server", future.cause());
+            }
+
+        }
+
+    }
+}
diff --git a/tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfTcpServerProvider.java b/tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NetconfTcpServerProvider.java
new file mode 100644 (file)
index 0000000..031f0f9
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.northbound.netconf;
+
+import com.google.common.net.InetAddresses;
+import com.google.inject.Inject;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import io.fd.honeycomb.infra.distro.InitializationException;
+import io.fd.honeycomb.northbound.NetconfConfiguration;
+import io.netty.channel.ChannelFuture;
+import io.netty.util.concurrent.GenericFutureListener;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import org.opendaylight.netconf.api.NetconfServerDispatcher;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class NetconfTcpServerProvider extends ProviderTrait<NetconfTcpServerProvider.NetconfTcpServer> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NetconfTcpServerProvider.class);
+
+    @Inject
+    private NetconfServerDispatcher dispatcher;
+    @Inject
+    private NetconfConfiguration cfgAttributes;
+
+    @Override
+    protected NetconfTcpServer create() {
+        if (!cfgAttributes.isNetconfTcpEnabled()) {
+            LOG.debug("NETCONF TCP disabled, skipping initalization");
+            return null;
+        }
+        LOG.info("Starting NETCONF TCP");
+        final InetAddress name = InetAddresses.forString(cfgAttributes.netconfTcpBindingAddress.get());
+        final InetSocketAddress unresolved = new InetSocketAddress(name, cfgAttributes.netconfTcpBindingPort.get());
+
+        ChannelFuture tcpServer = dispatcher.createServer(unresolved);
+        tcpServer.addListener(new TcpLoggingListener(unresolved));
+        return new NetconfTcpServer(tcpServer);
+    }
+
+    public static final class NetconfTcpServer {
+        private Object tcpServer;
+
+        NetconfTcpServer(final ChannelFuture tcpServer) {
+            this.tcpServer = tcpServer;
+        }
+
+        public Object getTcpServer() {
+            return tcpServer;
+        }
+    }
+
+    private static final class TcpLoggingListener implements GenericFutureListener<ChannelFuture> {
+        private final InetSocketAddress unresolved;
+
+        TcpLoggingListener(final InetSocketAddress unresolved) {
+            this.unresolved = unresolved;
+        }
+
+        @Override
+        public void operationComplete(ChannelFuture future) throws Exception {
+            if (future.isDone() && future.isSuccess()) {
+                LOG.info("Netconf TCP endpoint started successfully at {}", unresolved);
+            } else {
+                LOG.warn("Unable to start TCP netconf server at {}", unresolved, future.cause());
+                throw new InitializationException("Unable to start TCP netconf server", future.cause());
+            }
+        }
+    }
+}
diff --git a/tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NettyThreadGroupProvider.java b/tests/honeynode221/netconf/src/main/java/io/fd/honeycomb/northbound/netconf/NettyThreadGroupProvider.java
new file mode 100644 (file)
index 0000000..b36a31d
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.northbound.netconf;
+
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import com.google.inject.Inject;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import io.fd.honeycomb.northbound.NetconfConfiguration;
+import io.netty.channel.nio.NioEventLoopGroup;
+
+public final class NettyThreadGroupProvider extends ProviderTrait<NioEventLoopGroup> {
+
+    @Inject
+    private NetconfConfiguration cfgAttributes;
+
+    @Override
+    protected NioEventLoopGroup create() {
+        return new NioEventLoopGroup(cfgAttributes.netconfNettyThreads,
+                new ThreadFactoryBuilder().setNameFormat("netconf-netty-%d").build());
+    }
+}
diff --git a/tests/honeynode221/netconf/src/main/resources/honeycomb-minimal-resources/config/netconf-whitelist.xml b/tests/honeynode221/netconf/src/main/resources/honeycomb-minimal-resources/config/netconf-whitelist.xml
new file mode 100644 (file)
index 0000000..371ee2b
--- /dev/null
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<yangModuleWhitelist>
+    <modules>
+        <module>
+            <package>org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715</package>
+            <description>
+                This module contains a collection of generally useful derived
+                YANG data types for Internet addresses and related things.
+
+                Dependency for network-topology,ietf-netconf-notifications,network-topology
+            </description>
+        </module>
+        <module>
+            <package>org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev160621</package>
+            <description>
+                This module contains monitoring information about the YANG
+                modules and submodules that are used within a YANG-based
+                server.
+
+                Required for mounting of netconf devices(Operational read does not work without it)
+            </description>
+        </module>
+        <module>
+            <package>org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601</package>
+            <description>
+                NETCONF Protocol Data Types and Protocol Operations.
+
+                Dependency of ietf-netconf-notifications
+            </description>
+        </module>
+        <module>
+            <package>org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206
+            </package>
+            <description>
+                This module defines a YANG data model for use with the
+                NETCONF protocol that allows the NETCONF client to
+                receive common NETCONF base event notifications.
+
+                Directly used for netconf notification binding
+            </description>
+        </module>
+        <module>
+            <package>org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev130712</package>
+            <description>
+                Required for mounting of netconf devices(Operational read does not work without it)
+            </description>
+        </module>
+        <module>
+            <package>org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714</package>
+            <description>
+                Conversion of the 'ncEvent' XSD in the
+                NETCONF Notifications RFC.
+
+                Directly used for netconf notification binding
+            </description>
+        </module>
+        <module>
+            <package>org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714</package>
+            <description>
+                Conversion of the 'manageEvent' XSD in the NETCONF
+                Notifications RFC.
+
+                Directly used for netconf notification binding
+            </description>
+        </module>
+        <module>
+            <package>org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004
+            </package>
+            <description>
+                NETCONF Monitoring Module.
+                All elements in this module are read-only.
+
+                Required for mounting of netconf devices(Operational read does not work without it)
+            </description>
+        </module>
+        <module>
+            <package>
+                org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.extension.rev131210
+            </package>
+            <description>
+                Required for mounting of netconf devices(Operational read does not work without it)
+            </description>
+        </module>
+    </modules>
+</yangModuleWhitelist>
diff --git a/tests/honeynode221/netconf/src/main/resources/honeycomb-minimal-resources/config/netconf.json b/tests/honeynode221/netconf/src/main/resources/honeycomb-minimal-resources/config/netconf.json
new file mode 100644 (file)
index 0000000..a5b592b
--- /dev/null
@@ -0,0 +1,10 @@
+{
+  "netconf-netty-threads": 2,
+  "netconf-tcp-enabled": "false",
+  "netconf-tcp-binding-address": "127.0.0.1",
+  "netconf-tcp-binding-port": 7777,
+  "netconf-ssh-enabled": "true",
+  "netconf-ssh-binding-address": "0.0.0.0",
+  "netconf-ssh-binding-port": 2831,
+  "netconf-notification-stream-name": "honeycomb"
+}
\ No newline at end of file
diff --git a/tests/honeynode221/pom.xml b/tests/honeynode221/pom.xml
new file mode 100644 (file)
index 0000000..585b798
--- /dev/null
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2015 Cisco and/or its affiliates.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at:
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<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">
+
+  <groupId>io.fd.honeycomb.transportpce</groupId>
+  <artifactId>honeynode-plugin-aggregator</artifactId>
+  <version>1.18.01</version>
+  <name>honeynode-plugin-aggregator</name>
+  <packaging>pom</packaging>
+  <modelVersion>4.0.0</modelVersion>
+
+  <modules>
+    <module>minimal-distribution-core</module>
+    <module>minimal-distribution</module>
+    <module>honeynode-common</module>
+    <module>honeynode-plugin-api</module>
+    <module>honeynode-plugin-impl</module>
+    <module>netconf-netty-util</module>
+    <module>netconf</module>
+    <module>restconf</module>
+    <module>honeynode-distribution</module>
+  </modules>
+
+  <!-- DO NOT install or deploy the repo root pom as it's only needed to initiate a build -->
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-deploy-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-install-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/tests/honeynode221/restconf/asciidoc/Readme.adoc b/tests/honeynode221/restconf/asciidoc/Readme.adoc
new file mode 100644 (file)
index 0000000..957949a
--- /dev/null
@@ -0,0 +1,14 @@
+= restconf
+
+Provides modules and configuration for RESTCONF northbound interface.
+
+* To start RESTCONF HTTP use
+ ** "restconf-http-enabled": "true"
+* To start RESTCONF HTTPS use
+ ** "restconf-https-enabled": "true"
+* To disable RESTCONF start use
+ ** "restconf-http-enabled": "false"
+ ** "restconf-https-enabled": "false"
+* To disable RESTCONF fully
+ ** comment/remove io.fd.honeycomb.northbound.restconf.RestconfModule
+from distribution module configuration
\ No newline at end of file
diff --git a/tests/honeynode221/restconf/pom.xml b/tests/honeynode221/restconf/pom.xml
new file mode 100644 (file)
index 0000000..3e68a0d
--- /dev/null
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright (c) 2017 Cisco and/or its affiliates.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at:
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<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">
+    <parent>
+        <artifactId>impl-parent</artifactId>
+        <groupId>io.fd.honeycomb.common</groupId>
+        <version>1.18.01</version>
+        <relativePath/>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>io.fd.honeycomb.transportpce</groupId>
+    <artifactId>restconf</artifactId>
+    <version>1.18.01</version>
+
+    <properties>
+        <jersey.version>1.19.1</jersey.version>
+        <servlet.version>3.1.0</servlet.version>
+        <jetty.version>9.3.11.v20160721</jetty.version>
+        <yang.modules.whitelist>
+            ${project.basedir}/src/main/resources/honeycomb-minimal-resources/config/restconf-whitelist.xml
+        </yang.modules.whitelist>
+    </properties>
+
+    <dependencies>
+        <!-- TPCE dependencies  -->
+        <dependency>
+            <groupId>io.fd.honeycomb.transportpce</groupId>
+            <artifactId>honeynode-plugin-impl</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+         <dependency>
+            <groupId>io.fd.honeycomb.transportpce</groupId>
+            <artifactId>minimal-distribution-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <!-- DI-->
+        <dependency>
+            <groupId>com.google.inject</groupId>
+            <artifactId>guice</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>net.jmob</groupId>
+            <artifactId>guice.conf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.fd.honeycomb</groupId>
+            <artifactId>binding-init</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <!-- Northbound common -->
+        <dependency>
+            <groupId>io.fd.honeycomb.northbound</groupId>
+            <artifactId>common</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <!-- ODL-Restconf -->
+        <dependency>
+            <groupId>org.opendaylight.netconf</groupId>
+            <artifactId>sal-rest-connector</artifactId>
+        </dependency>
+
+        <!-- Jersey + Jetty for RESTCONF -->
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-server</artifactId>
+            <version>${jetty.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <version>${servlet.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-webapp</artifactId>
+            <version>${jetty.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-servlets</artifactId>
+            <version>${jetty.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.jersey</groupId>
+            <artifactId>jersey-server</artifactId>
+            <version>${jersey.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.jersey</groupId>
+            <artifactId>jersey-core</artifactId>
+            <version>${jersey.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.jersey</groupId>
+            <artifactId>jersey-servlet</artifactId>
+            <version>${jersey.version}</version>
+        </dependency>
+
+        <!-- javax.annotation -->
+        <dependency>
+            <groupId>com.google.code.findbugs</groupId>
+            <artifactId>jsr305</artifactId>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/tests/honeynode221/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/HttpConnectorProvider.java b/tests/honeynode221/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/HttpConnectorProvider.java
new file mode 100644 (file)
index 0000000..04a767c
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.northbound.restconf;
+
+import com.google.inject.Inject;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+final class HttpConnectorProvider extends ProviderTrait<ServerConnector> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(HttpConnectorProvider.class);
+
+    @Inject
+    private RestconfConfiguration cfg;
+    @Inject
+    private Server server;
+
+    @Override
+    protected ServerConnector create() {
+        if (!cfg.isRestconfHttpEnabled()) {
+            LOG.debug("RESTCONF HTTP disabled, skipping initialization");
+            return null;
+        }
+
+        LOG.info("Starting RESTCONF HTTP");
+        ServerConnector httpConnector = new ServerConnector(server, cfg.acceptorsSize.get(), cfg.selectorsSize.get());
+        httpConnector.setHost(cfg.restconfBindingAddress.get());
+        httpConnector.setPort(cfg.restconfPort.get());
+        server.addConnector(httpConnector);
+        return httpConnector;
+    }
+}
diff --git a/tests/honeynode221/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/HttpsConnectorProvider.java b/tests/honeynode221/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/HttpsConnectorProvider.java
new file mode 100644 (file)
index 0000000..5a27bcb
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.northbound.restconf;
+
+import com.google.inject.Inject;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+
+import java.net.URL;
+
+import org.eclipse.jetty.http.HttpVersion;
+import org.eclipse.jetty.server.HttpConnectionFactory;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.SslConnectionFactory;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+final class HttpsConnectorProvider extends ProviderTrait<ServerConnector> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(HttpsConnectorProvider.class);
+
+    @Inject
+    private RestconfConfiguration cfg;
+    @Inject
+    private Server server;
+
+    @Override
+    protected ServerConnector create() {
+        if (!cfg.isRestconfHttpsEnabled()) {
+            LOG.debug("RESTCONF HTTPS disabled, skipping initialization");
+            return null;
+        }
+        LOG.info("Starting RESTCONF HTTPS");
+        // SSL Context Factory
+        // Based on:
+        // https://github.com/eclipse/jetty.project/blob/jetty-9.3.x/examples/embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java
+        // https://wiki.eclipse.org/Jetty/Howto/Configure_SSL#Loading_Keys_and_Certificates_via_PKCS12
+        // Keystore created with:
+        // openssl genrsa -des3 -out honeycomb.key
+        // openssl req -new -x509 -key honeycomb.key -out honeycomb.crt
+        // openssl pkcs12 -inkey honeycomb.key -in honeycomb.crt -export -out honeycomb.pkcs12
+        // keytool -importkeystore -srckeystore honeycomb.pkcs12 -srcstoretype PKCS12 -destkeystore honeycomb-keystore
+        SslContextFactory sslContextFactory = new SslContextFactory();
+        URL keystoreURL = getClass().getResource(cfg.restconfKeystore.get());
+        sslContextFactory.setKeyStorePath(keystoreURL.getPath());
+        sslContextFactory.setKeyStorePassword(cfg.keystorePassword.get());
+        sslContextFactory.setKeyManagerPassword((cfg.keystoreManagerPassword.get()));
+        URL truststoreURL = getClass().getResource(cfg.restconfTruststore.get());
+        sslContextFactory.setTrustStorePath(truststoreURL.getPath());
+        sslContextFactory.setTrustStorePassword((cfg.truststorePassword.get()));
+        // TODO HONEYCOMB-167 make this more configurable
+        sslContextFactory.setExcludeCipherSuites("SSL_RSA_WITH_DES_CBC_SHA", "SSL_DHE_RSA_WITH_DES_CBC_SHA",
+                "SSL_DHE_DSS_WITH_DES_CBC_SHA", "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
+                "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
+                "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA");
+
+        // SSL Connector
+        ServerConnector sslConnector =
+                new ServerConnector(server, cfg.httpsAcceptorsSize.get(), cfg.httpsSelectorsSize.get(),
+                        // The ssl connection factory delegates the real processing to http connection factory
+                        new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()),
+                        // That's why http connection factory is also required here
+                        // Order is IMPORTANT here
+                        new HttpConnectionFactory()
+                );
+        sslConnector.setHost(cfg.restconfHttpsBindingAddress.get());
+        sslConnector.setPort(cfg.restconfHttpsPort.get());
+        server.addConnector(sslConnector);
+        return sslConnector;
+    }
+}
diff --git a/tests/honeynode221/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/JettyServerProvider.java b/tests/honeynode221/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/JettyServerProvider.java
new file mode 100644 (file)
index 0000000..a874595
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.northbound.restconf;
+
+import com.google.inject.Inject;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import io.fd.honeycomb.northbound.CredentialsConfiguration;
+import java.net.URL;
+import java.util.Collections;
+import org.eclipse.jetty.security.ConstraintMapping;
+import org.eclipse.jetty.security.ConstraintSecurityHandler;
+import org.eclipse.jetty.security.HashLoginService;
+import org.eclipse.jetty.security.authentication.BasicAuthenticator;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.handler.gzip.GzipHandler;
+import org.eclipse.jetty.util.security.Constraint;
+import org.eclipse.jetty.util.security.Password;
+import org.eclipse.jetty.util.thread.QueuedThreadPool;
+import org.eclipse.jetty.webapp.WebAppContext;
+
+final class JettyServerProvider extends ProviderTrait<Server> {
+
+    private static final String REALM = "HCRealm";
+    // Mime types to be compressed when requested
+    private static final String[] GZIP_MIME_TYPES = {"application/xml",
+        "xml",
+        "application/yang.data+xml",
+        "application/json",
+        "application/yang.data+json"};
+
+    @Inject
+    private RestconfConfiguration cfg;
+
+    @Inject
+    private CredentialsConfiguration credentialsCfg;
+
+    @Override
+    protected Server create() {
+        Server server = new Server(new QueuedThreadPool(cfg.restPoolMaxSize.get(), cfg.restPoolMinSize.get()));
+
+        // Load Realm for basic auth
+        HashLoginService service = new HashLoginService(REALM);
+        // Reusing the name as role
+        service.putUser(credentialsCfg.username, new Password(credentialsCfg.password),
+                new String[]{credentialsCfg.username});
+        server.addBean(service);
+
+        final URL resource = getClass().getResource("/");
+        WebAppContext webapp = new WebAppContext(resource.getPath(), cfg.restconfRootPath.get());
+
+        server.setHandler(getGzip(service, webapp));
+        return server;
+    }
+
+    private GzipHandler getGzip(final HashLoginService service, final WebAppContext webapp) {
+        final GzipHandler gzipHandler = new GzipHandler();
+        gzipHandler.setIncludedMimeTypes(GZIP_MIME_TYPES);
+        gzipHandler.setHandler(getBaseAuth(service, webapp));
+        return gzipHandler;
+    }
+
+    private ConstraintSecurityHandler getBaseAuth(HashLoginService service, WebAppContext webapp) {
+        Constraint constraint = new Constraint();
+        constraint.setName("auth");
+        constraint.setAuthenticate(true);
+        constraint.setRoles(new String[]{credentialsCfg.username});
+
+        ConstraintMapping mapping = new ConstraintMapping();
+        mapping.setPathSpec("/*");
+        mapping.setConstraint(constraint);
+
+        ConstraintSecurityHandler security = new ConstraintSecurityHandler();
+        security.setConstraintMappings(Collections.singletonList(mapping));
+        security.setAuthenticator(new BasicAuthenticator());
+        security.setLoginService(service);
+
+        security.setHandler(webapp);
+        return security;
+    }
+}
diff --git a/tests/honeynode221/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/JettyServerStarter.java b/tests/honeynode221/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/JettyServerStarter.java
new file mode 100644 (file)
index 0000000..1bd50bb
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.northbound.restconf;
+
+import static io.fd.honeycomb.northbound.restconf.RestconfModule.RESTCONF_HTTP;
+import static io.fd.honeycomb.northbound.restconf.RestconfModule.RESTCONF_HTTPS;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+import io.fd.honeycomb.binding.init.ProviderTrait;
+
+import javax.annotation.Nullable;
+
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.opendaylight.netconf.sal.rest.api.RestConnector;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class JettyServerStarter extends ProviderTrait<JettyServerStarter.ServerInit> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(JettyServerStarter.class);
+
+    @Inject
+    private Server server;
+
+    // injecting all connectors to make sure that server is started after they are added
+    @Inject
+    private RestConnector connector;
+
+    // if HTTP is disabled, null will be injected
+    @Nullable
+    @Inject(optional = true)
+    @Named(RESTCONF_HTTP)
+    private ServerConnector httpConnectorInit;
+
+    // if HTTPS is disabled, null will be injected
+    @Nullable
+    @Inject(optional = true)
+    @Named(RESTCONF_HTTPS)
+    private ServerConnector httpsConnectorInit;
+
+    @Override
+    protected ServerInit create() {
+        try {
+            LOG.info("Starting RESTCONF Jetty server");
+            server.start();
+            LOG.info("RESTCONF Jetty server successfully started");
+        } catch (Exception e) {
+            LOG.error("Unable to start RESTCONF Jetty server", e);
+            throw new IllegalStateException("Unable to start RESTCONF Jetty server", e);
+        }
+
+        return new ServerInit() {
+        };
+    }
+
+    interface ServerInit {
+    }
+}
diff --git a/tests/honeynode221/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/RestconfConfiguration.java b/tests/honeynode221/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/RestconfConfiguration.java
new file mode 100644 (file)
index 0000000..b61287d
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.northbound.restconf;
+
+import java.util.Optional;
+import net.jmob.guice.conf.core.BindConfig;
+import net.jmob.guice.conf.core.InjectConfig;
+import net.jmob.guice.conf.core.Syntax;
+
+//TODO - HONEYCOMB-377 - do not include module to active modules if disabled
+@BindConfig(value = "restconf", syntax = Syntax.JSON)
+public class RestconfConfiguration {
+
+    @InjectConfig("restconf-http-enabled")
+    public String restconfHttp;
+    @InjectConfig("restconf-binding-address")
+    public Optional<String> restconfBindingAddress;
+    @InjectConfig("restconf-port")
+    public Optional<Integer> restconfPort;
+    @InjectConfig("restconf-https-enabled")
+    public String restconfHttps;
+    @InjectConfig("restconf-https-binding-address")
+    public Optional<String> restconfHttpsBindingAddress;
+    @InjectConfig("restconf-https-port")
+    public Optional<Integer> restconfHttpsPort;
+    /**
+     * Restconf keystore file name. It will be loaded from the classpath so must be present in one of the folders
+     * packaged with the distribution e.g. cert/
+     */
+    @InjectConfig("restconf-keystore")
+    public Optional<String> restconfKeystore = Optional.of("/honeycomb-keystore");
+    @InjectConfig("restconf-keystore-password")
+    public Optional<String> keystorePassword;
+    @InjectConfig("restconf-keystore-manager-password")
+    public Optional<String> keystoreManagerPassword;
+    /**
+     * Restconf truststore file name. It will be loaded from the classpath so must be present in one of the folders
+     * packaged with the distribution e.g. cert/
+     */
+    @InjectConfig("restconf-truststore")
+    public Optional<String> restconfTruststore;
+    @InjectConfig("restconf-truststore-password")
+    public Optional<String> truststorePassword;
+    @InjectConfig("restconf-websocket-address")
+    public Optional<String> restconfWebsocketAddress;
+    @InjectConfig("restconf-websocket-port")
+    public Optional<Integer> restconfWebsocketPort;
+    @InjectConfig("restconf-root-path")
+    public Optional<String> restconfRootPath = Optional.of("/restconf");
+    @InjectConfig("restconf-pool-max-size")
+    public Optional<Integer> restPoolMaxSize = Optional.of(10);
+    @InjectConfig("restconf-pool-min-size")
+    public Optional<Integer> restPoolMinSize = Optional.of(1);
+    @InjectConfig("restconf-acceptors-size")
+    public Optional<Integer> acceptorsSize = Optional.of(1);
+    @InjectConfig("restconf-selectors-size")
+    public Optional<Integer> selectorsSize = Optional.of(1);
+    @InjectConfig("restconf-https-acceptors-size")
+    public Optional<Integer> httpsAcceptorsSize = Optional.of(1);
+    @InjectConfig("restconf-https-selectors-size")
+    public Optional<Integer> httpsSelectorsSize = Optional.of(1);
+
+    public boolean isRestconfHttpEnabled() {
+        return Boolean.valueOf(restconfHttp);
+    }
+
+    public boolean isRestconfHttpsEnabled() {
+        return Boolean.valueOf(restconfHttps);
+    }
+
+    public boolean isRestconfEnabled() {
+        return isRestconfHttpEnabled() || isRestconfHttpsEnabled();
+    }
+
+    @Override
+    public String toString() {
+        return "RestconfConfiguration{" +
+            "restconfHttp='" + restconfHttp + '\'' +
+            ", restconfBindingAddress=" + restconfBindingAddress +
+            ", restconfPort=" + restconfPort +
+            ", restconfHttps='" + restconfHttps + '\'' +
+            ", restconfHttpsBindingAddress=" + restconfHttpsBindingAddress +
+            ", restconfHttpsPort=" + restconfHttpsPort +
+            ", restconfKeystore=" + restconfKeystore +
+            ", keystorePassword=" + keystorePassword +
+            ", keystoreManagerPassword=" + keystoreManagerPassword +
+            ", restconfTruststore=" + restconfTruststore +
+            ", truststorePassword=" + truststorePassword +
+            ", restconfWebsocketAddress=" + restconfWebsocketAddress +
+            ", restconfWebsocketPort=" + restconfWebsocketPort +
+            ", restconfRootPath=" + restconfRootPath +
+            ", restPoolMaxSize=" + restPoolMaxSize +
+            ", restPoolMinSize=" + restPoolMinSize +
+            ", acceptorsSize=" + acceptorsSize +
+            ", selectorsSize=" + selectorsSize +
+            ", httpsAcceptorsSize=" + httpsAcceptorsSize +
+            ", httpsSelectorsSize=" + httpsSelectorsSize +
+            '}';
+    }
+}
diff --git a/tests/honeynode221/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/RestconfConfigurationModule.java b/tests/honeynode221/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/RestconfConfigurationModule.java
new file mode 100644 (file)
index 0000000..1e18a37
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.northbound.restconf;
+
+import com.google.inject.AbstractModule;
+import net.jmob.guice.conf.core.ConfigurationModule;
+
+public class RestconfConfigurationModule extends AbstractModule {
+
+    @Override
+    protected void configure() {
+        install(ConfigurationModule.create());
+        requestInjection(RestconfConfiguration.class);
+    }
+}
diff --git a/tests/honeynode221/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/RestconfModule.java b/tests/honeynode221/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/RestconfModule.java
new file mode 100644 (file)
index 0000000..9f9ecf7
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.northbound.restconf;
+
+import com.google.inject.Singleton;
+import com.google.inject.name.Names;
+import io.fd.honeycomb.northbound.NorthboundAbstractModule;
+import io.fd.honeycomb.northbound.restconf.JettyServerStarter.ServerInit;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.opendaylight.netconf.sal.rest.api.RestConnector;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class RestconfModule extends NorthboundAbstractModule<RestconfConfiguration> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(RestconfModule.class);
+
+    public static final String RESTCONF_HTTP = "restconf-http";
+    public static final String RESTCONF_HTTPS = "restconf-https";
+
+    public RestconfModule() {
+        super(new RestconfConfigurationModule(), RestconfConfiguration.class);
+    }
+
+    @Override
+    protected void configure() {
+        if (!getConfiguration().isRestconfEnabled()) {
+            LOG.info("Restconf is disabled, skipping configuration");
+            return;
+        }
+
+        LOG.info("Starting RESTCONF Northbound");
+        install(new RestconfConfigurationModule());
+        bind(Server.class).toProvider(JettyServerProvider.class).in(Singleton.class);
+        bind(ServerConnector.class).annotatedWith(Names.named(RESTCONF_HTTP))
+                .toProvider(HttpConnectorProvider.class)
+                .in(Singleton.class);
+        bind(ServerConnector.class).annotatedWith(Names.named(RESTCONF_HTTPS))
+                .toProvider(HttpsConnectorProvider.class)
+                .in(Singleton.class);
+        bind(RestConnector.class).toProvider(RestconfProvider.class).in(Singleton.class);
+        bind(ServerInit.class).toProvider(JettyServerStarter.class).asEagerSingleton();
+    }
+}
diff --git a/tests/honeynode221/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/RestconfProvider.java b/tests/honeynode221/restconf/src/main/java/io/fd/honeycomb/northbound/restconf/RestconfProvider.java
new file mode 100644 (file)
index 0000000..6650e31
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2016, 2017 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.northbound.restconf;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+
+import io.fd.honeycomb.binding.init.ProviderTrait;
+import io.fd.honeycomb.data.init.ShutdownHandler;
+
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.opendaylight.controller.md.sal.dom.broker.impl.DOMNotificationRouter;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.netconf.sal.rest.api.RestConnector;
+import org.opendaylight.netconf.sal.restconf.impl.RestconfProviderImpl;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
+
+final class RestconfProvider extends ProviderTrait<RestConnector> {
+
+    @Inject
+    private RestconfConfiguration cfg;
+    @Inject
+//    @Named(HONEYCOMB_CONFIG)
+    //Modified in order to connect TPCE to device config datastore
+    @Named("device-databroker")
+    private DOMDataBroker domDataBroker;
+    @Inject
+    private SchemaService schemaService;
+    @Inject
+    private DOMRpcService rpcService;
+    @Inject
+    private DOMNotificationRouter notificationService;
+    @Inject
+    private ShutdownHandler shutdownHandler;
+    @Inject
+    private DOMMountPointService mountPointService;
+
+    @Override
+    protected RestconfProviderImpl create() {
+        final RestconfProviderImpl instance = new RestconfProviderImpl(domDataBroker, schemaService, rpcService,
+            notificationService, mountPointService,
+            IpAddressBuilder.getDefaultInstance(cfg.restconfWebsocketAddress.get()),
+            new PortNumber(cfg.restconfWebsocketPort.get()));
+
+        // Required to properly initialize restconf (broker, schema ctx, etc.).
+        // Without that restconf would fail with 503 (service not available).
+        instance.start();
+
+        shutdownHandler.register(instance.getClass().getCanonicalName(), instance);
+        return instance;
+    }
+}
diff --git a/tests/honeynode221/restconf/src/main/resources/honeycomb-minimal-resources/config/restconf-whitelist.xml b/tests/honeynode221/restconf/src/main/resources/honeycomb-minimal-resources/config/restconf-whitelist.xml
new file mode 100644 (file)
index 0000000..5274cf4
--- /dev/null
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<yangModuleWhitelist>
+    <modules>
+        <module>
+            <package>org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715</package>
+            <description>
+                This module contains a collection of generally useful derived
+                YANG data types for Internet addresses and related things.
+
+                Dependency for ietf-restconf-monitoring
+            </description>
+        </module>
+        <module>
+            <package>org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715</package>
+            <description>
+                This module contains a collection of generally useful derived
+                YANG data types.
+
+                Dependency for ietf-restconf-monitoring
+            </description>
+        </module>
+        <module>
+            <package>org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.restconf.monitoring.rev170126
+            </package>
+            <description>
+                This module contains monitoring information for the
+                RESTCONF protocol.
+
+                Required for mounting of netconf devices
+            </description>
+        </module>
+        <module>
+            <package>org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev160621</package>
+            <description>
+                This module contains monitoring information about the YANG
+                modules and submodules that are used within a YANG-based
+                server.
+
+                Required for mounting of netconf devices
+            </description>
+        </module>
+    </modules>
+</yangModuleWhitelist>
diff --git a/tests/honeynode221/restconf/src/main/resources/honeycomb-minimal-resources/config/restconf.json b/tests/honeynode221/restconf/src/main/resources/honeycomb-minimal-resources/config/restconf.json
new file mode 100644 (file)
index 0000000..ec4061c
--- /dev/null
@@ -0,0 +1,22 @@
+{
+  "restconf-http-enabled": "true",
+  "restconf-root-path": "/restconf",
+  "restconf-binding-address": "127.0.0.1",
+  "restconf-port": 8183,
+  "restconf-https-enabled": "true",
+  "restconf-https-binding-address": "0.0.0.0",
+  "restconf-https-port": 8445,
+  "restconf-keystore": "/honeycomb-keystore",
+  "restconf-keystore-password": "OBF:1v9s1unr1unn1vv51zlk1t331vg91x1b1vgl1t331zly1vu51uob1uo71v8u",
+  "restconf-keystore-manager-password": "OBF:1v9s1unr1unn1vv51zlk1t331vg91x1b1vgl1t331zly1vu51uob1uo71v8u",
+  "restconf-truststore": "/honeycomb-keystore",
+  "restconf-truststore-password": "OBF:1v9s1unr1unn1vv51zlk1t331vg91x1b1vgl1t331zly1vu51uob1uo71v8u",
+  "restconf-websocket-address": "0.0.0.0",
+  "restconf-websocket-port": 7779,
+  "restconf-pool-max-size": 10,
+  "restconf-pool-min-size": 1,
+  "restconf-acceptors-size": 1,
+  "restconf-selectors-size": 1,
+  "restconf-https-acceptors-size": 1,
+  "restconf-https-selectors-size": 1
+}
diff --git a/tests/sample_configs/openroadm/2.2.1/oper-ROADMA.xml b/tests/sample_configs/openroadm/2.2.1/oper-ROADMA.xml
new file mode 100644 (file)
index 0000000..8883693
--- /dev/null
@@ -0,0 +1,805 @@
+<?xml version="1.0" encoding="utf-8"?>
+<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+  <netconf xmlns="urn:ietf:params:xml:ns:netmod:notification">
+      <streams>
+          <stream>
+              <name>OPENROADM</name>
+          </stream>
+    </streams>
+  </netconf>
+  <org-openroadm-device xmlns="http://org/openroadm/device">
+     <info>
+      <node-id>ROADM-A1</node-id>
+      <node-number>2</node-number>
+      <node-type>rdm</node-type>
+      <clli>NodeA</clli>
+      <vendor>vendorA</vendor>
+      <model>model2</model>
+      <serial-id>0002</serial-id>
+      <ipAddress>127.0.0.11</ipAddress>
+      <prefix-length>28</prefix-length>
+      <defaultGateway>127.0.0.20</defaultGateway>
+      <source>static</source>
+      <current-ipAddress>127.0.0.11</current-ipAddress>
+      <current-prefix-length>28</current-prefix-length>
+      <current-defaultGateway>127.0.0.20</current-defaultGateway>
+      <macAddress>00:01:02:03:04:05</macAddress>
+      <softwareVersion>swversion1234</softwareVersion>
+      <openroadm-version>2.2.1</openroadm-version>
+      <template>template_1</template>
+      <current-datetime>2017-10-22T15:23:43Z</current-datetime>
+      <max-degrees>2</max-degrees>
+      <max-srgs>3</max-srgs>
+      <geoLocation>
+        <latitude>1.0000</latitude>
+        <longitude>2.0000</longitude>
+      </geoLocation>
+      <max-num-bin-15min-historical-pm>32</max-num-bin-15min-historical-pm>
+      <max-num-bin-24hour-historical-pm>7</max-num-bin-24hour-historical-pm>
+    </info>
+    <users>
+      <user>
+        <name>openroadm</name>
+        <password>openroadm</password>
+        <group>sudo</group>
+      </user>
+    </users>
+    <circuit-packs>
+      <circuit-pack-name>1/0</circuit-pack-name>
+      <circuit-pack-type>WSSDEG</circuit-pack-type>
+      <circuit-pack-product-code>DegW</circuit-pack-product-code>
+      <administrative-state>inService</administrative-state>
+      <vendor>vendorA</vendor>
+      <model>WSS9</model>
+      <serial-id>nodeid-1234</serial-id>
+      <type>Dir1</type>
+      <product-code>DegRxTx</product-code>
+      <manufacture-date>2017-08-08T10:47:04.698808+00:00</manufacture-date>
+      <clei>wss1</clei>
+      <hardware-version>0.1</hardware-version>
+      <operational-state>inService</operational-state>
+      <circuit-pack-category>
+        <type>circuitPack</type>
+      </circuit-pack-category>
+      <equipment-state>not-reserved-available</equipment-state>
+      <circuit-pack-mode>inServiceMode</circuit-pack-mode>
+      <shelf>1</shelf>
+      <slot>1</slot>
+      <cp-slots>
+        <slot-name>OSC-SLOT</slot-name>
+        <label>OSC-SLOT</label>
+        <provisioned-circuit-pack>1/0/OSC-PLUG</provisioned-circuit-pack>
+      </cp-slots>
+      <cp-slots>
+        <slot-name>ETH-PLUG</slot-name>
+        <label>ETH-PLUG</label>
+        <provisioned-circuit-pack>1/0/ETH-PLUG</provisioned-circuit-pack>
+      </cp-slots>
+      <ports>
+        <port-name>C1</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <circuit-id>1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <logical-connection-point>DEG1-CTP-TXRX</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>C2</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <circuit-id>1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <logical-connection-point>DEG1-CTP-TXRX</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>C3</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <circuit-id>1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <logical-connection-point>DEG1-CTP-TXRX</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>C4</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <circuit-id>1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <logical-connection-point>DEG1-CTP-TXRX</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>L1</port-name>
+        <port-type>LINE</port-type>
+        <port-qual>roadm-external</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <label>Dir1-RxTxAMP port</label>
+        <circuit-id>1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <partner-port>
+          <circuit-pack-name></circuit-pack-name>
+          <port-name></port-name>
+        </partner-port>
+        <logical-connection-point>DEG1-TTP-TXRX</logical-connection-point>
+        <supported-interface-capability xmlns:x="http://org/openroadm/port/types">x:if-OTS</supported-interface-capability>
+        <supported-interface-capability xmlns:x="http://org/openroadm/port/types">x:if-OMS</supported-interface-capability>
+        <supported-interface-capability xmlns:x="http://org/openroadm/port/types">x:if-OCH</supported-interface-capability>
+      </ports>
+    </circuit-packs>
+    <circuit-packs>
+      <circuit-pack-name>1/0/ETH-PLUG</circuit-pack-name>
+      <circuit-pack-type>port</circuit-pack-type>
+      <circuit-pack-product-code>Eth</circuit-pack-product-code>
+      <administrative-state>inService</administrative-state>
+      <vendor>VendorA</vendor>
+      <model>GIGAETHMGT</model>
+      <serial-id>nodeid-1234</serial-id>
+      <type>eth</type>
+      <product-code>eth</product-code>
+      <manufacture-date>2017-08-08T10:47:04.698808+00:00</manufacture-date>
+      <clei>ETHE</clei>
+      <hardware-version>0.1</hardware-version>
+      <operational-state>inService</operational-state>
+      <circuit-pack-category>
+        <type>circuitPack</type>
+      </circuit-pack-category>
+      <equipment-state>not-reserved-available</equipment-state>
+      <circuit-pack-mode>inServiceMode</circuit-pack-mode>
+      <shelf>1</shelf>
+      <slot>1</slot>
+      <subSlot>0</subSlot>
+      <parent-circuit-pack>
+        <circuit-pack-name>1/0</circuit-pack-name>
+        <cp-slot-name>ETH-PLUG</cp-slot-name>
+      </parent-circuit-pack>
+      <ports>
+        <port-name>ETH-PLUG</port-name>
+        <port-type>1GEX</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+      </ports>
+    </circuit-packs>
+    <circuit-packs>
+      <circuit-pack-name>1/0/OSC-PLUG</circuit-pack-name>
+      <circuit-pack-type>port</circuit-pack-type>
+      <administrative-state>inService</administrative-state>
+      <vendor>vendorA</vendor>
+      <model>SFP/SFP+</model>
+      <serial-id>00000163600843</serial-id>
+      <product-code>oooooo</product-code>
+      <manufacture-date>2017-08-08T10:47:04.698808+00:00</manufacture-date>
+      <clei>oscplug</clei>
+      <hardware-version>01</hardware-version>
+      <equipment-state>not-reserved-available</equipment-state>
+      <circuit-pack-mode>NORMAL</circuit-pack-mode>
+      <shelf>2</shelf>
+      <slot>0</slot>
+      <subSlot>0</subSlot>
+      <parent-circuit-pack>
+        <circuit-pack-name>1/0</circuit-pack-name>
+        <cp-slot-name>OSC-SLOT</cp-slot-name>
+      </parent-circuit-pack>
+      <ports>
+        <port-name>OSC-PORT</port-name>
+        <port-type>1GEX</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+      </ports>
+    </circuit-packs>
+    <circuit-packs>
+      <circuit-pack-name>2/0</circuit-pack-name>
+      <circuit-pack-type>WSSDEG</circuit-pack-type>
+      <circuit-pack-product-code>DegE</circuit-pack-product-code>
+      <administrative-state>inService</administrative-state>
+      <vendor>vendorA</vendor>
+      <model>WSS9</model>
+      <serial-id>nodeid-1234</serial-id>
+      <type>Dir2</type>
+      <product-code>DegTxRx</product-code>
+      <manufacture-date>2017-08-08T10:47:04.698808+00:00</manufacture-date>
+      <clei>wss1</clei>
+      <hardware-version>0.1</hardware-version>
+      <operational-state>inService</operational-state>
+      <circuit-pack-category>
+        <type>circuitPack</type>
+      </circuit-pack-category>
+      <equipment-state>not-reserved-available</equipment-state>
+      <circuit-pack-mode>inServiceMode</circuit-pack-mode>
+      <shelf>1</shelf>
+      <slot>2</slot>
+      <cp-slots>
+        <slot-name>OSC-SLOT</slot-name>
+        <label>OSC-SLOT</label>
+        <provisioned-circuit-pack>2/0/OSC-PLUG</provisioned-circuit-pack>
+      </cp-slots>
+      <cp-slots>
+        <slot-name>ETH-PLUG</slot-name>
+        <label>ETH-PLUG</label>
+        <provisioned-circuit-pack>2/0/ETH-PLUG</provisioned-circuit-pack>
+      </cp-slots>
+      <ports>
+        <port-name>C1</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <circuit-id>1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <logical-connection-point>DEG2-CTP-TXRX</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>C2</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <circuit-id>1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <logical-connection-point>DEG2-CTP-TXRX</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>C3</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <circuit-id>1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <logical-connection-point>DEG2-CTP-TXRX</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>C4</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <circuit-id>1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <logical-connection-point>DEG2-CTP-TXRX</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>L1</port-name>
+        <port-type>LINE</port-type>
+        <port-qual>roadm-external</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <label>Dir2-RxTxAMP port</label>
+        <circuit-id>1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <partner-port>
+          <circuit-pack-name></circuit-pack-name>
+          <port-name></port-name>
+        </partner-port>
+        <logical-connection-point>DEG2-TTP-TXRX</logical-connection-point>
+        <supported-interface-capability xmlns:x="http://org/openroadm/port/types">x:if-OTS</supported-interface-capability>
+        <supported-interface-capability xmlns:x="http://org/openroadm/port/types">x:if-OMS</supported-interface-capability>
+        <supported-interface-capability xmlns:x="http://org/openroadm/port/types">x:if-OCH</supported-interface-capability>
+        <interfaces>
+          <interface-name>OTS-DEG2-TTP-TXRX</interface-name>
+        </interfaces>
+        <interfaces>
+          <interface-name>OMS-DEG2-TTP-TXRX</interface-name>
+        </interfaces>
+      </ports>
+    </circuit-packs>
+    <circuit-packs>
+      <circuit-pack-name>2/0/ETH-PLUG</circuit-pack-name>
+      <circuit-pack-type>port</circuit-pack-type>
+      <circuit-pack-product-code>Eth</circuit-pack-product-code>
+      <administrative-state>inService</administrative-state>
+      <vendor>VENDORA</vendor>
+      <model>GIGAETHMGT</model>
+      <serial-id>nodeid-1234</serial-id>
+      <type>eth</type>
+      <product-code>eth</product-code>
+      <manufacture-date>2017-08-08T10:47:04.698808+00:00</manufacture-date>
+      <clei>ETHE</clei>
+      <hardware-version>0.1</hardware-version>
+      <operational-state>inService</operational-state>
+      <circuit-pack-category>
+        <type>circuitPack</type>
+      </circuit-pack-category>
+      <equipment-state>not-reserved-available</equipment-state>
+      <circuit-pack-mode>inServiceMode</circuit-pack-mode>
+      <shelf>1</shelf>
+      <slot>1</slot>
+      <subSlot>0</subSlot>
+      <parent-circuit-pack>
+        <circuit-pack-name>2/0</circuit-pack-name>
+        <cp-slot-name>ETH-PLUG</cp-slot-name>
+      </parent-circuit-pack>
+      <ports>
+        <port-name>ETH-PLUG</port-name>
+        <port-type>1GEX</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+      </ports>
+    </circuit-packs>
+    <circuit-packs>
+      <circuit-pack-name>2/0/OSC-PLUG</circuit-pack-name>
+      <circuit-pack-type>port</circuit-pack-type>
+      <administrative-state>inService</administrative-state>
+      <vendor>vendorA</vendor>
+      <model>SFP/SFP+</model>
+      <serial-id>00000163600843</serial-id>
+      <product-code>oooooo</product-code>
+      <manufacture-date>2017-08-08T10:47:04.698808+00:00</manufacture-date>
+      <clei>oscplug</clei>
+      <hardware-version>01</hardware-version>
+      <equipment-state>not-reserved-available</equipment-state>
+      <circuit-pack-mode>NORMAL</circuit-pack-mode>
+      <shelf>2</shelf>
+      <slot>0</slot>
+      <subSlot>0</subSlot>
+      <parent-circuit-pack>
+        <circuit-pack-name>2/0</circuit-pack-name>
+        <cp-slot-name>OSC-SLOT</cp-slot-name>
+      </parent-circuit-pack>
+      <ports>
+        <port-name>OSC-PORT</port-name>
+        <port-type>1GEX</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+      </ports>
+    </circuit-packs>
+    <circuit-packs>
+      <circuit-pack-name>3/0</circuit-pack-name>
+      <circuit-pack-type>ADDDROP</circuit-pack-type>
+      <circuit-pack-product-code>SRGRx</circuit-pack-product-code>
+      <administrative-state>inService</administrative-state>
+      <vendor>vendorA</vendor>
+      <model>WSS</model>
+      <serial-id>nodeid-1234</serial-id>
+      <type>SRG1</type>
+      <product-code>SRGRx</product-code>
+      <manufacture-date>2007-10-10T00:00:00Z</manufacture-date>
+      <clei>12345678901</clei>
+      <hardware-version>0.1</hardware-version>
+      <operational-state>inService</operational-state>
+      <circuit-pack-category>
+        <type>circuitPack</type>
+      </circuit-pack-category>
+      <equipment-state>reserved-for-facility-available</equipment-state>
+      <circuit-pack-mode>inServiceMode</circuit-pack-mode>
+      <shelf>1</shelf>
+      <slot>2</slot>
+      <ports>
+        <port-name>C1</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-external</port-qual>
+        <port-wavelength-type>wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <label>SRG1-client port 1</label>
+        <circuit-id>SRG1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <partner-port>
+          <circuit-pack-name></circuit-pack-name>
+          <port-name></port-name>
+        </partner-port>
+        <logical-connection-point>SRG1-PP1</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>C2</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-external</port-qual>
+        <port-wavelength-type>wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <label>SRG1-client port 2</label>
+        <circuit-id>SRG1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <partner-port>
+          <circuit-pack-name></circuit-pack-name>
+          <port-name></port-name>
+        </partner-port>
+        <logical-connection-point>SRG1-PP2</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>C3</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-external</port-qual>
+        <port-wavelength-type>wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <label>SRG1-client port 3</label>
+        <circuit-id>SRG1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <partner-port>
+          <circuit-pack-name></circuit-pack-name>
+          <port-name></port-name>
+        </partner-port>
+        <logical-connection-point>SRG1-PP3</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>C4</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-external</port-qual>
+        <port-wavelength-type>wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <label>SRG1-client port 4</label>
+        <circuit-id>SRG1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <partner-port>
+          <circuit-pack-name></circuit-pack-name>
+          <port-name></port-name>
+        </partner-port>
+        <logical-connection-point>SRG1-PP4</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>AD-DEG1</port-name>
+        <port-type>Edge</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <logical-connection-point>SRG1-CP-TXRX</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>AD-DEG2</port-name>
+        <port-type>Edge</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <logical-connection-point>SRG1-CP-TXRX</logical-connection-point>
+      </ports>
+    </circuit-packs>
+    <circuit-packs>
+      <circuit-pack-name>5/0</circuit-pack-name>
+      <circuit-pack-type>ADDDROP</circuit-pack-type>
+      <circuit-pack-product-code>SRGRx</circuit-pack-product-code>
+      <administrative-state>inService</administrative-state>
+      <vendor>vendorA</vendor>
+      <model>WSS</model>
+      <serial-id>nodeid-1234</serial-id>
+      <type>SRG1</type>
+      <product-code>SRGRx</product-code>
+      <manufacture-date>2007-10-10T00:00:00Z</manufacture-date>
+      <clei>12345678901</clei>
+      <hardware-version>0.1</hardware-version>
+      <operational-state>inService</operational-state>
+      <circuit-pack-category>
+        <type>circuitPack</type>
+      </circuit-pack-category>
+      <equipment-state>reserved-for-facility-available</equipment-state>
+      <circuit-pack-mode>inServiceMode</circuit-pack-mode>
+      <shelf>1</shelf>
+      <slot>2</slot>
+      <ports>
+        <port-name>C1</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-external</port-qual>
+        <port-wavelength-type>wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <label>SRG1-client port 1</label>
+        <circuit-id>SRG1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <partner-port>
+          <circuit-pack-name></circuit-pack-name>
+          <port-name></port-name>
+        </partner-port>
+        <logical-connection-point>SRG3-PP1</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>C2</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-external</port-qual>
+        <port-wavelength-type>wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <label>SRG1-client port 2</label>
+        <circuit-id>SRG1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <partner-port>
+          <circuit-pack-name></circuit-pack-name>
+          <port-name></port-name>
+        </partner-port>
+        <logical-connection-point>SRG3-PP2</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>C3</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-external</port-qual>
+        <port-wavelength-type>wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <label>SRG1-client port 3</label>
+        <circuit-id>SRG1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <partner-port>
+          <circuit-pack-name></circuit-pack-name>
+          <port-name></port-name>
+        </partner-port>
+        <logical-connection-point>SRG3-PP3</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>C4</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-external</port-qual>
+        <port-wavelength-type>wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <label>SRG1-client port 4</label>
+        <circuit-id>SRG1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <partner-port>
+          <circuit-pack-name></circuit-pack-name>
+          <port-name></port-name>
+        </partner-port>
+        <logical-connection-point>SRG3-PP4</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>AD-DEG1</port-name>
+        <port-type>Edge</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <logical-connection-point>SRG3-CP-TXRX</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>AD-DEG2</port-name>
+        <port-type>Edge</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <logical-connection-point>SRG3-CP-TXRX</logical-connection-point>
+      </ports>
+    </circuit-packs>
+
+    <interface>
+      <name>1GE-interface-1</name>
+      <supporting-circuit-pack-name>1/0/ETH-PLUG</supporting-circuit-pack-name>
+      <supporting-port>ETH-PLUG</supporting-port>
+      <type xmlns:openROADM-if="http://org/openroadm/interfaces">openROADM-if:ethernetCsmacd</type>
+      <operational-state>inService</operational-state>
+      <administrative-state>inService</administrative-state>
+      <ethernet xmlns="http://org/openroadm/ethernet-interfaces">
+        <speed>1000</speed>
+        <duplex>full</duplex>
+        <mtu>1800</mtu>
+        <auto-negotiation>enabled</auto-negotiation>
+        <curr-speed>1000</curr-speed>
+        <curr-duplex>FULL</curr-duplex>
+      </ethernet>
+   </interface>
+    <interface>
+      <name>1GE-interface-2</name>
+      <supporting-circuit-pack-name>2/0/ETH-PLUG</supporting-circuit-pack-name>
+      <supporting-port>ETH-PLUG</supporting-port>
+      <type xmlns:openROADM-if="http://org/openroadm/interfaces">openROADM-if:ethernetCsmacd</type>
+      <operational-state>inService</operational-state>
+      <administrative-state>inService</administrative-state>
+      <ethernet xmlns="http://org/openroadm/ethernet-interfaces">
+        <speed>1000</speed>
+        <duplex>full</duplex>
+        <mtu>1800</mtu>
+        <auto-negotiation>enabled</auto-negotiation>
+        <curr-speed>1000</curr-speed>
+        <curr-duplex>FULL</curr-duplex>
+      </ethernet>
+   </interface>
+    <interface>
+      <name>OTS-DEG2-TTP-TXRX</name>
+      <supporting-circuit-pack-name>2/0</supporting-circuit-pack-name>
+      <supporting-port>L1</supporting-port>
+      <type xmlns:openROADM-if="http://org/openroadm/interfaces">openROADM-if:opticalTransport</type>
+      <operational-state>inService</operational-state>
+      <administrative-state>inService</administrative-state>
+      <ots xmlns="http://org/openroadm/optical-transport-interfaces">
+        <fiber-type>smf</fiber-type>
+        <span-loss-transmit>6</span-loss-transmit>
+        <span-loss-receive>15</span-loss-receive>
+        <ingress-span-loss-aging-margin>0</ingress-span-loss-aging-margin>
+      </ots>
+   </interface>
+    <interface>
+      <name>OMS-DEG2-TTP-TXRX</name>
+      <supporting-circuit-pack-name>2/0</supporting-circuit-pack-name>
+      <supporting-port>L1</supporting-port>
+      <supporting-interface>OTS-DEG2-TTP-TXRX</supporting-interface>      
+      <type xmlns:openROADM-if="http://org/openroadm/interfaces">openROADM-if:openROADMOpticalMultiplex</type> 
+      <description>TBD</description>      
+      <circuit-id>TBD</circuit-id>
+      <operational-state>inService</operational-state>
+      <administrative-state>inService</administrative-state>      
+    </interface>
+
+    <protocols>
+      <lldp xmlns="http://org/openroadm/lldp">
+        <global-config>
+          <adminStatus>enable</adminStatus>
+          <msgTxHoldMultiplier>4</msgTxHoldMultiplier>
+          <msgTxInterval>20</msgTxInterval>
+        </global-config>
+        <nbr-list>
+          <if-name>
+            <ifName>1GE-interface-1</ifName>
+            <remoteSysName>ROADM-B1</remoteSysName>
+            <remoteMgmtAddress>1.1.1.1</remoteMgmtAddress>
+            <remoteChassisId>1?</remoteChassisId>
+            <remotePortId>1GE-interface-1</remotePortId>
+            <remoteChassisIdSubType>chassiscomponent</remoteChassisIdSubType>
+            <remotePortIdSubType>ifalias</remotePortIdSubType>
+            <remoteMgmtAddressSubType>ipV4</remoteMgmtAddressSubType>
+          </if-name>
+          <if-name>
+            <ifName>1GE-interface-2</ifName>
+            <remoteSysName>ROADM-C1</remoteSysName>
+            <remoteMgmtAddress>1.1.1.1</remoteMgmtAddress>
+            <remoteChassisId>1?</remoteChassisId>
+            <remotePortId>1GE-interface-1</remotePortId>
+            <remoteChassisIdSubType>chassiscomponent</remoteChassisIdSubType>
+            <remotePortIdSubType>ifalias</remotePortIdSubType>
+            <remoteMgmtAddressSubType>ipV4</remoteMgmtAddressSubType>
+          </if-name>
+        </nbr-list>
+        <port-config>
+          <ifName>1GE-interface-1</ifName>
+          <adminStatus>txandrx</adminStatus>
+        </port-config>
+        <port-config>
+          <ifName>1GE-interface-2</ifName>
+          <adminStatus>txandrx</adminStatus>
+        </port-config>
+      </lldp>
+    </protocols>
+
+    <degree>
+      <degree-number>1</degree-number>
+      <max-wavelengths>96</max-wavelengths>
+      <circuit-packs>
+        <index>1</index>
+        <circuit-pack-name>1/0</circuit-pack-name>
+      </circuit-packs>
+      <circuit-packs>
+        <index>2</index>
+        <circuit-pack-name>1/0/ETH-PLUG</circuit-pack-name>
+      </circuit-packs>
+      <connection-ports>
+        <index>1</index>
+        <circuit-pack-name>1/0</circuit-pack-name>
+        <port-name>L1</port-name>
+      </connection-ports>
+    </degree>
+    <degree>
+      <degree-number>2</degree-number>
+      <max-wavelengths>96</max-wavelengths>
+      <circuit-packs>
+        <index>1</index>
+        <circuit-pack-name>2/0</circuit-pack-name>
+      </circuit-packs>
+      <circuit-packs>
+        <index>2</index>
+        <circuit-pack-name>2/0/ETH-PLUG</circuit-pack-name>
+      </circuit-packs>
+      <connection-ports>
+        <index>1</index>
+        <circuit-pack-name>2/0</circuit-pack-name>
+        <port-name>L1</port-name>
+      </connection-ports>
+    </degree>
+    <shared-risk-group>
+      <srg-number>1</srg-number>
+      <max-add-drop-ports>4</max-add-drop-ports>
+      <wavelength-duplication>one-per-srg</wavelength-duplication>
+      <circuit-packs>
+        <index>1</index>
+        <circuit-pack-name>3/0</circuit-pack-name>
+      </circuit-packs>
+      <current-provisioned-add-drop-ports>4</current-provisioned-add-drop-ports>
+    </shared-risk-group>
+    <shared-risk-group>
+      <srg-number>3</srg-number>
+      <max-add-drop-ports>4</max-add-drop-ports>
+      <wavelength-duplication>one-per-srg</wavelength-duplication>
+      <circuit-packs>
+        <index>1</index>
+        <circuit-pack-name>5/0</circuit-pack-name>
+      </circuit-packs>
+      <current-provisioned-add-drop-ports>4</current-provisioned-add-drop-ports>
+    </shared-risk-group>
+  </org-openroadm-device>
+
+  <current-pm-list xmlns="http://org/openroadm/pm">
+  <current-pm-entry>
+    <pm-resource-instance xmlns:d="http://org/openroadm/device">/d:org-openroadm-device/d:interface[d:name='OTS-DEG2-TTP-TXRX']</pm-resource-instance>
+    <pm-resource-type>interface</pm-resource-type>
+    <pm-resource-type-extension></pm-resource-type-extension>
+    <retrieval-time>2018-06-07T13:22:58+00:00</retrieval-time>
+    <current-pm>
+      <type>opticalPowerOutput</type>
+      <extension></extension>
+      <location>nearEnd</location>
+      <direction>tx</direction>
+      <measurement>
+        <granularity>15min</granularity>
+        <pmParameterValue>2.5</pmParameterValue>
+        <pmParameterUnit>dBm</pmParameterUnit>
+        <validity>complete</validity>
+      </measurement>
+      <measurement>
+        <granularity>24Hour</granularity>
+        <pmParameterValue>2.23</pmParameterValue>
+        <pmParameterUnit>dBm</pmParameterUnit>
+        <validity>complete</validity>
+      </measurement>
+    </current-pm>
+    <current-pm>
+      <type>opticalPowerInput</type>
+      <extension></extension>
+      <location>nearEnd</location>
+      <direction>rx</direction>
+      <measurement>
+        <granularity>15min</granularity>
+        <pmParameterValue>-45.1</pmParameterValue>
+        <pmParameterUnit>dBm</pmParameterUnit>
+        <validity>complete</validity>
+      </measurement>
+      <measurement>
+        <granularity>24Hour</granularity>
+        <pmParameterValue>-49.3</pmParameterValue>
+        <pmParameterUnit>dBm</pmParameterUnit>
+        <validity>complete</validity>
+      </measurement>
+    </current-pm>
+    <current-pm>
+      <type>opticalReturnLoss</type>
+      <extension></extension>
+      <location>nearEnd</location>
+      <direction>rx</direction>
+      <measurement>
+        <granularity>15min</granularity>
+        <pmParameterValue>40</pmParameterValue>
+        <pmParameterUnit>dBm</pmParameterUnit>
+        <validity>complete</validity>
+      </measurement>
+      <measurement>
+        <granularity>24Hour</granularity>
+        <pmParameterValue>44</pmParameterValue>
+        <pmParameterUnit>dBm</pmParameterUnit>
+        <validity>complete</validity>
+      </measurement>
+    </current-pm>
+  </current-pm-entry>
+  </current-pm-list>
+
+ </data>
diff --git a/tests/sample_configs/openroadm/2.2.1/oper-ROADMB.xml b/tests/sample_configs/openroadm/2.2.1/oper-ROADMB.xml
new file mode 100644 (file)
index 0000000..4b2efc4
--- /dev/null
@@ -0,0 +1,477 @@
+<?xml version="1.0" encoding="utf-8"?>
+<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+  <netconf xmlns="urn:ietf:params:xml:ns:netmod:notification">
+      <streams>
+          <stream>
+              <name>OPENROADM</name>
+          </stream>
+    </streams>
+  </netconf>
+  <org-openroadm-device xmlns="http://org/openroadm/device">
+     <info>
+      <node-id>ROADM-B1</node-id>
+      <node-number>3</node-number>
+      <node-type>rdm</node-type>
+      <clli>NodeB</clli>
+      <vendor>vendorA</vendor>
+      <model>model2</model>
+      <serial-id>0002</serial-id>
+      <ipAddress>127.0.0.11</ipAddress>
+      <prefix-length>28</prefix-length>
+      <defaultGateway>127.0.0.20</defaultGateway>
+      <source>static</source>
+      <current-ipAddress>127.0.0.11</current-ipAddress>
+      <current-prefix-length>28</current-prefix-length>
+      <current-defaultGateway>127.0.0.20</current-defaultGateway>
+      <macAddress>00:01:02:03:04:05</macAddress>
+      <softwareVersion>swversion1234</softwareVersion>
+      <openroadm-version>2.2.1</openroadm-version>
+      <template>template_1</template>
+      <current-datetime>2017-10-22T15:23:43Z</current-datetime>
+      <max-degrees>2</max-degrees>
+      <max-srgs>3</max-srgs>
+      <geoLocation>
+        <latitude>1.0000</latitude>
+        <longitude>2.0000</longitude>
+      </geoLocation>
+      <max-num-bin-15min-historical-pm>32</max-num-bin-15min-historical-pm>
+      <max-num-bin-24hour-historical-pm>7</max-num-bin-24hour-historical-pm>
+    </info>
+    <users>
+      <user>
+        <name>openroadm</name>
+        <password>openroadm</password>
+        <group>sudo</group>
+      </user>
+    </users>
+    <circuit-packs>
+      <circuit-pack-name>1/0</circuit-pack-name>
+      <circuit-pack-type>WSSDEG</circuit-pack-type>
+      <circuit-pack-product-code>DegW</circuit-pack-product-code>
+      <administrative-state>inService</administrative-state>
+      <vendor>vendorA</vendor>
+      <model>WSS9</model>
+      <serial-id>nodeid-1234</serial-id>
+      <type>Dir1</type>
+      <product-code>DegRxTx</product-code>
+      <manufacture-date>2017-08-08T10:47:04.698808+00:00</manufacture-date>
+      <clei>wss1</clei>
+      <hardware-version>0.1</hardware-version>
+      <operational-state>inService</operational-state>
+      <circuit-pack-category>
+        <type>circuitPack</type>
+      </circuit-pack-category>
+      <equipment-state>not-reserved-available</equipment-state>
+      <circuit-pack-mode>inServiceMode</circuit-pack-mode>
+      <shelf>1</shelf>
+      <slot>1</slot>
+      <cp-slots>
+        <slot-name>OSC-SLOT</slot-name>
+        <label>OSC-SLOT</label>
+        <provisioned-circuit-pack>1/0/OSC-PLUG</provisioned-circuit-pack>
+      </cp-slots>
+      <cp-slots>
+        <slot-name>ETH-PLUG</slot-name>
+        <label>ETH-PLUG</label>
+        <provisioned-circuit-pack>1/0/ETH-PLUG</provisioned-circuit-pack>
+      </cp-slots>
+      <ports>
+        <port-name>C1</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <circuit-id>1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <logical-connection-point>DEG1-CTP-TXRX</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>C2</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <circuit-id>1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <logical-connection-point>DEG1-CTP-TXRX</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>C3</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <circuit-id>1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <logical-connection-point>DEG1-CTP-TXRX</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>C4</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <circuit-id>1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <logical-connection-point>DEG1-CTP-TXRX</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>L1</port-name>
+        <port-type>LINE</port-type>
+        <port-qual>roadm-external</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <label>Dir1-RxTxAMP port</label>
+        <circuit-id>1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <partner-port>
+          <circuit-pack-name></circuit-pack-name>
+          <port-name></port-name>
+        </partner-port>
+        <logical-connection-point>DEG1-TTP-TXRX</logical-connection-point>
+        <supported-interface-capability xmlns:x="http://org/openroadm/port/types">x:if-OTS</supported-interface-capability>
+        <supported-interface-capability xmlns:x="http://org/openroadm/port/types">x:if-OMS</supported-interface-capability>
+        <supported-interface-capability xmlns:x="http://org/openroadm/port/types">x:if-OCH</supported-interface-capability>
+      </ports>
+    </circuit-packs>
+    <circuit-packs>
+      <circuit-pack-name>1/0/ETH-PLUG</circuit-pack-name>
+      <circuit-pack-type>port</circuit-pack-type>
+      <circuit-pack-product-code>Eth</circuit-pack-product-code>
+      <administrative-state>inService</administrative-state>
+      <vendor>VendorA</vendor>
+      <model>GIGAETHMGT</model>
+      <serial-id>nodeid-1234</serial-id>
+      <type>eth</type>
+      <product-code>eth</product-code>
+      <manufacture-date>2017-08-08T10:47:04.698808+00:00</manufacture-date>
+      <clei>ETHE</clei>
+      <hardware-version>0.1</hardware-version>
+      <operational-state>inService</operational-state>
+      <circuit-pack-category>
+        <type>circuitPack</type>
+      </circuit-pack-category>
+      <equipment-state>not-reserved-available</equipment-state>
+      <circuit-pack-mode>inServiceMode</circuit-pack-mode>
+      <shelf>1</shelf>
+      <slot>1</slot>
+      <subSlot>0</subSlot>
+      <parent-circuit-pack>
+        <circuit-pack-name>1/0</circuit-pack-name>
+        <cp-slot-name>ETH-PLUG</cp-slot-name>
+      </parent-circuit-pack>
+      <ports>
+        <port-name>ETH-PLUG</port-name>
+        <port-type>1GEX</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+      </ports>
+    </circuit-packs>
+    <circuit-packs>
+      <circuit-pack-name>1/0/OSC-PLUG</circuit-pack-name>
+      <circuit-pack-type>port</circuit-pack-type>
+      <administrative-state>inService</administrative-state>
+      <vendor>vendorA</vendor>
+      <model>SFP/SFP+</model>
+      <serial-id>00000163600843</serial-id>
+      <product-code>oooooo</product-code>
+      <manufacture-date>2017-08-08T10:47:04.698808+00:00</manufacture-date>
+      <clei>oscplug</clei>
+      <hardware-version>01</hardware-version>
+      <equipment-state>not-reserved-available</equipment-state>
+      <circuit-pack-mode>NORMAL</circuit-pack-mode>
+      <shelf>2</shelf>
+      <slot>0</slot>
+      <subSlot>0</subSlot>
+      <parent-circuit-pack>
+        <circuit-pack-name>1/0</circuit-pack-name>
+        <cp-slot-name>OSC-SLOT</cp-slot-name>
+      </parent-circuit-pack>
+      <ports>
+        <port-name>OSC-PORT</port-name>
+        <port-type>1GEX</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+      </ports>
+    </circuit-packs>
+    <circuit-packs>
+      <circuit-pack-name>2/0</circuit-pack-name>
+      <circuit-pack-type>WSSDEG</circuit-pack-type>
+      <circuit-pack-product-code>DegE</circuit-pack-product-code>
+      <administrative-state>inService</administrative-state>
+      <vendor>vendorA</vendor>
+      <model>WSS9</model>
+      <serial-id>nodeid-1234</serial-id>
+      <type>Dir2</type>
+      <product-code>DegRxTx</product-code>
+      <manufacture-date>2017-08-08T10:47:04.698808+00:00</manufacture-date>
+      <clei>wss1</clei>
+      <hardware-version>0.1</hardware-version>
+      <operational-state>inService</operational-state>
+      <circuit-pack-category>
+        <type>circuitPack</type>
+      </circuit-pack-category>
+      <equipment-state>not-reserved-available</equipment-state>
+      <circuit-pack-mode>inServiceMode</circuit-pack-mode>
+      <shelf>1</shelf>
+      <slot>2</slot>
+      <cp-slots>
+        <slot-name>OSC-SLOT</slot-name>
+        <label>OSC-SLOT</label>
+        <provisioned-circuit-pack>2/0/OSC-PLUG</provisioned-circuit-pack>
+      </cp-slots>
+      <cp-slots>
+        <slot-name>ETH-PLUG</slot-name>
+        <label>ETH-PLUG</label>
+        <provisioned-circuit-pack>2/0/ETH-PLUG</provisioned-circuit-pack>
+      </cp-slots>
+      <ports>
+        <port-name>C1</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <circuit-id>1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <logical-connection-point>DEG2-CTP-TXRX</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>C2</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <circuit-id>1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <logical-connection-point>DEG2-CTP-TXRX</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>C3</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <circuit-id>1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <logical-connection-point>DEG2-CTP-TXRX</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>C4</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <circuit-id>1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <logical-connection-point>DEG2-CTP-TXRX</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>L1</port-name>
+        <port-type>LINE</port-type>
+        <port-qual>roadm-external</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <label>Dir2-RxTxAMP port</label>
+        <circuit-id>1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <partner-port>
+          <circuit-pack-name></circuit-pack-name>
+          <port-name></port-name>
+        </partner-port>
+        <logical-connection-point>DEG2-TTP-TXRX</logical-connection-point>
+        <supported-interface-capability xmlns:x="http://org/openroadm/port/types">x:if-OTS</supported-interface-capability>
+        <supported-interface-capability xmlns:x="http://org/openroadm/port/types">x:if-OMS</supported-interface-capability>
+        <supported-interface-capability xmlns:x="http://org/openroadm/port/types">x:if-OCH</supported-interface-capability>
+      </ports>
+    </circuit-packs>
+    <circuit-packs>
+      <circuit-pack-name>2/0/ETH-PLUG</circuit-pack-name>
+      <circuit-pack-type>port</circuit-pack-type>
+      <circuit-pack-product-code>Eth</circuit-pack-product-code>
+      <administrative-state>inService</administrative-state>
+      <vendor>VendorA</vendor>
+      <model>GIGAETHMGT</model>
+      <serial-id>nodeid-1234</serial-id>
+      <type>eth</type>
+      <product-code>eth</product-code>
+      <manufacture-date>2017-08-08T10:47:04.698808+00:00</manufacture-date>
+      <clei>ETHE</clei>
+      <hardware-version>0.1</hardware-version>
+      <operational-state>inService</operational-state>
+      <circuit-pack-category>
+        <type>circuitPack</type>
+      </circuit-pack-category>
+      <equipment-state>not-reserved-available</equipment-state>
+      <circuit-pack-mode>inServiceMode</circuit-pack-mode>
+      <shelf>1</shelf>
+      <slot>2</slot>
+      <subSlot>0</subSlot>
+      <parent-circuit-pack>
+        <circuit-pack-name>2/0</circuit-pack-name>
+        <cp-slot-name>ETH-PLUG</cp-slot-name>
+      </parent-circuit-pack>
+      <ports>
+        <port-name>ETH-PLUG</port-name>
+        <port-type>1GEX</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+      </ports>
+    </circuit-packs>
+    <circuit-packs>
+      <circuit-pack-name>2/0/OSC-PLUG</circuit-pack-name>
+      <circuit-pack-type>port</circuit-pack-type>
+      <administrative-state>inService</administrative-state>
+      <vendor>vendorA</vendor>
+      <model>SFP/SFP+</model>
+      <serial-id>00000163600843</serial-id>
+      <product-code>oooooo</product-code>
+      <manufacture-date>2017-08-08T10:47:04.698808+00:00</manufacture-date>
+      <clei>oscplug</clei>
+      <hardware-version>01</hardware-version>
+      <equipment-state>not-reserved-available</equipment-state>
+      <circuit-pack-mode>NORMAL</circuit-pack-mode>
+      <shelf>1</shelf>
+      <slot>2</slot>
+      <subSlot>0</subSlot>
+      <parent-circuit-pack>
+        <circuit-pack-name>2/0</circuit-pack-name>
+        <cp-slot-name>OSC-SLOT</cp-slot-name>
+      </parent-circuit-pack>
+      <ports>
+        <port-name>OSC-PORT</port-name>
+        <port-type>1GEX</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+      </ports>
+    </circuit-packs>
+
+    <interface>
+      <name>1GE-interface-1</name>
+      <supporting-circuit-pack-name>1/0/ETH-PLUG</supporting-circuit-pack-name>
+      <supporting-port>ETH-PLUG</supporting-port>
+      <type xmlns:openROADM-if="http://org/openroadm/interfaces">openROADM-if:ethernetCsmacd</type>
+      <operational-state>inService</operational-state>
+      <administrative-state>inService</administrative-state>
+      <ethernet xmlns="http://org/openroadm/ethernet-interfaces">
+        <speed>1000</speed>
+        <duplex>full</duplex>
+        <mtu>1800</mtu>
+        <auto-negotiation>enabled</auto-negotiation>
+        <curr-speed>1000</curr-speed>
+        <curr-duplex>FULL</curr-duplex>
+      </ethernet>
+   </interface>
+   <interface>
+      <name>1GE-interface-2</name>
+      <supporting-circuit-pack-name>2/0/ETH-PLUG</supporting-circuit-pack-name>
+      <supporting-port>ETH-PLUG</supporting-port>
+      <type xmlns:openROADM-if="http://org/openroadm/interfaces">openROADM-if:ethernetCsmacd</type>
+      <operational-state>inService</operational-state>
+      <administrative-state>inService</administrative-state>
+      <ethernet xmlns="http://org/openroadm/ethernet-interfaces">
+        <speed>1000</speed>
+        <duplex>full</duplex>
+        <mtu>1800</mtu>
+        <auto-negotiation>enabled</auto-negotiation>
+        <curr-speed>1000</curr-speed>
+        <curr-duplex>FULL</curr-duplex>
+      </ethernet>
+   </interface>
+   <protocols>
+      <lldp xmlns="http://org/openroadm/lldp">
+        <global-config>
+          <adminStatus>enable</adminStatus>
+          <msgTxHoldMultiplier>4</msgTxHoldMultiplier>
+          <msgTxInterval>20</msgTxInterval>
+        </global-config>
+        <nbr-list>
+          <if-name>
+            <ifName>1GE-interface-1</ifName>
+            <remoteSysName>ROADM-A1</remoteSysName>
+            <remoteMgmtAddress>1.1.1.1</remoteMgmtAddress>
+            <remoteChassisId>1?</remoteChassisId>
+            <remotePortId>1GE-interface-1</remotePortId>
+            <remoteChassisIdSubType>chassiscomponent</remoteChassisIdSubType>
+            <remotePortIdSubType>ifalias</remotePortIdSubType>
+            <remoteMgmtAddressSubType>ipV4</remoteMgmtAddressSubType>
+          </if-name>
+          <if-name>
+            <ifName>1GE-interface-2</ifName>
+            <remoteSysName>ROADM-C1</remoteSysName>
+            <remoteMgmtAddress>1.1.1.1</remoteMgmtAddress>
+            <remoteChassisId>1?</remoteChassisId>
+            <remotePortId>1GE-interface-2</remotePortId>
+            <remoteChassisIdSubType>chassiscomponent</remoteChassisIdSubType>
+            <remotePortIdSubType>ifalias</remotePortIdSubType>
+            <remoteMgmtAddressSubType>ipV4</remoteMgmtAddressSubType>
+          </if-name>
+        </nbr-list>
+        <port-config>
+          <ifName>1GE-interface-1</ifName>
+          <adminStatus>txandrx</adminStatus>
+        </port-config>
+        <port-config>
+          <ifName>1GE-interface-2</ifName>
+          <adminStatus>txandrx</adminStatus>
+        </port-config>
+      </lldp>
+    </protocols>
+
+    <degree>
+      <degree-number>1</degree-number>
+      <max-wavelengths>96</max-wavelengths>
+      <circuit-packs>
+        <index>1</index>
+        <circuit-pack-name>1/0</circuit-pack-name>
+      </circuit-packs>
+      <circuit-packs>
+        <index>2</index>
+        <circuit-pack-name>1/0/ETH-PLUG</circuit-pack-name>
+      </circuit-packs>
+      <connection-ports>
+        <index>1</index>
+        <circuit-pack-name>1/0</circuit-pack-name>
+        <port-name>L1</port-name>
+      </connection-ports>
+    </degree>
+    <degree>
+      <degree-number>2</degree-number>
+      <max-wavelengths>96</max-wavelengths>
+      <circuit-packs>
+        <index>1</index>
+        <circuit-pack-name>2/0</circuit-pack-name>
+      </circuit-packs>
+      <circuit-packs>
+        <index>2</index>
+        <circuit-pack-name>2/0/ETH-PLUG</circuit-pack-name>
+      </circuit-packs>
+      <connection-ports>
+        <index>1</index>
+        <circuit-pack-name>2/0</circuit-pack-name>
+        <port-name>L1</port-name>
+      </connection-ports>
+    </degree>
+  </org-openroadm-device>
+ </data>
diff --git a/tests/sample_configs/openroadm/2.2.1/oper-ROADMC.xml b/tests/sample_configs/openroadm/2.2.1/oper-ROADMC.xml
new file mode 100644 (file)
index 0000000..0a09b8c
--- /dev/null
@@ -0,0 +1,689 @@
+<?xml version="1.0" encoding="utf-8"?>
+<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+  <netconf xmlns="urn:ietf:params:xml:ns:netmod:notification">
+      <streams>
+          <stream>
+              <name>OPENROADM</name>
+          </stream>
+    </streams>
+  </netconf>
+  <org-openroadm-device xmlns="http://org/openroadm/device">
+     <info>
+      <node-id>ROADM-C1</node-id>
+      <node-number>4</node-number>
+      <node-type>rdm</node-type>
+      <clli>NodeC</clli>
+      <vendor>vendorA</vendor>
+      <model>model2</model>
+      <serial-id>0002</serial-id>
+      <ipAddress>127.0.0.11</ipAddress>
+      <prefix-length>28</prefix-length>
+      <defaultGateway>127.0.0.20</defaultGateway>
+      <source>static</source>
+      <current-ipAddress>127.0.0.11</current-ipAddress>
+      <current-prefix-length>28</current-prefix-length>
+      <current-defaultGateway>127.0.0.20</current-defaultGateway>
+      <macAddress>00:01:02:03:04:05</macAddress>
+      <softwareVersion>swversion1234</softwareVersion>
+      <openroadm-version>2.2.1</openroadm-version>
+      <template>template_1</template>
+      <current-datetime>2017-10-22T15:23:43Z</current-datetime>
+      <max-degrees>2</max-degrees>
+      <max-srgs>3</max-srgs>
+      <geoLocation>
+        <latitude>1.0000</latitude>
+        <longitude>2.0000</longitude>
+      </geoLocation>
+      <max-num-bin-15min-historical-pm>32</max-num-bin-15min-historical-pm>
+      <max-num-bin-24hour-historical-pm>7</max-num-bin-24hour-historical-pm>
+    </info>
+    <users>
+      <user>
+        <name>openroadm</name>
+        <password>openroadm</password>
+        <group>sudo</group>
+      </user>
+    </users>
+    <circuit-packs>
+      <circuit-pack-name>1/0</circuit-pack-name>
+      <circuit-pack-type>WSSDEG</circuit-pack-type>
+      <circuit-pack-product-code>DegW</circuit-pack-product-code>
+      <administrative-state>inService</administrative-state>
+      <vendor>vendorA</vendor>
+      <model>WSS9</model>
+      <serial-id>nodeid-1234</serial-id>
+      <type>Dir1</type>
+      <product-code>DegRxTx</product-code>
+      <manufacture-date>2017-08-08T10:47:04.698808+00:00</manufacture-date>
+      <clei>wss1</clei>
+      <hardware-version>0.1</hardware-version>
+      <operational-state>inService</operational-state>
+      <circuit-pack-category>
+        <type>circuitPack</type>
+      </circuit-pack-category>
+      <equipment-state>not-reserved-available</equipment-state>
+      <circuit-pack-mode>inServiceMode</circuit-pack-mode>
+      <shelf>1</shelf>
+      <slot>1</slot>
+      <cp-slots>
+        <slot-name>OSC-SLOT</slot-name>
+        <label>OSC-SLOT</label>
+        <provisioned-circuit-pack>1/0/OSC-PLUG</provisioned-circuit-pack>
+      </cp-slots>
+      <cp-slots>
+        <slot-name>ETH-PLUG</slot-name>
+        <label>ETH-PLUG</label>
+        <provisioned-circuit-pack>1/0/ETH-PLUG</provisioned-circuit-pack>
+      </cp-slots>
+      <ports>
+        <port-name>C1</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <circuit-id>1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <logical-connection-point>DEG1-CTP-TXRX</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>C2</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <circuit-id>1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <logical-connection-point>DEG1-CTP-TXRX</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>C3</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <circuit-id>1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <logical-connection-point>DEG1-CTP-TXRX</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>C4</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <circuit-id>1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <logical-connection-point>DEG1-CTP-TXRX</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>L1</port-name>
+        <port-type>LINE</port-type>
+        <port-qual>roadm-external</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <label>Dir1-RxTxAMP port</label>
+        <circuit-id>1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <partner-port>
+          <circuit-pack-name></circuit-pack-name>
+          <port-name></port-name>
+        </partner-port>
+        <interfaces>
+          <interface-name>OTS-DEG1-TTP-TXRX</interface-name>
+        </interfaces>
+        <interfaces>
+          <interface-name>OMS-DEG1-TTP-TXRX</interface-name>
+        </interfaces>
+        <logical-connection-point>DEG1-TTP-TXRX</logical-connection-point>
+        <supported-interface-capability xmlns:x="http://org/openroadm/port/types">x:if-OTS</supported-interface-capability>
+        <supported-interface-capability xmlns:x="http://org/openroadm/port/types">x:if-OMS</supported-interface-capability>
+        <supported-interface-capability xmlns:x="http://org/openroadm/port/types">x:if-OCH</supported-interface-capability>
+      </ports>
+    </circuit-packs>
+    <circuit-packs>
+      <circuit-pack-name>1/0/ETH-PLUG</circuit-pack-name>
+      <circuit-pack-type>port</circuit-pack-type>
+      <circuit-pack-product-code>Eth</circuit-pack-product-code>
+      <administrative-state>inService</administrative-state>
+      <vendor>VENDORA</vendor>
+      <model>GIGAETHMGT</model>
+      <serial-id>nodeid-1234</serial-id>
+      <type>eth</type>
+      <product-code>eth</product-code>
+      <manufacture-date>2017-08-08T10:47:04.698808+00:00</manufacture-date>
+      <clei>ETHE</clei>
+      <hardware-version>0.1</hardware-version>
+      <operational-state>inService</operational-state>
+      <circuit-pack-category>
+        <type>circuitPack</type>
+      </circuit-pack-category>
+      <equipment-state>not-reserved-available</equipment-state>
+      <circuit-pack-mode>inServiceMode</circuit-pack-mode>
+      <shelf>1</shelf>
+      <slot>1</slot>
+      <subSlot>0</subSlot>
+      <parent-circuit-pack>
+        <circuit-pack-name>1/0</circuit-pack-name>
+        <cp-slot-name>ETH-PLUG</cp-slot-name>
+      </parent-circuit-pack>
+      <ports>
+        <port-name>ETH-PLUG</port-name>
+        <port-type>1GEX</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+      </ports>
+    </circuit-packs>
+    <circuit-packs>
+      <circuit-pack-name>1/0/OSC-PLUG</circuit-pack-name>
+      <circuit-pack-type>port</circuit-pack-type>
+      <administrative-state>inService</administrative-state>
+      <vendor>vendorA</vendor>
+      <model>SFP/SFP+</model>
+      <serial-id>00000163600843</serial-id>
+      <product-code>oooooo</product-code>
+      <manufacture-date>2017-08-08T10:47:04.698808+00:00</manufacture-date>
+      <clei>oscplug</clei>
+      <hardware-version>01</hardware-version>
+      <equipment-state>not-reserved-available</equipment-state>
+      <circuit-pack-mode>NORMAL</circuit-pack-mode>
+      <shelf>2</shelf>
+      <slot>0</slot>
+      <subSlot>0</subSlot>
+      <parent-circuit-pack>
+        <circuit-pack-name>1/0</circuit-pack-name>
+        <cp-slot-name>OSC-SLOT</cp-slot-name>
+      </parent-circuit-pack>
+      <ports>
+        <port-name>OSC-PORT</port-name>
+        <port-type>1GEX</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+      </ports>
+    </circuit-packs>
+    <circuit-packs>
+      <circuit-pack-name>2/0</circuit-pack-name>
+      <circuit-pack-type>WSSDEG</circuit-pack-type>
+      <circuit-pack-product-code>DegW</circuit-pack-product-code>
+      <administrative-state>inService</administrative-state>
+      <vendor>vendorA</vendor>
+      <model>WSS9</model>
+      <serial-id>nodeid-1234</serial-id>
+      <type>Dir2</type>
+      <product-code>DegRxTx</product-code>
+      <manufacture-date>2017-08-08T10:47:04.698808+00:00</manufacture-date>
+      <clei>wss1</clei>
+      <hardware-version>0.1</hardware-version>
+      <operational-state>inService</operational-state>
+      <circuit-pack-category>
+        <type>circuitPack</type>
+      </circuit-pack-category>
+      <equipment-state>not-reserved-available</equipment-state>
+      <circuit-pack-mode>inServiceMode</circuit-pack-mode>
+      <shelf>1</shelf>
+      <slot>2</slot>
+      <cp-slots>
+        <slot-name>OSC-SLOT</slot-name>
+        <label>OSC-SLOT</label>
+        <provisioned-circuit-pack>2/0/OSC-PLUG</provisioned-circuit-pack>
+      </cp-slots>
+      <cp-slots>
+        <slot-name>ETH-PLUG</slot-name>
+        <label>ETH-PLUG</label>
+        <provisioned-circuit-pack>1/0/ETH-PLUG</provisioned-circuit-pack>
+      </cp-slots>
+      <ports>
+        <port-name>C1</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <circuit-id>1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <logical-connection-point>DEG2-CTP-TXRX</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>C2</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <circuit-id>1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <logical-connection-point>DEG2-CTP-TXRX</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>C3</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <circuit-id>1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <logical-connection-point>DEG2-CTP-TXRX</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>C4</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <circuit-id>1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <logical-connection-point>DEG2-CTP-TXRX</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>L1</port-name>
+        <port-type>LINE</port-type>
+        <port-qual>roadm-external</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <label>Dir2-RxTxAMP port</label>
+        <circuit-id>1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <partner-port>
+          <circuit-pack-name></circuit-pack-name>
+          <port-name></port-name>
+        </partner-port>
+        <logical-connection-point>DEG2-TTP-TXRX</logical-connection-point>
+        <supported-interface-capability xmlns:x="http://org/openroadm/port/types">x:if-OTS</supported-interface-capability>
+        <supported-interface-capability xmlns:x="http://org/openroadm/port/types">x:if-OMS</supported-interface-capability>
+        <supported-interface-capability xmlns:x="http://org/openroadm/port/types">x:if-OCH</supported-interface-capability>
+      </ports>
+    </circuit-packs>
+    <circuit-packs>
+      <circuit-pack-name>2/0/ETH-PLUG</circuit-pack-name>
+      <circuit-pack-type>port</circuit-pack-type>
+      <circuit-pack-product-code>Eth</circuit-pack-product-code>
+      <administrative-state>inService</administrative-state>
+      <vendor>VendorA</vendor>
+      <model>GIGAETHMGT</model>
+      <serial-id>nodeid-1234</serial-id>
+      <type>eth</type>
+      <product-code>eth</product-code>
+      <manufacture-date>2017-08-08T10:47:04.698808+00:00</manufacture-date>
+      <clei>ETHE</clei>
+      <hardware-version>0.1</hardware-version>
+      <operational-state>inService</operational-state>
+      <circuit-pack-category>
+        <type>circuitPack</type>
+      </circuit-pack-category>
+      <equipment-state>not-reserved-available</equipment-state>
+      <circuit-pack-mode>inServiceMode</circuit-pack-mode>
+      <shelf>1</shelf>
+      <slot>2</slot>
+      <subSlot>0</subSlot>
+      <parent-circuit-pack>
+        <circuit-pack-name>2/0</circuit-pack-name>
+        <cp-slot-name>ETH-PLUG</cp-slot-name>
+      </parent-circuit-pack>
+      <ports>
+        <port-name>ETH-PLUG</port-name>
+        <port-type>1GEX</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+      </ports>
+    </circuit-packs>
+    <circuit-packs>
+      <circuit-pack-name>2/0/OSC-PLUG</circuit-pack-name>
+      <circuit-pack-type>port</circuit-pack-type>
+      <administrative-state>inService</administrative-state>
+      <vendor>vendorA</vendor>
+      <model>SFP/SFP+</model>
+      <serial-id>00000163600843</serial-id>
+      <product-code>oooooo</product-code>
+      <manufacture-date>2017-08-08T10:47:04.698808+00:00</manufacture-date>
+      <clei>oscplug</clei>
+      <hardware-version>01</hardware-version>
+      <equipment-state>not-reserved-available</equipment-state>
+      <circuit-pack-mode>NORMAL</circuit-pack-mode>
+      <shelf>2</shelf>
+      <slot>0</slot>
+      <subSlot>0</subSlot>
+      <parent-circuit-pack>
+        <circuit-pack-name>1/0</circuit-pack-name>
+        <cp-slot-name>OSC-SLOT</cp-slot-name>
+      </parent-circuit-pack>
+      <ports>
+        <port-name>OSC-PORT</port-name>
+        <port-type>1GEX</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+      </ports>
+    </circuit-packs>
+    <circuit-packs>
+      <circuit-pack-name>3/0</circuit-pack-name>
+      <circuit-pack-type>ADDDROP</circuit-pack-type>
+      <circuit-pack-product-code>SRGRx</circuit-pack-product-code>
+      <administrative-state>inService</administrative-state>
+      <vendor>vendorA</vendor>
+      <model>WSS</model>
+      <serial-id>nodeid-1234</serial-id>
+      <type>SRG1</type>
+      <product-code>SRGRx</product-code>
+      <manufacture-date>2007-10-10T00:00:00Z</manufacture-date>
+      <clei>12345678901</clei>
+      <hardware-version>0.1</hardware-version>
+      <operational-state>inService</operational-state>
+      <circuit-pack-category>
+        <type>circuitPack</type>
+      </circuit-pack-category>
+      <equipment-state>reserved-for-facility-available</equipment-state>
+      <circuit-pack-mode>inServiceMode</circuit-pack-mode>
+      <shelf>1</shelf>
+      <slot>2</slot>
+      <ports>
+        <port-name>C1</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-external</port-qual>
+        <port-wavelength-type>wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <label>SRG1-client port 1</label>
+        <circuit-id>SRG1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <partner-port>
+          <circuit-pack-name></circuit-pack-name>
+          <port-name></port-name>
+        </partner-port>
+        <logical-connection-point>SRG1-PP1</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>C2</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-external</port-qual>
+        <port-wavelength-type>wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <label>SRG1-client port 2</label>
+        <circuit-id>SRG1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <partner-port>
+          <circuit-pack-name></circuit-pack-name>
+          <port-name></port-name>
+        </partner-port>
+        <logical-connection-point>SRG1-PP2</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>C3</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-external</port-qual>
+        <port-wavelength-type>wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <label>SRG1-client port 3</label>
+        <circuit-id>SRG1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <partner-port>
+          <circuit-pack-name></circuit-pack-name>
+          <port-name></port-name>
+        </partner-port>
+        <logical-connection-point>SRG1-PP3</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>C4</port-name>
+        <port-type>Client</port-type>
+        <port-qual>roadm-external</port-qual>
+        <port-wavelength-type>wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <label>SRG1-client port 4</label>
+        <circuit-id>SRG1</circuit-id>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <partner-port>
+          <circuit-pack-name></circuit-pack-name>
+          <port-name></port-name>
+        </partner-port>
+        <logical-connection-point>SRG1-PP4</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>AD-DEG1</port-name>
+        <port-type>Edge</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <logical-connection-point>SRG1-CP-TXRX</logical-connection-point>
+      </ports>
+      <ports>
+        <port-name>AD-DEG2</port-name>
+        <port-type>Edge</port-type>
+        <port-qual>roadm-internal</port-qual>
+        <port-wavelength-type>multi-wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <logical-connection-point>SRG1-CP-TXRX</logical-connection-point>
+      </ports>
+    </circuit-packs>
+
+    <interface>
+      <name>1GE-interface-1</name>
+      <supporting-circuit-pack-name>1/0/ETH-PLUG</supporting-circuit-pack-name>
+      <supporting-port>ETH-PLUG</supporting-port>
+      <type xmlns:openROADM-if="http://org/openroadm/interfaces">openROADM-if:ethernetCsmacd</type>
+      <operational-state>inService</operational-state>
+      <administrative-state>inService</administrative-state>
+      <ethernet xmlns="http://org/openroadm/ethernet-interfaces">
+        <speed>1000</speed>
+        <duplex>full</duplex>
+        <mtu>1800</mtu>
+        <auto-negotiation>enabled</auto-negotiation>
+        <curr-speed>1000</curr-speed>
+        <curr-duplex>FULL</curr-duplex>
+      </ethernet>
+   </interface>
+   <interface>
+      <name>1GE-interface-2</name>
+      <supporting-circuit-pack-name>2/0/ETH-PLUG</supporting-circuit-pack-name>
+      <supporting-port>ETH-PLUG</supporting-port>
+      <type xmlns:openROADM-if="http://org/openroadm/interfaces">openROADM-if:ethernetCsmacd</type>
+      <operational-state>inService</operational-state>
+      <administrative-state>inService</administrative-state>
+      <ethernet xmlns="http://org/openroadm/ethernet-interfaces">
+        <speed>1000</speed>
+        <duplex>full</duplex>
+        <mtu>1800</mtu>
+        <auto-negotiation>enabled</auto-negotiation>
+        <curr-speed>1000</curr-speed>
+        <curr-duplex>FULL</curr-duplex>
+      </ethernet>
+   </interface>
+   <interface>
+      <name>OTS-DEG1-TTP-TXRX</name>
+      <supporting-circuit-pack-name>1/0</supporting-circuit-pack-name>
+      <supporting-port>L1</supporting-port>
+      <type xmlns:openROADM-if="http://org/openroadm/interfaces">openROADM-if:opticalTransport</type>
+      <operational-state>inService</operational-state>
+      <administrative-state>inService</administrative-state>
+      <ots xmlns="http://org/openroadm/optical-transport-interfaces">
+        <fiber-type>smf</fiber-type>
+        <span-loss-transmit>6</span-loss-transmit>
+        <span-loss-receive>15</span-loss-receive>
+        <ingress-span-loss-aging-margin>0</ingress-span-loss-aging-margin>
+      </ots>
+   </interface>
+    <interface>
+      <name>OMS-DEG1-TTP-TXRX</name>
+      <supporting-circuit-pack-name>1/0</supporting-circuit-pack-name>
+      <supporting-port>L1</supporting-port>
+      <supporting-interface>OTS-DEG1-TTP-TXRX</supporting-interface>      
+      <type xmlns:openROADM-if="http://org/openroadm/interfaces">openROADM-if:openROADMOpticalMultiplex</type> 
+      <description>TBD</description>      
+      <circuit-id>TBD</circuit-id>
+      <operational-state>inService</operational-state>
+      <administrative-state>inService</administrative-state>      
+    </interface>
+
+    <protocols>
+      <lldp xmlns="http://org/openroadm/lldp">
+        <global-config>
+          <adminStatus>enable</adminStatus>
+          <msgTxHoldMultiplier>4</msgTxHoldMultiplier>
+          <msgTxInterval>20</msgTxInterval>
+        </global-config>
+        <nbr-list>
+          <if-name>
+            <ifName>1GE-interface-1</ifName>
+            <remoteSysName>ROADM-A1</remoteSysName>
+            <remoteMgmtAddress>1.1.1.1</remoteMgmtAddress>
+            <remoteChassisId>1?</remoteChassisId>
+            <remotePortId>1GE-interface-2</remotePortId>
+            <remoteChassisIdSubType>chassiscomponent</remoteChassisIdSubType>
+            <remotePortIdSubType>ifalias</remotePortIdSubType>
+            <remoteMgmtAddressSubType>ipV4</remoteMgmtAddressSubType>
+          </if-name>
+          <if-name>
+            <ifName>1GE-interface-2</ifName>
+            <remoteSysName>ROADM-B1</remoteSysName>
+            <remoteMgmtAddress>1.1.1.1</remoteMgmtAddress>
+            <remoteChassisId>1?</remoteChassisId>
+            <remotePortId>1GE-interface-2</remotePortId>
+            <remoteChassisIdSubType>chassiscomponent</remoteChassisIdSubType>
+            <remotePortIdSubType>ifalias</remotePortIdSubType>
+            <remoteMgmtAddressSubType>ipV4</remoteMgmtAddressSubType>
+          </if-name>
+        </nbr-list>
+        <port-config>
+          <ifName>1GE-interface-1</ifName>
+          <adminStatus>txandrx</adminStatus>
+        </port-config>
+        <port-config>
+          <ifName>1GE-interface-2</ifName>
+          <adminStatus>txandrx</adminStatus>
+        </port-config>
+      </lldp>
+    </protocols>
+
+    <degree>
+      <degree-number>1</degree-number>
+      <max-wavelengths>96</max-wavelengths>
+      <circuit-packs>
+        <index>1</index>
+        <circuit-pack-name>1/0</circuit-pack-name>
+      </circuit-packs>
+      <circuit-packs>
+        <index>2</index>
+        <circuit-pack-name>1/0/ETH-PLUG</circuit-pack-name>
+      </circuit-packs>
+      <connection-ports>
+        <index>1</index>
+        <circuit-pack-name>1/0</circuit-pack-name>
+        <port-name>L1</port-name>
+      </connection-ports>
+    </degree>
+    <degree>
+      <degree-number>2</degree-number>
+      <max-wavelengths>96</max-wavelengths>
+      <circuit-packs>
+        <index>1</index>
+        <circuit-pack-name>2/0</circuit-pack-name>
+      </circuit-packs>
+      <circuit-packs>
+        <index>2</index>
+        <circuit-pack-name>2/0/ETH-PLUG</circuit-pack-name>
+      </circuit-packs>
+      <connection-ports>
+        <index>1</index>
+        <circuit-pack-name>2/0</circuit-pack-name>
+        <port-name>L1</port-name>
+      </connection-ports>
+    </degree>
+    <shared-risk-group>
+      <srg-number>1</srg-number>
+      <max-add-drop-ports>4</max-add-drop-ports>
+      <wavelength-duplication>one-per-srg</wavelength-duplication>
+      <circuit-packs>
+        <index>1</index>
+        <circuit-pack-name>3/0</circuit-pack-name>
+      </circuit-packs>
+      <current-provisioned-add-drop-ports>4</current-provisioned-add-drop-ports>
+    </shared-risk-group>
+  </org-openroadm-device>
+
+  <current-pm-list xmlns="http://org/openroadm/pm">
+  <current-pm-entry>
+    <pm-resource-instance xmlns:d="http://org/openroadm/device">/d:org-openroadm-device/d:interface[d:name='OTS-DEG1-TTP-TXRX']</pm-resource-instance>
+    <pm-resource-type>interface</pm-resource-type>
+    <pm-resource-type-extension></pm-resource-type-extension>
+    <retrieval-time>2018-06-07T13:22:58+00:00</retrieval-time>
+    <current-pm>
+      <type>opticalPowerOutput</type>
+      <extension></extension>
+      <location>nearEnd</location>
+      <direction>tx</direction>
+      <measurement>
+        <granularity>15min</granularity>
+        <pmParameterValue>4.6</pmParameterValue>
+        <pmParameterUnit>dBm</pmParameterUnit>
+        <validity>complete</validity>
+      </measurement>
+      <measurement>
+        <granularity>24Hour</granularity>
+        <pmParameterValue>3.26</pmParameterValue>
+        <pmParameterUnit>dBm</pmParameterUnit>
+        <validity>complete</validity>
+      </measurement>
+    </current-pm>
+    <current-pm>
+      <type>opticalPowerInput</type>
+      <extension></extension>
+      <location>nearEnd</location>
+      <direction>rx</direction>
+      <measurement>
+        <granularity>15min</granularity>
+        <pmParameterValue>-15.1</pmParameterValue>
+        <pmParameterUnit>dBm</pmParameterUnit>
+        <validity>complete</validity>
+      </measurement>
+      <measurement>
+        <granularity>24Hour</granularity>
+        <pmParameterValue>-17.3</pmParameterValue>
+        <pmParameterUnit>dBm</pmParameterUnit>
+        <validity>complete</validity>
+      </measurement>
+    </current-pm>
+    <current-pm>
+      <type>opticalReturnLoss</type>
+      <extension></extension>
+      <location>nearEnd</location>
+      <direction>rx</direction>
+      <measurement>
+        <granularity>15min</granularity>
+        <pmParameterValue>49.1</pmParameterValue>
+        <pmParameterUnit>dBm</pmParameterUnit>
+        <validity>complete</validity>
+      </measurement>
+      <measurement>
+        <granularity>24Hour</granularity>
+        <pmParameterValue>45</pmParameterValue>
+        <pmParameterUnit>dBm</pmParameterUnit>
+        <validity>complete</validity>
+      </measurement>
+    </current-pm>
+  </current-pm-entry>
+  </current-pm-list>
+
+ </data>
diff --git a/tests/sample_configs/openroadm/2.2.1/oper-XPDRA.xml b/tests/sample_configs/openroadm/2.2.1/oper-XPDRA.xml
new file mode 100644 (file)
index 0000000..b8fa22f
--- /dev/null
@@ -0,0 +1,346 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+  <netconf xmlns="urn:ietf:params:xml:ns:netmod:notification">
+  <streams>
+    <stream>
+      <name>OPENROADM</name>
+    </stream>
+  </streams>
+</netconf>
+  <org-openroadm-device xmlns="http://org/openroadm/device">
+    <info>
+      <node-id>XPDR-A1</node-id>
+      <node-number>1</node-number>
+      <node-type>xpdr</node-type>
+      <clli>NodeA</clli>
+      <vendor>vendorA</vendor>
+      <model>model2</model>
+      <serial-id>nodeid-1234</serial-id>
+      <ipAddress>1.2.3.4</ipAddress>
+      <prefix-length>24</prefix-length>
+      <defaultGateway>1.2.3.4</defaultGateway>
+      <source>static</source>
+      <current-ipAddress>1.2.3.4</current-ipAddress>
+      <current-prefix-length>10</current-prefix-length>
+      <current-defaultGateway>1.2.3.1</current-defaultGateway>
+      <macAddress>00:01:02:03:04:05</macAddress>
+      <softwareVersion>swversion1234</softwareVersion>
+      <openroadm-version>2.2</openroadm-version>
+      <template>template_TRANSPONDER</template>
+      <current-datetime>2017-10-22T15:23:43Z</current-datetime>
+      <geoLocation>
+        <latitude>1.0000</latitude>
+        <longitude>2.0000</longitude>
+      </geoLocation>
+    </info>
+    <users>
+      <user>
+        <name>openroadm</name>
+        <password>openroadm</password>
+        <group>sudo</group>
+      </user>
+    </users>
+    <shelves>
+      <shelf-name>1</shelf-name>
+      <shelf-type>pizza</shelf-type>
+      <rack>XYZ</rack>
+      <shelf-position>1</shelf-position>
+      <administrative-state>inService</administrative-state>
+      <vendor>vendorA</vendor>
+      <model>1</model>
+      <serial-id>nodeid-1</serial-id>
+      <type>pizza</type>
+      <product-code>zzz</product-code>
+      <manufacture-date>2017-04-01T00:00:00+00:00</manufacture-date>
+      <clei>1234567890</clei>
+      <hardware-version>0.1</hardware-version>
+      <operational-state>inService</operational-state>
+      <due-date>2017-02-24T15:56:10+00:00</due-date>
+      <slots>
+        <slot-name>1</slot-name>
+        <label>1</label>
+        <provisioned-circuit-pack>1/0</provisioned-circuit-pack>
+      </slots>
+    </shelves>
+    <circuit-packs>
+      <circuit-pack-name>1/0</circuit-pack-name>
+      <circuit-pack-type>Base_transponder_circuit_pack</circuit-pack-type>
+      <circuit-pack-product-code>baseXPDR</circuit-pack-product-code>
+      <administrative-state>inService</administrative-state>
+      <vendor>VendorA</vendor>
+      <model>model1</model>
+      <serial-id>nodeid-1234</serial-id>
+      <type>XPDR1</type>
+      <product-code>baseXPDR</product-code>
+      <manufacture-date>2007-10-10T00:00:00Z</manufacture-date>
+      <clei>12345678901</clei>
+      <hardware-version>0.1</hardware-version>
+      <operational-state>inService</operational-state>
+      <is-pluggable-optics>false</is-pluggable-optics>
+      <circuit-pack-mode>inServiceMode</circuit-pack-mode>
+      <shelf>1</shelf>
+      <slot>1</slot>
+      <cp-slots>
+        <slot-name>1</slot-name>
+        <label>1</label>
+        <provisioned-circuit-pack>1/0/1-PLUG-NET</provisioned-circuit-pack>
+      </cp-slots>
+      <cp-slots>
+        <slot-name>2</slot-name>
+        <label>2</label>
+        <provisioned-circuit-pack>1/0/1-PLUG-CLIENT</provisioned-circuit-pack>
+      </cp-slots>
+      <cp-slots>
+        <slot-name>3</slot-name>
+        <label>1</label>
+        <provisioned-circuit-pack>1/0/2-PLUG-NET</provisioned-circuit-pack>
+      </cp-slots>
+      <cp-slots>
+        <slot-name>4</slot-name>
+        <label>2</label>
+        <provisioned-circuit-pack>1/0/2-PLUG-CLIENT</provisioned-circuit-pack>
+      </cp-slots>
+    </circuit-packs>
+    <circuit-packs>
+      <circuit-pack-name>1/0/1-PLUG-NET</circuit-pack-name>
+      <circuit-pack-type>line_pluggable</circuit-pack-type>
+      <circuit-pack-product-code>Line_NW_P</circuit-pack-product-code>
+      <vendor>VendorA</vendor>
+      <model>CFP2</model>
+      <serial-id>_1234_</serial-id>
+      <type>line/network pluggable</type>
+      <product-code>Line_NW_P</product-code>
+      <hardware-version>0.1</hardware-version>
+      <operational-state>inService</operational-state>
+      <circuit-pack-mode>NORMAL</circuit-pack-mode>
+      <shelf>1</shelf>
+      <slot>1</slot>
+      <subSlot>1</subSlot>
+      <is-pluggable-optics>true</is-pluggable-optics>
+      <ports>
+        <port-name>1</port-name>
+        <port-type>CFP2</port-type>
+        <port-qual>xpdr-network</port-qual>
+        <port-wavelength-type>wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <label>2</label>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <supported-interface-capability xmlns:org-openroadm-port-types="http://org/openroadm/port/types">org-openroadm-port-types:if-OCH</supported-interface-capability>
+        <transponder-port>
+          <port-power-capability-min-rx>-22.00</port-power-capability-min-rx>
+          <port-power-capability-min-tx>-5.00</port-power-capability-min-tx>
+          <port-power-capability-max-rx>1.00</port-power-capability-max-rx>
+          <port-power-capability-max-tx>0.00</port-power-capability-max-tx>
+        </transponder-port>
+      </ports>
+      <parent-circuit-pack>
+        <circuit-pack-name>1/0</circuit-pack-name>
+        <cp-slot-name>1</cp-slot-name>
+      </parent-circuit-pack>
+    </circuit-packs>
+    <circuit-packs>
+      <circuit-pack-name>1/0/1-PLUG-CLIENT</circuit-pack-name>
+      <circuit-pack-type>client_pluggable</circuit-pack-type>
+      <circuit-pack-product-code>Client_P</circuit-pack-product-code>
+      <vendor>VendorA</vendor>
+      <model>client_pluggable</model>
+      <serial-id>_1234_</serial-id>
+      <type>QSFP28</type>
+      <product-code>Client_P</product-code>
+      <hardware-version>0.1</hardware-version>
+      <operational-state>inService</operational-state>
+      <circuit-pack-mode>NORMAL</circuit-pack-mode>
+      <shelf>1</shelf>
+      <slot>1</slot>
+      <subSlot>1</subSlot>
+      <is-pluggable-optics>true</is-pluggable-optics>
+      <ports>
+        <port-name>C1</port-name>
+        <port-type>QSFP28</port-type>
+        <port-qual>xpdr-client</port-qual>
+        <port-wavelength-type>wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <label>2</label>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <supported-interface-capability xmlns:org-openroadm-port-types="http://org/openroadm/port/types">org-openroadm-port-types:if-100GE</supported-interface-capability>
+        <transponder-port>
+          <port-power-capability-min-rx>-4.00</port-power-capability-min-rx>
+          <port-power-capability-min-tx>-10.00</port-power-capability-min-tx>
+          <port-power-capability-max-rx>4.00</port-power-capability-max-rx>
+          <port-power-capability-max-tx>4.00</port-power-capability-max-tx>
+        </transponder-port>
+      </ports>
+      <parent-circuit-pack>
+        <circuit-pack-name>1/0</circuit-pack-name>
+        <cp-slot-name>2</cp-slot-name>
+      </parent-circuit-pack>
+    </circuit-packs>
+    <circuit-packs>
+      <circuit-pack-name>1/0/2-PLUG-NET</circuit-pack-name>
+      <circuit-pack-type>line_pluggable</circuit-pack-type>
+      <circuit-pack-product-code>Line_NW_P</circuit-pack-product-code>
+      <vendor>VendorA</vendor>
+      <model>CFP2</model>
+      <serial-id>_1234_</serial-id>
+      <type>line/network pluggable</type>
+      <product-code>Line_NW_P</product-code>
+      <hardware-version>0.1</hardware-version>
+      <operational-state>inService</operational-state>
+      <circuit-pack-mode>NORMAL</circuit-pack-mode>
+      <shelf>1</shelf>
+      <slot>1</slot>
+      <subSlot>1</subSlot>
+      <is-pluggable-optics>true</is-pluggable-optics>
+      <ports>
+        <port-name>1</port-name>
+        <port-type>CFP2</port-type>
+        <port-qual>xpdr-network</port-qual>
+        <port-wavelength-type>wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <label>2</label>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <supported-interface-capability xmlns:org-openroadm-port-types="http://org/openroadm/port/types">org-openroadm-port-types:if-OCH</supported-interface-capability>
+        <transponder-port>
+          <port-power-capability-min-rx>-22.00</port-power-capability-min-rx>
+          <port-power-capability-min-tx>-5.00</port-power-capability-min-tx>
+          <port-power-capability-max-rx>1.00</port-power-capability-max-rx>
+          <port-power-capability-max-tx>0.00</port-power-capability-max-tx>
+        </transponder-port>
+      </ports>
+      <parent-circuit-pack>
+        <circuit-pack-name>1/0</circuit-pack-name>
+        <cp-slot-name>3</cp-slot-name>
+      </parent-circuit-pack>
+    </circuit-packs>
+    <circuit-packs>
+      <circuit-pack-name>1/0/2-PLUG-CLIENT</circuit-pack-name>
+      <circuit-pack-type>client_pluggable</circuit-pack-type>
+      <circuit-pack-product-code>Client_P</circuit-pack-product-code>
+      <vendor>VendorA</vendor>
+      <model>client_pluggable</model>
+      <serial-id>_1234_</serial-id>
+      <type>QSFP28</type>
+      <product-code>Client_P</product-code>
+      <hardware-version>0.1</hardware-version>
+      <operational-state>inService</operational-state>
+      <circuit-pack-mode>NORMAL</circuit-pack-mode>
+      <shelf>1</shelf>
+      <slot>1</slot>
+      <subSlot>1</subSlot>
+      <is-pluggable-optics>true</is-pluggable-optics>
+      <ports>
+        <port-name>C1</port-name>
+        <port-type>QSFP28</port-type>
+        <port-qual>xpdr-client</port-qual>
+        <port-wavelength-type>wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <label>2</label>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <supported-interface-capability xmlns:org-openroadm-port-types="http://org/openroadm/port/types">org-openroadm-port-types:if-100GE</supported-interface-capability>
+        <transponder-port>
+          <port-power-capability-min-rx>-4.00</port-power-capability-min-rx>
+          <port-power-capability-min-tx>-10.00</port-power-capability-min-tx>
+          <port-power-capability-max-rx>4.00</port-power-capability-max-rx>
+          <port-power-capability-max-tx>4.00</port-power-capability-max-tx>
+        </transponder-port>
+      </ports>
+      <parent-circuit-pack>
+        <circuit-pack-name>1/0</circuit-pack-name>
+        <cp-slot-name>4</cp-slot-name>
+      </parent-circuit-pack>
+    </circuit-packs>
+
+    <connection-map>
+      <connection-map-number>1</connection-map-number>
+      <source>
+        <circuit-pack-name>1/0/1-PLUG-CLIENT</circuit-pack-name>
+        <port-name>C1</port-name>
+      </source>
+      <destination>
+        <circuit-pack-name>1/0/1-PLUG-NET</circuit-pack-name>
+        <port-name>1</port-name>
+      </destination>
+    </connection-map>
+    <connection-map>
+      <connection-map-number>2</connection-map-number>
+      <source>
+        <circuit-pack-name>1/0/1-PLUG-NET</circuit-pack-name>
+        <port-name>1</port-name>
+      </source>
+      <destination>
+        <circuit-pack-name>1/0/1-PLUG-CLIENT</circuit-pack-name>
+        <port-name>C1</port-name>
+      </destination>
+    </connection-map>
+    <connection-map>
+      <connection-map-number>3</connection-map-number>
+      <source>
+        <circuit-pack-name>1/0/2-PLUG-CLIENT</circuit-pack-name>
+        <port-name>C1</port-name>
+      </source>
+      <destination>
+        <circuit-pack-name>1/0/2-PLUG-NET</circuit-pack-name>
+        <port-name>1</port-name>
+      </destination>
+    </connection-map>
+    <connection-map>
+      <connection-map-number>4</connection-map-number>
+      <source>
+        <circuit-pack-name>1/0/2-PLUG-NET</circuit-pack-name>
+        <port-name>1</port-name>
+      </source>
+      <destination>
+        <circuit-pack-name>1/0/2-PLUG-CLIENT</circuit-pack-name>
+        <port-name>C1</port-name>
+      </destination>
+    </connection-map>
+  </org-openroadm-device>
+  <current-pm-list xmlns="http://org/openroadm/pm">
+  <current-pm-entry>
+    <pm-resource-instance xmlns:d="http://org/openroadm/device">/d:org-openroadm-device/d:interface[d:name='XPDR1-NETWORK1-OTU']</pm-resource-instance>
+    <pm-resource-type>interface</pm-resource-type>
+    <pm-resource-type-extension></pm-resource-type-extension>
+    <retrieval-time>2018-06-07T13:22:58+00:00</retrieval-time>
+    <current-pm>
+      <type>opticalPowerOutput</type>
+      <extension></extension>
+      <location>nearEnd</location>
+      <direction>tx</direction>
+      <measurement>
+        <granularity>15min</granularity>
+        <pmParameterValue>2.5</pmParameterValue>
+        <pmParameterUnit>dBm</pmParameterUnit>
+        <validity>complete</validity>
+      </measurement>
+      <measurement>
+        <granularity>24Hour</granularity>
+        <pmParameterValue>2.23</pmParameterValue>
+        <pmParameterUnit>dBm</pmParameterUnit>
+        <validity>complete</validity>
+      </measurement>
+    </current-pm>
+    <current-pm>
+      <type>opticalPowerInput</type>
+      <extension></extension>
+      <location>nearEnd</location>
+      <direction>rx</direction>
+      <measurement>
+        <granularity>15min</granularity>
+        <pmParameterValue>-45.1</pmParameterValue>
+        <pmParameterUnit>dBm</pmParameterUnit>
+        <validity>complete</validity>
+      </measurement>
+      <measurement>
+        <granularity>24Hour</granularity>
+        <pmParameterValue>-49.3</pmParameterValue>
+        <pmParameterUnit>dBm</pmParameterUnit>
+        <validity>complete</validity>
+      </measurement>
+    </current-pm>
+  </current-pm-entry>
+</current-pm-list>
+</data>
diff --git a/tests/sample_configs/openroadm/2.2.1/oper-XPDRC.xml b/tests/sample_configs/openroadm/2.2.1/oper-XPDRC.xml
new file mode 100644 (file)
index 0000000..b0d1969
--- /dev/null
@@ -0,0 +1,346 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+  <netconf xmlns="urn:ietf:params:xml:ns:netmod:notification">
+  <streams>
+    <stream>
+      <name>OPENROADM</name>
+    </stream>
+  </streams>
+</netconf>
+  <org-openroadm-device xmlns="http://org/openroadm/device">
+    <info>
+      <node-id>XPDR-C1</node-id>
+      <node-number>1</node-number>
+      <node-type>xpdr</node-type>
+      <clli>NodeC</clli>
+      <vendor>vendorA</vendor>
+      <model>model2</model>
+      <serial-id>nodeid-1234</serial-id>
+      <ipAddress>1.2.3.4</ipAddress>
+      <prefix-length>24</prefix-length>
+      <defaultGateway>1.2.3.4</defaultGateway>
+      <source>static</source>
+      <current-ipAddress>1.2.3.4</current-ipAddress>
+      <current-prefix-length>10</current-prefix-length>
+      <current-defaultGateway>1.2.3.1</current-defaultGateway>
+      <macAddress>00:01:02:03:04:05</macAddress>
+      <softwareVersion>swversion1234</softwareVersion>
+      <openroadm-version>2.2</openroadm-version>
+      <template>template_TRANSPONDER</template>
+      <current-datetime>2017-10-22T15:23:43Z</current-datetime>
+      <geoLocation>
+        <latitude>1.0000</latitude>
+        <longitude>2.0000</longitude>
+      </geoLocation>
+    </info>
+    <users>
+      <user>
+        <name>openroadm</name>
+        <password>openroadm</password>
+        <group>sudo</group>
+      </user>
+    </users>
+    <shelves>
+      <shelf-name>1</shelf-name>
+      <shelf-type>pizza</shelf-type>
+      <rack>XYZ</rack>
+      <shelf-position>1</shelf-position>
+      <administrative-state>inService</administrative-state>
+      <vendor>vendorA</vendor>
+      <model>1</model>
+      <serial-id>nodeid-1</serial-id>
+      <type>pizza</type>
+      <product-code>zzz</product-code>
+      <manufacture-date>2017-04-01T00:00:00+00:00</manufacture-date>
+      <clei>1234567890</clei>
+      <hardware-version>0.1</hardware-version>
+      <operational-state>inService</operational-state>
+      <due-date>2017-02-24T15:56:10+00:00</due-date>
+      <slots>
+        <slot-name>1</slot-name>
+        <label>1</label>
+        <provisioned-circuit-pack>1/0</provisioned-circuit-pack>
+      </slots>
+    </shelves>
+    <circuit-packs>
+      <circuit-pack-name>1/0</circuit-pack-name>
+      <circuit-pack-type>Base_transponder_circuit_pack</circuit-pack-type>
+      <circuit-pack-product-code>baseXPDR</circuit-pack-product-code>
+      <administrative-state>inService</administrative-state>
+      <vendor>VendorA</vendor>
+      <model>model1</model>
+      <serial-id>nodeid-1234</serial-id>
+      <type>XPDR1</type>
+      <product-code>baseXPDR</product-code>
+      <manufacture-date>2007-10-10T00:00:00Z</manufacture-date>
+      <clei>12345678901</clei>
+      <hardware-version>0.1</hardware-version>
+      <operational-state>inService</operational-state>
+      <is-pluggable-optics>false</is-pluggable-optics>
+      <circuit-pack-mode>inServiceMode</circuit-pack-mode>
+      <shelf>1</shelf>
+      <slot>1</slot>
+      <cp-slots>
+        <slot-name>1</slot-name>
+        <label>1</label>
+        <provisioned-circuit-pack>1/0/1-PLUG-NET</provisioned-circuit-pack>
+      </cp-slots>
+      <cp-slots>
+        <slot-name>2</slot-name>
+        <label>2</label>
+        <provisioned-circuit-pack>1/0/1-PLUG-CLIENT</provisioned-circuit-pack>
+      </cp-slots>
+      <cp-slots>
+        <slot-name>3</slot-name>
+        <label>1</label>
+        <provisioned-circuit-pack>1/0/2-PLUG-NET</provisioned-circuit-pack>
+      </cp-slots>
+      <cp-slots>
+        <slot-name>4</slot-name>
+        <label>2</label>
+        <provisioned-circuit-pack>1/0/3-PLUG-CLIENT</provisioned-circuit-pack>
+      </cp-slots>
+    </circuit-packs>
+    <circuit-packs>
+      <circuit-pack-name>1/0/1-PLUG-NET</circuit-pack-name>
+      <circuit-pack-type>line_pluggable</circuit-pack-type>
+      <circuit-pack-product-code>Line_NW_P</circuit-pack-product-code>
+      <vendor>VendorA</vendor>
+      <model>CFP2</model>
+      <serial-id>_1234_</serial-id>
+      <type>line/network pluggable</type>
+      <product-code>Line_NW_P</product-code>
+      <hardware-version>0.1</hardware-version>
+      <operational-state>inService</operational-state>
+      <circuit-pack-mode>NORMAL</circuit-pack-mode>
+      <shelf>1</shelf>
+      <slot>1</slot>
+      <subSlot>1</subSlot>
+      <is-pluggable-optics>true</is-pluggable-optics>
+      <ports>
+        <port-name>1</port-name>
+        <port-type>CFP2</port-type>
+        <port-qual>xpdr-network</port-qual>
+        <port-wavelength-type>wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <label>2</label>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <supported-interface-capability xmlns:org-openroadm-port-types="http://org/openroadm/port/types">org-openroadm-port-types:if-OCH</supported-interface-capability>
+        <transponder-port>
+          <port-power-capability-min-rx>-22.00</port-power-capability-min-rx>
+          <port-power-capability-min-tx>-5.00</port-power-capability-min-tx>
+          <port-power-capability-max-rx>1.00</port-power-capability-max-rx>
+          <port-power-capability-max-tx>0.00</port-power-capability-max-tx>
+        </transponder-port>
+      </ports>
+      <parent-circuit-pack>
+        <circuit-pack-name>1/0</circuit-pack-name>
+        <cp-slot-name>1</cp-slot-name>
+      </parent-circuit-pack>
+    </circuit-packs>
+    <circuit-packs>
+      <circuit-pack-name>1/0/1-PLUG-CLIENT</circuit-pack-name>
+      <circuit-pack-type>client_pluggable</circuit-pack-type>
+      <circuit-pack-product-code>Client_P</circuit-pack-product-code>
+      <vendor>VendorA</vendor>
+      <model>client_pluggable</model>
+      <serial-id>_1234_</serial-id>
+      <type>QSFP28</type>
+      <product-code>Client_P</product-code>
+      <hardware-version>0.1</hardware-version>
+      <operational-state>inService</operational-state>
+      <circuit-pack-mode>NORMAL</circuit-pack-mode>
+      <shelf>1</shelf>
+      <slot>1</slot>
+      <subSlot>1</subSlot>
+      <is-pluggable-optics>true</is-pluggable-optics>
+      <ports>
+        <port-name>C1</port-name>
+        <port-type>QSFP28</port-type>
+        <port-qual>xpdr-client</port-qual>
+        <port-wavelength-type>wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <label>2</label>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <supported-interface-capability xmlns:org-openroadm-port-types="http://org/openroadm/port/types">org-openroadm-port-types:if-100GE</supported-interface-capability>
+        <transponder-port>
+          <port-power-capability-min-rx>-4.00</port-power-capability-min-rx>
+          <port-power-capability-min-tx>-10.00</port-power-capability-min-tx>
+          <port-power-capability-max-rx>4.00</port-power-capability-max-rx>
+          <port-power-capability-max-tx>4.00</port-power-capability-max-tx>
+        </transponder-port>
+      </ports>
+      <parent-circuit-pack>
+        <circuit-pack-name>1/0</circuit-pack-name>
+        <cp-slot-name>2</cp-slot-name>
+      </parent-circuit-pack>
+    </circuit-packs>
+    <circuit-packs>
+      <circuit-pack-name>1/0/2-PLUG-NET</circuit-pack-name>
+      <circuit-pack-type>line_pluggable</circuit-pack-type>
+      <circuit-pack-product-code>Line_NW_P</circuit-pack-product-code>
+      <vendor>VendorA</vendor>
+      <model>CFP2</model>
+      <serial-id>_1234_</serial-id>
+      <type>line/network pluggable</type>
+      <product-code>Line_NW_P</product-code>
+      <hardware-version>0.1</hardware-version>
+      <operational-state>inService</operational-state>
+      <circuit-pack-mode>NORMAL</circuit-pack-mode>
+      <shelf>1</shelf>
+      <slot>1</slot>
+      <subSlot>1</subSlot>
+      <is-pluggable-optics>true</is-pluggable-optics>
+      <ports>
+        <port-name>1</port-name>
+        <port-type>CFP2</port-type>
+        <port-qual>xpdr-network</port-qual>
+        <port-wavelength-type>wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <label>2</label>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <supported-interface-capability xmlns:org-openroadm-port-types="http://org/openroadm/port/types">org-openroadm-port-types:if-OCH</supported-interface-capability>
+        <transponder-port>
+          <port-power-capability-min-rx>-22.00</port-power-capability-min-rx>
+          <port-power-capability-min-tx>-5.00</port-power-capability-min-tx>
+          <port-power-capability-max-rx>1.00</port-power-capability-max-rx>
+          <port-power-capability-max-tx>0.00</port-power-capability-max-tx>
+        </transponder-port>
+      </ports>
+      <parent-circuit-pack>
+        <circuit-pack-name>1/0</circuit-pack-name>
+        <cp-slot-name>3</cp-slot-name>
+      </parent-circuit-pack>
+    </circuit-packs>
+    <circuit-packs>
+      <circuit-pack-name>1/0/2-PLUG-CLIENT</circuit-pack-name>
+      <circuit-pack-type>client_pluggable</circuit-pack-type>
+      <circuit-pack-product-code>Client_P</circuit-pack-product-code>
+      <vendor>VendorA</vendor>
+      <model>client_pluggable</model>
+      <serial-id>_1234_</serial-id>
+      <type>QSFP28</type>
+      <product-code>Client_P</product-code>
+      <hardware-version>0.1</hardware-version>
+      <operational-state>inService</operational-state>
+      <circuit-pack-mode>NORMAL</circuit-pack-mode>
+      <shelf>1</shelf>
+      <slot>1</slot>
+      <subSlot>1</subSlot>
+      <is-pluggable-optics>true</is-pluggable-optics>
+      <ports>
+        <port-name>C1</port-name>
+        <port-type>QSFP28</port-type>
+        <port-qual>xpdr-client</port-qual>
+        <port-wavelength-type>wavelength</port-wavelength-type>
+        <port-direction>bidirectional</port-direction>
+        <label>2</label>
+        <administrative-state>inService</administrative-state>
+        <operational-state>inService</operational-state>
+        <supported-interface-capability xmlns:org-openroadm-port-types="http://org/openroadm/port/types">org-openroadm-port-types:if-100GE</supported-interface-capability>
+        <transponder-port>
+          <port-power-capability-min-rx>-4.00</port-power-capability-min-rx>
+          <port-power-capability-min-tx>-10.00</port-power-capability-min-tx>
+          <port-power-capability-max-rx>4.00</port-power-capability-max-rx>
+          <port-power-capability-max-tx>4.00</port-power-capability-max-tx>
+        </transponder-port>
+      </ports>
+      <parent-circuit-pack>
+        <circuit-pack-name>1/0</circuit-pack-name>
+        <cp-slot-name>4</cp-slot-name>
+      </parent-circuit-pack>
+    </circuit-packs>
+
+    <connection-map>
+      <connection-map-number>1</connection-map-number>
+      <source>
+        <circuit-pack-name>1/0/1-PLUG-CLIENT</circuit-pack-name>
+        <port-name>C1</port-name>
+      </source>
+      <destination>
+        <circuit-pack-name>1/0/1-PLUG-NET</circuit-pack-name>
+        <port-name>1</port-name>
+      </destination>
+    </connection-map>
+    <connection-map>
+      <connection-map-number>2</connection-map-number>
+      <source>
+        <circuit-pack-name>1/0/1-PLUG-NET</circuit-pack-name>
+        <port-name>1</port-name>
+      </source>
+      <destination>
+        <circuit-pack-name>1/0/1-PLUG-CLIENT</circuit-pack-name>
+        <port-name>C1</port-name>
+      </destination>
+    </connection-map>
+    <connection-map>
+      <connection-map-number>3</connection-map-number>
+      <source>
+        <circuit-pack-name>1/0/2-PLUG-CLIENT</circuit-pack-name>
+        <port-name>C1</port-name>
+      </source>
+      <destination>
+        <circuit-pack-name>1/0/2-PLUG-NET</circuit-pack-name>
+        <port-name>1</port-name>
+      </destination>
+    </connection-map>
+    <connection-map>
+      <connection-map-number>4</connection-map-number>
+      <source>
+        <circuit-pack-name>1/0/2-PLUG-NET</circuit-pack-name>
+        <port-name>1</port-name>
+      </source>
+      <destination>
+        <circuit-pack-name>1/0/2-PLUG-CLIENT</circuit-pack-name>
+        <port-name>C1</port-name>
+      </destination>
+    </connection-map>
+  </org-openroadm-device>
+  <current-pm-list xmlns="http://org/openroadm/pm">
+  <current-pm-entry>
+    <pm-resource-instance xmlns:d="http://org/openroadm/device">/d:org-openroadm-device/d:interface[d:name='XPDR1-NETWORK1-OTU']</pm-resource-instance>
+    <pm-resource-type>interface</pm-resource-type>
+    <pm-resource-type-extension></pm-resource-type-extension>
+    <retrieval-time>2018-06-07T13:22:58+00:00</retrieval-time>
+    <current-pm>
+      <type>opticalPowerOutput</type>
+      <extension></extension>
+      <location>nearEnd</location>
+      <direction>tx</direction>
+      <measurement>
+        <granularity>15min</granularity>
+        <pmParameterValue>2.5</pmParameterValue>
+        <pmParameterUnit>dBm</pmParameterUnit>
+        <validity>complete</validity>
+      </measurement>
+      <measurement>
+        <granularity>24Hour</granularity>
+        <pmParameterValue>2.23</pmParameterValue>
+        <pmParameterUnit>dBm</pmParameterUnit>
+        <validity>complete</validity>
+      </measurement>
+    </current-pm>
+    <current-pm>
+      <type>opticalPowerInput</type>
+      <extension></extension>
+      <location>nearEnd</location>
+      <direction>rx</direction>
+      <measurement>
+        <granularity>15min</granularity>
+        <pmParameterValue>-45.1</pmParameterValue>
+        <pmParameterUnit>dBm</pmParameterUnit>
+        <validity>complete</validity>
+      </measurement>
+      <measurement>
+        <granularity>24Hour</granularity>
+        <pmParameterValue>-49.3</pmParameterValue>
+        <pmParameterUnit>dBm</pmParameterUnit>
+        <validity>complete</validity>
+      </measurement>
+    </current-pm>
+  </current-pm-entry>
+</current-pm-list>
+</data>