HONEYCOMB-122 Update reader registry to share similar APIs as writer
authorMaros Marsalek <[email protected]>
Wed, 13 Jul 2016 09:52:51 +0000 (11:52 +0200)
committerMaros Marsalek <[email protected]>
Thu, 21 Jul 2016 12:18:59 +0000 (14:18 +0200)
+ Extract common registry builder base code
(Reader registry is not flat, so there is not full control over ordering as with writers
but it is sufficient)
+ Split CompositeReader into CompositeReader, SubtreeReader and GenericReader
+ No need to build composite structure in ReaderFactories (registry does that internally)
+ Keep only ReaderCustomizer + ListReaderCustomizer, no root reader (same for writers)

Change-Id: Ic4e5bc96ad47a6cbcada4efcc2209db5c16d2a6c
Signed-off-by: Maros Marsalek <[email protected]>
143 files changed:
v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeDelegator.java
v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ReadableDataTreeDelegator.java
v3po/data-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/data/impl/rev160411/OperationalDataTreeModule.java
v3po/data-impl/src/main/yang/data-impl.yang
v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeDelegatorTest.java
v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ReadableDataTreeDelegatorTest.java
v3po/impl/src/main/config/context-datatree-config.xml
v3po/impl/src/main/config/default-config.xml
v3po/impl/src/main/config/netconf-north-config.xml
v3po/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/v3po/impl/rev141210/ContextReaderModule.java
v3po/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/v3po/impl/rev141210/NetconfMonitoringReaderModule.java
v3po/impl/src/main/yang/v3po-impl.yang
v3po/it/it-test/src/test/java/io/fd/honeycomb/v3po/data/impl/HoneycombWriteInfraTest.java
v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/ModifiableSubtreeManagerRegistryBuilder.java [new file with mode: 0644]
v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/SubtreeManager.java
v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/SubtreeManagerRegistryBuilder.java [moved from v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/WriterRegistryBuilder.java with 79% similarity]
v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/ChildReader.java [deleted file]
v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/ListReader.java
v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/Reader.java
v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/ReaderFactory.java [new file with mode: 0644]
v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/registry/ModifiableReaderRegistryBuilder.java [new file with mode: 0644]
v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/registry/ReaderRegistry.java [moved from v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/ReaderRegistry.java with 60% similarity]
v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/registry/ReaderRegistryBuilder.java [moved from v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/TraversalType.java with 58% similarity]
v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/ListWriter.java [new file with mode: 0644]
v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/ModifiableWriterRegistry.java [deleted file]
v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/WriterFactory.java
v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/registry/ModifiableWriterRegistryBuilder.java [new file with mode: 0644]
v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/registry/WriterRegistry.java [moved from v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/WriterRegistry.java with 96% similarity]
v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/registry/WriterRegistryBuilder.java [new file with mode: 0644]
v3po/translate-api/src/main/yang/translate-api.yang
v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/AbstractCompositeReader.java [deleted file]
v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/CompositeChildReader.java [deleted file]
v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/CompositeListReader.java [deleted file]
v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/CompositeRootReader.java [deleted file]
v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/GenericListReader.java [new file with mode: 0644]
v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/GenericReader.java [new file with mode: 0644]
v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/write/GenericListWriter.java
v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/write/GenericWriter.java
v3po/translate-impl/src/test/java/io/fd/honeycomb/v3po/translate/impl/write/GenericWriterTest.java
v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/read/ChildReaderCustomizer.java [deleted file]
v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/read/ListReaderCustomizer.java
v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/read/ReaderCustomizer.java [moved from v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/read/RootReaderCustomizer.java with 71% similarity]
v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/write/ChildWriterCustomizer.java [deleted file]
v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/write/ListWriterCustomizer.java
v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/write/WriterCustomizer.java [moved from v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/write/RootWriterCustomizer.java with 93% similarity]
v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/AbstractSubtreeManagerRegistryBuilderBuilder.java [new file with mode: 0644]
v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/RWUtils.java
v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/TransactionMappingContext.java [moved from v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/TransactionMappingContext.java with 96% similarity]
v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/AbstractGenericReader.java [new file with mode: 0644]
v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/BindingBrokerReader.java
v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/CloseableReader.java [deleted file]
v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/KeepaliveReaderWrapper.java [moved from v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/KeepaliveReaderWrapper.java with 84% similarity]
v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/NoopReaderCustomizer.java
v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveAugmentReaderCustomizer.java [deleted file]
v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveChildReaderCustomizer.java [deleted file]
v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveReader.java [new file with mode: 0644]
v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveReaderCustomizer.java [new file with mode: 0644]
v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveRootReaderCustomizer.java [deleted file]
v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/CompositeReader.java [new file with mode: 0644]
v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/CompositeReaderRegistry.java [moved from v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/DelegatingReaderRegistry.java with 79% similarity]
v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/CompositeReaderRegistryBuilder.java [new file with mode: 0644]
v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/SubtreeReader.java [new file with mode: 0644]
v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/TypeHierarchy.java [new file with mode: 0644]
v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/AbstractGenericWriter.java [moved from v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/write/AbstractCompositeWriter.java with 94% similarity]
v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/CloseableWriter.java [deleted file]
v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/NoopWriterRegistry.java
v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/registry/FlatWriterRegistry.java
v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/registry/FlatWriterRegistryBuilder.java
v3po/translate-utils/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/translate/utils/rev160406/DelegatingReaderRegistryModule.java
v3po/translate-utils/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/translate/utils/rev160406/NoopWriterRegistryModule.java
v3po/translate-utils/src/main/yang/translate-utils.yang
v3po/translate-utils/src/test/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveAugmentReaderCustomizerTest.java [deleted file]
v3po/translate-utils/src/test/java/io/fd/honeycomb/v3po/translate/util/read/registry/TypeHierarchyTest.java [new file with mode: 0644]
v3po/translate-utils/src/test/java/io/fd/honeycomb/v3po/translate/util/write/registry/FlatWriterRegistryBuilderTest.java
v3po/translate-utils/src/test/java/io/fd/honeycomb/v3po/translate/util/write/registry/FlatWriterRegistryTest.java
v3po/v3po2vpp/src/main/config/default-config.xml
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/initializers/VppInitializer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/AclCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/EthernetCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterfaceCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/L2Customizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RewriteCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RoutingCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceAclCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceL2Customizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/TapCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VhostUserCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanGpeCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4AddressCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4Customizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4NeighbourCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv6Customizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/SubInterfaceIpv4AddressCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/AclCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/EthernetCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2Customizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/RewriteCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceAclCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceL2Customizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/TapCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VhostUserCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanGpeCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/ip/Ipv4Customizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/ip/Ipv6Customizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vpp/L2FibEntryCustomizer.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppclassifier/ClassifySessionWriter.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppclassifier/ClassifyTableWriter.java
v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizer.java
v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesHoneycombWriterModule.java
v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesStateHoneycombReaderModule.java
v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/Readme.adoc
v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/SubinterfaceAugmentationWriterFactory.java
v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/SubinterfaceStateAugmentationReaderFactory.java
v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppClassifierHoneycombWriterModule.java
v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppClassifierStateHoneycombReaderModule.java
v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppHoneycombWriterModule.java
v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppStateHoneycombReaderModule.java
v3po/v3po2vpp/src/main/yang/v3po2vpp.yang
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4AddressCustomizerTest.java
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4NeighbourCustomizerTest.java
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/AclCustomizerTest.java
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizerTest.java
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2CustomizerTest.java
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/RewriteCustomizerTest.java
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceCustomizerTest.java
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizerTest.java
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanGpeCustomizerTest.java
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/ip/Ipv4AddressCustomizerTest.java
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/ChildReaderCustomizerTest.java [deleted file]
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/ListReaderCustomizerTest.java
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/ReaderCustomizerTest.java [moved from v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/RootReaderCustomizerTest.java with 83% similarity]
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppclassifier/ClassifySessionReaderTest.java
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppclassifier/ClassifyTableReaderTest.java
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizerTest.java
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/L2FibEntryCustomizerTest.java
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizerTest.java
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateTest.java
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateTestUtils.java
v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/AbstractInterfaceTypeCustomizer.java

index 77aa12a..2c2581e 100644 (file)
@@ -28,11 +28,11 @@ import io.fd.honeycomb.v3po.data.DataModification;
 import io.fd.honeycomb.v3po.data.ReadableDataManager;
 import io.fd.honeycomb.v3po.translate.TranslationException;
 import io.fd.honeycomb.v3po.translate.util.RWUtils;
-import io.fd.honeycomb.v3po.translate.util.write.TransactionMappingContext;
+import io.fd.honeycomb.v3po.translate.util.TransactionMappingContext;
 import io.fd.honeycomb.v3po.translate.util.write.TransactionWriteContext;
 import io.fd.honeycomb.v3po.translate.write.DataObjectUpdate;
 import io.fd.honeycomb.v3po.translate.write.WriteContext;
-import io.fd.honeycomb.v3po.translate.write.WriterRegistry;
+import io.fd.honeycomb.v3po.translate.write.registry.WriterRegistry;
 import java.util.Map;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
index 8dc7f8f..aff023e 100644 (file)
@@ -31,8 +31,8 @@ import io.fd.honeycomb.v3po.translate.MappingContext;
 import io.fd.honeycomb.v3po.translate.ModificationCache;
 import io.fd.honeycomb.v3po.translate.read.ReadContext;
 import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.read.ReaderRegistry;
-import io.fd.honeycomb.v3po.translate.util.write.TransactionMappingContext;
+import io.fd.honeycomb.v3po.translate.read.registry.ReaderRegistry;
+import io.fd.honeycomb.v3po.translate.util.TransactionMappingContext;
 import java.util.Collection;
 import java.util.Map;
 import javax.annotation.Nonnull;
index 2e49cb7..1526fdd 100644 (file)
@@ -38,7 +38,7 @@ public class OperationalDataTreeModule extends
         LOG.debug("OperationalDataTreeModule.createInstance()");
         return new CloseableOperationalDataTree(
                 new ReadableDataTreeDelegator(getSerializerDependency(), getSchemaServiceDependency().getGlobalContext(),
-                        getReaderRegistryDependency(), getContextBindingBrokerDependency()));
+                        getReaderRegistryBuilderDependency().build(), getContextBindingBrokerDependency()));
     }
 
     private static final class CloseableOperationalDataTree implements ReadableDataManager, AutoCloseable {
index 9228463..ee48553 100644 (file)
@@ -156,11 +156,11 @@ module data-impl {
                 }
             }
 
-            container reader-registry {
+            container reader-registry-builder {
                 uses config:service-ref {
                     refine type {
                         mandatory true;
-                        config:required-identity tapi:honeycomb-reader-registry;
+                        config:required-identity tapi:honeycomb-reader-registry-builder;
                     }
                 }
             }
index c265366..915d738 100644 (file)
@@ -42,7 +42,7 @@ import io.fd.honeycomb.v3po.data.DataModification;
 import io.fd.honeycomb.v3po.translate.TranslationException;
 import io.fd.honeycomb.v3po.translate.write.DataObjectUpdate;
 import io.fd.honeycomb.v3po.translate.write.WriteContext;
-import io.fd.honeycomb.v3po.translate.write.WriterRegistry;
+import io.fd.honeycomb.v3po.translate.write.registry.WriterRegistry;
 import java.util.AbstractMap;
 import java.util.Collections;
 import java.util.HashMap;
index c8d4fe4..e1b0720 100644 (file)
@@ -36,7 +36,7 @@ import com.google.common.collect.Multimap;
 import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.Futures;
 import io.fd.honeycomb.v3po.translate.read.ReadContext;
-import io.fd.honeycomb.v3po.translate.read.ReaderRegistry;
+import io.fd.honeycomb.v3po.translate.read.registry.ReaderRegistry;
 import java.util.Collections;
 import java.util.Map;
 import org.junit.Before;
@@ -142,7 +142,7 @@ public class ReadableDataTreeDelegatorTest {
     }
 
     @Test
-    public void testReadFailed() throws Exception{
+    public void testReadFailed() throws Exception {
         doThrow(io.fd.honeycomb.v3po.translate.read.ReadFailedException.class).when(reader).readAll(any(ReadContext.class));
 
         final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> future =
index 02d2f61..2c17de1 100644 (file)
         <module>
           <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:utils">prefix:delegating-reader-registry</type>
           <name>read-registry</name>
-          <root-readers>
-            <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-reader</type>
+          <reader-factory>
+            <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-reader-factory</type>
             <name>context-reader</name>
-          </root-readers>
+          </reader-factory>
         </module>
         <!-- END: Special reader for Context -->
 
 
       <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
         <service>
-          <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-reader</type>
+          <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-reader-factory</type>
           <instance>
             <name>context-reader</name>
             <provider>/modules/module[type='context-reader'][name='context-reader']</provider>
index cc6c7c6..63f40c6 100644 (file)
             <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-dom-mapping-service</type>
             <name>runtime-mapping-singleton</name>
           </serializer>
-          <reader-registry>
+          <reader-registry-builder>
             <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-reader-registry</type>
             <name>read-registry</name>
-          </reader-registry>
+          </reader-registry-builder>
           <context-binding-broker>
             <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-async-data-broker</type>
             <name>honeycomb-context-binding-data-broker</name>
index ef500c6..35bd5ff 100644 (file)
                 <module>
                     <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:utils">prefix:delegating-reader-registry</type>
                     <name>read-registry</name>
-                    <root-readers>
-                        <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-reader</type>
+                    <reader-factory>
+                        <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-reader-factory</type>
                         <name>netconf-monitoring-reader</name>
-                    </root-readers>
+                    </reader-factory>
                 </module>
                 <!-- END: Special reader for Netconf monitoring. -->
 
                 </service>
 
                 <service>
-                    <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-reader</type>
+                    <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-reader-factory</type>
                     <instance>
                         <name>netconf-monitoring-reader</name>
                         <provider>/modules/module[type='netconf-monitoring-reader'][name='netconf-monitoring-reader']</provider>
index df22a2b..c15fe52 100644 (file)
@@ -1,9 +1,12 @@
 package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.impl.rev141210;
 
+import io.fd.honeycomb.v3po.translate.read.registry.ModifiableReaderRegistryBuilder;
 import io.fd.honeycomb.v3po.translate.util.read.BindingBrokerReader;
-import io.fd.honeycomb.v3po.translate.util.read.CloseableReader;
+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.honeycomb.params.xml.ns.yang.naming.context.rev160513.Contexts;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.ContextsBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 /**
 * A reader to provide mapping context related data
@@ -24,8 +27,27 @@ public class ContextReaderModule extends org.opendaylight.yang.gen.v1.urn.openda
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-        return new CloseableReader<>(new BindingBrokerReader<>(Contexts.class, getContextBindingBrokerDependency(),
-            LogicalDatastoreType.OPERATIONAL));
+        return new ReaderFactory(getContextBindingBrokerDependency());
     }
 
+    private static final class ReaderFactory implements AutoCloseable, io.fd.honeycomb.v3po.translate.read.ReaderFactory {
+
+        private final DataBroker contextBindingBrokerDependency;
+
+        public ReaderFactory(final DataBroker contextBindingBrokerDependency) {
+            this.contextBindingBrokerDependency = contextBindingBrokerDependency;
+        }
+
+        @Override
+        public void init(final ModifiableReaderRegistryBuilder registry) {
+            registry.add(new BindingBrokerReader<>(InstanceIdentifier.create(Contexts.class),
+                    contextBindingBrokerDependency,
+                    LogicalDatastoreType.OPERATIONAL, ContextsBuilder.class));
+        }
+
+        @Override
+        public void close() throws Exception {
+            // TODO no unregister
+        }
+    }
 }
index feb7768..4557518 100644 (file)
@@ -1,9 +1,12 @@
 package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.impl.rev141210;
 
+import io.fd.honeycomb.v3po.translate.read.registry.ModifiableReaderRegistryBuilder;
 import io.fd.honeycomb.v3po.translate.util.read.BindingBrokerReader;
-import io.fd.honeycomb.v3po.translate.util.read.CloseableReader;
+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 class NetconfMonitoringReaderModule extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.impl.rev141210.AbstractNetconfMonitoringReaderModule {
     public NetconfMonitoringReaderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
@@ -21,8 +24,28 @@ public class NetconfMonitoringReaderModule extends org.opendaylight.yang.gen.v1.
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-        return new CloseableReader<>(new BindingBrokerReader<>(NetconfState.class, getNetconfMonitoringBindingBrokerDependency(),
-            LogicalDatastoreType.OPERATIONAL));
+        return new ReaderFactory(getNetconfMonitoringBindingBrokerDependency());
     }
 
+
+    private static final class ReaderFactory implements AutoCloseable, io.fd.honeycomb.v3po.translate.read.ReaderFactory {
+
+        private final DataBroker netconfMonitoringBindingBrokerDependency;
+
+        public ReaderFactory(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));
+        }
+
+        @Override
+        public void close() throws Exception {
+            // TODO no unregister
+        }
+    }
 }
index 40b00ec..065e99f 100644 (file)
@@ -135,7 +135,7 @@ module v3po-impl {
 
     identity netconf-monitoring-reader {
         base config:module-type;
-        config:provided-service tapi:honeycomb-reader;
+        config:provided-service tapi:honeycomb-reader-factory;
     }
 
     augment "/config:modules/config:module/config:configuration" {
@@ -156,7 +156,7 @@ module v3po-impl {
 
     identity context-reader {
         base config:module-type;
-        config:provided-service tapi:honeycomb-reader;
+        config:provided-service tapi:honeycomb-reader-factory;
         description "A reader to provide mapping context related data";
     }
 
index f65b3e1..51fc227 100644 (file)
@@ -33,7 +33,7 @@ import io.fd.honeycomb.v3po.data.DataModification;
 import io.fd.honeycomb.v3po.translate.util.write.registry.FlatWriterRegistryBuilder;
 import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import io.fd.honeycomb.v3po.translate.write.Writer;
-import io.fd.honeycomb.v3po.translate.write.WriterRegistry;
+import io.fd.honeycomb.v3po.translate.write.registry.WriterRegistry;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -182,17 +182,17 @@ public class HoneycombWriteInfraTest {
 
     private void initWriterRegistry() {
         writerRegistry = new FlatWriterRegistryBuilder()
-                .addWriter(complexAugmentWriter) // unordered
-                .addWriter(nestedListWriter) // 6
-                .addWriterAfter(listInContainerWriter, NESTED_LIST_ID) // 7
-                .addWriterAfter(containerInListWriter, LIST_IN_CONTAINER_ID) // 8
-                .addWriterAfter(containerWithListWriter, CONTAINER_IN_LIST_ID) // 9
-                .addWriterBefore(containerFromGroupingWriter, NESTED_LIST_ID) // 5
-                .addWriterBefore(containerWithChoiceWriter, CONTAINER_FROM_GROUPING_ID) // 4
-                .addWriterBefore(simpleContainerWriter, CONTAINER_WITH_CHOICE_ID) // 3
-                .addWriterBefore(c3Writer, SIMPLE_CONTAINER_ID) // 2
-                .addWriterBefore(simpleAugmentWriter, SIMPLE_CONTAINER_ID) // 2
-                .addWriterBefore(complexAugmentContainerWriter, Sets.newHashSet(C3_ID, SIMPLE_AUGMENT_ID)) // 1
+                .add(complexAugmentWriter) // unordered
+                .add(nestedListWriter) // 6
+                .addAfter(listInContainerWriter, NESTED_LIST_ID) // 7
+                .addAfter(containerInListWriter, LIST_IN_CONTAINER_ID) // 8
+                .addAfter(containerWithListWriter, CONTAINER_IN_LIST_ID) // 9
+                .addBefore(containerFromGroupingWriter, NESTED_LIST_ID) // 5
+                .addBefore(containerWithChoiceWriter, CONTAINER_FROM_GROUPING_ID) // 4
+                .addBefore(simpleContainerWriter, CONTAINER_WITH_CHOICE_ID) // 3
+                .addBefore(c3Writer, SIMPLE_CONTAINER_ID) // 2
+                .addBefore(simpleAugmentWriter, SIMPLE_CONTAINER_ID) // 2
+                .addBefore(complexAugmentContainerWriter, Sets.newHashSet(C3_ID, SIMPLE_AUGMENT_ID)) // 1
                 .build();
     }
 
@@ -540,7 +540,7 @@ public class HoneycombWriteInfraTest {
     public void testSubtreeWriter() throws Exception {
         writerRegistry = new FlatWriterRegistryBuilder()
                 // Handles also container from grouping
-                .addSubtreeWriter(Sets.newHashSet(CONTAINER_FROM_GROUPING_ID), containerWithChoiceWriter)
+                .subtreeAdd(Sets.newHashSet(CONTAINER_FROM_GROUPING_ID), containerWithChoiceWriter)
                 .build();
 
         final ModifiableDataTreeDelegator modifiableDataTreeDelegator =
diff --git a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/ModifiableSubtreeManagerRegistryBuilder.java b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/ModifiableSubtreeManagerRegistryBuilder.java
new file mode 100644 (file)
index 0000000..591a9e9
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * 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.v3po.translate;
+
+import java.util.Collection;
+import java.util.Set;
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Registry builder where {@link SubtreeManager}s can be added with or without relationships between them.
+ * The relationships express what the order of execution should be.
+ */
+public interface ModifiableSubtreeManagerRegistryBuilder<S extends SubtreeManager<? extends DataObject>> {
+
+    /**
+     * Add a handler responsible for writing only a single complex node.
+     */
+    ModifiableSubtreeManagerRegistryBuilder<S> add(@Nonnull S handler);
+
+    /**
+     * Add a handler responsible for writing multiple complex nodes within a subtree its responsible for. Identifiers for
+     * subtree nodes handled by a single handler have to be relative from {@link DataObject} that represents subtree
+     * root.
+     */
+    ModifiableSubtreeManagerRegistryBuilder<S> subtreeAdd(@Nonnull Set<InstanceIdentifier<?>> handledChildren,
+                                                          @Nonnull S handler);
+
+    /**
+     * Add a handler and make sure it will be executed before handler identifier by relatedType is executed.
+     */
+    ModifiableSubtreeManagerRegistryBuilder<S> addBefore(@Nonnull S handler,
+                                                         @Nonnull InstanceIdentifier<?> relatedType);
+
+    ModifiableSubtreeManagerRegistryBuilder<S> addBefore(@Nonnull S handler,
+                                                         @Nonnull Collection<InstanceIdentifier<?>> relatedTypes);
+
+    ModifiableSubtreeManagerRegistryBuilder<S> subtreeAddBefore(@Nonnull Set<InstanceIdentifier<?>> handledChildren,
+                                                                @Nonnull S handler,
+                                                                @Nonnull InstanceIdentifier<?> relatedType);
+
+    ModifiableSubtreeManagerRegistryBuilder<S> subtreeAddBefore(@Nonnull Set<InstanceIdentifier<?>> handledChildren,
+                                                                @Nonnull S handler,
+                                                                @Nonnull Collection<InstanceIdentifier<?>> relatedTypes);
+
+    /**
+     * Add a handler and make sure it will be executed after handler identifier by relatedType is executed.
+     */
+    ModifiableSubtreeManagerRegistryBuilder<S> addAfter(@Nonnull S handler,
+                                                        @Nonnull InstanceIdentifier<?> relatedType);
+
+    ModifiableSubtreeManagerRegistryBuilder<S> addAfter(@Nonnull S handler,
+                                                        @Nonnull Collection<InstanceIdentifier<?>> relatedTypes);
+
+    ModifiableSubtreeManagerRegistryBuilder<S> subtreeAddAfter(@Nonnull Set<InstanceIdentifier<?>> handledChildren,
+                                                               @Nonnull S handler,
+                                                               @Nonnull InstanceIdentifier<?> relatedType);
+
+    ModifiableSubtreeManagerRegistryBuilder<S> subtreeAddAfter(@Nonnull Set<InstanceIdentifier<?>> handledChildren,
+                                                               @Nonnull S handler,
+                                                               @Nonnull Collection<InstanceIdentifier<?>> relatedTypes);
+}
index 39e4036..4084276 100644 (file)
@@ -30,9 +30,9 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 public interface SubtreeManager<D extends DataObject> {
 
     /**
-     * Gets the type of node managed by this reader
+     * Gets the type of node managed by this reader.
      *
-     * @return Class object for node managed by this reader
+     * @return Absolute instance identifier for managed type
      */
     @Nonnull
     InstanceIdentifier<D> getManagedDataObjectType();
  * limitations under the License.
  */
 
-package io.fd.honeycomb.v3po.translate.write;
+package io.fd.honeycomb.v3po.translate;
 
-/**
- * Builder for writer registries.
- */
-public interface WriterRegistryBuilder {
+public interface SubtreeManagerRegistryBuilder<R> {
 
-    WriterRegistry build();
+    R build();
 }
diff --git a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/ChildReader.java b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/ChildReader.java
deleted file mode 100644 (file)
index 02b6b8d..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.v3po.translate.read;
-
-import com.google.common.annotations.Beta;
-import javax.annotation.Nonnull;
-import org.opendaylight.yangtools.concepts.Builder;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-/**
- * Child reader allowing its parent to pass the builder object
- *
- * @param <C> Specific DataObject derived type, that is handled by this reader
- */
-@Beta
-public interface ChildReader<C extends DataObject> extends Reader<C> {
-
-    /**
-     * Reads subtree starting from node managed by this reader and place the subtree within parent builder object if the
-     * data exists.
-     *
-     * @param id            Unique identifier pointing to the node managed by this reader. Useful when necessary to
-     *                      determine the exact position within more complex subtrees.
-     * @param parentBuilder Builder of parent DataObject. Objects read on this level (if any) must be placed into the
-     *                      parent builder.
-     * @param ctx Read context
-     *
-     * @throws ReadFailedException if read was unsuccessful
-     */
-    void read(@Nonnull final InstanceIdentifier<? extends DataObject> id,
-              @Nonnull final Builder<? extends DataObject> parentBuilder,
-              @Nonnull final ReadContext ctx) throws ReadFailedException;
-
-}
-
index faf6f0a..13a7a55 100644 (file)
 package io.fd.honeycomb.v3po.translate.read;
 
 import com.google.common.annotations.Beta;
+import java.util.Collections;
 import java.util.List;
 import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.concepts.Builder;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.Identifiable;
 import org.opendaylight.yangtools.yang.binding.Identifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 /**
- * List reader, allowing read of all the elements
+ * List reader, allowing read of all the elements.
  *
  * @param <D> Specific DataObject derived type, that is handled by this reader
  */
 @Beta
-public interface ListReader<D extends DataObject & Identifiable<K>, K extends Identifier<D>> extends Reader<D> {
+public interface ListReader
+        <D extends DataObject & Identifiable<K>, K extends Identifier<D>, B extends Builder<D>> extends Reader<D, B> {
 
     /**
-     * Read all elements in this list
+     * Read all elements in this list.
      *
      * @param id Wildcarded identifier of list managed by this reader
      * @param ctx Read context
@@ -42,6 +45,22 @@ public interface ListReader<D extends DataObject & Identifiable<K>, K extends Id
      * @throws ReadFailedException if read was unsuccessful
      */
     @Nonnull
-    List<D> readList(@Nonnull final InstanceIdentifier<D> id,
-                     @Nonnull final ReadContext ctx) throws ReadFailedException;
+    List<D> readList(@Nonnull final InstanceIdentifier<D> id, @Nonnull final ReadContext ctx)
+            throws ReadFailedException;
+
+    /**
+     * Get IDs for all entries in the list.
+     */
+    List<K> getAllIds(@Nonnull InstanceIdentifier<D> id, @Nonnull ReadContext ctx)
+            throws ReadFailedException;
+
+    /**
+     * Merge read data into provided parent builder.
+     */
+    void merge(@Nonnull final Builder<? extends DataObject> builder, @Nonnull final List<D> readData);
+
+    @Override
+    default void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, @Nonnull final D readValue) {
+        merge(parentBuilder, Collections.singletonList(readValue));
+    }
 }
index 122263c..d0bf0de 100644 (file)
@@ -20,16 +20,17 @@ import com.google.common.annotations.Beta;
 import com.google.common.base.Optional;
 import io.fd.honeycomb.v3po.translate.SubtreeManager;
 import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.concepts.Builder;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 /**
- * Base reader, responsible for translation between DataObjects and any other side
+ * Base reader, responsible for translation between DataObjects and any other side.
  *
  * @param <D> Specific DataObject derived type, that is handled by this reader
  */
 @Beta
-public interface Reader<D extends DataObject> extends SubtreeManager<D> {
+public interface Reader<D extends DataObject, B extends Builder<D>> extends SubtreeManager<D> {
 
     // TODO make async
 
@@ -45,7 +46,31 @@ public interface Reader<D extends DataObject> extends SubtreeManager<D> {
      * @throws ReadFailedException if read was unsuccessful
      */
     @Nonnull
-    Optional<? extends DataObject> read(@Nonnull final InstanceIdentifier<? extends DataObject> id,
+    Optional<? extends DataObject> read(@Nonnull InstanceIdentifier<? extends DataObject> id,
                                         @Nonnull ReadContext ctx) throws ReadFailedException;
 
+    /**
+     * Fill in current node's attributes
+     *
+     * @param id {@link InstanceIdentifier} pointing to current node. In case of keyed list, key must be present.
+     * @param builder Builder object for current node where the read attributes must be placed
+     * @param ctx Current read context
+     */
+    void readCurrentAttributes(@Nonnull InstanceIdentifier<D> id,
+                               @Nonnull B builder,
+                               @Nonnull ReadContext ctx) throws ReadFailedException;
+
+    /**
+     * Return new instance of a builder object for current node
+     *
+     * @param id {@link InstanceIdentifier} pointing to current node. In case of keyed list, key must be present.
+     * @return Builder object for current node type
+     */
+    @Nonnull
+    B getBuilder(InstanceIdentifier<D> id);
+
+    /**
+     * Merge read data into provided parent builder.
+     */
+    void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, @Nonnull final D readValue);
 }
diff --git a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/ReaderFactory.java b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/ReaderFactory.java
new file mode 100644 (file)
index 0000000..6d6d52a
--- /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.v3po.translate.read;
+
+import com.google.common.annotations.Beta;
+import io.fd.honeycomb.v3po.translate.read.registry.ModifiableReaderRegistryBuilder;
+import javax.annotation.Nonnull;
+
+/**
+ * Factory producing readers for {@link ModifiableReaderRegistryBuilder}.
+ */
+@Beta
+public interface ReaderFactory {
+
+    /**
+     * Initialize 1 or more readers and add them to provided registry.
+     */
+    void init(@Nonnull ModifiableReaderRegistryBuilder registry);
+}
diff --git a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/registry/ModifiableReaderRegistryBuilder.java b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/registry/ModifiableReaderRegistryBuilder.java
new file mode 100644 (file)
index 0000000..c2eba4f
--- /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.v3po.translate.read.registry;
+
+import com.google.common.annotations.Beta;
+import io.fd.honeycomb.v3po.translate.ModifiableSubtreeManagerRegistryBuilder;
+import io.fd.honeycomb.v3po.translate.read.Reader;
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Mutable registry that allows adding new readers.
+ */
+@Beta
+public interface ModifiableReaderRegistryBuilder
+        extends ModifiableSubtreeManagerRegistryBuilder<Reader<? extends DataObject, ? extends Builder<?>>> {
+
+    // TODO we should be able to add structural/reflexive readers automatically in the registry builder, we just need builder class
+    // We would need generated class loading strategy instance and then load builder classes relying on naming + package conventions of Binding spec
+    /**
+     * Add a structural reader that performs no read operation on its own, just fills in the hierarchy.
+     */
+    <D extends DataObject> void addStructuralReader(@Nonnull InstanceIdentifier<D> id,
+                                                    @Nonnull Class<? extends Builder<D>> builderType);
+}
  * limitations under the License.
  */
 
-package io.fd.honeycomb.v3po.translate.read;
+package io.fd.honeycomb.v3po.translate.read.registry;
 
 import com.google.common.annotations.Beta;
+import com.google.common.base.Optional;
 import com.google.common.collect.Multimap;
+import io.fd.honeycomb.v3po.translate.read.ReadContext;
+import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
 import javax.annotation.Nonnull;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -26,7 +29,7 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
  * Simple delegating reader suitable as a holder for all other root readers, providing readAll feature.
  */
 @Beta
-public interface ReaderRegistry extends Reader<DataObject> {
+public interface ReaderRegistry {
 
     /**
      * Performs read on all registered root readers and merges the results into a Multimap. Keys represent identifiers
@@ -40,4 +43,20 @@ public interface ReaderRegistry extends Reader<DataObject> {
     @Nonnull
     Multimap<InstanceIdentifier<? extends DataObject>, ? extends DataObject> readAll(@Nonnull final ReadContext ctx)
             throws ReadFailedException;
+
+    /**
+     * Reads data identified by id.
+     *
+     * @param id unique identifier of subtree to be read. The subtree must contain managed data object type. For
+     *           identifiers pointing below node managed by this reader, it's reader's responsibility to filter out the
+     *           right node or to delegate the read to a child reader.
+     * @param ctx Read context
+     *
+     * @return List of DataObjects identified by id. If the ID points to a single node, it will be wrapped in a list
+     * @throws ReadFailedException if read was unsuccessful
+     */
+    @Nonnull
+    Optional<? extends DataObject> read(@Nonnull InstanceIdentifier<? extends DataObject> id,
+                                        @Nonnull ReadContext ctx)
+            throws ReadFailedException;
 }
  * limitations under the License.
  */
 
-package io.fd.honeycomb.v3po.translate.impl;
+package io.fd.honeycomb.v3po.translate.read.registry;
+
+import com.google.common.annotations.Beta;
+import io.fd.honeycomb.v3po.translate.SubtreeManagerRegistryBuilder;
 
 /**
- * Type of traversal to be used by readers/writers in a tree
+ * Builder for reader registries.
  */
-public enum TraversalType {
-
-    /**
-     * Read current attributes before reading from children
-     */
-    PREORDER,
-
-    /**
-     * Read from children before reading current attributes
-     */
-    POSTORDER
-
-    // TODO implement different traversal types as injectable iterators
-    // TODO implement above traversal types in readers
-
-}
\ No newline at end of file
+@Beta
+public interface ReaderRegistryBuilder extends SubtreeManagerRegistryBuilder<ReaderRegistry> {
+}
diff --git a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/ListWriter.java b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/ListWriter.java
new file mode 100644 (file)
index 0000000..f29289d
--- /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.v3po.translate.write;
+
+import com.google.common.annotations.Beta;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.Identifiable;
+import org.opendaylight.yangtools.yang.binding.Identifier;
+
+/**
+ * List writer, responsible for translation between a list of DataObjects and any other side.
+ * Handling all update operations(create, update, delete)
+ *
+ * @param <D> Specific DataObject derived type, that is handled by this writer
+ * @param <K> Identifier/key for D
+ */
+@Beta
+public interface ListWriter<D extends DataObject & Identifiable<K>, K extends Identifier<D>> extends Writer<D> {
+}
diff --git a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/ModifiableWriterRegistry.java b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/ModifiableWriterRegistry.java
deleted file mode 100644 (file)
index 71ecbb8..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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.v3po.translate.write;
-
-import com.google.common.annotations.Beta;
-import java.util.Collection;
-import java.util.Set;
-import javax.annotation.Nonnull;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-/**
- * Mutable registry that allows adding new writers.
- */
-@Beta
-public interface ModifiableWriterRegistry {
-
-    /**
-     * Add a writer responsible for writing only a single complex node.
-     */
-    ModifiableWriterRegistry addWriter(@Nonnull Writer<? extends DataObject> writer);
-
-    /**
-     * Add a writer responsible for writing multiple complex nodes within a subtree its responsible for.
-     * Identifiers for subtree nodes handled by a single writer have to be relative from {@link DataObject} that
-     * represents subtree root.
-     */
-    ModifiableWriterRegistry addSubtreeWriter(@Nonnull Set<InstanceIdentifier<?>> handledChildren,
-                                              @Nonnull Writer<? extends DataObject> writer);
-
-    /**
-     * Add a writer and make sure it will be executed before writer identifier by relatedType is executed.
-     */
-    ModifiableWriterRegistry addWriterBefore(@Nonnull Writer<? extends DataObject> writer,
-                                             @Nonnull InstanceIdentifier<?> relatedType);
-
-    ModifiableWriterRegistry addSubtreeWriterBefore(@Nonnull Set<InstanceIdentifier<?>> handledChildren,
-                                                    @Nonnull Writer<? extends DataObject> writer,
-                                                    @Nonnull InstanceIdentifier<?> relatedType);
-
-    ModifiableWriterRegistry addWriterBefore(@Nonnull Writer<? extends DataObject> writer,
-                                             @Nonnull Collection<InstanceIdentifier<?>> relatedTypes);
-
-    ModifiableWriterRegistry addSubtreeWriterBefore(@Nonnull Set<InstanceIdentifier<?>> handledChildren,
-                                                    @Nonnull Writer<? extends DataObject> writer,
-                                                    @Nonnull Collection<InstanceIdentifier<?>> relatedTypes);
-
-    /**
-     * Add a writer and make sure it will be executed after writer identifier by relatedType is executed.
-     */
-    ModifiableWriterRegistry addWriterAfter(@Nonnull Writer<? extends DataObject> writer,
-                                            @Nonnull InstanceIdentifier<?> relatedType);
-
-    ModifiableWriterRegistry addSubtreeWriterAfter(@Nonnull Set<InstanceIdentifier<?>> handledChildren,
-                                                   @Nonnull Writer<? extends DataObject> writer,
-                                                   @Nonnull InstanceIdentifier<?> relatedType);
-
-    ModifiableWriterRegistry addWriterAfter(@Nonnull Writer<? extends DataObject> writer,
-                                            @Nonnull Collection<InstanceIdentifier<?>> relatedTypes);
-
-    ModifiableWriterRegistry addSubtreeWriterAfter(@Nonnull Set<InstanceIdentifier<?>> handledChildren,
-                                                   @Nonnull Writer<? extends DataObject> writer,
-                                                   @Nonnull Collection<InstanceIdentifier<?>> relatedTypes);
-}
index 4287964..dfcffa4 100644 (file)
 package io.fd.honeycomb.v3po.translate.write;
 
 import com.google.common.annotations.Beta;
+import io.fd.honeycomb.v3po.translate.write.registry.ModifiableWriterRegistryBuilder;
+import javax.annotation.Nonnull;
 
+/**
+ * Factory producing writers for {@link ModifiableWriterRegistryBuilder}.
+ */
 @Beta
 public interface WriterFactory {
 
     /**
      * Initialize 1 or more writers and add them to provided registry.
      */
-    void init(ModifiableWriterRegistry registry);
+    void init(@Nonnull ModifiableWriterRegistryBuilder registry);
 }
diff --git a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/registry/ModifiableWriterRegistryBuilder.java b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/registry/ModifiableWriterRegistryBuilder.java
new file mode 100644 (file)
index 0000000..8670a50
--- /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.v3po.translate.write.registry;
+
+import com.google.common.annotations.Beta;
+import io.fd.honeycomb.v3po.translate.ModifiableSubtreeManagerRegistryBuilder;
+import io.fd.honeycomb.v3po.translate.write.Writer;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+/**
+ * Mutable registry that allows adding new writers.
+ */
+@Beta
+public interface ModifiableWriterRegistryBuilder
+        extends ModifiableSubtreeManagerRegistryBuilder<Writer<? extends DataObject>> {
+
+}
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package io.fd.honeycomb.v3po.translate.write;
+package io.fd.honeycomb.v3po.translate.write.registry;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
@@ -23,16 +23,18 @@ import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Multimap;
 import com.google.common.collect.Sets;
 import io.fd.honeycomb.v3po.translate.TranslationException;
+import io.fd.honeycomb.v3po.translate.write.DataObjectUpdate;
+import io.fd.honeycomb.v3po.translate.write.WriteContext;
+import io.fd.honeycomb.v3po.translate.write.Writer;
 import java.util.Set;
 import javax.annotation.Nonnull;
-import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 /**
  * Special {@link Writer} capable of performing bulk updates.
  */
 @Beta
-public interface WriterRegistry extends Writer<DataObject> {
+public interface WriterRegistry {
 
     /**
      * Performs bulk update.
diff --git a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/registry/WriterRegistryBuilder.java b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/registry/WriterRegistryBuilder.java
new file mode 100644 (file)
index 0000000..3f0289e
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * 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.v3po.translate.write.registry;
+
+import com.google.common.annotations.Beta;
+import io.fd.honeycomb.v3po.translate.SubtreeManagerRegistryBuilder;
+
+/**
+ * Builder for writer registries.
+ */
+@Beta
+public interface WriterRegistryBuilder extends SubtreeManagerRegistryBuilder<WriterRegistry> {
+}
index 414ee20..796632d 100644 (file)
@@ -14,14 +14,19 @@ module translate-api {
             "Initial revision.";
     }
 
-    identity honeycomb-reader {
+    identity honeycomb-reader-factory {
         base "config:service-type";
-        config:java-class io.fd.honeycomb.v3po.translate.read.Reader;
+        config:java-class io.fd.honeycomb.v3po.translate.read.ReaderFactory;
     }
 
     identity honeycomb-reader-registry {
         base "config:service-type";
-        config:java-class io.fd.honeycomb.v3po.translate.read.ReaderRegistry;
+        config:java-class io.fd.honeycomb.v3po.translate.read.registry.ModifiableReaderRegistryBuilder;
+    }
+
+    identity honeycomb-reader-registry-builder {
+        base "config:service-type";
+        config:java-class io.fd.honeycomb.v3po.translate.read.registry.ReaderRegistryBuilder;
     }
 
     identity honeycomb-writer-factory {
@@ -31,12 +36,12 @@ module translate-api {
 
     identity honeycomb-writer-registry {
         base "config:service-type";
-        config:java-class io.fd.honeycomb.v3po.translate.write.ModifiableWriterRegistry;
+        config:java-class io.fd.honeycomb.v3po.translate.write.registry.ModifiableWriterRegistryBuilder;
     }
 
     identity honeycomb-writer-registry-builder {
         base "config:service-type";
-        config:java-class io.fd.honeycomb.v3po.translate.write.WriterRegistryBuilder;
+        config:java-class io.fd.honeycomb.v3po.translate.write.registry.WriterRegistryBuilder;
     }
 
     identity honeycomb-mapping-context {
diff --git a/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/AbstractCompositeReader.java b/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/AbstractCompositeReader.java
deleted file mode 100644 (file)
index c99e0ed..0000000
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * 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.v3po.translate.impl.read;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterables;
-import io.fd.honeycomb.v3po.translate.impl.TraversalType;
-import io.fd.honeycomb.v3po.translate.util.ReflectionUtils;
-import io.fd.honeycomb.v3po.translate.util.RWUtils;
-import io.fd.honeycomb.v3po.translate.read.ChildReader;
-import io.fd.honeycomb.v3po.translate.read.ReadContext;
-import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.read.Reader;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import org.opendaylight.yangtools.concepts.Builder;
-import org.opendaylight.yangtools.yang.binding.Augmentation;
-import org.opendaylight.yangtools.yang.binding.ChildOf;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.Identifier;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Beta
-abstract class AbstractCompositeReader<D extends DataObject, B extends Builder<D>> implements Reader<D> {
-
-    private static final Logger LOG = LoggerFactory.getLogger(AbstractCompositeReader.class);
-
-    private final Map<Class<? extends DataObject>, ChildReader<? extends ChildOf<D>>> childReaders;
-    private final Map<Class<? extends DataObject>, ChildReader<? extends Augmentation<D>>> augReaders;
-    private final InstanceIdentifier<D> instanceIdentifier;
-    private final TraversalType traversalType;
-
-    AbstractCompositeReader(final Class<D> managedDataObjectType,
-                            final List<ChildReader<? extends ChildOf<D>>> childReaders,
-                            final List<ChildReader<? extends Augmentation<D>>> augReaders,
-                            final TraversalType traversalType) {
-        this.traversalType = traversalType;
-        this.childReaders = RWUtils.uniqueLinkedIndex(childReaders, RWUtils.MANAGER_CLASS_FUNCTION);
-        this.augReaders = RWUtils.uniqueLinkedIndex(augReaders, RWUtils.MANAGER_CLASS_AUG_FUNCTION);
-        this.instanceIdentifier = InstanceIdentifier.create(managedDataObjectType);
-    }
-
-    @Nonnull
-    @Override
-    public final InstanceIdentifier<D> getManagedDataObjectType() {
-        return instanceIdentifier;
-    }
-
-    /**
-     * @param id {@link InstanceIdentifier} pointing to current node. In case of keyed list, key must be present.
-     *
-     */
-    protected Optional<D> readCurrent(final InstanceIdentifier<D> id,
-                                      @Nonnull final ReadContext ctx) throws ReadFailedException {
-        LOG.debug("{}: Reading current: {}", this, id);
-        final B builder = getBuilder(id);
-        // Cache empty value to determine if anything has changed later TODO cache in a field
-        final D emptyValue = builder.build();
-
-        switch (traversalType) {
-            case PREORDER: {
-                LOG.trace("{}: Reading current attributes", this);
-                readCurrentAttributes(id, builder, ctx);
-                readChildren(id, ctx, builder);
-                break;
-            }
-            case POSTORDER: {
-                readChildren(id, ctx, builder);
-                LOG.trace("{}: Reading current attributes", this);
-                readCurrentAttributes(id, builder, ctx);
-                break;
-            }
-        }
-
-        // Need to check whether anything was filled in to determine if data is present or not.
-        final D built = builder.build();
-        final Optional<D> read = built.equals(emptyValue)
-            ? Optional.<D>absent()
-            : Optional.of(built);
-
-        LOG.debug("{}: Current node read successfully. Result: {}", this, read);
-        return read;
-    }
-
-    private void readChildren(final InstanceIdentifier<D> id, final @Nonnull ReadContext ctx, final B builder)
-        throws ReadFailedException {
-        // TODO expect exceptions from reader
-        for (ChildReader<? extends ChildOf<D>> child : childReaders.values()) {
-            LOG.debug("{}: Reading child from: {}", this, child);
-            child.read(id, builder, ctx);
-        }
-
-        for (ChildReader<? extends Augmentation<D>> child : augReaders.values()) {
-            LOG.debug("{}: Reading augment from: {}", this, child);
-            child.read(id, builder, ctx);
-        }
-    }
-
-    @Nonnull
-    @Override
-    @SuppressWarnings("unchecked")
-    public Optional<? extends DataObject> read(@Nonnull final InstanceIdentifier<? extends DataObject> id,
-                                               @Nonnull final ReadContext ctx)
-            throws ReadFailedException {
-        LOG.trace("{}: Reading : {}", this, id);
-        if (id.getTargetType().equals(getManagedDataObjectType().getTargetType())) {
-            return readCurrent((InstanceIdentifier<D>) id, ctx);
-        } else {
-            return readSubtree(id, ctx);
-        }
-    }
-
-    private Optional<? extends DataObject> readSubtree(final InstanceIdentifier<? extends DataObject> id,
-                                                       @Nonnull final ReadContext ctx)
-            throws ReadFailedException {
-        LOG.debug("{}: Reading subtree: {}", this, id);
-        final Class<? extends DataObject> next = RWUtils.getNextId(id, getManagedDataObjectType()).getType();
-        final ChildReader<? extends ChildOf<D>> reader = childReaders.get(next);
-        final ChildReader<? extends Augmentation<D>> augReader = augReaders.get(next);
-
-        if (reader != null) {
-            LOG.debug("{}: Reading subtree: {} from: {}", this, id, reader);
-            return reader.read(id, ctx);
-        }if (augReader != null) {
-            LOG.debug("{}: Reading subtree: {} from: {}", this, id, augReader);
-            return augReader.read(id, ctx);
-        } else {
-            LOG.debug("{}: Dedicated subtree reader missing for: {}. Reading current and filtering", this, next);
-            // If there's no dedicated reader, use read current
-            final InstanceIdentifier<D> currentId = RWUtils.cutId(id, getManagedDataObjectType());
-            final Optional<D> current = readCurrent(currentId, ctx);
-            // then perform post-reading filtering (return only requested sub-node)
-            final Optional<? extends DataObject> readSubtree = current.isPresent()
-                ? filterSubtree(current.get(), id, getManagedDataObjectType().getTargetType())
-                : current;
-
-            LOG.debug("{}: Subtree: {} read successfully. Result: {}", this, id, readSubtree);
-            return readSubtree;
-        }
-    }
-
-    /**
-     * Fill in current node's attributes
-     *
-     * @param id {@link InstanceIdentifier} pointing to current node. In case of keyed list, key must be present.
-     * @param builder Builder object for current node where the read attributes must be placed
-     * @param ctx Current read context
-     */
-    protected abstract void readCurrentAttributes(@Nonnull final InstanceIdentifier<D> id, @Nonnull final B builder,
-                                                  @Nonnull final ReadContext ctx) throws ReadFailedException;
-
-    /**
-     * Return new instance of a builder object for current node
-     *
-     * @param id {@link InstanceIdentifier} pointing to current node. In case of keyed list, key must be present.
-     * @return Builder object for current node type
-     */
-    protected abstract B getBuilder(InstanceIdentifier<D> id);
-
-    // TODO move filtering out of here into a dedicated Filter ifc
-    @Nonnull
-    private static Optional<? extends DataObject> filterSubtree(@Nonnull final DataObject parent,
-                                                                @Nonnull final InstanceIdentifier<? extends DataObject> absolutPath,
-                                                                @Nonnull final Class<?> managedType) {
-        final InstanceIdentifier.PathArgument nextId =
-                RWUtils.getNextId(absolutPath, InstanceIdentifier.create(parent.getClass()));
-
-        final Optional<? extends DataObject> nextParent = findNextParent(parent, nextId, managedType);
-
-        if (Iterables.getLast(absolutPath.getPathArguments()).equals(nextId)) {
-            return nextParent; // we found the dataObject identified by absolutePath
-        } else if (nextParent.isPresent()) {
-            return filterSubtree(nextParent.get(), absolutPath, nextId.getType());
-        } else {
-            return nextParent; // we can't go further, return Optional.absent()
-        }
-    }
-
-    private static Optional<? extends DataObject> findNextParent(@Nonnull final DataObject parent,
-                                                                 @Nonnull final InstanceIdentifier.PathArgument nextId,
-                                                                 @Nonnull final Class<?> managedType) {
-        // TODO is there a better way than reflection ? e.g. convert into NN and filter out with a utility
-        Optional<Method> method = ReflectionUtils.findMethodReflex(managedType, "get",
-                Collections.<Class<?>>emptyList(), nextId.getType());
-
-        if (method.isPresent()) {
-            return Optional.fromNullable(filterSingle(parent, nextId, method.get()));
-        } else {
-            // List child nodes
-            method = ReflectionUtils.findMethodReflex(managedType,
-                    "get" + nextId.getType().getSimpleName(), Collections.<Class<?>>emptyList(), List.class);
-
-            if (method.isPresent()) {
-                return filterList(parent, nextId, method.get());
-            } else {
-                throw new IllegalStateException(
-                        "Unable to filter " + nextId + " from " + parent + " getters not found using reflexion");
-            }
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    private static Optional<? extends DataObject> filterList(final DataObject parent,
-                                                             final InstanceIdentifier.PathArgument nextId,
-                                                             final Method method) {
-        final List<? extends DataObject> invoke = (List<? extends DataObject>) invoke(method, nextId, parent);
-
-        checkArgument(nextId instanceof InstanceIdentifier.IdentifiableItem<?, ?>,
-            "Unable to perform wildcarded read for %s", nextId);
-        final Identifier key = ((InstanceIdentifier.IdentifiableItem) nextId).getKey();
-        return Iterables.tryFind(invoke, new Predicate<DataObject>() {
-            @Override
-            public boolean apply(@Nullable final DataObject input) {
-                final Optional<Method> keyGetter =
-                    ReflectionUtils.findMethodReflex(nextId.getType(), "get",
-                        Collections.<Class<?>>emptyList(), key.getClass());
-                final Object actualKey;
-                actualKey = invoke(keyGetter.get(), nextId, input);
-                return key.equals(actualKey);
-            }
-        });
-    }
-
-    private static DataObject filterSingle(final DataObject parent,
-                                           final InstanceIdentifier.PathArgument nextId, final Method method) {
-        return nextId.getType().cast(invoke(method, nextId, parent));
-    }
-
-    private static Object invoke(final Method method,
-                                 final InstanceIdentifier.PathArgument nextId, final DataObject parent) {
-        try {
-            return method.invoke(parent);
-        } catch (IllegalAccessException | InvocationTargetException e) {
-            throw new IllegalArgumentException("Unable to get " + nextId + " from " + parent, e);
-        }
-    }
-
-    @Override
-    public String toString() {
-        return String.format("Reader[%s]", getManagedDataObjectType().getTargetType().getSimpleName());
-    }
-}
diff --git a/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/CompositeChildReader.java b/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/CompositeChildReader.java
deleted file mode 100644 (file)
index 89f9f56..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * 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.v3po.translate.impl.read;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Optional;
-import io.fd.honeycomb.v3po.translate.impl.TraversalType;
-import io.fd.honeycomb.v3po.translate.read.ReadContext;
-import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.util.RWUtils;
-import io.fd.honeycomb.v3po.translate.read.ChildReader;
-import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
-import java.util.List;
-import javax.annotation.Nonnull;
-import javax.annotation.concurrent.ThreadSafe;
-import org.opendaylight.yangtools.concepts.Builder;
-import org.opendaylight.yangtools.yang.binding.Augmentation;
-import org.opendaylight.yangtools.yang.binding.ChildOf;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-/**
- * Composite implementation of {@link ChildReader} able to place the read result into
- * parent builder object.
- */
-@Beta
-@ThreadSafe
-public final class CompositeChildReader<C extends DataObject, B extends Builder<C>> extends AbstractCompositeReader<C, B>
-    implements ChildReader<C> {
-
-    private final ChildReaderCustomizer<C, B> customizer;
-
-    /**
-     * Create new {@link CompositeChildReader}
-     *
-     * @param managedDataObjectType Class object for managed data type
-     * @param childReaders Child nodes(container, list) readers
-     * @param augReaders Child augmentations readers
-     * @param customizer Customizer instance to customize this generic reader
-     *
-     */
-    public CompositeChildReader(@Nonnull final Class<C> managedDataObjectType,
-                                @Nonnull final List<ChildReader<? extends ChildOf<C>>> childReaders,
-                                @Nonnull final List<ChildReader<? extends Augmentation<C>>> augReaders,
-                                @Nonnull final ChildReaderCustomizer<C, B> customizer) {
-        this(managedDataObjectType, childReaders, augReaders, customizer, TraversalType.PREORDER);
-    }
-
-    /**
-     * Create new {@link CompositeChildReader}
-     *
-     * @param managedDataObjectType Class object for managed data type
-     * @param childReaders Child nodes(container, list) readers
-     * @param augReaders Child augmentations readers
-     * @param customizer Customizer instance to customize this generic reader
-     * @param traversalType Type of traversal to use in the tree of readers
-     *
-     */
-    public CompositeChildReader(@Nonnull final Class<C> managedDataObjectType,
-                                @Nonnull final List<ChildReader<? extends ChildOf<C>>> childReaders,
-                                @Nonnull final List<ChildReader<? extends Augmentation<C>>> augReaders,
-                                @Nonnull final ChildReaderCustomizer<C, B> customizer,
-                                @Nonnull final TraversalType traversalType) {
-        super(managedDataObjectType, childReaders, augReaders, traversalType);
-        this.customizer = customizer;
-    }
-
-    /**
-     * @see {@link CompositeChildReader#CompositeChildReader(Class, List, List, ChildReaderCustomizer)}
-     */
-    public CompositeChildReader(@Nonnull final Class<C> managedDataObjectType,
-                                @Nonnull final List<ChildReader<? extends ChildOf<C>>> childReaders,
-                                @Nonnull final ChildReaderCustomizer<C, B> customizer) {
-        this(managedDataObjectType, childReaders, RWUtils.<C>emptyAugReaderList(), customizer);
-    }
-
-    /**
-     * @see {@link CompositeChildReader#CompositeChildReader(Class, List, List, ChildReaderCustomizer)}
-     */
-    public CompositeChildReader(@Nonnull final Class<C> managedDataObjectType,
-                                @Nonnull final ChildReaderCustomizer<C, B> customizer) {
-        this(managedDataObjectType, RWUtils.emptyChildReaderList(), RWUtils.emptyAugReaderList(),
-            customizer);
-    }
-
-    @Override
-    public final void read(@Nonnull final InstanceIdentifier<? extends DataObject> parentId,
-                           @Nonnull final Builder<? extends DataObject> parentBuilder,
-                           @Nonnull final ReadContext ctx) throws ReadFailedException {
-        final Optional<C> read = readCurrent(RWUtils.appendTypeToId(parentId, getManagedDataObjectType()), ctx);
-
-        if(read.isPresent()) {
-            customizer.merge(parentBuilder, read.get());
-        }
-    }
-
-    @Override
-    protected void readCurrentAttributes(@Nonnull final InstanceIdentifier<C> id, @Nonnull final B builder,
-                                         @Nonnull final ReadContext ctx)
-            throws ReadFailedException {
-        customizer.readCurrentAttributes(id, builder, ctx);
-    }
-
-    @Override
-    protected B getBuilder(@Nonnull final InstanceIdentifier<C> id) {
-        return customizer.getBuilder(id);
-    }
-
-}
diff --git a/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/CompositeListReader.java b/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/CompositeListReader.java
deleted file mode 100644 (file)
index 7c438f6..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * 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.v3po.translate.impl.read;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Optional;
-import io.fd.honeycomb.v3po.translate.impl.TraversalType;
-import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.util.RWUtils;
-import io.fd.honeycomb.v3po.translate.read.ChildReader;
-import io.fd.honeycomb.v3po.translate.read.ListReader;
-import io.fd.honeycomb.v3po.translate.read.ReadContext;
-import io.fd.honeycomb.v3po.translate.spi.read.ListReaderCustomizer;
-import java.util.ArrayList;
-import java.util.List;
-import javax.annotation.Nonnull;
-import javax.annotation.concurrent.ThreadSafe;
-import org.opendaylight.yangtools.concepts.Builder;
-import org.opendaylight.yangtools.yang.binding.Augmentation;
-import org.opendaylight.yangtools.yang.binding.ChildOf;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.Identifiable;
-import org.opendaylight.yangtools.yang.binding.Identifier;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Composite implementation of {@link ChildReader} able to place the read result into parent builder object intended
- * for list node type.
- *
- * This reader checks if the IDs are wildcarded in which case it performs read of all list entries. In case the ID has a
- * key, it reads only the specified value.
- */
-@Beta
-@ThreadSafe
-public final class CompositeListReader<C extends DataObject & Identifiable<K>, K extends Identifier<C>, B extends Builder<C>>
-        extends AbstractCompositeReader<C, B> implements ChildReader<C>, ListReader<C, K> {
-
-    private static final Logger LOG = LoggerFactory.getLogger(CompositeListReader.class);
-
-    private final ListReaderCustomizer<C, K, B> customizer;
-
-    /**
-     * Create new {@link CompositeListReader}
-     *
-     * @param managedDataObjectType Class object for managed data type. Must come from a list node type.
-     * @param childReaders          Child nodes(container, list) readers
-     * @param augReaders            Child augmentations readers
-     * @param customizer            Customizer instance to customize this generic reader
-     */
-    public CompositeListReader(@Nonnull final Class<C> managedDataObjectType,
-                               @Nonnull final List<ChildReader<? extends ChildOf<C>>> childReaders,
-                               @Nonnull final List<ChildReader<? extends Augmentation<C>>> augReaders,
-                               @Nonnull final ListReaderCustomizer<C, K, B> customizer) {
-        this(managedDataObjectType, childReaders, augReaders, customizer, TraversalType.PREORDER);
-    }
-
-    /**
-     * Create new {@link CompositeListReader}
-     *
-     * @param managedDataObjectType Class object for managed data type. Must come from a list node type.
-     * @param childReaders          Child nodes(container, list) readers
-     * @param augReaders            Child augmentations readers
-     * @param customizer            Customizer instance to customize this generic reader
-     * @param traversalType Type of traversal to use in the tree of readers
-     */
-    public CompositeListReader(@Nonnull final Class<C> managedDataObjectType,
-                               @Nonnull final List<ChildReader<? extends ChildOf<C>>> childReaders,
-                               @Nonnull final List<ChildReader<? extends Augmentation<C>>> augReaders,
-                               @Nonnull final ListReaderCustomizer<C, K, B> customizer,
-                               @Nonnull final TraversalType traversalType) {
-        super(managedDataObjectType, childReaders, augReaders, traversalType);
-        this.customizer = customizer;
-    }
-
-    /**
-     * @see {@link CompositeListReader#CompositeListReader(Class, List, List, ListReaderCustomizer)}
-     */
-    public CompositeListReader(@Nonnull final Class<C> managedDataObjectType,
-                               @Nonnull final List<ChildReader<? extends ChildOf<C>>> childReaders,
-                               @Nonnull final ListReaderCustomizer<C, K, B> customizer) {
-        this(managedDataObjectType, childReaders, RWUtils.<C>emptyAugReaderList(), customizer);
-    }
-
-    /**
-     * @see {@link CompositeListReader#CompositeListReader(Class, List, List, ListReaderCustomizer)}
-     */
-    public CompositeListReader(@Nonnull final Class<C> managedDataObjectType,
-                               @Nonnull final ListReaderCustomizer<C, K, B> customizer) {
-        this(managedDataObjectType, RWUtils.<C>emptyChildReaderList(), RWUtils.<C>emptyAugReaderList(),
-                customizer);
-    }
-
-    @Override
-    public void read(@Nonnull final InstanceIdentifier<? extends DataObject> id,
-                     @Nonnull final Builder<? extends DataObject> parentBuilder,
-                     @Nonnull final ReadContext ctx) throws ReadFailedException {
-        // Create ID pointing to current node
-        final InstanceIdentifier<C> currentId = RWUtils.appendTypeToId(id, getManagedDataObjectType());
-        // Read all, since current ID is definitely wildcarded
-        final List<C> ifcs = readList(currentId, ctx);
-        customizer.merge(parentBuilder, ifcs);
-    }
-
-    @Override
-    @Nonnull
-    public List<C> readList(@Nonnull final InstanceIdentifier<C> id,
-                            @Nonnull final ReadContext ctx) throws ReadFailedException {
-        LOG.trace("{}: Reading all list entries", this);
-        final List<K> allIds = customizer.getAllIds(id, ctx);
-        LOG.debug("{}: Reading list entries for: {}", this, allIds);
-
-        final ArrayList<C> allEntries = new ArrayList<>(allIds.size());
-        for (K key : allIds) {
-            final InstanceIdentifier.IdentifiableItem<C, K> currentBdItem =
-                    RWUtils.getCurrentIdItem(id, key);
-            final InstanceIdentifier<C> keyedId = RWUtils.replaceLastInId(id, currentBdItem);
-            final Optional<C> read = readCurrent(keyedId, ctx);
-            if(read.isPresent()) {
-                final DataObject singleItem = read.get();
-                checkArgument(getManagedDataObjectType().getTargetType().isAssignableFrom(singleItem.getClass()));
-                allEntries.add(getManagedDataObjectType().getTargetType().cast(singleItem));
-            }
-        }
-        return allEntries;
-    }
-
-    @Override
-    protected void readCurrentAttributes(@Nonnull final InstanceIdentifier<C> id, @Nonnull final B builder,
-                                         @Nonnull final ReadContext ctx)
-            throws ReadFailedException {
-        customizer.readCurrentAttributes(id, builder, ctx);
-    }
-
-    @Override
-    protected B getBuilder(@Nonnull final InstanceIdentifier<C> id) {
-        return customizer.getBuilder(id);
-    }
-
-}
diff --git a/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/CompositeRootReader.java b/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/CompositeRootReader.java
deleted file mode 100644 (file)
index ea157aa..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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.v3po.translate.impl.read;
-
-import com.google.common.annotations.Beta;
-import io.fd.honeycomb.v3po.translate.impl.TraversalType;
-import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.util.RWUtils;
-import io.fd.honeycomb.v3po.translate.read.ChildReader;
-import io.fd.honeycomb.v3po.translate.read.ReadContext;
-import io.fd.honeycomb.v3po.translate.read.Reader;
-import io.fd.honeycomb.v3po.translate.spi.read.RootReaderCustomizer;
-import java.util.List;
-import javax.annotation.Nonnull;
-import javax.annotation.concurrent.ThreadSafe;
-import org.opendaylight.yangtools.concepts.Builder;
-import org.opendaylight.yangtools.yang.binding.Augmentation;
-import org.opendaylight.yangtools.yang.binding.ChildOf;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-/**
- * Composite implementation of {@link Reader}
- */
-@Beta
-@ThreadSafe
-public final class CompositeRootReader<C extends DataObject, B extends Builder<C>> extends AbstractCompositeReader<C, B>
-    implements Reader<C> {
-
-    private final RootReaderCustomizer<C, B> customizer;
-
-    /**
-     * Create new {@link CompositeRootReader}
-     *
-     * @param managedDataObjectType Class object for managed data type
-     * @param childReaders Child nodes(container, list) readers
-     * @param augReaders Child augmentations readers
-     * @param customizer Customizer instance to customize this generic reader
-     *
-     */
-    public CompositeRootReader(@Nonnull final Class<C> managedDataObjectType,
-                               @Nonnull final List<ChildReader<? extends ChildOf<C>>> childReaders,
-                               @Nonnull final List<ChildReader<? extends Augmentation<C>>> augReaders,
-                               @Nonnull final RootReaderCustomizer<C, B> customizer) {
-        this(managedDataObjectType, childReaders, augReaders, customizer, TraversalType.PREORDER);
-    }
-
-    /**
-     * Create new {@link CompositeRootReader}
-     *
-     * @param managedDataObjectType Class object for managed data type
-     * @param childReaders Child nodes(container, list) readers
-     * @param augReaders Child augmentations readers
-     * @param customizer Customizer instance to customize this generic reader
-     * @param traversalType Type of traversal to use in the tree of readers
-     *
-     */
-    public CompositeRootReader(@Nonnull final Class<C> managedDataObjectType,
-                               @Nonnull final List<ChildReader<? extends ChildOf<C>>> childReaders,
-                               @Nonnull final List<ChildReader<? extends Augmentation<C>>> augReaders,
-                               @Nonnull final RootReaderCustomizer<C, B> customizer,
-                               @Nonnull final TraversalType traversalType) {
-        super(managedDataObjectType, childReaders, augReaders, traversalType);
-        this.customizer = customizer;
-    }
-
-    /**
-     * @see {@link CompositeRootReader#CompositeRootReader(Class, List, List, RootReaderCustomizer)}
-     */
-    public CompositeRootReader(@Nonnull final Class<C> managedDataObjectType,
-                               @Nonnull final List<ChildReader<? extends ChildOf<C>>> childReaders,
-                               @Nonnull final RootReaderCustomizer<C, B> customizer) {
-        this(managedDataObjectType, childReaders, RWUtils.<C>emptyAugReaderList(), customizer);
-    }
-
-    /**
-     * @see {@link CompositeRootReader#CompositeRootReader(Class, List, List, RootReaderCustomizer)}
-     */
-    public CompositeRootReader(@Nonnull final Class<C> managedDataObjectType,
-                               @Nonnull final RootReaderCustomizer<C, B> customizer) {
-        this(managedDataObjectType, RWUtils.<C>emptyChildReaderList(), RWUtils.<C>emptyAugReaderList(),
-            customizer);
-    }
-
-    @Override
-    protected void readCurrentAttributes(@Nonnull final InstanceIdentifier<C> id, @Nonnull final B builder,
-                                         @Nonnull final ReadContext ctx) throws ReadFailedException {
-        customizer.readCurrentAttributes(id, builder, ctx);
-    }
-
-    @Override
-    protected B getBuilder(@Nonnull final InstanceIdentifier<C> id) {
-        return customizer.getBuilder(id);
-    }
-
-}
diff --git a/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/GenericListReader.java b/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/GenericListReader.java
new file mode 100644 (file)
index 0000000..54dad55
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * 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.v3po.translate.impl.read;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Optional;
+import io.fd.honeycomb.v3po.translate.read.ListReader;
+import io.fd.honeycomb.v3po.translate.read.ReadContext;
+import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
+import io.fd.honeycomb.v3po.translate.spi.read.ListReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.util.RWUtils;
+import io.fd.honeycomb.v3po.translate.util.read.AbstractGenericReader;
+import java.util.ArrayList;
+import java.util.List;
+import javax.annotation.Nonnull;
+import javax.annotation.concurrent.ThreadSafe;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.Identifiable;
+import org.opendaylight.yangtools.yang.binding.Identifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Composite implementation of {@link ListReader} able to place the read result into parent builder object intended
+ * for list node type.
+ * <p/>
+ * This reader checks if the IDs are wildcarded in which case it performs read of all list entries. In case the ID has a
+ * key, it reads only the specified value.
+ */
+@Beta
+@ThreadSafe
+public final class GenericListReader<C extends DataObject & Identifiable<K>, K extends Identifier<C>, B extends Builder<C>>
+        extends AbstractGenericReader<C, B> implements ListReader<C, K, B> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(GenericListReader.class);
+
+    private final ListReaderCustomizer<C, K, B> customizer;
+
+    /**
+     * Create new {@link GenericListReader}
+     *
+     * @param managedDataObjectType Class object for managed data type. Must come from a list node type.
+     * @param customizer            Customizer instance to customize this generic reader
+     */
+    public GenericListReader(@Nonnull final InstanceIdentifier<C> managedDataObjectType,
+                             @Nonnull final ListReaderCustomizer<C, K, B> customizer) {
+        super(managedDataObjectType);
+        this.customizer = customizer;
+    }
+
+    @Override
+    @Nonnull
+    public List<C> readList(@Nonnull final InstanceIdentifier<C> id,
+                            @Nonnull final ReadContext ctx) throws ReadFailedException {
+        LOG.trace("{}: Reading all list entries", this);
+        final List<K> allIds = getAllIds(id, ctx);
+        LOG.debug("{}: Reading list entries for: {}", this, allIds);
+
+        final ArrayList<C> allEntries = new ArrayList<>(allIds.size());
+        for (K key : allIds) {
+            final InstanceIdentifier.IdentifiableItem<C, K> currentBdItem = RWUtils.getCurrentIdItem(id, key);
+            final InstanceIdentifier<C> keyedId = RWUtils.replaceLastInId(id, currentBdItem);
+            final Optional<C> read = readCurrent(keyedId, ctx);
+            if (read.isPresent()) {
+                final DataObject singleItem = read.get();
+                checkArgument(getManagedDataObjectType().getTargetType().isAssignableFrom(singleItem.getClass()));
+                allEntries.add(getManagedDataObjectType().getTargetType().cast(singleItem));
+            }
+        }
+        return allEntries;
+    }
+
+    @Override
+    public List<K> getAllIds(@Nonnull final InstanceIdentifier<C> id, @Nonnull final ReadContext ctx)
+            throws ReadFailedException {
+        return customizer.getAllIds(id, ctx);
+    }
+
+    @Override
+    public void merge(@Nonnull final Builder<? extends DataObject> builder, @Nonnull final List<C> readData) {
+        customizer.merge(builder, readData);
+    }
+
+    @Override
+    public void readCurrentAttributes(@Nonnull final InstanceIdentifier<C> id, @Nonnull final B builder,
+                                      @Nonnull final ReadContext ctx)
+            throws ReadFailedException {
+        customizer.readCurrentAttributes(id, builder, ctx);
+    }
+
+    @Override
+    public B getBuilder(@Nonnull final InstanceIdentifier<C> id) {
+        return customizer.getBuilder(id);
+    }
+
+}
diff --git a/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/GenericReader.java b/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/GenericReader.java
new file mode 100644 (file)
index 0000000..eace7fa
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * 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.v3po.translate.impl.read;
+
+import com.google.common.annotations.Beta;
+import io.fd.honeycomb.v3po.translate.read.ReadContext;
+import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
+import io.fd.honeycomb.v3po.translate.read.Reader;
+import io.fd.honeycomb.v3po.translate.spi.read.ReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.util.read.AbstractGenericReader;
+import javax.annotation.Nonnull;
+import javax.annotation.concurrent.ThreadSafe;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Composite implementation of {@link Reader}.
+ */
+@Beta
+@ThreadSafe
+public final class GenericReader<C extends DataObject, B extends Builder<C>> extends AbstractGenericReader<C, B>
+    implements Reader<C, B> {
+
+    private final ReaderCustomizer<C, B> customizer;
+
+    /**
+     * Create a new {@link GenericReader}.
+     *
+     * @param id Instance identifier for managed data type
+     * @param customizer Customizer instance to customize this generic reader
+     */
+    public GenericReader(@Nonnull final InstanceIdentifier<C> id,
+                         @Nonnull final ReaderCustomizer<C, B> customizer) {
+        super(id);
+        this.customizer = customizer;
+    }
+
+    @Override
+    public void readCurrentAttributes(@Nonnull final InstanceIdentifier<C> id,
+                                      @Nonnull final B builder,
+                                      @Nonnull final ReadContext ctx) throws ReadFailedException {
+        customizer.readCurrentAttributes(id, builder, ctx);
+    }
+
+    @Override
+    public B getBuilder(@Nonnull final InstanceIdentifier<C> id) {
+        return customizer.getBuilder(id);
+    }
+
+    @Override
+    public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, @Nonnull final C readValue) {
+        customizer.merge(parentBuilder, readValue);
+    }
+
+}
index b61fb51..32daf59 100644 (file)
 package io.fd.honeycomb.v3po.translate.impl.write;
 
 import io.fd.honeycomb.v3po.translate.spi.write.ListWriterCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.write.WriterCustomizer;
 import io.fd.honeycomb.v3po.translate.util.RWUtils;
+import io.fd.honeycomb.v3po.translate.util.write.AbstractGenericWriter;
+import io.fd.honeycomb.v3po.translate.write.ListWriter;
 import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
-import io.fd.honeycomb.v3po.translate.write.Writer;
 import javax.annotation.Nonnull;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.Identifiable;
@@ -28,12 +30,12 @@ import org.opendaylight.yangtools.yang.binding.Identifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 /**
- * Special writer handling updates for nodes of type list.
+ * Generic list node writer with customizable behavior thanks to injected customizer.
  */
 public final class GenericListWriter<D extends DataObject & Identifiable<K>, K extends Identifier<D>> extends
-    AbstractCompositeWriter<D> implements Writer<D> {
+        AbstractGenericWriter<D> implements ListWriter<D, K> {
 
-    private final ListWriterCustomizer<D, K> customizer;
+    private final WriterCustomizer<D> customizer;
 
     public GenericListWriter(@Nonnull final InstanceIdentifier<D> type,
                              @Nonnull final ListWriterCustomizer<D, K> customizer) {
index 6ca80ca..65c192f 100644 (file)
@@ -16,7 +16,8 @@
 
 package io.fd.honeycomb.v3po.translate.impl.write;
 
-import io.fd.honeycomb.v3po.translate.spi.write.RootWriterCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.write.WriterCustomizer;
+import io.fd.honeycomb.v3po.translate.util.write.AbstractGenericWriter;
 import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
 import javax.annotation.Nonnull;
@@ -24,14 +25,14 @@ import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 /**
- * Special writer handling updates for any complex nodes.
+ * Generic writer with customizable behavior thanks to injected customizer.
  */
-public final class GenericWriter<D extends DataObject> extends AbstractCompositeWriter<D> {
+public final class GenericWriter<D extends DataObject> extends AbstractGenericWriter<D> {
 
-    private final RootWriterCustomizer<D> customizer;
+    private final WriterCustomizer<D> customizer;
 
     public GenericWriter(@Nonnull final InstanceIdentifier<D> type,
-                         @Nonnull final RootWriterCustomizer<D> customizer) {
+                         @Nonnull final WriterCustomizer<D> customizer) {
         super(type);
         this.customizer = customizer;
     }
index 919072b..87f1896 100644 (file)
@@ -20,7 +20,7 @@ import static org.junit.Assert.assertEquals;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
-import io.fd.honeycomb.v3po.translate.spi.write.RootWriterCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.write.WriterCustomizer;
 import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import org.junit.Before;
 import org.junit.Test;
@@ -34,7 +34,7 @@ public class GenericWriterTest {
     private static final InstanceIdentifier<DataObject>
             DATA_OBJECT_INSTANCE_IDENTIFIER = InstanceIdentifier.create(DataObject.class);
     @Mock
-    private RootWriterCustomizer<DataObject> customizer;
+    private WriterCustomizer<DataObject> customizer;
     @Mock
     private WriteContext ctx;
 
diff --git a/v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/read/ChildReaderCustomizer.java b/v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/read/ChildReaderCustomizer.java
deleted file mode 100644 (file)
index 8acc54d..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.v3po.translate.spi.read;
-
-import com.google.common.annotations.Beta;
-import javax.annotation.Nonnull;
-import org.opendaylight.yangtools.concepts.Builder;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-
-/**
- * CompositeChildReader SPI to customize its behavior
- *
- * @param <C> Specific DataObject derived type (Identifiable), that is handled by this customizer
- * @param <B> Specific Builder for handled type (C)
- */
-@Beta
-public interface ChildReaderCustomizer<C extends DataObject, B extends Builder<C>> extends
-    RootReaderCustomizer<C, B> {
-
-    // FIXME need to capture parent builder type, but that's inconvenient at best, is it ok to leave it Builder<?> and
-    // cast in specific customizers ? ... probably better than adding another type parameter
-
-    /**
-     * Merge read data into provided parent builder
-     */
-    void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, @Nonnull final C readValue);
-}
index 4a2e02c..5955755 100644 (file)
@@ -19,6 +19,7 @@ package io.fd.honeycomb.v3po.translate.spi.read;
 import com.google.common.annotations.Beta;
 import io.fd.honeycomb.v3po.translate.read.ReadContext;
 import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
+import java.util.Collections;
 import java.util.List;
 import javax.annotation.Nonnull;
 import org.opendaylight.yangtools.concepts.Builder;
@@ -28,7 +29,7 @@ import org.opendaylight.yangtools.yang.binding.Identifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 /**
- * CompositeListReader SPI to customize its behavior
+ * CompositeListReader SPI to customize its behavior.
  *
  * @param <C> Specific DataObject derived type (Identifiable), that is handled by this customizer
  * @param <K> Specific Identifier for handled type (C)
@@ -36,7 +37,7 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
  */
 @Beta
 public interface ListReaderCustomizer<C extends DataObject & Identifiable<K>, K extends Identifier<C>, B extends Builder<C>>
-    extends RootReaderCustomizer<C, B> {
+    extends ReaderCustomizer<C, B> {
 
     /**
      * Return list with IDs of all list nodes to be read.
@@ -51,7 +52,12 @@ public interface ListReaderCustomizer<C extends DataObject & Identifiable<K>, K
     // TODO does it make sense with vpp APIs ? Should we replace it with a simple readAll ?
 
     /**
-     * Merge read data into provided parent builder
+     * Merge read data into provided parent builder.
      */
     void merge(@Nonnull final Builder<? extends DataObject> builder, @Nonnull final List<C> readData);
+
+    @Override
+    default void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, @Nonnull final C readValue) {
+        merge(parentBuilder, Collections.singletonList(readValue));
+    }
 }
@@ -25,13 +25,13 @@ import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 /**
- * CompositeRootReader SPI to customize its behavior
+ * CompositeChildReader SPI to customize its behavior.
  *
- * @param <C> Specific DataObject derived type, that is handled by this customizer
+ * @param <C> Specific DataObject derived type (Identifiable), that is handled by this customizer
  * @param <B> Specific Builder for handled type (C)
  */
 @Beta
-public interface RootReaderCustomizer<C extends DataObject, B extends Builder<C>> {
+public interface ReaderCustomizer<C extends DataObject, B extends Builder<C>> {
 
     /**
      * Creates new builder that will be used to build read value.
@@ -39,7 +39,6 @@ public interface RootReaderCustomizer<C extends DataObject, B extends Builder<C>
     @Nonnull
     B getBuilder(@Nonnull final InstanceIdentifier<C> id);
 
-
     /**
      * Adds current data (identified by id) to the provided builder.
      *
@@ -48,6 +47,17 @@ public interface RootReaderCustomizer<C extends DataObject, B extends Builder<C>
      * @param ctx
      * @throws ReadFailedException if read was unsuccessful
      */
-    void readCurrentAttributes(@Nonnull final InstanceIdentifier<C> id, @Nonnull final B builder,
+    void readCurrentAttributes(@Nonnull final InstanceIdentifier<C> id,
+                               @Nonnull final B builder,
                                @Nonnull final ReadContext ctx) throws ReadFailedException;
+
+    // FIXME need to capture parent builder type, but that's inconvenient at best, is it ok to leave it Builder<?> and
+    // cast in specific customizers ? ... probably better than adding another type parameter
+
+    /**
+     * Merge read data into provided parent builder.
+     */
+    void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, @Nonnull final C readValue);
+
+
 }
diff --git a/v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/write/ChildWriterCustomizer.java b/v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/write/ChildWriterCustomizer.java
deleted file mode 100644 (file)
index e8f2484..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.v3po.translate.spi.write;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Optional;
-import javax.annotation.Nonnull;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-/**
- * CompositeChildWriter SPI to customize its behavior
- *
- * @param <D> Specific DataObject derived type (Identifiable), that is handled by this customizer
- */
-@Beta
-public interface ChildWriterCustomizer<D extends DataObject> extends RootWriterCustomizer<D> {
-
-    /**
-     * Get child of parentData identified by currentId
-     *
-     * @param currentId Identifier(from root) of data being extracted
-     * @param parentData Parent data object from which managed data object must be extracted
-     */
-    @Nonnull
-    Optional<D> extract(@Nonnull final InstanceIdentifier<D> currentId, @Nonnull final DataObject parentData);
-
-}
index ecc5911..41cdb94 100644 (file)
 package io.fd.honeycomb.v3po.translate.spi.write;
 
 import com.google.common.annotations.Beta;
-import com.google.common.base.Optional;
-import java.util.List;
-import javax.annotation.Nonnull;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.Identifiable;
 import org.opendaylight.yangtools.yang.binding.Identifier;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 /**
- * CompositeListWriter SPI to customize its behavior
+ * CompositeListWriter SPI to customize its behavior.
  *
  * @param <C> Specific DataObject derived type (Identifiable), that is handled by this customizer
  * @param <K> Specific Identifier for handled type (C)
  */
 @Beta
 public interface ListWriterCustomizer<C extends DataObject & Identifiable<K>, K extends Identifier<C>> extends
-    RootWriterCustomizer<C> {
-
-    /**
-     * Get children of parentData identified by currentId
-     *
-     * @param currentId Identifier(from root) of data being extracted
-     * @param parentData Parent data object from which managed data object must be extracted
-     */
-    @Nonnull
-    Optional<List<C>> extract(@Nonnull final InstanceIdentifier<C> currentId, @Nonnull final DataObject parentData);
-    // TODO consider removing Optional and make extract return @Nullable (applies also to ChildWriterCustomizer)
+    WriterCustomizer<C> {
 
 }
\ No newline at end of file
@@ -24,12 +24,12 @@ import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 /**
- * CompositeRootReader SPI to customize its behavior
+ * CompositeChildWriter SPI to customize its behavior.
  *
- * @param <D> Specific DataObject derived type, that is handled by this customizer
+ * @param <D> Specific DataObject derived type (Identifiable), that is handled by this customizer
  */
 @Beta
-public interface RootWriterCustomizer<D extends DataObject> {
+public interface WriterCustomizer<D extends DataObject> {
 
     /**
      * Handle write operation. C from CRUD.
@@ -71,4 +71,5 @@ public interface RootWriterCustomizer<D extends DataObject> {
     void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<D> id,
                                  @Nonnull final D dataBefore,
                                  @Nonnull final WriteContext writeContext) throws WriteFailedException;
+
 }
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/AbstractSubtreeManagerRegistryBuilderBuilder.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/AbstractSubtreeManagerRegistryBuilderBuilder.java
new file mode 100644 (file)
index 0000000..23a6633
--- /dev/null
@@ -0,0 +1,213 @@
+/*
+ * 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.v3po.translate.util;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Sets;
+import io.fd.honeycomb.v3po.translate.ModifiableSubtreeManagerRegistryBuilder;
+import io.fd.honeycomb.v3po.translate.SubtreeManager;
+import io.fd.honeycomb.v3po.translate.SubtreeManagerRegistryBuilder;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import javax.annotation.Nonnull;
+import org.jgrapht.experimental.dag.DirectedAcyclicGraph;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public abstract class AbstractSubtreeManagerRegistryBuilderBuilder<S extends SubtreeManager<? extends DataObject>, R>
+        implements ModifiableSubtreeManagerRegistryBuilder<S>, SubtreeManagerRegistryBuilder<R>, AutoCloseable {
+
+    // Using directed acyclic graph to represent the ordering relationships between writers
+    private final DirectedAcyclicGraph<InstanceIdentifier<?>, Order>
+            handlersRelations = new DirectedAcyclicGraph<>((sourceVertex, targetVertex) -> new Order());
+    private final Map<InstanceIdentifier<?>, S> handlersMap = new HashMap<>();
+
+    /**
+     * Add handler without any special relationship to any other type.
+     */
+    @Override
+    public AbstractSubtreeManagerRegistryBuilderBuilder<S, R> add(@Nonnull final S handler) {
+        // Make IID wildcarded just in case
+        // + the way InstanceIdentifier.create + equals work for Identifiable items is unexpected, meaning updates would
+        // not be matched to writers in registry
+        final InstanceIdentifier<?> targetType = RWUtils.makeIidWildcarded(handler.getManagedDataObjectType());
+        checkWriterNotPresentYet(targetType);
+        handlersRelations.addVertex(targetType);
+        handlersMap.put(targetType, handler);
+        return this;
+    }
+
+    /**
+     * Add handler without any special relationship to any other type.
+     */
+    @Override
+    public AbstractSubtreeManagerRegistryBuilderBuilder<S, R> subtreeAdd(@Nonnull final Set<InstanceIdentifier<?>> handledChildren,
+                                                                         @Nonnull final S handler) {
+        add(getSubtreeHandler(handledChildren, handler));
+        return this;
+    }
+
+    private void checkWriterNotPresentYet(final InstanceIdentifier<?> targetType) {
+        Preconditions.checkArgument(!handlersMap.containsKey(targetType),
+                "Writer for type: %s already present: %s", targetType, handlersMap.get(targetType));
+    }
+
+    /**
+     * Add handler with relationship: to be executed before handler handling relatedType.
+     */
+    @Override
+    public AbstractSubtreeManagerRegistryBuilderBuilder<S, R> addBefore(@Nonnull final S handler,
+                                                                        @Nonnull final InstanceIdentifier<?> relatedType) {
+        final InstanceIdentifier<?> targetType = RWUtils.makeIidWildcarded(handler.getManagedDataObjectType());
+        final InstanceIdentifier<?> wildcardedRelatedType = RWUtils.makeIidWildcarded(relatedType);
+        checkWriterNotPresentYet(targetType);
+        handlersRelations.addVertex(targetType);
+        handlersRelations.addVertex(wildcardedRelatedType);
+        addEdge(targetType, wildcardedRelatedType);
+        handlersMap.put(targetType, handler);
+        return this;
+    }
+
+    @Override
+    public AbstractSubtreeManagerRegistryBuilderBuilder<S, R> addBefore(@Nonnull final S handler,
+                                                                        @Nonnull final Collection<InstanceIdentifier<?>> relatedTypes) {
+        final InstanceIdentifier<?> targetType = RWUtils.makeIidWildcarded(handler.getManagedDataObjectType());
+        checkWriterNotPresentYet(targetType);
+        handlersRelations.addVertex(targetType);
+        relatedTypes.stream()
+                .map(RWUtils::makeIidWildcarded)
+                .forEach(handlersRelations::addVertex);
+        relatedTypes.stream()
+                .map(RWUtils::makeIidWildcarded)
+                .forEach(type -> addEdge(targetType, type));
+        handlersMap.put(targetType, handler);
+        return this;
+    }
+
+    @Override
+    public AbstractSubtreeManagerRegistryBuilderBuilder<S, R> subtreeAddBefore(
+            @Nonnull final Set<InstanceIdentifier<?>> handledChildren,
+            @Nonnull final S handler,
+            @Nonnull final InstanceIdentifier<?> relatedType) {
+        return addBefore(getSubtreeHandler(handledChildren, handler), relatedType);
+    }
+
+    @Override
+    public AbstractSubtreeManagerRegistryBuilderBuilder<S, R> subtreeAddBefore(
+            @Nonnull final Set<InstanceIdentifier<?>> handledChildren,
+            @Nonnull final S handler,
+            @Nonnull final Collection<InstanceIdentifier<?>> relatedTypes) {
+        return addBefore(getSubtreeHandler(handledChildren, handler), relatedTypes);
+    }
+
+    protected abstract S getSubtreeHandler(@Nonnull final Set<InstanceIdentifier<?>> handledChildren,
+                                           @Nonnull final S handler);
+
+    /**
+     * Add handler with relationship: to be executed after handler handling relatedType.
+     */
+    @Override
+    public AbstractSubtreeManagerRegistryBuilderBuilder<S, R> addAfter(@Nonnull final S handler,
+                                                                       @Nonnull final InstanceIdentifier<?> relatedType) {
+        final InstanceIdentifier<?> targetType = RWUtils.makeIidWildcarded(handler.getManagedDataObjectType());
+        final InstanceIdentifier<?> wildcardedRelatedType = RWUtils.makeIidWildcarded(relatedType);
+        checkWriterNotPresentYet(targetType);
+        handlersRelations.addVertex(targetType);
+        handlersRelations.addVertex(wildcardedRelatedType);
+        // set edge to indicate before relationship, just reversed
+        addEdge(wildcardedRelatedType, targetType);
+        handlersMap.put(targetType, handler);
+        return this;
+    }
+
+    @Override
+    public AbstractSubtreeManagerRegistryBuilderBuilder<S, R> addAfter(@Nonnull final S handler,
+                                                                       @Nonnull final Collection<InstanceIdentifier<?>> relatedTypes) {
+        final InstanceIdentifier<?> targetType = RWUtils.makeIidWildcarded(handler.getManagedDataObjectType());
+        checkWriterNotPresentYet(targetType);
+        handlersRelations.addVertex(targetType);
+        relatedTypes.stream()
+                .map(RWUtils::makeIidWildcarded)
+                .forEach(handlersRelations::addVertex);
+        // set edge to indicate before relationship, just reversed
+        relatedTypes.stream()
+                .map(RWUtils::makeIidWildcarded)
+                .forEach(type -> addEdge(type, targetType));
+        handlersMap.put(targetType, handler);
+        return this;
+    }
+
+    @Override
+    public AbstractSubtreeManagerRegistryBuilderBuilder<S, R> subtreeAddAfter(
+            @Nonnull final Set<InstanceIdentifier<?>> handledChildren,
+            @Nonnull final S handler,
+            @Nonnull final InstanceIdentifier<?> relatedType) {
+        return addAfter(getSubtreeHandler(handledChildren, handler), relatedType);
+    }
+
+    @Override
+    public AbstractSubtreeManagerRegistryBuilderBuilder<S, R> subtreeAddAfter(
+            @Nonnull final Set<InstanceIdentifier<?>> handledChildren,
+            @Nonnull final S handler,
+            @Nonnull final Collection<InstanceIdentifier<?>> relatedTypes) {
+        return addAfter(getSubtreeHandler(handledChildren, handler), relatedTypes);
+    }
+
+
+    private void addEdge(final InstanceIdentifier<?> targetType,
+                         final InstanceIdentifier<?> relatedType) {
+        try {
+            handlersRelations.addDagEdge(targetType, relatedType);
+        } catch (DirectedAcyclicGraph.CycleFoundException e) {
+            throw new IllegalArgumentException(String.format(
+                    "Unable to add writer with relation: %s -> %s. Loop detected", targetType, relatedType), e);
+        }
+    }
+
+    protected ImmutableMap<InstanceIdentifier<?>, S> getMappedHandlers() {
+        final ImmutableMap.Builder<InstanceIdentifier<?>, S> builder = ImmutableMap.builder();
+        // Iterate writer types according to their relationships from graph
+        handlersRelations.iterator()
+                .forEachRemaining(writerType -> {
+                    // There might be types stored just for relationship sake, no real writer, ignoring those
+                    if (handlersMap.containsKey(writerType)) {
+                        builder.put(writerType, handlersMap.get(writerType));
+                    }
+                });
+
+        // TODO we could optimize subtree handlers, if there is a dedicated handler for a node managed by a subtree
+        // handler, recreate the subtree handler with a subset of handled child nodes
+        // This way it is not necessary to change the configuration of subtree writer, just to add a dedicated child
+        // writer. This will be needed if we ever switch to annotations for reader/writer hierarchy initialization
+
+        return builder.build();
+    }
+
+    @Override
+    public void close() throws Exception {
+        handlersMap.clear();
+        // Wrap sets into another set to avoid concurrent modification ex in graph
+        handlersRelations.removeAllEdges(Sets.newHashSet(handlersRelations.edgeSet()));
+        handlersRelations.removeAllVertices(Sets.newHashSet(handlersRelations.vertexSet()));
+    }
+
+    // Represents edges in graph
+    private class Order {}
+}
index 55ae9ec..ba9d8e1 100644 (file)
@@ -22,7 +22,6 @@ import com.google.common.base.Predicate;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Maps;
 import io.fd.honeycomb.v3po.translate.SubtreeManager;
-import io.fd.honeycomb.v3po.translate.read.ChildReader;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
@@ -32,7 +31,6 @@ import java.util.stream.Collectors;
 import java.util.stream.StreamSupport;
 import javax.annotation.Nonnull;
 import org.opendaylight.yangtools.yang.binding.Augmentation;
-import org.opendaylight.yangtools.yang.binding.ChildOf;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.Identifiable;
 import org.opendaylight.yangtools.yang.binding.Identifier;
@@ -75,24 +73,6 @@ public final class RWUtils {
         return Iterables.get(pathArguments, i + 1);
     }
 
-    public static <T> List<ChildReader<? extends ChildOf<T>>> emptyChildReaderList() {
-        return Collections.emptyList();
-    }
-
-    public static <T> List<ChildReader<? extends Augmentation<T>>> emptyAugReaderList() {
-        return Collections.emptyList();
-    }
-
-    public static <T> List<ChildReader<? extends Augmentation<T>>> singletonAugReaderList(
-        ChildReader<? extends Augmentation<T>> item) {
-        return Collections.<ChildReader<? extends Augmentation<T>>>singletonList(item);
-    }
-
-    public static <T> List<ChildReader<? extends ChildOf<T>>> singletonChildReaderList(
-        ChildReader<? extends ChildOf<T>> item) {
-        return Collections.<ChildReader<? extends ChildOf<T>>>singletonList(item);
-    }
-
     /**
      * Replace last item in ID with a provided IdentifiableItem of the same type
      */
@@ -170,25 +150,16 @@ public final class RWUtils {
         }
     };
 
-    @SuppressWarnings("unchecked")
-    public static <D extends DataObject> InstanceIdentifier<D> appendTypeToId(
-        final InstanceIdentifier<? extends DataObject> parentId, final InstanceIdentifier<D> type) {
-        Preconditions.checkArgument(!parentId.contains(type),
-            "Unexpected InstanceIdentifier %s, already contains %s", parentId, type);
-        final InstanceIdentifier.PathArgument t = Iterables.getOnlyElement(type.getPathArguments());
-        return (InstanceIdentifier<D>) InstanceIdentifier.create(Iterables.concat(
-            parentId.getPathArguments(), Collections.singleton(t)));
-    }
-
     /**
      * Transform a keyed instance identifier into a wildcarded one.
      */
-    public static InstanceIdentifier<?> makeIidWildcarded(final InstanceIdentifier<?> id) {
+    @SuppressWarnings("unchecked")
+    public static <D extends DataObject> InstanceIdentifier<D> makeIidWildcarded(final InstanceIdentifier<D> id) {
         final List<InstanceIdentifier.PathArgument> transformedPathArguments =
                 StreamSupport.stream(id.getPathArguments().spliterator(), false)
                         .map(RWUtils::cleanPathArgumentFromKeys)
                         .collect(Collectors.toList());
-        return InstanceIdentifier.create(transformedPathArguments);
+        return (InstanceIdentifier<D>) InstanceIdentifier.create(transformedPathArguments);
     }
 
     private static InstanceIdentifier.PathArgument cleanPathArgumentFromKeys(final InstanceIdentifier.PathArgument pathArgument) {
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package io.fd.honeycomb.v3po.translate.util.write;
+package io.fd.honeycomb.v3po.translate.util;
 
 import com.google.common.base.Optional;
 import com.google.common.util.concurrent.CheckedFuture;
@@ -28,7 +28,7 @@ import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 /**
- * Binding Transaction backed mapping context
+ * Binding Transaction backed mapping context.
  */
 public class TransactionMappingContext implements MappingContext {
 
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/AbstractGenericReader.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/AbstractGenericReader.java
new file mode 100644 (file)
index 0000000..9bfbc24
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * 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.v3po.translate.util.read;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Optional;
+import io.fd.honeycomb.v3po.translate.read.ReadContext;
+import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
+import io.fd.honeycomb.v3po.translate.read.Reader;
+import io.fd.honeycomb.v3po.translate.util.RWUtils;
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Beta
+public abstract class AbstractGenericReader<D extends DataObject, B extends Builder<D>> implements Reader<D, B> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractGenericReader.class);
+
+    private final InstanceIdentifier<D> instanceIdentifier;
+
+    protected AbstractGenericReader(final InstanceIdentifier<D> managedDataObjectType) {
+        this.instanceIdentifier = RWUtils.makeIidWildcarded(managedDataObjectType);
+    }
+
+    @Nonnull
+    @Override
+    public final InstanceIdentifier<D> getManagedDataObjectType() {
+        return instanceIdentifier;
+    }
+
+    /**
+     * @param id {@link InstanceIdentifier} pointing to current node. In case of keyed list, key must be present.
+     *
+     */
+    protected Optional<D> readCurrent(@Nonnull final InstanceIdentifier<D> id,
+                                      @Nonnull final ReadContext ctx) throws ReadFailedException {
+        LOG.debug("{}: Reading current: {}", this, id);
+        final B builder = getBuilder(id);
+        // Cache empty value to determine if anything has changed later TODO cache in a field
+        final D emptyValue = builder.build();
+
+        LOG.trace("{}: Reading current attributes", this);
+        readCurrentAttributes(id, builder, ctx);
+
+        // Need to check whether anything was filled in to determine if data is present or not.
+        final D built = builder.build();
+        final Optional<D> read = built.equals(emptyValue)
+            ? Optional.absent()
+            : Optional.of(built);
+
+        LOG.debug("{}: Current node read successfully. Result: {}", this, read);
+        return read;
+    }
+
+    @Nonnull
+    @Override
+    @SuppressWarnings("unchecked")
+    public Optional<? extends DataObject> read(@Nonnull final InstanceIdentifier<? extends DataObject> id,
+                                               @Nonnull final ReadContext ctx)
+            throws ReadFailedException {
+        LOG.trace("{}: Reading : {}", this, id);
+        checkArgument(id.getTargetType().equals(getManagedDataObjectType().getTargetType()));
+        return readCurrent((InstanceIdentifier<D>) id, ctx);
+    }
+
+    @Override
+    public String toString() {
+        return String.format("Reader[%s]", getManagedDataObjectType().getTargetType().getSimpleName());
+    }
+}
index 58695cf..68aa395 100644 (file)
@@ -25,23 +25,29 @@ import javax.annotation.Nonnull;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yangtools.concepts.Builder;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 /**
- * Simple DataBroker backed reader allowing to delegate reads to different brokers
+ * Simple DataBroker backed reader allowing to delegate reads to different brokers.
  */
-public final class BindingBrokerReader<D extends DataObject> implements Reader<D> {
+public final class BindingBrokerReader<D extends DataObject, B extends Builder<D>>
+        implements Reader<D, B>, AutoCloseable {
 
     private final InstanceIdentifier<D> instanceIdentifier;
     private final DataBroker dataBroker;
     private final LogicalDatastoreType datastoreType;
+    private final ReflexiveReaderCustomizer<D, B> reflexiveReaderCustomizer;
 
-    public BindingBrokerReader(final Class<D> managedDataObjectType, final DataBroker dataBroker,
-                               final LogicalDatastoreType datastoreType) {
+    public BindingBrokerReader(final InstanceIdentifier<D> instanceIdentifier,
+                               final DataBroker dataBroker,
+                               final LogicalDatastoreType datastoreType,
+                               final Class<B> builderClass) {
+        this.reflexiveReaderCustomizer = new ReflexiveReaderCustomizer<>(instanceIdentifier.getTargetType(), builderClass);
+        this.instanceIdentifier = instanceIdentifier;
         this.dataBroker = dataBroker;
         this.datastoreType = datastoreType;
-        this.instanceIdentifier = InstanceIdentifier.create(managedDataObjectType);
     }
 
     @Nonnull
@@ -59,9 +65,32 @@ public final class BindingBrokerReader<D extends DataObject> implements Reader<D
         }
     }
 
+    @Override
+    public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, @Nonnull final D readValue) {
+        reflexiveReaderCustomizer.merge(parentBuilder, readValue);
+    }
+
+    @Nonnull
+    @Override
+    public B getBuilder(final InstanceIdentifier<D> id) {
+        return reflexiveReaderCustomizer.getBuilder(id);
+    }
+
+    @Override
+    public void readCurrentAttributes(@Nonnull final InstanceIdentifier<D> id,
+                                      @Nonnull final B builder,
+                                      @Nonnull final ReadContext ctx) throws ReadFailedException {
+        throw new UnsupportedOperationException("Not supported");
+    }
+
     @Nonnull
     @Override
     public InstanceIdentifier<D> getManagedDataObjectType() {
         return instanceIdentifier;
     }
+
+    @Override
+    public void close() throws Exception {
+        // Noop
+    }
 }
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/CloseableReader.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/CloseableReader.java
deleted file mode 100644 (file)
index 5492062..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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.v3po.translate.util.read;
-
-import com.google.common.base.Optional;
-import io.fd.honeycomb.v3po.translate.read.ReadContext;
-import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.read.Reader;
-import javax.annotation.Nonnull;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-/**
- * Closeable wrapper for a reader
- */
-public final class CloseableReader<D extends DataObject> implements Reader<D>, AutoCloseable {
-
-    private Reader<D> compositeRootReader;
-
-    public CloseableReader(@Nonnull final Reader<D> compositeRootReader) {
-        this.compositeRootReader = compositeRootReader;
-    }
-
-    @Nonnull
-    @Override
-    public Optional<? extends DataObject> read(@Nonnull InstanceIdentifier<? extends DataObject> id,
-                                               @Nonnull ReadContext ctx) throws ReadFailedException {
-        return compositeRootReader.read(id, ctx);
-    }
-
-    @Nonnull
-    @Override
-    public InstanceIdentifier<D> getManagedDataObjectType() {
-        return compositeRootReader.getManagedDataObjectType();
-    }
-
-    @Override
-    public String toString() {
-        return compositeRootReader.toString();
-    }
-
-    @Override
-    public void close() throws Exception {
-        //NOOP
-    }
-}
  * limitations under the License.
  */
 
-package io.fd.honeycomb.v3po.translate.util;
+package io.fd.honeycomb.v3po.translate.util.read;
 
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import io.fd.honeycomb.v3po.translate.MappingContext;
 import io.fd.honeycomb.v3po.translate.ModificationCache;
-import io.fd.honeycomb.v3po.translate.read.ChildReader;
 import io.fd.honeycomb.v3po.translate.read.ReadContext;
 import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
+import io.fd.honeycomb.v3po.translate.read.Reader;
 import java.io.Closeable;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledFuture;
@@ -39,13 +39,13 @@ import org.slf4j.LoggerFactory;
  * Reader wrapper that periodically invokes a read to determine whether reads are still fully functional.
  * In case a specific error occurs, Keep-alive failure listener gets notified.
  */
-public final class KeepaliveReaderWrapper<D extends DataObject> implements ChildReader<D>, Runnable, Closeable {
+public final class KeepaliveReaderWrapper<D extends DataObject, B extends Builder<D>> implements Reader<D, B>, Runnable, Closeable {
 
     private static final Logger LOG = LoggerFactory.getLogger(KeepaliveReaderWrapper.class);
 
     private static final NoopReadContext CTX = new NoopReadContext();
 
-    private final ChildReader<D> delegate;
+    private final Reader<D, B> delegate;
     private final Class<? extends Exception> exceptionType;
     private final KeepaliveFailureListener failureListener;
     private final ScheduledFuture<?> scheduledFuture;
@@ -59,7 +59,7 @@ public final class KeepaliveReaderWrapper<D extends DataObject> implements Child
      * @param delayInSeconds number of seconds to wait between keepalive calls
      * @param failureListener listener to be called whenever a keepalive failure is detected
      */
-    public KeepaliveReaderWrapper(@Nonnull final ChildReader<D> delegate,
+    public KeepaliveReaderWrapper(@Nonnull final Reader<D, B> delegate,
                                   @Nonnull final ScheduledExecutorService executor,
                                   @Nonnull final Class<? extends Exception> exception,
                                   @Nonnegative final int delayInSeconds,
@@ -73,17 +73,25 @@ public final class KeepaliveReaderWrapper<D extends DataObject> implements Child
     }
 
     @Nonnull
-    @Override
-    public Optional<? extends DataObject> read(@Nonnull final InstanceIdentifier<? extends DataObject> id,
+    public Optional<? extends DataObject> read(@Nonnull final InstanceIdentifier id,
                                                @Nonnull final ReadContext ctx) throws ReadFailedException {
         return delegate.read(id, ctx);
     }
 
-    @Override
-    public void read(@Nonnull final InstanceIdentifier<? extends DataObject> id,
-                     @Nonnull final Builder<? extends DataObject> parentBuilder, @Nonnull final ReadContext ctx)
-        throws ReadFailedException {
-        delegate.read(id, parentBuilder, ctx);
+    public void readCurrentAttributes(@Nonnull final InstanceIdentifier<D> id,
+                                      @Nonnull final B builder,
+                                      @Nonnull final ReadContext ctx) throws ReadFailedException {
+        delegate.readCurrentAttributes(id, builder, ctx);
+    }
+
+    @Nonnull
+    public B getBuilder(final InstanceIdentifier<D> id) {
+        return delegate.getBuilder(id);
+    }
+
+    public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder,
+                      @Nonnull final D readValue) {
+        delegate.merge(parentBuilder, readValue);
     }
 
     @Nonnull
@@ -99,7 +107,7 @@ public final class KeepaliveReaderWrapper<D extends DataObject> implements Child
             final Optional<? extends DataObject> read = read(delegate.getManagedDataObjectType(), CTX);
             LOG.debug("Keepalive executed successfully with data: {}", read);
         } catch (Exception e) {
-            if(exceptionType.isAssignableFrom(e.getClass())) {
+            if (exceptionType.isAssignableFrom(e.getClass())) {
                 LOG.warn("Keepalive failed. Notifying listener", e);
                 failureListener.onKeepaliveFailure();
             }
index cf494ef..a4de9fe 100644 (file)
@@ -18,13 +18,13 @@ package io.fd.honeycomb.v3po.translate.util.read;
 
 import io.fd.honeycomb.v3po.translate.read.ReadContext;
 import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.spi.read.RootReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.read.ReaderCustomizer;
 import org.opendaylight.yangtools.concepts.Builder;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 public abstract class NoopReaderCustomizer<C extends DataObject, B extends Builder<C>> implements
-    RootReaderCustomizer<C, B> {
+        ReaderCustomizer<C, B> {
 
     @Override
     public void readCurrentAttributes(InstanceIdentifier<C> id, final B builder, final ReadContext context) throws
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveAugmentReaderCustomizer.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveAugmentReaderCustomizer.java
deleted file mode 100644 (file)
index 38107ed..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.v3po.translate.util.read;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import com.google.common.base.Optional;
-import com.google.common.collect.Lists;
-import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
-import io.fd.honeycomb.v3po.translate.util.ReflectionUtils;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import org.opendaylight.yangtools.concepts.Builder;
-import org.opendaylight.yangtools.yang.binding.Augmentation;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-
-/**
- * Might be slow !
- */
-public class ReflexiveAugmentReaderCustomizer<C extends DataObject, B extends Builder<C>>
-    extends ReflexiveRootReaderCustomizer<C, B>
-    implements ChildReaderCustomizer<C,B> {
-
-    private final Class<C> augType;
-
-    public ReflexiveAugmentReaderCustomizer(final Class<B> builderClass, final Class<C> augType) {
-        super(builderClass);
-        this.augType = augType;
-    }
-
-    @Override
-    public void merge(final Builder<? extends DataObject> parentBuilder, final C readValue) {
-        final Optional<Method> method =
-            ReflectionUtils.findMethodReflex(parentBuilder.getClass(), "addAugmentation",
-                Lists.newArrayList(Class.class, Augmentation.class), parentBuilder.getClass());
-
-        checkArgument(method.isPresent(), "Not possible to add augmentations to builder: %s", parentBuilder);
-        try {
-            method.get().invoke(parentBuilder, augType, readValue);
-        } catch (IllegalAccessException | InvocationTargetException e) {
-            throw new IllegalArgumentException("Unable to set " + readValue + " to " + parentBuilder, e);
-        }
-    }
-
-}
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveChildReaderCustomizer.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveChildReaderCustomizer.java
deleted file mode 100644 (file)
index 3d5f9f4..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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.v3po.translate.util.read;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import io.fd.honeycomb.v3po.translate.util.ReflectionUtils;
-import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Collections;
-import org.opendaylight.yangtools.concepts.Builder;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-
-/**
- * Might be slow !
- */
-public class ReflexiveChildReaderCustomizer<C extends DataObject, B extends Builder<C>>
-    extends ReflexiveRootReaderCustomizer<C, B>
-    implements ChildReaderCustomizer<C,B> {
-
-    public ReflexiveChildReaderCustomizer(final Class<B> builderClass) {
-        super(builderClass);
-    }
-
-    // TODO Could be just a default implementation in interface (making this a mixin)
-
-    @Override
-    public void merge(final Builder<? extends DataObject> parentBuilder, final C readValue) {
-        final Optional<Method> method =
-            ReflectionUtils.findMethodReflex(parentBuilder.getClass(), "set",
-                Collections.<Class<?>>singletonList(readValue.getClass()), parentBuilder.getClass());
-
-        Preconditions.checkArgument(method.isPresent(), "Unable to set %s to %s", readValue, parentBuilder);
-
-        try {
-            method.get().invoke(parentBuilder, readValue);
-        } catch (IllegalAccessException | InvocationTargetException e) {
-            throw new IllegalArgumentException("Unable to set " + readValue + " to " + parentBuilder, e);
-        }
-    }
-
-}
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveReader.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveReader.java
new file mode 100644 (file)
index 0000000..51725e7
--- /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.v3po.translate.util.read;
+
+import io.fd.honeycomb.v3po.translate.read.ReadContext;
+import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Reader that performs no read operation on its own, just fills in the hierarchy.
+ * <p/>
+ * Might be slow due to reflection !
+ */
+public final class ReflexiveReader<C extends DataObject, B extends Builder<C>> extends AbstractGenericReader<C, B> {
+
+    private final ReflexiveReaderCustomizer<C, B> customizer;
+
+    public ReflexiveReader(final InstanceIdentifier<C> identifier, final Class<B> builderClass) {
+        super(identifier);
+        this.customizer = new ReflexiveReaderCustomizer<>(identifier.getTargetType(), builderClass);
+    }
+
+    @Override
+    public void readCurrentAttributes(@Nonnull final InstanceIdentifier<C> id, @Nonnull final B builder,
+                                      @Nonnull final ReadContext ctx)
+            throws ReadFailedException {
+        customizer.readCurrentAttributes(id, builder, ctx);
+    }
+
+    @Nonnull
+    @Override
+    public B getBuilder(final InstanceIdentifier<C> id) {
+        return customizer.getBuilder(id);
+    }
+
+    @Override
+    public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, @Nonnull final C readValue) {
+        customizer.merge(parentBuilder, readValue);
+    }
+}
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveReaderCustomizer.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveReaderCustomizer.java
new file mode 100644 (file)
index 0000000..f9efca3
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * 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.v3po.translate.util.read;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
+import io.fd.honeycomb.v3po.translate.util.ReflectionUtils;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Might be slow !
+ */
+final class ReflexiveReaderCustomizer<C extends DataObject, B extends Builder<C>> extends NoopReaderCustomizer<C, B> {
+
+    private final Class<C> typeClass;
+    private final Class<B> builderClass;
+
+    public ReflexiveReaderCustomizer(final Class<C> typeClass, final Class<B> builderClass) {
+        this.typeClass = typeClass;
+        this.builderClass = builderClass;
+    }
+
+    protected Class<C> getTypeClass() {
+        return typeClass;
+    }
+
+    protected Class<B> getBuilderClass() {
+        return builderClass;
+    }
+
+    @Nonnull
+    @Override
+    public B getBuilder(@Nonnull InstanceIdentifier<C> id) {
+        try {
+            return builderClass.newInstance();
+        } catch (InstantiationException | IllegalAccessException e) {
+            throw new IllegalStateException("Unable to instantiate " + builderClass, e);
+        }
+    }
+
+    @Override
+    public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, @Nonnull final C readValue) {
+        if (Augmentation.class.isAssignableFrom(typeClass)) {
+            mergeAugmentation(parentBuilder, (Class<? extends Augmentation<?>>) typeClass, readValue);
+        } else {
+            mergeRegular(parentBuilder, readValue);
+        }
+    }
+
+    private static void mergeRegular(@Nonnull final Builder<? extends DataObject> parentBuilder,
+                                     @Nonnull final DataObject readValue) {
+        final Optional<Method> method =
+                ReflectionUtils.findMethodReflex(parentBuilder.getClass(), "set",
+                        Collections.singletonList(readValue.getClass()), parentBuilder.getClass());
+
+        checkArgument(method.isPresent(), "Unable to set %s to %s", readValue, parentBuilder);
+
+        try {
+            method.get().invoke(parentBuilder, readValue);
+        } catch (IllegalAccessException | InvocationTargetException e) {
+            throw new IllegalArgumentException("Unable to set " + readValue + " to " + parentBuilder, e);
+        }
+    }
+
+    private static void mergeAugmentation(@Nonnull final Builder<? extends DataObject> parentBuilder,
+                                          @Nonnull final Class<? extends Augmentation<?>> typeClass,
+                                          @Nonnull final DataObject readValue) {
+        final Optional<Method> method =
+                ReflectionUtils.findMethodReflex(parentBuilder.getClass(), "addAugmentation",
+                        Lists.newArrayList(Class.class, Augmentation.class), parentBuilder.getClass());
+
+        checkArgument(method.isPresent(), "Not possible to add augmentations to builder: %s", parentBuilder);
+        try {
+            method.get().invoke(parentBuilder, typeClass, readValue);
+        } catch (IllegalAccessException | InvocationTargetException e) {
+            throw new IllegalArgumentException("Unable to set " + readValue + " to " + parentBuilder, e);
+        }
+    }
+
+}
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveRootReaderCustomizer.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveRootReaderCustomizer.java
deleted file mode 100644 (file)
index 029f359..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.v3po.translate.util.read;
-
-import org.opendaylight.yangtools.concepts.Builder;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-/**
- * Might be slow !
- */
-public class ReflexiveRootReaderCustomizer<C extends DataObject, B extends Builder<C>>  extends NoopReaderCustomizer<C, B> {
-
-    private final Class<B> builderClass;
-
-    public ReflexiveRootReaderCustomizer(final Class<B> builderClass) {
-        this.builderClass = builderClass;
-    }
-
-    @Override
-    public B getBuilder(InstanceIdentifier<C> id) {
-        try {
-            return builderClass.newInstance();
-        } catch (InstantiationException | IllegalAccessException e) {
-            throw new IllegalStateException("Unable to instantiate " + builderClass, e);
-        }
-    }
-}
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/CompositeReader.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/CompositeReader.java
new file mode 100644 (file)
index 0000000..64ecaf0
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * 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.v3po.translate.util.read.registry;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+import io.fd.honeycomb.v3po.translate.read.ListReader;
+import io.fd.honeycomb.v3po.translate.read.ReadContext;
+import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
+import io.fd.honeycomb.v3po.translate.read.Reader;
+import io.fd.honeycomb.v3po.translate.util.RWUtils;
+import io.fd.honeycomb.v3po.translate.util.read.AbstractGenericReader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.Identifiable;
+import org.opendaylight.yangtools.yang.binding.Identifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class CompositeReader<D extends DataObject, B extends Builder<D>> extends AbstractGenericReader<D, B> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CompositeReader.class);
+
+    private final Reader<D, B> delegate;
+    private final ImmutableMap<Class<?>, Reader<? extends DataObject, ? extends Builder<?>>> childReaders;
+
+    private CompositeReader(final Reader<D, B> reader,
+                            final ImmutableMap<Class<?>, Reader<? extends DataObject, ? extends Builder<?>>> childReaders) {
+        super(reader.getManagedDataObjectType());
+        this.delegate = reader;
+        this.childReaders = childReaders;
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <D extends DataObject> InstanceIdentifier<D> appendTypeToId(
+        final InstanceIdentifier<? extends DataObject> parentId, final InstanceIdentifier<D> type) {
+        final InstanceIdentifier.PathArgument t = new InstanceIdentifier.Item<>(type.getTargetType());
+        return (InstanceIdentifier<D>) InstanceIdentifier.create(Iterables.concat(
+            parentId.getPathArguments(), Collections.singleton(t)));
+    }
+
+    @Nonnull
+    @Override
+    public Optional<? extends DataObject> read(@Nonnull final InstanceIdentifier<? extends DataObject> id,
+                                               @Nonnull final ReadContext ctx) throws ReadFailedException {
+        if (shouldReadCurrent(id)) {
+            return readCurrent((InstanceIdentifier<D>) id, ctx);
+        } else if (shouldDelegateToChild(id)) {
+            return readSubtree(id, ctx);
+        } else {
+            // Fallback
+            return delegate.read(id, ctx);
+        }
+    }
+
+    private boolean shouldReadCurrent(@Nonnull final InstanceIdentifier<? extends DataObject> id) {
+        return id.getTargetType().equals(getManagedDataObjectType().getTargetType());
+    }
+
+    private boolean shouldDelegateToChild(@Nonnull final InstanceIdentifier<? extends DataObject> id) {
+        return childReaders.containsKey(RWUtils.getNextId(id, getManagedDataObjectType()).getType());
+    }
+
+    private Optional<? extends DataObject> readSubtree(final InstanceIdentifier<? extends DataObject> id,
+                                                       final ReadContext ctx) throws ReadFailedException {
+        final InstanceIdentifier.PathArgument nextId = RWUtils.getNextId(id, getManagedDataObjectType());
+        final Reader<?, ? extends Builder<?>> nextReader = childReaders.get(nextId.getType());
+        checkArgument(nextReader != null, "Unable to read: %s. No delegate present, available readers at next level: %s",
+                id, childReaders.keySet());
+        return nextReader.read(id, ctx);
+    }
+
+    @SuppressWarnings("unchecked")
+    private void readChildren(final InstanceIdentifier<D> id, @Nonnull final ReadContext ctx, final B builder)
+            throws ReadFailedException {
+        for (Reader child : childReaders.values()) {
+            LOG.debug("{}: Reading child node from: {}", this, child);
+            final InstanceIdentifier childId = appendTypeToId(id, child.getManagedDataObjectType());
+
+            if (child instanceof ListReader) {
+                final List<? extends DataObject> list = ((ListReader) child).readList(childId, ctx);
+                ((ListReader) child).merge(builder, list);
+            } else {
+                final Optional<? extends DataObject> read = child.read(childId, ctx);
+                if (read.isPresent()) {
+                    child.merge(builder, read.get());
+                }
+            }
+        }
+    }
+
+    @Override
+    public void readCurrentAttributes(@Nonnull final InstanceIdentifier<D> id, @Nonnull final B builder,
+                                      @Nonnull final ReadContext ctx)
+            throws ReadFailedException {
+        delegate.readCurrentAttributes(id, builder, ctx);
+        readChildren(id, ctx, builder);
+    }
+
+    @Nonnull
+    @Override
+    public B getBuilder(final InstanceIdentifier<D> id) {
+        return delegate.getBuilder(id);
+    }
+
+    @Override
+    public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, @Nonnull final D readValue) {
+        delegate.merge(parentBuilder, readValue);
+    }
+
+    /**
+     * Wrap a Reader as a Composite Reader.
+     */
+    static <D extends DataObject, B extends Builder<D>> Reader<D, B> createForReader(
+            @Nonnull final Reader<D, B> reader,
+            @Nonnull final ImmutableMap<Class<?>, Reader<?, ? extends Builder<?>>> childReaders) {
+
+        return (reader instanceof ListReader)
+                ? new CompositeListReader<>((ListReader) reader, childReaders)
+                : new CompositeReader<>(reader, childReaders);
+    }
+
+    private static class CompositeListReader<D extends DataObject & Identifiable<K>, B extends Builder<D>, K extends Identifier<D>>
+            extends CompositeReader<D, B>
+            implements ListReader<D, K, B> {
+
+        private final ListReader<D, K, B> delegate;
+
+        private CompositeListReader(final ListReader<D, K, B> reader,
+                                    final ImmutableMap<Class<?>, Reader<? extends DataObject, ? extends Builder<?>>> childReaders) {
+            super(reader, childReaders);
+            this.delegate = reader;
+        }
+
+        @Nonnull
+        @Override
+        public List<D> readList(@Nonnull final InstanceIdentifier<D> id, @Nonnull final ReadContext ctx)
+                throws ReadFailedException {
+            LOG.trace("{}: Reading all list entries", this);
+            final List<K> allIds = delegate.getAllIds(id, ctx);
+            LOG.debug("{}: Reading list entries for: {}", this, allIds);
+
+            // Override read list in order to perform readCurrent + readChildren here
+            final ArrayList<D> allEntries = new ArrayList<>(allIds.size());
+            for (K key : allIds) {
+                final InstanceIdentifier.IdentifiableItem<D, K> currentBdItem = RWUtils.getCurrentIdItem(id, key);
+                final InstanceIdentifier<D> keyedId = RWUtils.replaceLastInId(id, currentBdItem);
+                final Optional<D> read = readCurrent(keyedId, ctx);
+                if (read.isPresent()) {
+                    final DataObject singleItem = read.get();
+                    checkArgument(getManagedDataObjectType().getTargetType().isAssignableFrom(singleItem.getClass()));
+                    allEntries.add(getManagedDataObjectType().getTargetType().cast(singleItem));
+                }
+            }
+            return allEntries;
+        }
+
+        @Override
+        public void merge(@Nonnull final Builder<? extends DataObject> builder, @Nonnull final List<D> readData) {
+            delegate.merge(builder, readData);
+        }
+
+        @Override
+        public List<K> getAllIds(@Nonnull final InstanceIdentifier<D> id,
+                                 @Nonnull final ReadContext ctx) throws ReadFailedException {
+            return delegate.getAllIds(id, ctx);
+        }
+    }
+
+}
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package io.fd.honeycomb.v3po.translate.util.read;
+package io.fd.honeycomb.v3po.translate.util.read.registry;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
@@ -25,13 +25,14 @@ import com.google.common.collect.Multimap;
 import io.fd.honeycomb.v3po.translate.read.ListReader;
 import io.fd.honeycomb.v3po.translate.read.ReadContext;
 import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.read.ReaderRegistry;
-import io.fd.honeycomb.v3po.translate.util.RWUtils;
 import io.fd.honeycomb.v3po.translate.read.Reader;
+import io.fd.honeycomb.v3po.translate.read.registry.ReaderRegistry;
+import io.fd.honeycomb.v3po.translate.util.RWUtils;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.concepts.Builder;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
@@ -40,21 +41,21 @@ import org.slf4j.LoggerFactory;
 /**
  * Simple reader registry able to perform and aggregated read (ROOT read) on top of all provided readers. Also able to
  * delegate a specific read to one of the delegate readers.
- *
+ * <p/>
  * This could serve as a utility to hold & hide all available readers in upper layers.
  */
-public final class DelegatingReaderRegistry implements ReaderRegistry {
+public final class CompositeReaderRegistry implements ReaderRegistry {
 
-    private static final Logger LOG = LoggerFactory.getLogger(DelegatingReaderRegistry.class);
+    private static final Logger LOG = LoggerFactory.getLogger(CompositeReaderRegistry.class);
 
-    private final Map<Class<? extends DataObject>, Reader<? extends DataObject>> rootReaders;
+    private final Map<Class<? extends DataObject>, Reader<? extends DataObject, ? extends Builder<?>>> rootReaders;
 
     /**
-     * Create new {@link DelegatingReaderRegistry}
+     * Create new {@link CompositeReaderRegistry}.
      *
      * @param rootReaders List of delegate readers
      */
-    public DelegatingReaderRegistry(@Nonnull final List<Reader<? extends DataObject>> rootReaders) {
+    public CompositeReaderRegistry(@Nonnull final List<Reader<? extends DataObject, ? extends Builder<?>>> rootReaders) {
         this.rootReaders = RWUtils.uniqueLinkedIndex(checkNotNull(rootReaders), RWUtils.MANAGER_CLASS_FUNCTION);
     }
 
@@ -67,7 +68,7 @@ public final class DelegatingReaderRegistry implements ReaderRegistry {
         LOG.trace("Reading from all delegates: {}", rootReaders.values());
 
         final Multimap<InstanceIdentifier<? extends DataObject>, DataObject> objects = LinkedListMultimap.create();
-        for (Reader<? extends DataObject> rootReader : rootReaders.values()) {
+        for (Reader<? extends DataObject, ? extends Builder<?>> rootReader : rootReaders.values()) {
             LOG.debug("Reading from delegate: {}", rootReader);
 
             if (rootReader instanceof ListReader) {
@@ -94,20 +95,10 @@ public final class DelegatingReaderRegistry implements ReaderRegistry {
             throws ReadFailedException {
         final InstanceIdentifier.PathArgument first = checkNotNull(
                 Iterables.getFirst(id.getPathArguments(), null), "Empty id");
-        final Reader<? extends DataObject> reader = rootReaders.get(first.getType());
+        final Reader<? extends DataObject, ? extends Builder<?>> reader = rootReaders.get(first.getType());
         checkNotNull(reader,
                 "Unable to read %s. Missing reader. Current readers for: %s", id, rootReaders.keySet());
         LOG.debug("Reading from delegate: {}", reader);
         return reader.read(id, ctx);
     }
-
-    /**
-     * @throws UnsupportedOperationException This getter is not supported for reader registry since it does not manage a
-     *                                       specific node type
-     */
-    @Nonnull
-    @Override
-    public InstanceIdentifier<DataObject> getManagedDataObjectType() {
-        throw new UnsupportedOperationException("Root registry has no type");
-    }
 }
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/CompositeReaderRegistryBuilder.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/CompositeReaderRegistryBuilder.java
new file mode 100644 (file)
index 0000000..3adda71
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * 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.v3po.translate.util.read.registry;
+
+import com.google.common.collect.ImmutableMap;
+import io.fd.honeycomb.v3po.translate.read.Reader;
+import io.fd.honeycomb.v3po.translate.read.registry.ModifiableReaderRegistryBuilder;
+import io.fd.honeycomb.v3po.translate.read.registry.ReaderRegistry;
+import io.fd.honeycomb.v3po.translate.read.registry.ReaderRegistryBuilder;
+import io.fd.honeycomb.v3po.translate.util.AbstractSubtreeManagerRegistryBuilderBuilder;
+import io.fd.honeycomb.v3po.translate.util.read.ReflexiveReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
+import javax.annotation.concurrent.NotThreadSafe;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@NotThreadSafe
+public final class CompositeReaderRegistryBuilder
+        extends AbstractSubtreeManagerRegistryBuilderBuilder<Reader<? extends DataObject, ? extends Builder<?>>, ReaderRegistry>
+        implements ModifiableReaderRegistryBuilder, ReaderRegistryBuilder {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CompositeReaderRegistryBuilder.class);
+
+    @Override
+    protected Reader<? extends DataObject, ? extends Builder<?>> getSubtreeHandler(@Nonnull final Set<InstanceIdentifier<?>> handledChildren,
+                                                                                   @Nonnull final Reader<? extends DataObject, ? extends Builder<?>> reader) {
+        return SubtreeReader.createForReader(handledChildren, reader);
+    }
+
+    @Override
+    public <D extends DataObject> void addStructuralReader(@Nonnull InstanceIdentifier<D> id,
+                                                           @Nonnull Class<? extends Builder<D>> builderType) {
+        add(new ReflexiveReader<>(id, builderType));
+    }
+
+    /**
+     * Create {@link CompositeReaderRegistry} with Readers ordered according to submitted relationships.
+     * <p/>
+     * Note: The ordering only applies between nodes on the same level, inter-level and inter-subtree relationships are
+     * ignored.
+     */
+    @Override
+    public ReaderRegistry build() {
+        ImmutableMap<InstanceIdentifier<?>, Reader<? extends DataObject, ? extends Builder<?>>> mappedReaders =
+                getMappedHandlers();
+        LOG.debug("Building Reader registry with Readers: {}",
+                mappedReaders.keySet().stream()
+                        .map(InstanceIdentifier::getTargetType)
+                        .map(Class::getSimpleName)
+                        .collect(Collectors.joining(", ")));
+
+        LOG.trace("Building Reader registry with Readers: {}", mappedReaders);
+        final List<InstanceIdentifier<?>> readerOrder = new ArrayList<>(mappedReaders.keySet());
+
+        // Wrap readers into composite readers recursively, collect roots and create registry
+        final TypeHierarchy typeHierarchy = TypeHierarchy.create(mappedReaders.keySet());
+        final List<Reader<? extends DataObject, ? extends Builder<?>>> orderedRootReaders =
+                typeHierarchy.getRoots().stream()
+                        .map(rootId -> toCompositeReader(rootId, mappedReaders, typeHierarchy))
+                        .collect(Collectors.toList());
+
+        // We are violating the ordering from mappedReaders, since we are forming a composite structure
+        // but at least order root writers
+        orderedRootReaders.sort((reader1, reader2) -> readerOrder.indexOf(reader1.getManagedDataObjectType())
+                - readerOrder.indexOf(reader2.getManagedDataObjectType()));
+
+        return new CompositeReaderRegistry(orderedRootReaders);
+    }
+
+    private Reader<? extends DataObject, ? extends Builder<?>> toCompositeReader(
+            final InstanceIdentifier<?> instanceIdentifier,
+            final ImmutableMap<InstanceIdentifier<?>, Reader<? extends DataObject, ? extends Builder<?>>> mappedReaders,
+            final TypeHierarchy typeHierarchy) {
+
+        // Order child readers according to the mappedReadersCollection
+        final ImmutableMap.Builder<Class<?>, Reader<?, ? extends Builder<?>>> childReadersMapB = ImmutableMap.builder();
+        for (InstanceIdentifier<?> childId : mappedReaders.keySet()) {
+            if (typeHierarchy.getDirectChildren(instanceIdentifier).contains(childId)) {
+                childReadersMapB.put(childId.getTargetType(), toCompositeReader(childId, mappedReaders, typeHierarchy));
+            }
+        }
+
+        final ImmutableMap<Class<?>, Reader<?, ? extends Builder<?>>> childReadersMap = childReadersMapB.build();
+        return childReadersMap.isEmpty()
+                ? mappedReaders.get(instanceIdentifier)
+                : CompositeReader.createForReader(mappedReaders.get(instanceIdentifier), childReadersMap);
+    }
+}
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/SubtreeReader.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/SubtreeReader.java
new file mode 100644 (file)
index 0000000..98fcac6
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ * 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.v3po.translate.util.read.registry;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import io.fd.honeycomb.v3po.translate.read.ListReader;
+import io.fd.honeycomb.v3po.translate.read.ReadContext;
+import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
+import io.fd.honeycomb.v3po.translate.read.Reader;
+import io.fd.honeycomb.v3po.translate.util.RWUtils;
+import io.fd.honeycomb.v3po.translate.util.ReflectionUtils;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.Identifiable;
+import org.opendaylight.yangtools.yang.binding.Identifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Simple Reader delegate for subtree Readers (Readers handling also children nodes) providing a list of all the
+ * children nodes being handled.
+ */
+class SubtreeReader<D extends DataObject, B extends Builder<D>> implements Reader<D, B> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(SubtreeReader.class);
+
+    private final Reader<D, B> delegate;
+    private final Set<InstanceIdentifier<?>> handledChildTypes = new HashSet<>();
+
+    private SubtreeReader(final Reader<D, B> delegate, Set<InstanceIdentifier<?>> handledTypes) {
+        this.delegate = delegate;
+        for (InstanceIdentifier<?> handledType : handledTypes) {
+            // Iid has to start with Reader's handled root type
+            checkArgument(delegate.getManagedDataObjectType().getTargetType().equals(
+                    handledType.getPathArguments().iterator().next().getType()),
+                    "Handled node from subtree has to be identified by an instance identifier starting from: %s."
+                            + "Instance identifier was: %s", getManagedDataObjectType().getTargetType(), handledType);
+            checkArgument(Iterables.size(handledType.getPathArguments()) > 1,
+                    "Handled node from subtree identifier too short: %s", handledType);
+            handledChildTypes.add(InstanceIdentifier.create(Iterables.concat(
+                    getManagedDataObjectType().getPathArguments(), Iterables.skip(handledType.getPathArguments(), 1))));
+        }
+    }
+
+    /**
+     * Return set of types also handled by this Reader. All of the types are children of the type managed by this Reader
+     * excluding the type of this Reader.
+     */
+    Set<InstanceIdentifier<?>> getHandledChildTypes() {
+        return handledChildTypes;
+    }
+
+    @Override
+    @Nonnull
+    public Optional<? extends DataObject> read(
+            @Nonnull final InstanceIdentifier<? extends DataObject> id,
+            @Nonnull final ReadContext ctx) throws ReadFailedException {
+        final InstanceIdentifier<?> wildcarded = RWUtils.makeIidWildcarded(id);
+
+        // Reading entire subtree and filtering if is current reader responsible
+        if (getHandledChildTypes().contains(wildcarded)) {
+            LOG.debug("{}: Subtree node managed by this writer requested: {}. Reading current and filtering", this, id);
+            // If there's no dedicated reader, use read current
+            final InstanceIdentifier<D> currentId = RWUtils.cutId(id, getManagedDataObjectType());
+            final Optional<? extends DataObject> current = read(currentId, ctx);
+            // then perform post-reading filtering (return only requested sub-node)
+            final Optional<? extends DataObject> readSubtree = current.isPresent()
+                ? filterSubtree(current.get(), id, getManagedDataObjectType().getTargetType())
+                : current;
+
+            LOG.debug("{}: Subtree: {} read successfully. Result: {}", this, id, readSubtree);
+            return readSubtree;
+
+        // Fallback solution, try delegate, maybe it can read the ID
+        } else {
+            return delegate.read(id, ctx);
+        }
+    }
+
+    @Override
+    public void readCurrentAttributes(@Nonnull final InstanceIdentifier<D> id, @Nonnull final B builder,
+                                      @Nonnull final ReadContext ctx)
+            throws ReadFailedException {
+        delegate.readCurrentAttributes(id, builder, ctx);
+    }
+
+    @Nonnull
+    @Override
+    public B getBuilder(final InstanceIdentifier<D> id) {
+        return delegate.getBuilder(id);
+    }
+
+    @Override
+    public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, @Nonnull final D readValue) {
+        delegate.merge(parentBuilder, readValue);
+    }
+
+    @Nonnull
+    private static Optional<? extends DataObject> filterSubtree(@Nonnull final DataObject parent,
+                                                                @Nonnull final InstanceIdentifier<? extends DataObject> absolutPath,
+                                                                @Nonnull final Class<?> managedType) {
+        final InstanceIdentifier.PathArgument nextId =
+                RWUtils.getNextId(absolutPath, InstanceIdentifier.create(parent.getClass()));
+
+        final Optional<? extends DataObject> nextParent = findNextParent(parent, nextId, managedType);
+
+        if (Iterables.getLast(absolutPath.getPathArguments()).equals(nextId)) {
+            return nextParent; // we found the dataObject identified by absolutePath
+        } else if (nextParent.isPresent()) {
+            return filterSubtree(nextParent.get(), absolutPath, nextId.getType());
+        } else {
+            return nextParent; // we can't go further, return Optional.absent()
+        }
+    }
+
+    private static Optional<? extends DataObject> findNextParent(@Nonnull final DataObject parent,
+                                                                 @Nonnull final InstanceIdentifier.PathArgument nextId,
+                                                                 @Nonnull final Class<?> managedType) {
+        // TODO is there a better way than reflection ? e.g. convert into NN and filter out with a utility
+        Optional<Method> method = ReflectionUtils.findMethodReflex(managedType, "get",
+                Collections.emptyList(), nextId.getType());
+
+        if (method.isPresent()) {
+            return Optional.fromNullable(filterSingle(parent, nextId, method.get()));
+        } else {
+            // List child nodes
+            method = ReflectionUtils.findMethodReflex(managedType,
+                    "get" + nextId.getType().getSimpleName(), Collections.emptyList(), List.class);
+
+            if (method.isPresent()) {
+                return filterList(parent, nextId, method.get());
+            } else {
+                throw new IllegalStateException(
+                        "Unable to filter " + nextId + " from " + parent + " getters not found using reflexion");
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private static Optional<? extends DataObject> filterList(final DataObject parent,
+                                                             final InstanceIdentifier.PathArgument nextId,
+                                                             final Method method) {
+        final List<? extends DataObject> invoke = (List<? extends DataObject>) invoke(method, nextId, parent);
+
+        checkArgument(nextId instanceof InstanceIdentifier.IdentifiableItem<?, ?>,
+                "Unable to perform wildcarded read for %s", nextId);
+        final Identifier key = ((InstanceIdentifier.IdentifiableItem) nextId).getKey();
+        // TODO replace with stream().filter().findFirst() when we switch to using java's Optional instead of Guava's
+        // because now we would have to do awkward Optional transformation since findFirstReturns guava's optional
+        return Iterables.tryFind(invoke, new Predicate<DataObject>() {
+
+            @Override
+            public boolean apply(@Nullable final DataObject input) {
+                final Optional<Method> keyGetter = ReflectionUtils.findMethodReflex(nextId.getType(), "get",
+                                Collections.emptyList(), key.getClass());
+                final Object actualKey;
+                actualKey = invoke(keyGetter.get(), nextId, input);
+                return key.equals(actualKey);
+            }
+        });
+    }
+
+    private static DataObject filterSingle(final DataObject parent,
+                                           final InstanceIdentifier.PathArgument nextId, final Method method) {
+        return nextId.getType().cast(invoke(method, nextId, parent));
+    }
+
+    private static Object invoke(final Method method,
+                                 final InstanceIdentifier.PathArgument nextId, final DataObject parent) {
+        try {
+            return method.invoke(parent);
+        } catch (IllegalAccessException | InvocationTargetException e) {
+            throw new IllegalArgumentException("Unable to get " + nextId + " from " + parent, e);
+        }
+    }
+
+    @Override
+    @Nonnull
+    public InstanceIdentifier<D> getManagedDataObjectType() {
+        return delegate.getManagedDataObjectType();
+    }
+
+    /**
+     * Wrap a Reader as a subtree Reader.
+     */
+    static <D extends DataObject, B extends Builder<D>> Reader<D, B> createForReader(@Nonnull final Set<InstanceIdentifier<?>> handledChildren,
+                                                                                     @Nonnull final Reader<D, B> reader) {
+        return (reader instanceof ListReader)
+                ? new SubtreeListReader<>((ListReader) reader, handledChildren)
+                : new SubtreeReader<>(reader, handledChildren);
+    }
+
+    private static final class SubtreeListReader<D extends DataObject & Identifiable<K>, B extends Builder<D>, K extends Identifier<D>>
+            extends SubtreeReader<D, B> implements ListReader<D, K, B> {
+
+        private final ListReader<D, K, B> delegate;
+
+        private SubtreeListReader(final ListReader<D, K, B> delegate,
+                                  final Set<InstanceIdentifier<?>> handledTypes) {
+            super(delegate, handledTypes);
+            this.delegate = delegate;
+        }
+
+        @Nonnull
+        @Override
+        public List<D> readList(@Nonnull final InstanceIdentifier<D> id, @Nonnull final ReadContext ctx)
+                throws ReadFailedException {
+            return delegate.readList(id, ctx);
+        }
+
+        @Override
+        public void merge(@Nonnull final Builder<? extends DataObject> builder, @Nonnull final List<D> readData) {
+            delegate.merge(builder, readData);
+        }
+
+        @Override
+        public List<K> getAllIds(@Nonnull final InstanceIdentifier<D> id,
+                                 @Nonnull final ReadContext ctx) throws ReadFailedException {
+            return delegate.getAllIds(id, ctx);
+        }
+    }
+
+}
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/TypeHierarchy.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/TypeHierarchy.java
new file mode 100644 (file)
index 0000000..005e3bc
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * 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.v3po.translate.util.read.registry;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import com.google.common.collect.Iterables;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
+import org.jgrapht.experimental.dag.DirectedAcyclicGraph;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+final class TypeHierarchy {
+    private final DirectedAcyclicGraph<InstanceIdentifier<?>, Parent> hierarchy;
+
+    private TypeHierarchy(@Nonnull final DirectedAcyclicGraph<InstanceIdentifier<?>, Parent> hierarchy) {
+        this.hierarchy = hierarchy;
+    }
+
+    Set<InstanceIdentifier<?>> getAllChildren(InstanceIdentifier<?> id) {
+        final HashSet<InstanceIdentifier<?>> instanceIdentifiers = new HashSet<>();
+        for (InstanceIdentifier<?> childId : getDirectChildren(id)) {
+            instanceIdentifiers.add(childId);
+            instanceIdentifiers.addAll(getAllChildren(childId));
+        }
+        return instanceIdentifiers;
+    }
+
+    Set<InstanceIdentifier<?>> getDirectChildren(InstanceIdentifier<?> id) {
+        checkArgument(hierarchy.vertexSet().contains(id),
+                "Unknown reader: %s. Known readers: %s", id, hierarchy.vertexSet());
+
+        return hierarchy.outgoingEdgesOf(id).stream()
+                .map(hierarchy::getEdgeTarget)
+                .collect(Collectors.toSet());
+    }
+
+    Set<InstanceIdentifier<?>> getRoots() {
+        return hierarchy.vertexSet().stream()
+                .filter(vertex -> hierarchy.incomingEdgesOf(vertex).size() == 0)
+                .collect(Collectors.toSet());
+    }
+
+    /**
+     * Create reader hierarchy from a flat set of instance identifiers.
+     *
+     * @param allIds Set of unkeyed instance identifiers
+     */
+    static TypeHierarchy create(@Nonnull Set<InstanceIdentifier<?>> allIds) {
+        final DirectedAcyclicGraph<InstanceIdentifier<?>, Parent>
+                readersHierarchy = new DirectedAcyclicGraph<>((sourceVertex, targetVertex) -> new Parent());
+
+        for (InstanceIdentifier<?> allId : allIds) {
+            checkArgument(!Iterables.isEmpty(allId.getPathArguments()), "Empty ID detected");
+
+            if (Iterables.size(allId.getPathArguments()) == 1) {
+                readersHierarchy.addVertex(allId);
+            }
+
+            List<InstanceIdentifier.PathArgument> pathArgs = new LinkedList<>();
+            pathArgs.add(allId.getPathArguments().iterator().next());
+
+            for (InstanceIdentifier.PathArgument pathArgument : Iterables.skip(allId.getPathArguments(), 1)) {
+                final InstanceIdentifier<?> previous = InstanceIdentifier.create(pathArgs);
+                pathArgs.add(pathArgument);
+                final InstanceIdentifier<?> current = InstanceIdentifier.create(pathArgs);
+
+                readersHierarchy.addVertex(previous);
+                readersHierarchy.addVertex(current);
+
+                try {
+                    readersHierarchy.addDagEdge(previous, current);
+                } catch (DirectedAcyclicGraph.CycleFoundException e) {
+                    throw new IllegalArgumentException("Loop in hierarchy detected", e);
+                }
+            }
+        }
+
+        return new TypeHierarchy(readersHierarchy);
+    }
+
+    private static final class Parent{}
+}
  * limitations under the License.
  */
 
-package io.fd.honeycomb.v3po.translate.impl.write;
+package io.fd.honeycomb.v3po.translate.util.write;
 
 import static com.google.common.base.Preconditions.checkArgument;
 
+import io.fd.honeycomb.v3po.translate.util.RWUtils;
 import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
 import io.fd.honeycomb.v3po.translate.write.Writer;
@@ -28,14 +29,14 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-abstract class AbstractCompositeWriter<D extends DataObject> implements Writer<D> {
+public abstract class AbstractGenericWriter<D extends DataObject> implements Writer<D> {
 
-    private static final Logger LOG = LoggerFactory.getLogger(AbstractCompositeWriter.class);
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractGenericWriter.class);
 
     private final InstanceIdentifier<D> instanceIdentifier;
 
-    AbstractCompositeWriter(final InstanceIdentifier<D> type) {
-        this.instanceIdentifier = type;
+    protected AbstractGenericWriter(final InstanceIdentifier<D> type) {
+        this.instanceIdentifier = RWUtils.makeIidWildcarded(type);
     }
 
     protected void writeCurrent(final InstanceIdentifier<D> id, final D data, final WriteContext ctx)
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/CloseableWriter.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/CloseableWriter.java
deleted file mode 100644 (file)
index 3442f83..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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.v3po.translate.util.write;
-
-import io.fd.honeycomb.v3po.translate.write.WriteContext;
-import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
-import io.fd.honeycomb.v3po.translate.write.Writer;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-/**
- * Closeable wrapper for a writer
- */
-public final class CloseableWriter<D extends DataObject> implements Writer<D>, AutoCloseable {
-
-    private Writer<D> vppCompositeRootWriter;
-
-    public CloseableWriter(
-        final Writer<D> vppCompositeRootWriter) {
-        this.vppCompositeRootWriter = vppCompositeRootWriter;
-    }
-
-    @Override
-    public void update(
-        @Nonnull final InstanceIdentifier<? extends DataObject> id,
-        @Nullable final DataObject dataBefore,
-        @Nullable final DataObject dataAfter,
-        @Nonnull final WriteContext ctx) throws WriteFailedException {
-        vppCompositeRootWriter.update(id, dataBefore, dataAfter, ctx);
-    }
-
-    @Nonnull
-    @Override
-    public InstanceIdentifier<D> getManagedDataObjectType() {
-        return vppCompositeRootWriter.getManagedDataObjectType();
-    }
-
-    @Override
-    public String toString() {
-        return vppCompositeRootWriter.toString();
-    }
-
-    @Override
-    public void close() throws Exception {
-
-    }
-}
index 236ad89..7c45fcd 100644 (file)
@@ -18,14 +18,8 @@ package io.fd.honeycomb.v3po.translate.util.write;
 
 import io.fd.honeycomb.v3po.translate.TranslationException;
 import io.fd.honeycomb.v3po.translate.write.WriteContext;
-import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
-import io.fd.honeycomb.v3po.translate.write.WriterRegistry;
+import io.fd.honeycomb.v3po.translate.write.registry.WriterRegistry;
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * Empty registry that does not perform any changes. Can be used in data layer, if we want to disable passing data to
@@ -33,29 +27,12 @@ import org.slf4j.LoggerFactory;
  */
 public class NoopWriterRegistry implements WriterRegistry, AutoCloseable {
 
-    private static final Logger LOG = LoggerFactory.getLogger(NoopWriterRegistry.class);
-
-    @Override
-    public void update(@Nonnull final InstanceIdentifier<? extends DataObject> id,
-                       @Nullable final DataObject dataBefore, @Nullable final DataObject dataAfter,
-                       @Nonnull final WriteContext ctx) throws WriteFailedException {
-        LOG.trace("NoopWriterRegistry.update id={}, dataBefore{}, dataAfter={], ctx={}", id, dataBefore, dataAfter,
-                ctx);
-        // NOOP
-    }
-
     @Override
     public void update(@Nonnull final DataObjectUpdates updates,
                        @Nonnull final WriteContext ctx) throws TranslationException {
         // NOOP
     }
 
-    @Nonnull
-    @Override
-    public InstanceIdentifier<DataObject> getManagedDataObjectType() {
-        throw new UnsupportedOperationException("Noop registry has no type");
-    }
-
     @Override
     public void close() throws Exception {
         // NOOP
index 4abad23..7433de8 100644 (file)
@@ -21,7 +21,6 @@ import static com.google.common.base.Preconditions.checkArgument;
 import com.google.common.base.Optional;
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMultimap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Multimap;
@@ -32,7 +31,7 @@ import io.fd.honeycomb.v3po.translate.write.DataObjectUpdate;
 import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
 import io.fd.honeycomb.v3po.translate.write.Writer;
-import io.fd.honeycomb.v3po.translate.write.WriterRegistry;
+import io.fd.honeycomb.v3po.translate.write.registry.WriterRegistry;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
@@ -90,15 +89,6 @@ final class FlatWriterRegistry implements WriterRegistry {
         return handledTypesBuilder.build();
     }
 
-    @Override
-    public void update(@Nonnull final InstanceIdentifier<? extends DataObject> id,
-                       @Nullable final DataObject dataBefore,
-                       @Nullable final DataObject dataAfter,
-                       @Nonnull final WriteContext ctx) throws WriteFailedException {
-        singleUpdate(ImmutableMultimap.of(
-                RWUtils.makeIidWildcarded(id), DataObjectUpdate.create(id, dataBefore, dataAfter)), ctx);
-    }
-
     @Override
     public void update(@Nonnull final DataObjectUpdates updates,
                        @Nonnull final WriteContext ctx) throws TranslationException {
@@ -265,12 +255,6 @@ final class FlatWriterRegistry implements WriterRegistry {
         return writers.get(singleType);
     }
 
-    @Nonnull
-    @Override
-    public InstanceIdentifier<DataObject> getManagedDataObjectType() {
-        throw new UnsupportedOperationException("Registry has no managed type");
-    }
-
     // FIXME unit test
     private final class ReverterImpl implements Reverter {
 
index f5d218f..bfac2ee 100644 (file)
 package io.fd.honeycomb.v3po.translate.util.write.registry;
 
 import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableMap;
-import io.fd.honeycomb.v3po.translate.util.RWUtils;
-import io.fd.honeycomb.v3po.translate.write.ModifiableWriterRegistry;
+import io.fd.honeycomb.v3po.translate.util.AbstractSubtreeManagerRegistryBuilderBuilder;
 import io.fd.honeycomb.v3po.translate.write.Writer;
-import io.fd.honeycomb.v3po.translate.write.WriterRegistryBuilder;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
+import io.fd.honeycomb.v3po.translate.write.registry.ModifiableWriterRegistryBuilder;
+import io.fd.honeycomb.v3po.translate.write.registry.WriterRegistry;
+import io.fd.honeycomb.v3po.translate.write.registry.WriterRegistryBuilder;
 import java.util.Set;
 import java.util.stream.Collectors;
 import javax.annotation.Nonnull;
 import javax.annotation.concurrent.NotThreadSafe;
-import org.jgrapht.experimental.dag.DirectedAcyclicGraph;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
@@ -40,156 +36,24 @@ import org.slf4j.LoggerFactory;
  * Builder for {@link FlatWriterRegistry} allowing users to specify inter-writer relationships.
  */
 @NotThreadSafe
-public final class FlatWriterRegistryBuilder implements ModifiableWriterRegistry, WriterRegistryBuilder, AutoCloseable {
+public final class FlatWriterRegistryBuilder
+        extends AbstractSubtreeManagerRegistryBuilderBuilder<Writer<? extends DataObject>, WriterRegistry>
+        implements ModifiableWriterRegistryBuilder, WriterRegistryBuilder {
 
     private static final Logger LOG = LoggerFactory.getLogger(FlatWriterRegistryBuilder.class);
 
-    // Using directed acyclic graph to represent the ordering relationships between writers
-    private final DirectedAcyclicGraph<InstanceIdentifier<?>, WriterRelation>
-            writersRelations = new DirectedAcyclicGraph<>((sourceVertex, targetVertex) -> new WriterRelation());
-    private final Map<InstanceIdentifier<?>, Writer<?>> writersMap = new HashMap<>();
-
-    /**
-     * AddWriter without any special relationship to any other type.
-     */
-    @Override
-    public FlatWriterRegistryBuilder addWriter(@Nonnull final Writer<? extends DataObject> writer) {
-        // Make IID wildcarded just in case
-        // + the way InstanceIdentifier.create + equals work for Identifiable items is unexpected, meaning updates would
-        // not be matched to writers in registry
-        final InstanceIdentifier<?> targetType = RWUtils.makeIidWildcarded(writer.getManagedDataObjectType());
-        checkWriterNotPresentYet(targetType);
-        writersRelations.addVertex(targetType);
-        writersMap.put(targetType, writer);
-        return this;
-    }
-
-    /**
-     * AddWriter without any special relationship to any other type.
-     */
-    @Override
-    public FlatWriterRegistryBuilder addSubtreeWriter(@Nonnull final Set<InstanceIdentifier<?>> handledChildren,
-                                                      @Nonnull final Writer<? extends DataObject> writer) {
-        addWriter(SubtreeWriter.createForWriter(handledChildren, writer));
-        return this;
-    }
-
-    private void checkWriterNotPresentYet(final InstanceIdentifier<?> targetType) {
-        Preconditions.checkArgument(!writersMap.containsKey(targetType),
-                "Writer for type: %s already present: %s", targetType, writersMap.get(targetType));
-    }
-
-    /**
-     * Add writer with relationship: to be executed before writer handling relatedType.
-     */
-    @Override
-    public FlatWriterRegistryBuilder addWriterBefore(@Nonnull final Writer<? extends DataObject> writer,
-                                                     @Nonnull final InstanceIdentifier<?> relatedType) {
-        final InstanceIdentifier<?> targetType = RWUtils.makeIidWildcarded(writer.getManagedDataObjectType());
-        final InstanceIdentifier<?> wildcardedRelatedType = RWUtils.makeIidWildcarded(relatedType);
-        checkWriterNotPresentYet(targetType);
-        writersRelations.addVertex(targetType);
-        writersRelations.addVertex(wildcardedRelatedType);
-        addEdge(targetType, wildcardedRelatedType);
-        writersMap.put(targetType, writer);
-        return this;
-    }
-
-    @Override
-    public FlatWriterRegistryBuilder addSubtreeWriterBefore(@Nonnull final Set<InstanceIdentifier<?>> handledChildren,
-                                                            @Nonnull final Writer<? extends DataObject> writer,
-                                                            @Nonnull final InstanceIdentifier<?> relatedType) {
-        return addWriterBefore(SubtreeWriter.createForWriter(handledChildren, writer), relatedType);
-    }
-
-    @Override
-    public FlatWriterRegistryBuilder addWriterBefore(@Nonnull final Writer<? extends DataObject> writer,
-                                                     @Nonnull final Collection<InstanceIdentifier<?>> relatedTypes) {
-        final InstanceIdentifier<?> targetType = RWUtils.makeIidWildcarded(writer.getManagedDataObjectType());
-        checkWriterNotPresentYet(targetType);
-        writersRelations.addVertex(targetType);
-        relatedTypes.stream()
-                .map(RWUtils::makeIidWildcarded)
-                .forEach(writersRelations::addVertex);
-        relatedTypes.stream()
-                .map(RWUtils::makeIidWildcarded)
-                .forEach(type -> addEdge(targetType, type));
-        writersMap.put(targetType, writer);
-        return this;
-    }
-
-    @Override
-    public FlatWriterRegistryBuilder addSubtreeWriterBefore(@Nonnull final Set<InstanceIdentifier<?>> handledChildren,
-                                                            @Nonnull final Writer<? extends DataObject> writer,
-                                                            @Nonnull final Collection<InstanceIdentifier<?>> relatedTypes) {
-        return addWriterBefore(SubtreeWriter.createForWriter(handledChildren, writer), relatedTypes);
-    }
-
-    /**
-     * Add writer with relationship: to be executed after writer handling relatedType.
-     */
-    @Override
-    public FlatWriterRegistryBuilder addWriterAfter(@Nonnull final Writer<? extends DataObject> writer,
-                                                    @Nonnull final InstanceIdentifier<?> relatedType) {
-        final InstanceIdentifier<?> targetType = RWUtils.makeIidWildcarded(writer.getManagedDataObjectType());
-        final InstanceIdentifier<?> wildcardedRelatedType = RWUtils.makeIidWildcarded(relatedType);
-        checkWriterNotPresentYet(targetType);
-        writersRelations.addVertex(targetType);
-        writersRelations.addVertex(wildcardedRelatedType);
-        // set edge to indicate before relationship, just reversed
-        addEdge(wildcardedRelatedType, targetType);
-        writersMap.put(targetType, writer);
-        return this;
-    }
-
-    @Override
-    public FlatWriterRegistryBuilder addSubtreeWriterAfter(@Nonnull final Set<InstanceIdentifier<?>> handledChildren,
-                                                           @Nonnull final Writer<? extends DataObject> writer,
-                                                           @Nonnull final InstanceIdentifier<?> relatedType) {
-        return addWriterAfter(SubtreeWriter.createForWriter(handledChildren, writer), relatedType);
-    }
-
-    @Override
-    public FlatWriterRegistryBuilder addWriterAfter(@Nonnull final Writer<? extends DataObject> writer,
-                                                    @Nonnull final Collection<InstanceIdentifier<?>> relatedTypes) {
-        final InstanceIdentifier<?> targetType = RWUtils.makeIidWildcarded(writer.getManagedDataObjectType());
-        checkWriterNotPresentYet(targetType);
-        writersRelations.addVertex(targetType);
-        relatedTypes.stream()
-                .map(RWUtils::makeIidWildcarded)
-                .forEach(writersRelations::addVertex);
-        // set edge to indicate before relationship, just reversed
-        relatedTypes.stream()
-                .map(RWUtils::makeIidWildcarded)
-                .forEach(type -> addEdge(type, targetType));
-        writersMap.put(targetType, writer);
-        return this;
-    }
-
     @Override
-    public FlatWriterRegistryBuilder addSubtreeWriterAfter(@Nonnull final Set<InstanceIdentifier<?>> handledChildren,
-                                                           @Nonnull final Writer<? extends DataObject> writer,
-                                                           @Nonnull final Collection<InstanceIdentifier<?>> relatedTypes) {
-        return addWriterAfter(SubtreeWriter.createForWriter(handledChildren, writer), relatedTypes);
-    }
-
-
-    private void addEdge(final InstanceIdentifier<?> targetType,
-                         final InstanceIdentifier<?> relatedType) {
-        try {
-            writersRelations.addDagEdge(targetType, relatedType);
-        } catch (DirectedAcyclicGraph.CycleFoundException e) {
-            throw new IllegalArgumentException(String.format(
-                    "Unable to add writer with relation: %s -> %s. Loop detected", targetType, relatedType), e);
-        }
+    protected Writer<? extends DataObject> getSubtreeHandler(final @Nonnull Set<InstanceIdentifier<?>> handledChildren,
+                                                             final @Nonnull Writer<? extends DataObject> writer) {
+        return SubtreeWriter.createForWriter(handledChildren, writer);
     }
 
     /**
      * Create FlatWriterRegistry with writers ordered according to submitted relationships.
      */
     @Override
-    public FlatWriterRegistry build() {
-        final ImmutableMap<InstanceIdentifier<?>, Writer<?>> mappedWriters = getMappedWriters();
+    public WriterRegistry build() {
+        final ImmutableMap<InstanceIdentifier<?>, Writer<?>> mappedWriters = getMappedHandlers();
         LOG.debug("Building writer registry with writers: {}",
                 mappedWriters.keySet().stream()
                         .map(InstanceIdentifier::getTargetType)
@@ -200,26 +64,8 @@ public final class FlatWriterRegistryBuilder implements ModifiableWriterRegistry
     }
 
     @VisibleForTesting
-    ImmutableMap<InstanceIdentifier<?>, Writer<?>> getMappedWriters() {
-        final ImmutableMap.Builder<InstanceIdentifier<?>, Writer<?>> builder = ImmutableMap.builder();
-        // Iterate writer types according to their relationships from graph
-        writersRelations.iterator()
-                .forEachRemaining(writerType -> {
-                    // There might be types stored just for relationship sake, no real writer, ignoring those
-                    if (writersMap.containsKey(writerType)) {
-                        builder.put(writerType, writersMap.get(writerType));
-                    }
-                });
-        return builder.build();
-    }
-
     @Override
-    public void close() throws Exception {
-        writersMap.clear();
-        writersRelations.removeAllEdges(writersRelations.edgeSet());
-        writersRelations.removeAllVertices(writersRelations.vertexSet());
+    protected ImmutableMap<InstanceIdentifier<?>, Writer<? extends DataObject>> getMappedHandlers() {
+        return super.getMappedHandlers();
     }
-
-    // Represents edges in graph
-    private static final class WriterRelation {}
 }
index fccd6b1..e1f04eb 100644 (file)
@@ -1,18 +1,6 @@
 package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.translate.utils.rev160406;
 
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Multimap;
-import io.fd.honeycomb.v3po.translate.read.ReadContext;
-import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.read.Reader;
-import io.fd.honeycomb.v3po.translate.read.ReaderRegistry;
-import io.fd.honeycomb.v3po.translate.util.read.DelegatingReaderRegistry;
-import java.util.List;
-import javax.annotation.Nonnull;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import io.fd.honeycomb.v3po.translate.util.read.registry.CompositeReaderRegistryBuilder;
 
 public class DelegatingReaderRegistryModule extends org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.translate.utils.rev160406.AbstractDelegatingReaderRegistryModule {
     public DelegatingReaderRegistryModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
@@ -30,53 +18,8 @@ public class DelegatingReaderRegistryModule extends org.opendaylight.yang.gen.v1
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-        final List<Reader<? extends DataObject>> rootReadersDependency = Lists.transform(getRootReadersDependency(),
-            new Function<Reader, Reader<? extends DataObject>>() {
-
-                @SuppressWarnings("unchecked")
-                @Override
-                public Reader<? extends DataObject> apply(final Reader input) {
-                    return input;
-                }
-            });
-        return new CloseableReaderRegistry(new DelegatingReaderRegistry(rootReadersDependency));
-    }
-
-
-
-    // TODO move to translate-utils
-    private static final class CloseableReaderRegistry implements ReaderRegistry, AutoCloseable {
-        private final DelegatingReaderRegistry delegatingReaderRegistry;
-
-        CloseableReaderRegistry(
-            final DelegatingReaderRegistry delegatingReaderRegistry) {
-            this.delegatingReaderRegistry = delegatingReaderRegistry;
-        }
-
-        @Override
-        @Nonnull
-        public Multimap<InstanceIdentifier<? extends DataObject>, ? extends DataObject> readAll(
-            @Nonnull final ReadContext ctx) throws ReadFailedException {
-            return delegatingReaderRegistry.readAll(ctx);
-        }
-
-        @Nonnull
-        @Override
-        public Optional<? extends DataObject> read(
-            @Nonnull final InstanceIdentifier<? extends DataObject> id,
-            @Nonnull final ReadContext ctx) throws ReadFailedException {
-            return delegatingReaderRegistry.read(id, ctx);
-        }
-
-        @Nonnull
-        @Override
-        public InstanceIdentifier<DataObject> getManagedDataObjectType() {
-            return delegatingReaderRegistry.getManagedDataObjectType();
-        }
-
-        @Override
-        public void close() throws Exception {
-            // NOOP
-        }
+        final CompositeReaderRegistryBuilder flatReaderRegistryBuilder = new CompositeReaderRegistryBuilder();
+        getReaderFactoryDependency().forEach(readerFactory -> readerFactory.init(flatReaderRegistryBuilder));
+        return flatReaderRegistryBuilder;
     }
 }
index fedd069..0f72df9 100644 (file)
@@ -1,8 +1,8 @@
 package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.translate.utils.rev160406;
 
 import io.fd.honeycomb.v3po.translate.util.write.NoopWriterRegistry;
-import io.fd.honeycomb.v3po.translate.write.WriterRegistry;
-import io.fd.honeycomb.v3po.translate.write.WriterRegistryBuilder;
+import io.fd.honeycomb.v3po.translate.write.registry.WriterRegistry;
+import io.fd.honeycomb.v3po.translate.write.registry.WriterRegistryBuilder;
 
 public class NoopWriterRegistryModule extends org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.translate.utils.rev160406.AbstractNoopWriterRegistryModule {
     public NoopWriterRegistryModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
index 2c00bb5..b543bba 100644 (file)
@@ -18,6 +18,7 @@ module translate-utils {
     identity delegating-reader-registry {
         base config:module-type;
         config:provided-service tapi:honeycomb-reader-registry;
+        config:provided-service tapi:honeycomb-reader-registry-builder;
         config:java-name-prefix DelegatingReaderRegistry;
     }
 
@@ -25,11 +26,11 @@ module translate-utils {
         case delegating-reader-registry {
             when "/config:modules/config:module/config:type = 'delegating-reader-registry'";
 
-                list root-readers {
+                list reader-factory {
                     uses config:service-ref {
                         refine type {
                             mandatory true;
-                            config:required-identity tapi:honeycomb-reader;
+                            config:required-identity tapi:honeycomb-reader-factory;
                         }
                     }
                 }
diff --git a/v3po/translate-utils/src/test/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveAugmentReaderCustomizerTest.java b/v3po/translate-utils/src/test/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveAugmentReaderCustomizerTest.java
deleted file mode 100644 (file)
index 3edc001..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.v3po.translate.util.read;
-
-import static org.junit.Assert.assertSame;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceStateAugmentation;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceStateAugmentationBuilder;
-
-public class ReflexiveAugmentReaderCustomizerTest {
-
-    private ReflexiveAugmentReaderCustomizer<VppInterfaceStateAugmentation, VppInterfaceStateAugmentationBuilder>
-        vppIfcStateAugmentCustomizer;
-
-    @Before
-    public void setUp() throws Exception {
-        vppIfcStateAugmentCustomizer =
-            new ReflexiveAugmentReaderCustomizer<>(VppInterfaceStateAugmentationBuilder.class,
-                VppInterfaceStateAugmentation.class);
-    }
-
-    @Test
-    public void testAddAugment() throws Exception {
-        final InterfaceBuilder parentBuilder = new InterfaceBuilder();
-        final VppInterfaceStateAugmentation augmentation = vppIfcStateAugmentCustomizer.getBuilder(null).build();
-        vppIfcStateAugmentCustomizer.merge(parentBuilder, augmentation);
-        assertSame(augmentation, parentBuilder.getAugmentation(VppInterfaceStateAugmentation.class));
-    }
-}
\ No newline at end of file
diff --git a/v3po/translate-utils/src/test/java/io/fd/honeycomb/v3po/translate/util/read/registry/TypeHierarchyTest.java b/v3po/translate-utils/src/test/java/io/fd/honeycomb/v3po/translate/util/read/registry/TypeHierarchyTest.java
new file mode 100644 (file)
index 0000000..92449af
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * 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.v3po.translate.util.read.registry;
+
+import static org.hamcrest.CoreMatchers.hasItem;
+import static org.hamcrest.CoreMatchers.hasItems;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import com.google.common.collect.Sets;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.binding.ChildOf;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class TypeHierarchyTest {
+
+    @Test
+    public void testHierarchy() throws Exception {
+        final TypeHierarchy typeHierarchy = TypeHierarchy.create(Sets.newHashSet(
+                DataObject3.DataObject31.DataObject311.IID,
+                DataObject3.DataObject31.IID,/* Included in previous already */
+                DataObject1.IID,
+                DataObject2.DataObject21.IID));
+
+        // Roots
+        assertThat(typeHierarchy.getRoots().size(), is(3));
+        assertThat(typeHierarchy.getRoots(), hasItems(DataObject1.IID, DataObject2.IID, DataObject3.IID));
+
+        // Leaves
+        assertThat(typeHierarchy.getDirectChildren(DataObject1.IID).size(), is(0));
+        assertThat(typeHierarchy.getDirectChildren(DataObject2.DataObject21.IID).size(), is(0));
+        assertThat(typeHierarchy.getDirectChildren(DataObject3.DataObject31.DataObject311.IID).size(), is(0));
+
+        // Intermediate leaves
+        assertThat(typeHierarchy.getDirectChildren(DataObject2.IID).size(), is(1));
+        assertThat(typeHierarchy.getDirectChildren(DataObject2.IID), hasItem(DataObject2.DataObject21.IID));
+        assertEquals(typeHierarchy.getDirectChildren(DataObject2.IID), typeHierarchy.getAllChildren(DataObject2.IID));
+
+        assertThat(typeHierarchy.getDirectChildren(DataObject3.DataObject31.IID).size(), is(1));
+        assertThat(typeHierarchy.getDirectChildren(DataObject3.DataObject31.IID), hasItem(
+                DataObject3.DataObject31.DataObject311.IID));
+        assertEquals(typeHierarchy.getDirectChildren(DataObject3.DataObject31.IID), typeHierarchy.getAllChildren(
+                DataObject3.DataObject31.IID));
+
+        assertThat(typeHierarchy.getDirectChildren(DataObject3.IID).size(), is(1));
+        assertThat(typeHierarchy.getDirectChildren(DataObject3.IID), hasItem(DataObject3.DataObject31.IID));
+        assertThat(typeHierarchy.getAllChildren(DataObject3.IID).size(), is(2));
+        assertTrue(typeHierarchy.getAllChildren(DataObject3.IID).contains(DataObject3.DataObject31.IID));
+        assertTrue(typeHierarchy.getAllChildren(DataObject3.IID).contains(DataObject3.DataObject31.DataObject311.IID));
+    }
+
+    private abstract static class DataObject1 implements DataObject {
+        static InstanceIdentifier<DataObject1> IID = InstanceIdentifier.create(DataObject1.class);
+    }
+    private abstract static class DataObject2 implements DataObject {
+        static InstanceIdentifier<DataObject2> IID = InstanceIdentifier.create(DataObject2.class);
+        private abstract static class DataObject21 implements DataObject, ChildOf<DataObject2> {
+            static InstanceIdentifier<DataObject21> IID = DataObject2.IID.child(DataObject21.class);
+        }
+    }
+    private abstract static class DataObject3 implements DataObject {
+        static InstanceIdentifier<DataObject3> IID = InstanceIdentifier.create(DataObject3.class);
+        private abstract static class DataObject31 implements DataObject, ChildOf<DataObject3> {
+            static InstanceIdentifier<DataObject31> IID = DataObject3.IID.child(DataObject31.class);
+            private abstract static class DataObject311 implements DataObject, ChildOf<DataObject31> {
+                static InstanceIdentifier<DataObject311> IID = DataObject31.IID.child(DataObject311.class);
+            }
+        }
+    }
+}
+
index ec407b6..da7ac09 100644 (file)
@@ -31,13 +31,13 @@ public class FlatWriterRegistryBuilderTest {
             1   ->  2   ->  3
                         ->  4
          */
-        flatWriterRegistryBuilder.addWriter(mockWriter(DataObject3.class));
-        flatWriterRegistryBuilder.addWriter(mockWriter(DataObject4.class));
-        flatWriterRegistryBuilder.addWriterBefore(mockWriter(DataObject2.class),
+        flatWriterRegistryBuilder.add(mockWriter(DataObject3.class));
+        flatWriterRegistryBuilder.add(mockWriter(DataObject4.class));
+        flatWriterRegistryBuilder.addBefore(mockWriter(DataObject2.class),
                 Lists.newArrayList(DataObject3.IID, DataObject4.IID));
-        flatWriterRegistryBuilder.addWriterBefore(mockWriter(DataObject1.class), DataObject2.IID);
+        flatWriterRegistryBuilder.addBefore(mockWriter(DataObject1.class), DataObject2.IID);
         final ImmutableMap<InstanceIdentifier<?>, Writer<?>> mappedWriters =
-                flatWriterRegistryBuilder.getMappedWriters();
+                flatWriterRegistryBuilder.getMappedHandlers();
 
         final ArrayList<InstanceIdentifier<?>> typesInList = Lists.newArrayList(mappedWriters.keySet());
         assertEquals(DataObject1.IID, typesInList.get(0));
@@ -53,12 +53,12 @@ public class FlatWriterRegistryBuilderTest {
             1   ->  2   ->  3
                         ->  4
          */
-        flatWriterRegistryBuilder.addWriter(mockWriter(DataObject1.class));
-        flatWriterRegistryBuilder.addWriterAfter(mockWriter(DataObject2.class), DataObject1.IID);
-        flatWriterRegistryBuilder.addWriterAfter(mockWriter(DataObject3.class), DataObject2.IID);
-        flatWriterRegistryBuilder.addWriterAfter(mockWriter(DataObject4.class), DataObject2.IID);
+        flatWriterRegistryBuilder.add(mockWriter(DataObject1.class));
+        flatWriterRegistryBuilder.addAfter(mockWriter(DataObject2.class), DataObject1.IID);
+        flatWriterRegistryBuilder.addAfter(mockWriter(DataObject3.class), DataObject2.IID);
+        flatWriterRegistryBuilder.addAfter(mockWriter(DataObject4.class), DataObject2.IID);
         final ImmutableMap<InstanceIdentifier<?>, Writer<?>> mappedWriters =
-                flatWriterRegistryBuilder.getMappedWriters();
+                flatWriterRegistryBuilder.getMappedHandlers();
 
         final List<InstanceIdentifier<?>> typesInList = Lists.newArrayList(mappedWriters.keySet());
         assertEquals(DataObject1.IID, typesInList.get(0));
@@ -73,27 +73,27 @@ public class FlatWriterRegistryBuilderTest {
         /*
             1   ->  2   ->  1
          */
-        flatWriterRegistryBuilder.addWriter(mockWriter(DataObject1.class));
-        flatWriterRegistryBuilder.addWriterAfter(mockWriter(DataObject2.class), DataObject1.IID);
-        flatWriterRegistryBuilder.addWriterAfter(mockWriter(DataObject1.class), DataObject2.IID);
+        flatWriterRegistryBuilder.add(mockWriter(DataObject1.class));
+        flatWriterRegistryBuilder.addAfter(mockWriter(DataObject2.class), DataObject1.IID);
+        flatWriterRegistryBuilder.addAfter(mockWriter(DataObject1.class), DataObject2.IID);
     }
 
     @Test(expected = IllegalArgumentException.class)
     public void testAddWriterTwice() throws Exception {
         final FlatWriterRegistryBuilder flatWriterRegistryBuilder = new FlatWriterRegistryBuilder();
-        flatWriterRegistryBuilder.addWriter(mockWriter(DataObject1.class));
-        flatWriterRegistryBuilder.addWriter(mockWriter(DataObject1.class));
+        flatWriterRegistryBuilder.add(mockWriter(DataObject1.class));
+        flatWriterRegistryBuilder.add(mockWriter(DataObject1.class));
     }
 
     @Test
     public void testAddSubtreeWriter() throws Exception {
         final FlatWriterRegistryBuilder flatWriterRegistryBuilder = new FlatWriterRegistryBuilder();
-        flatWriterRegistryBuilder.addSubtreeWriter(
+        flatWriterRegistryBuilder.subtreeAdd(
                 Sets.newHashSet(DataObject4.DataObject5.IID,
                                 DataObject4.DataObject5.IID),
                 mockWriter(DataObject4.class));
         final ImmutableMap<InstanceIdentifier<?>, Writer<?>> mappedWriters =
-                flatWriterRegistryBuilder.getMappedWriters();
+                flatWriterRegistryBuilder.getMappedHandlers();
         final ArrayList<InstanceIdentifier<?>> typesInList = Lists.newArrayList(mappedWriters.keySet());
 
         assertEquals(DataObject4.IID, typesInList.get(0));
index df32965..1b4a059 100644 (file)
@@ -20,7 +20,7 @@ import com.google.common.collect.Multimap;
 import io.fd.honeycomb.v3po.translate.write.DataObjectUpdate;
 import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import io.fd.honeycomb.v3po.translate.write.Writer;
-import io.fd.honeycomb.v3po.translate.write.WriterRegistry;
+import io.fd.honeycomb.v3po.translate.write.registry.WriterRegistry;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.InOrder;
@@ -48,19 +48,6 @@ public class FlatWriterRegistryTest {
         when(writer3.getManagedDataObjectType()).thenReturn(DataObject3.IID);
     }
 
-    @Test
-    public void testSingleUpdate() throws Exception {
-        final FlatWriterRegistry flatWriterRegistry =
-                new FlatWriterRegistry(ImmutableMap.of(DataObject1.IID, writer1));
-
-        final InstanceIdentifier<DataObject1> iid = InstanceIdentifier.create(DataObject1.class);
-        final DataObject1 before = mock(DataObject1.class);
-        final DataObject1 after = mock(DataObject1.class);
-        flatWriterRegistry.update(iid, before, after, ctx);
-
-        verify(writer1).update(iid, before, after, ctx);
-    }
-
     @Test
     public void testMultipleUpdatesForSingleWriter() throws Exception {
         final FlatWriterRegistry flatWriterRegistry =
@@ -272,17 +259,6 @@ public class FlatWriterRegistryTest {
         updates.put(iid, DataObjectUpdate.create(iid, mock(type), mock(type)));
     }
 
-    @Test(expected = IllegalArgumentException.class)
-    public void testSingleUpdateMissingWriter() throws Exception {
-        final FlatWriterRegistry flatWriterRegistry =
-                new FlatWriterRegistry(ImmutableMap.of());
-
-        final InstanceIdentifier<DataObject1> iid = InstanceIdentifier.create(DataObject1.class);
-        final DataObject1 before = mock(DataObject1.class);
-        final DataObject1 after = mock(DataObject1.class);
-        flatWriterRegistry.update(iid, before, after, ctx);
-    }
-
     private abstract static class DataObject1 implements DataObject {
         static final InstanceIdentifier<DataObject1> IID = InstanceIdentifier.create(DataObject1.class);
     }
index 435edd0..6a67138 100644 (file)
                 <module>
                     <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:utils">prefix:delegating-reader-registry</type>
                     <name>read-registry</name>
-                    <root-readers>
-                        <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-reader</type>
+                    <reader-factory>
+                        <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-reader-factory</type>
                         <name>vpp-state-honeycomb-reader</name>
-                    </root-readers>
-                    <root-readers>
-                        <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-reader</type>
+                    </reader-factory>
+                    <reader-factory>
+                        <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-reader-factory</type>
                         <name>interfaces-state-honeycomb-reader</name>
-                    </root-readers>
-                    <root-readers>
-                        <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-reader</type>
+                    </reader-factory>
+                    <reader-factory>
+                        <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-reader-factory</type>
                         <name>vpp-classifier-state-honeycomb-reader</name>
-                    </root-readers>
+                    </reader-factory>
                 </module>
 
                 <module>
 
             <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
                 <service>
-                    <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-reader</type>
+                    <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-reader-factory</type>
                     <instance>
                         <name>vpp-state-honeycomb-reader</name>
                         <provider>/modules/module[type='vpp-state-honeycomb-reader'][name='vpp-state-honeycomb-reader']
index 8c90c50..8db903d 100644 (file)
@@ -55,7 +55,6 @@ public class VppInitializer extends AbstractDataTreeConverter<VppState, Vpp> {
 
         VppBuilder vppBuilder = new VppBuilder();
         BridgeDomainsBuilder bdsBuilder = new BridgeDomainsBuilder();
-
         bdsBuilder.setBridgeDomain(Lists.transform(operationalData.getBridgeDomains().getBridgeDomain(), CONVERT_BD));
         vppBuilder.setBridgeDomains(bdsBuilder.build());
         return vppBuilder.build();
index 4e681f6..cb8eed2 100644 (file)
@@ -18,8 +18,7 @@ package io.fd.honeycomb.v3po.translate.v3po.interfaces;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
-import com.google.common.base.Optional;
-import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.write.WriterCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.v3po.util.WriteTimeoutException;
@@ -27,9 +26,7 @@ import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.Acl;
-import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.openvpp.jvpp.VppBaseCallException;
 import org.openvpp.jvpp.future.FutureJVpp;
@@ -37,9 +34,9 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * Customizer for enabling/disabling ACLs on given interface
+ * Customizer for enabling/disabling ACLs on given interface.
  */
-public class AclCustomizer extends FutureJVppCustomizer implements ChildWriterCustomizer<Acl>, AclWriter {
+public class AclCustomizer extends FutureJVppCustomizer implements WriterCustomizer<Acl>, AclWriter {
 
     private static final Logger LOG = LoggerFactory.getLogger(AclCustomizer.class);
     private final NamingContext interfaceContext;
@@ -52,13 +49,6 @@ public class AclCustomizer extends FutureJVppCustomizer implements ChildWriterCu
         this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null");
     }
 
-    @Nonnull
-    @Override
-    public Optional<Acl> extract(@Nonnull final InstanceIdentifier<Acl> currentId,
-                                 @Nonnull final DataObject parentData) {
-        return Optional.fromNullable(((VppInterfaceAugmentation) parentData).getAcl());
-    }
-
     @Override
     public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Acl> id, @Nonnull final Acl dataAfter,
                                        @Nonnull final WriteContext writeContext) throws WriteFailedException {
index dd3a856..27081b1 100644 (file)
 
 package io.fd.honeycomb.v3po.translate.v3po.interfaces;
 
-import com.google.common.base.Optional;
 import io.fd.honeycomb.v3po.translate.v3po.util.AbstractInterfaceTypeCustomizer;
 import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.EthernetCsmacd;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.Ethernet;
-import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.openvpp.jvpp.future.FutureJVpp;
 import org.slf4j.Logger;
@@ -43,13 +40,6 @@ public class EthernetCustomizer extends AbstractInterfaceTypeCustomizer<Ethernet
         return EthernetCsmacd.class;
     }
 
-    @Nonnull
-    @Override
-    public Optional<Ethernet> extract(@Nonnull final InstanceIdentifier<Ethernet> currentId,
-                                      @Nonnull final DataObject parentData) {
-        return Optional.fromNullable(((VppInterfaceAugmentation) parentData).getEthernet());
-    }
-
     @Override
     protected final void writeInterface(@Nonnull final InstanceIdentifier<Ethernet> id,
                                        @Nonnull final Ethernet dataAfter, @Nonnull final WriteContext writeContext) {
index de07bdc..ac57ab4 100644 (file)
@@ -16,7 +16,6 @@
 
 package io.fd.honeycomb.v3po.translate.v3po.interfaces;
 
-import com.google.common.base.Optional;
 import io.fd.honeycomb.v3po.translate.spi.write.ListWriterCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
@@ -24,13 +23,10 @@ import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
 import io.fd.honeycomb.v3po.translate.v3po.util.WriteTimeoutException;
 import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
-import java.util.List;
 import java.util.concurrent.CompletionStage;
 import javax.annotation.Nonnull;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
-import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.openvpp.jvpp.VppBaseCallException;
 import org.openvpp.jvpp.dto.SwInterfaceSetFlags;
@@ -89,14 +85,6 @@ public class InterfaceCustomizer extends FutureJVppCustomizer implements ListWri
         // TODO Handle deletes
     }
 
-    @Nonnull
-    @Override
-    public Optional<List<Interface>> extract(@Nonnull final InstanceIdentifier<Interface> currentId,
-                                   @Nonnull final DataObject parentData) {
-        return Optional.fromNullable(((Interfaces) parentData).getInterface());
-    }
-
-
     private void setInterface(final InstanceIdentifier<Interface> id, final Interface swIf,
                               final WriteContext writeContext)
         throws VppBaseCallException, WriteTimeoutException {
index dd40fbd..83b522b 100644 (file)
 
 package io.fd.honeycomb.v3po.translate.v3po.interfaces;
 
-import com.google.common.base.Optional;
-import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.write.WriterCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.L2;
-import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.openvpp.jvpp.future.FutureJVpp;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class L2Customizer extends FutureJVppCustomizer implements ChildWriterCustomizer<L2> {
+public class L2Customizer extends FutureJVppCustomizer implements WriterCustomizer<L2> {
 
     private static final Logger LOG = LoggerFactory.getLogger(L2Customizer.class);
     private final NamingContext interfaceContext;
@@ -45,12 +42,6 @@ public class L2Customizer extends FutureJVppCustomizer implements ChildWriterCus
         this.icWriteUtils = new InterconnectionWriteUtils(vppApi, interfaceContext, bridgeDomainContext);
     }
 
-    @Nonnull
-    @Override
-    public Optional<L2> extract(@Nonnull final InstanceIdentifier<L2> currentId, @Nonnull final DataObject parentData) {
-        return Optional.fromNullable(((VppInterfaceAugmentation) parentData).getL2());
-    }
-
     @Override
     public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<L2> id, @Nonnull final L2 dataAfter,
                                        @Nonnull final WriteContext writeContext)
index 9fa5783..54c6971 100644 (file)
@@ -18,9 +18,8 @@ package io.fd.honeycomb.v3po.translate.v3po.interfaces;
 
 import static io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils.booleanToByte;
 
-import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
-import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.write.WriterCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.v3po.util.SubInterfaceUtils;
@@ -36,11 +35,9 @@ import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527._802dot1q;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces._interface.sub.interfaces.SubInterface;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.L2;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.l2.Rewrite;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.l2.RewriteBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.tag.rewrite.PushTags;
-import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.openvpp.jvpp.VppBaseCallException;
 import org.openvpp.jvpp.dto.L2InterfaceVlanTagRewrite;
@@ -53,7 +50,7 @@ import org.slf4j.LoggerFactory;
  * Writer Customizer responsible for vlan tag rewrite.<br> Sends {@code l2_interface_vlan_tag_rewrite} message to
  * VPP.<br> Equivalent of invoking {@code vppctl set interface l2 tag-rewrite} command.
  */
-public class RewriteCustomizer extends FutureJVppCustomizer implements ChildWriterCustomizer<Rewrite> {
+public class RewriteCustomizer extends FutureJVppCustomizer implements WriterCustomizer<Rewrite> {
 
     private static final Logger LOG = LoggerFactory.getLogger(RewriteCustomizer.class);
     private final NamingContext interfaceContext;
@@ -64,13 +61,6 @@ public class RewriteCustomizer extends FutureJVppCustomizer implements ChildWrit
         this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null");
     }
 
-    @Nonnull
-    @Override
-    public Optional<Rewrite> extract(@Nonnull final InstanceIdentifier<Rewrite> currentId,
-                                     @Nonnull final DataObject parentData) {
-        return Optional.fromNullable(((L2) parentData).getRewrite());
-    }
-
     @Override
     public void writeCurrentAttributes(final InstanceIdentifier<Rewrite> id, final Rewrite dataAfter,
                                        final WriteContext writeContext)
index 9d41afd..1e81021 100644 (file)
 
 package io.fd.honeycomb.v3po.translate.v3po.interfaces;
 
-import com.google.common.base.Optional;
-import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.write.WriterCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
 import io.fd.honeycomb.v3po.translate.v3po.util.WriteTimeoutException;
 import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
+import java.util.concurrent.CompletionStage;
+import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.Routing;
-import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.openvpp.jvpp.VppBaseCallException;
 import org.openvpp.jvpp.dto.SwInterfaceSetTable;
@@ -36,10 +35,7 @@ import org.openvpp.jvpp.future.FutureJVpp;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.annotation.Nonnull;
-import java.util.concurrent.CompletionStage;
-
-public class RoutingCustomizer extends FutureJVppCustomizer implements ChildWriterCustomizer<Routing> {
+public class RoutingCustomizer extends FutureJVppCustomizer implements WriterCustomizer<Routing> {
 
     private static final Logger LOG = LoggerFactory.getLogger(RoutingCustomizer.class);
     private final NamingContext interfaceContext;
@@ -49,13 +45,6 @@ public class RoutingCustomizer extends FutureJVppCustomizer implements ChildWrit
         this.interfaceContext = interfaceContext;
     }
 
-    @Nonnull
-    @Override
-    public Optional<Routing> extract(@Nonnull final InstanceIdentifier<Routing> currentId,
-                                     @Nonnull final DataObject parentData) {
-        return Optional.fromNullable(((VppInterfaceAugmentation) parentData).getRouting());
-    }
-
     @Override
     public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Routing> id,
                                        @Nonnull final Routing dataAfter, @Nonnull final WriteContext writeContext)
index 9cba9c7..eb433dc 100644 (file)
@@ -19,7 +19,7 @@ package io.fd.honeycomb.v3po.translate.v3po.interfaces;
 import static com.google.common.base.Preconditions.checkNotNull;
 
 import com.google.common.base.Optional;
-import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.write.WriterCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.v3po.util.SubInterfaceUtils;
@@ -40,10 +40,10 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * Customizer for enabling/disabling ACLs on given sub-interface
+ * Customizer for enabling/disabling ACLs on given sub-interface.
  */
 public class SubInterfaceAclCustomizer extends FutureJVppCustomizer
-    implements ChildWriterCustomizer<Acl>, AclWriter {
+    implements WriterCustomizer<Acl>, AclWriter {
 
     private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceAclCustomizer.class);
     private final NamingContext interfaceContext;
@@ -56,13 +56,6 @@ public class SubInterfaceAclCustomizer extends FutureJVppCustomizer
         this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null");
     }
 
-    @Nonnull
-    @Override
-    public Optional<Acl> extract(@Nonnull final InstanceIdentifier<Acl> currentId,
-                                 @Nonnull final DataObject parentData) {
-        return Optional.fromNullable(((SubInterface) parentData).getAcl());
-    }
-
     @Override
     public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Acl> id, @Nonnull final Acl dataAfter,
                                        @Nonnull final WriteContext writeContext) throws WriteFailedException {
index 57676c8..c497186 100644 (file)
@@ -20,7 +20,6 @@ import static com.google.common.base.Preconditions.checkState;
 import static io.fd.honeycomb.v3po.translate.v3po.util.SubInterfaceUtils.getSubInterfaceName;
 import static io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils.booleanToByte;
 
-import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import io.fd.honeycomb.v3po.translate.spi.write.ListWriterCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
@@ -40,7 +39,6 @@ import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev1
 import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.dot1q.tag.or.any.Dot1qTag;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527._802dot1ad;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces._interface.SubInterfaces;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces._interface.sub.interfaces.SubInterface;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces._interface.sub.interfaces.SubInterfaceKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.match.attributes.MatchType;
@@ -48,7 +46,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.match.attributes.match.type.vlan.tagged.VlanTagged;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.Tags;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.tags.Tag;
-import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.openvpp.jvpp.VppBaseCallException;
 import org.openvpp.jvpp.dto.CreateSubif;
@@ -74,14 +71,6 @@ public class SubInterfaceCustomizer extends FutureJVppCustomizer
         this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null");
     }
 
-    @Nonnull
-    @Override
-    public Optional<List<SubInterface>> extract(@Nonnull final InstanceIdentifier<SubInterface> currentId,
-                                                @Nonnull final DataObject parentData) {
-        return Optional.fromNullable(((SubInterfaces) parentData).getSubInterface());
-    }
-
-
     @Override
     public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<SubInterface> id,
                                        @Nonnull final SubInterface dataAfter, @Nonnull final WriteContext writeContext)
index 8ab3e2c..567122d 100644 (file)
@@ -16,8 +16,7 @@
 
 package io.fd.honeycomb.v3po.translate.v3po.interfaces;
 
-import com.google.common.base.Optional;
-import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.write.WriterCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.v3po.util.SubInterfaceUtils;
@@ -29,7 +28,6 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces._interface.sub.interfaces.SubInterface;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces._interface.sub.interfaces.SubInterfaceKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.L2;
-import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.openvpp.jvpp.future.FutureJVpp;
 import org.slf4j.Logger;
@@ -38,7 +36,7 @@ import org.slf4j.LoggerFactory;
 /**
  * Customizer for writing vlan sub interface l2 configuration
  */
-public class SubInterfaceL2Customizer extends FutureJVppCustomizer implements ChildWriterCustomizer<L2> {
+public class SubInterfaceL2Customizer extends FutureJVppCustomizer implements WriterCustomizer<L2> {
 
     private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceL2Customizer.class);
     private final NamingContext interfaceContext;
@@ -51,12 +49,6 @@ public class SubInterfaceL2Customizer extends FutureJVppCustomizer implements Ch
         this.icWriterUtils = new InterconnectionWriteUtils(vppApi, interfaceContext, bridgeDomainContext);
     }
 
-    @Nonnull
-    @Override
-    public Optional<L2> extract(@Nonnull final InstanceIdentifier<L2> currentId, @Nonnull final DataObject parentData) {
-        return Optional.fromNullable(((SubInterface) parentData).getL2());
-    }
-
     @Override
     public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<L2> id, @Nonnull final L2 dataAfter,
                                        @Nonnull final WriteContext writeContext)
index d0e5179..6de3bc4 100644 (file)
 
 package io.fd.honeycomb.v3po.translate.v3po.interfaces;
 
-import com.google.common.base.Optional;
 import io.fd.honeycomb.v3po.translate.v3po.util.AbstractInterfaceTypeCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
 import io.fd.honeycomb.v3po.translate.v3po.util.WriteTimeoutException;
 import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
+import java.util.concurrent.CompletionStage;
+import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.Tap;
-import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.openvpp.jvpp.VppBaseCallException;
-import org.openvpp.jvpp.dto.*;
+import org.openvpp.jvpp.dto.TapConnect;
+import org.openvpp.jvpp.dto.TapConnectReply;
+import org.openvpp.jvpp.dto.TapDelete;
+import org.openvpp.jvpp.dto.TapDeleteReply;
+import org.openvpp.jvpp.dto.TapModify;
+import org.openvpp.jvpp.dto.TapModifyReply;
 import org.openvpp.jvpp.future.FutureJVpp;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.annotation.Nonnull;
-import java.util.concurrent.CompletionStage;
-
 public class TapCustomizer extends AbstractInterfaceTypeCustomizer<Tap> {
 
     private static final Logger LOG = LoggerFactory.getLogger(TapCustomizer.class);
@@ -49,13 +50,6 @@ public class TapCustomizer extends AbstractInterfaceTypeCustomizer<Tap> {
         this.interfaceContext = interfaceContext;
     }
 
-    @Nonnull
-    @Override
-    public Optional<Tap> extract(@Nonnull final InstanceIdentifier<Tap> currentId,
-                                   @Nonnull final DataObject parentData) {
-        return Optional.fromNullable(((VppInterfaceAugmentation) parentData).getTap());
-    }
-
     @Override
     protected Class<? extends InterfaceType> getExpectedInterfaceType() {
         return org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.Tap.class;
index 60df2cf..d087f30 100644 (file)
@@ -16,7 +16,6 @@
 
 package io.fd.honeycomb.v3po.translate.v3po.interfaces;
 
-import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import io.fd.honeycomb.v3po.translate.v3po.util.AbstractInterfaceTypeCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
@@ -24,22 +23,24 @@ import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
 import io.fd.honeycomb.v3po.translate.v3po.util.WriteTimeoutException;
 import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
+import java.util.concurrent.CompletionStage;
+import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VhostUserRole;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VhostUser;
-import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.openvpp.jvpp.VppBaseCallException;
-import org.openvpp.jvpp.dto.*;
+import org.openvpp.jvpp.dto.CreateVhostUserIf;
+import org.openvpp.jvpp.dto.CreateVhostUserIfReply;
+import org.openvpp.jvpp.dto.DeleteVhostUserIf;
+import org.openvpp.jvpp.dto.DeleteVhostUserIfReply;
+import org.openvpp.jvpp.dto.ModifyVhostUserIf;
+import org.openvpp.jvpp.dto.ModifyVhostUserIfReply;
 import org.openvpp.jvpp.future.FutureJVpp;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.annotation.Nonnull;
-import java.util.concurrent.CompletionStage;
-
 /**
  * Writer Customizer responsible for passing vhost user interface CRD operations to VPP
  */
@@ -53,13 +54,6 @@ public class VhostUserCustomizer extends AbstractInterfaceTypeCustomizer<VhostUs
         this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null");
     }
 
-    @Nonnull
-    @Override
-    public Optional<VhostUser> extract(@Nonnull final InstanceIdentifier<VhostUser> currentId,
-                                       @Nonnull final DataObject parentData) {
-        return Optional.fromNullable(((VppInterfaceAugmentation) parentData).getVhostUser());
-    }
-
     @Override
     protected Class<? extends InterfaceType> getExpectedInterfaceType() {
         return org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VhostUser.class;
index 3823480..82c5728 100644 (file)
@@ -18,7 +18,6 @@ package io.fd.honeycomb.v3po.translate.v3po.interfaces;
 
 import static com.google.common.base.Preconditions.checkArgument;
 
-import com.google.common.base.Optional;
 import com.google.common.net.InetAddresses;
 import io.fd.honeycomb.v3po.translate.v3po.util.AbstractInterfaceTypeCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
@@ -32,10 +31,8 @@ import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanTunnel;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.Vxlan;
-import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.openvpp.jvpp.VppBaseCallException;
 import org.openvpp.jvpp.dto.VxlanAddDelTunnel;
@@ -55,13 +52,6 @@ public class VxlanCustomizer extends AbstractInterfaceTypeCustomizer<Vxlan> {
         this.interfaceContext = interfaceContext;
     }
 
-    @Nonnull
-    @Override
-    public Optional<Vxlan> extract(@Nonnull final InstanceIdentifier<Vxlan> currentId,
-                                   @Nonnull final DataObject parentData) {
-        return Optional.fromNullable(((VppInterfaceAugmentation) parentData).getVxlan());
-    }
-
     @Override
     protected Class<? extends InterfaceType> getExpectedInterfaceType() {
         return VxlanTunnel.class;
index 9b7e4bd..ebe7bfe 100644 (file)
@@ -18,7 +18,6 @@ package io.fd.honeycomb.v3po.translate.v3po.interfaces;
 
 import static com.google.common.base.Preconditions.checkArgument;
 
-import com.google.common.base.Optional;
 import com.google.common.net.InetAddresses;
 import io.fd.honeycomb.v3po.translate.v3po.util.AbstractInterfaceTypeCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
@@ -32,10 +31,8 @@ import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanGpeTunnel;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VxlanGpe;
-import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.openvpp.jvpp.VppBaseCallException;
 import org.openvpp.jvpp.dto.VxlanGpeAddDelTunnel;
@@ -44,7 +41,6 @@ import org.openvpp.jvpp.future.FutureJVpp;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-// TODO extract common code from all Interface type specific writer customizers into a superclass
 public class VxlanGpeCustomizer extends AbstractInterfaceTypeCustomizer<VxlanGpe> {
 
     private static final Logger LOG = LoggerFactory.getLogger(VxlanGpeCustomizer.class);
@@ -55,13 +51,6 @@ public class VxlanGpeCustomizer extends AbstractInterfaceTypeCustomizer<VxlanGpe
         this.interfaceContext = interfaceContext;
     }
 
-    @Nonnull
-    @Override
-    public Optional<VxlanGpe> extract(@Nonnull final InstanceIdentifier<VxlanGpe> currentId,
-                                   @Nonnull final DataObject parentData) {
-        return Optional.fromNullable(((VppInterfaceAugmentation) parentData).getVxlanGpe());
-    }
-
     @Override
     protected Class<? extends InterfaceType> getExpectedInterfaceType() {
         return VxlanGpeTunnel.class;
@@ -102,25 +91,25 @@ public class VxlanGpeCustomizer extends AbstractInterfaceTypeCustomizer<VxlanGpe
     }
 
     private void createVxlanGpeTunnel(final InstanceIdentifier<VxlanGpe> id, final String swIfName,
-                                      final VxlanGpe VxlanGpe, final WriteContext writeContext)
+                                      final VxlanGpe vxlanGpe, final WriteContext writeContext)
         throws VppBaseCallException, WriteTimeoutException {
-        final byte isIpv6 = (byte) (isIpv6(VxlanGpe) ? 1 : 0);
-        final InetAddress Local = InetAddresses.forString(getAddressString(VxlanGpe.getLocal()));
-        final InetAddress Remote = InetAddresses.forString(getAddressString(VxlanGpe.getRemote()));
+        final byte isIpv6 = (byte) (isIpv6(vxlanGpe) ? 1 : 0);
+        final InetAddress Local = InetAddresses.forString(getAddressString(vxlanGpe.getLocal()));
+        final InetAddress Remote = InetAddresses.forString(getAddressString(vxlanGpe.getRemote()));
 
-        int vni = VxlanGpe.getVni().getValue().intValue();
-        byte protocol = (byte) VxlanGpe.getNextProtocol().getIntValue();
-        int encapVrfId = VxlanGpe.getEncapVrfId().intValue();
-        int decapVrfId = VxlanGpe.getDecapVrfId().intValue();
+        int vni = vxlanGpe.getVni().getValue().intValue();
+        byte protocol = (byte) vxlanGpe.getNextProtocol().getIntValue();
+        int encapVrfId = vxlanGpe.getEncapVrfId().intValue();
+        int decapVrfId = vxlanGpe.getDecapVrfId().intValue();
 
-        LOG.debug("Setting VxlanGpe tunnel for interface: {}. VxlanGpe: {}", swIfName, VxlanGpe);
+        LOG.debug("Setting VxlanGpe tunnel for interface: {}. VxlanGpe: {}", swIfName, vxlanGpe);
         final CompletionStage<VxlanGpeAddDelTunnelReply> VxlanGpeAddDelTunnelReplyCompletionStage =
                 getFutureJVpp().vxlanGpeAddDelTunnel(getVxlanGpeTunnelRequest((byte) 1 /* is add */, Local.getAddress(),
                     Remote.getAddress(), vni, protocol, encapVrfId, decapVrfId, isIpv6));
 
         final VxlanGpeAddDelTunnelReply reply =
                 TranslateUtils.getReplyForWrite(VxlanGpeAddDelTunnelReplyCompletionStage.toCompletableFuture(), id);
-        LOG.debug("VxlanGpe tunnel set successfully for: {}, VxlanGpe: {}", swIfName, VxlanGpe);
+        LOG.debug("VxlanGpe tunnel set successfully for: {}, VxlanGpe: {}", swIfName, vxlanGpe);
         if(interfaceContext.containsName(reply.swIfIndex, writeContext.getMappingContext())) {
             final String formerName = interfaceContext.getName(reply.swIfIndex, writeContext.getMappingContext());
             LOG.debug("Removing updated mapping of a vxlan-gpe tunnel, id: {}, former name: {}, new name: {}",
index a05bd8f..26d0554 100644 (file)
@@ -20,23 +20,19 @@ import static com.google.common.base.Preconditions.checkNotNull;
 import static io.fd.honeycomb.v3po.translate.v3po.interfaces.ip.Ipv4WriteUtils.addDelAddress;
 import static io.fd.honeycomb.v3po.translate.v3po.interfaces.ip.Ipv4WriteUtils.getSubnetMaskLength;
 
-import com.google.common.base.Optional;
 import io.fd.honeycomb.v3po.translate.spi.write.ListWriterCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
-import java.util.List;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Address;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.AddressKey;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.Subnet;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.Netmask;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.PrefixLength;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad;
-import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.openvpp.jvpp.VppBaseCallException;
 import org.openvpp.jvpp.future.FutureJVpp;
@@ -75,11 +71,6 @@ public class Ipv4AddressCustomizer extends FutureJVppCustomizer implements ListW
         setAddress(false, id, dataBefore, writeContext);
     }
 
-    @Override
-    public Optional<List<Address>> extract(InstanceIdentifier<Address> currentId, DataObject parentData) {
-        return Optional.fromNullable((((Ipv4) parentData).getAddress()));
-    }
-
     private void setAddress(boolean add, final InstanceIdentifier<Address> id, final Address address,
                             final WriteContext writeContext) throws WriteFailedException {
 
index cee6474..7eb45b2 100644 (file)
 
 package io.fd.honeycomb.v3po.translate.v3po.interfaces.ip;
 
-import com.google.common.base.Optional;
-import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.write.WriterCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface1;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4;
-import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.openvpp.jvpp.future.FutureJVpp;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class Ipv4Customizer extends FutureJVppCustomizer implements ChildWriterCustomizer<Ipv4> {
+public class Ipv4Customizer extends FutureJVppCustomizer implements WriterCustomizer<Ipv4> {
 
     private static final Logger LOG = LoggerFactory.getLogger(Ipv4Customizer.class);
     private final NamingContext interfaceContext;
@@ -42,14 +39,6 @@ public class Ipv4Customizer extends FutureJVppCustomizer implements ChildWriterC
         this.interfaceContext = interfaceContext;
     }
 
-    // TODO replace guava's Optionals with Java8
-    @Nonnull
-    @Override
-    public Optional<Ipv4> extract(@Nonnull final InstanceIdentifier<Ipv4> currentId,
-                                  @Nonnull final DataObject parentData) {
-        return Optional.fromNullable(((Interface1) parentData).getIpv4());
-    }
-
     @Override
     public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Ipv4> id,
                                        @Nonnull final Ipv4 dataAfter, @Nonnull final WriteContext writeContext)
index 99267dd..426d81f 100644 (file)
@@ -20,7 +20,6 @@ import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Preconditions.checkState;
 
-import com.google.common.base.Optional;
 import io.fd.honeycomb.v3po.translate.MappingContext;
 import io.fd.honeycomb.v3po.translate.spi.write.ListWriterCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
@@ -29,13 +28,11 @@ import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
 import io.fd.honeycomb.v3po.translate.v3po.util.WriteTimeoutException;
 import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
-import java.util.List;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Neighbor;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.NeighborKey;
-import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.openvpp.jvpp.VppBaseCallException;
 import org.openvpp.jvpp.dto.IpNeighborAddDel;
@@ -116,12 +113,6 @@ public class Ipv4NeighbourCustomizer extends FutureJVppCustomizer
         }
     }
 
-    @Override
-    public Optional<List<Neighbor>> extract(@Nonnull InstanceIdentifier<Neighbor> currentId,
-                                            @Nonnull DataObject parentData) {
-        return Optional.fromNullable((((Ipv4) parentData).getNeighbor()));
-    }
-
     private void addDelNeighbourAndReply(InstanceIdentifier<Neighbor> id, boolean add, int parentInterfaceIndex,
                                          Neighbor data)
             throws VppBaseCallException, WriteTimeoutException {
index 0fe8643..d43bc90 100644 (file)
 
 package io.fd.honeycomb.v3po.translate.v3po.interfaces.ip;
 
-import com.google.common.base.Optional;
-import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.write.WriterCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import javax.annotation.Nonnull;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface1;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv6;
-import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.openvpp.jvpp.future.FutureJVpp;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class Ipv6Customizer extends FutureJVppCustomizer implements ChildWriterCustomizer<Ipv6> {
+public class Ipv6Customizer extends FutureJVppCustomizer implements WriterCustomizer<Ipv6> {
 
     private static final Logger LOG = LoggerFactory.getLogger(Ipv6Customizer.class);
 
@@ -37,13 +34,6 @@ public class Ipv6Customizer extends FutureJVppCustomizer implements ChildWriterC
         super(vppApi);
     }
 
-    @Nonnull
-    @Override
-    public Optional<Ipv6> extract(@Nonnull final InstanceIdentifier<Ipv6> currentId,
-                                      @Nonnull final DataObject parentData) {
-        return Optional.fromNullable(((Interface1) parentData).getIpv6());
-    }
-
     @Override
     public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Ipv6> id,
                                        @Nonnull final Ipv6 dataAfter, @Nonnull final WriteContext writeContext) {
index ccdcc6c..3d41b89 100644 (file)
@@ -20,27 +20,23 @@ import static com.google.common.base.Preconditions.checkNotNull;
 import static io.fd.honeycomb.v3po.translate.v3po.interfaces.ip.Ipv4WriteUtils.addDelAddress;
 import static io.fd.honeycomb.v3po.translate.v3po.interfaces.ip.Ipv4WriteUtils.getSubnetMaskLength;
 
-import com.google.common.base.Optional;
 import io.fd.honeycomb.v3po.translate.spi.write.ListWriterCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.v3po.util.SubInterfaceUtils;
 import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
-import java.util.List;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces._interface.sub.interfaces.SubInterface;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces._interface.sub.interfaces.SubInterfaceKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.ip4.attributes.Ipv4;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.ip4.attributes.ipv4.Address;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.ip4.attributes.ipv4.AddressKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.ip4.attributes.ipv4.address.Subnet;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.ip4.attributes.ipv4.address.subnet.Netmask;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.ip4.attributes.ipv4.address.subnet.PrefixLength;
-import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.openvpp.jvpp.VppBaseCallException;
 import org.openvpp.jvpp.future.FutureJVpp;
@@ -81,11 +77,6 @@ public class SubInterfaceIpv4AddressCustomizer extends FutureJVppCustomizer
         setAddress(false, id, dataBefore, writeContext);
     }
 
-    @Override
-    public Optional<List<Address>> extract(InstanceIdentifier<Address> currentId, DataObject parentData) {
-        return Optional.fromNullable((((Ipv4) parentData).getAddress()));
-    }
-
     private void setAddress(boolean add, final InstanceIdentifier<Address> id, final Address address,
                             final WriteContext writeContext) throws WriteFailedException {
 
index d8d2d8e..c5b17e5 100644 (file)
@@ -21,7 +21,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
 
 import io.fd.honeycomb.v3po.translate.read.ReadContext;
 import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.read.ReaderCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
@@ -42,10 +42,10 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * Customizer for reading ACLs enabled on given interface
+ * Customizer for reading ACLs enabled on given interface.
  */
 public class AclCustomizer extends FutureJVppCustomizer
-    implements ChildReaderCustomizer<Acl, AclBuilder>, AclReader {
+    implements ReaderCustomizer<Acl, AclBuilder>, AclReader {
 
     private static final Logger LOG = LoggerFactory.getLogger(AclCustomizer.class);
     private final NamingContext interfaceContext;
index 5bbf339..a2643e4 100644 (file)
@@ -18,7 +18,7 @@ package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
 
 import io.fd.honeycomb.v3po.translate.read.ReadContext;
 import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.read.ReaderCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import javax.annotation.Nonnull;
@@ -37,7 +37,7 @@ import org.slf4j.LoggerFactory;
 
 
 public class EthernetCustomizer extends FutureJVppCustomizer
-        implements ChildReaderCustomizer<Ethernet, EthernetBuilder> {
+        implements ReaderCustomizer<Ethernet, EthernetBuilder> {
 
     private static final Logger LOG = LoggerFactory.getLogger(EthernetCustomizer.class);
     private NamingContext interfaceContext;
index e1496e3..e7c6b2a 100644 (file)
@@ -18,7 +18,7 @@ package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
 
 import io.fd.honeycomb.v3po.translate.read.ReadContext;
 import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.read.ReaderCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
@@ -34,15 +34,13 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.annotation.Nonnull;
-import java.util.Optional;
-import java.util.concurrent.CompletableFuture;
 
 import static com.google.common.base.Preconditions.checkState;
 
 /**
  * Customizer for reading ietf-interfaces:interfaces-state/interface/iface_name/v3po:l2
  */
-public class L2Customizer extends FutureJVppCustomizer implements ChildReaderCustomizer<L2, L2Builder> {
+public class L2Customizer extends FutureJVppCustomizer implements ReaderCustomizer<L2, L2Builder> {
 
     private static final Logger LOG = LoggerFactory.getLogger(L2Customizer.class);
     private final InterconnectionReadUtils icReadUtils;
index 9bb12da..e76ed76 100644 (file)
@@ -21,7 +21,7 @@ import static com.google.common.base.Preconditions.checkState;
 import com.google.common.base.Preconditions;
 import io.fd.honeycomb.v3po.translate.read.ReadContext;
 import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.read.ReaderCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.v3po.util.SubInterfaceUtils;
@@ -57,7 +57,7 @@ import org.slf4j.LoggerFactory;
  * Customizer for reading vlan tag-rewrite configuration state form the VPP.
  */
 public class RewriteCustomizer extends FutureJVppCustomizer
-        implements ChildReaderCustomizer<Rewrite, RewriteBuilder> {
+        implements ReaderCustomizer<Rewrite, RewriteBuilder> {
 
     private static final Logger LOG = LoggerFactory.getLogger(RewriteCustomizer.class);
     private final NamingContext interfaceContext;
index a00485f..276849b 100644 (file)
@@ -22,7 +22,7 @@ import static io.fd.honeycomb.v3po.translate.v3po.util.SubInterfaceUtils.getSubI
 
 import io.fd.honeycomb.v3po.translate.read.ReadContext;
 import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.read.ReaderCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
@@ -45,10 +45,10 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * Customizer for reading ACLs enabled on given sub-interface
+ * Customizer for reading ACLs enabled on given sub-interface.
  */
 public class SubInterfaceAclCustomizer extends FutureJVppCustomizer
-    implements ChildReaderCustomizer<Acl, AclBuilder>, AclReader {
+    implements ReaderCustomizer<Acl, AclBuilder>, AclReader {
 
     private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceAclCustomizer.class);
     private final NamingContext interfaceContext;
index 0c6d50b..6e9b167 100644 (file)
@@ -20,7 +20,7 @@ import static io.fd.honeycomb.v3po.translate.v3po.util.SubInterfaceUtils.getSubI
 
 import io.fd.honeycomb.v3po.translate.read.ReadContext;
 import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.read.ReaderCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import javax.annotation.Nonnull;
@@ -41,7 +41,7 @@ import org.slf4j.LoggerFactory;
 /**
  * Customizer for reading vlan sub interface L2 operational state
  */
-public class SubInterfaceL2Customizer extends FutureJVppCustomizer implements ChildReaderCustomizer<L2, L2Builder> {
+public class SubInterfaceL2Customizer extends FutureJVppCustomizer implements ReaderCustomizer<L2, L2Builder> {
 
     private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceL2Customizer.class);
     private final InterconnectionReadUtils icReadUtils;
index 3f79e55..c9a592e 100644 (file)
@@ -20,7 +20,7 @@ import static io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceUtils
 
 import io.fd.honeycomb.v3po.translate.read.ReadContext;
 import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.read.ReaderCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
@@ -48,7 +48,7 @@ import org.slf4j.LoggerFactory;
 
 
 public class TapCustomizer extends FutureJVppCustomizer
-        implements ChildReaderCustomizer<Tap, TapBuilder> {
+        implements ReaderCustomizer<Tap, TapBuilder> {
 
     private static final Logger LOG = LoggerFactory.getLogger(TapCustomizer.class);
     public static final String DUMPED_TAPS_CONTEXT_KEY = TapCustomizer.class.getName() + "dumpedTapsDuringGetAllIds";
index 23e1a6e..878eb31 100644 (file)
@@ -20,7 +20,7 @@ import static io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceUtils
 
 import io.fd.honeycomb.v3po.translate.read.ReadContext;
 import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.read.ReaderCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
@@ -50,7 +50,7 @@ import org.slf4j.LoggerFactory;
 
 
 public class VhostUserCustomizer extends FutureJVppCustomizer
-        implements ChildReaderCustomizer<VhostUser, VhostUserBuilder> {
+        implements ReaderCustomizer<VhostUser, VhostUserBuilder> {
 
     private static final Logger LOG = LoggerFactory.getLogger(VhostUserCustomizer.class);
     public static final String DUMPED_VHOST_USERS_CONTEXT_KEY = VhostUserCustomizer.class.getName() + "dumpedVhostUsersDuringGetAllIds";
index 3d82820..b57274a 100644 (file)
@@ -21,7 +21,7 @@ import static io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceUtils
 
 import io.fd.honeycomb.v3po.translate.read.ReadContext;
 import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.read.ReaderCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
@@ -52,10 +52,10 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class VxlanCustomizer extends FutureJVppCustomizer
-        implements ChildReaderCustomizer<Vxlan, VxlanBuilder> {
+        implements ReaderCustomizer<Vxlan, VxlanBuilder> {
 
     private static final Logger LOG = LoggerFactory.getLogger(VxlanCustomizer.class);
-    private NamingContext interfaceContext;
+    private final NamingContext interfaceContext;
 
     public VxlanCustomizer(@Nonnull final FutureJVpp jvpp, @Nonnull final NamingContext interfaceContext) {
         super(jvpp);
index de05dc4..2e45a2b 100644 (file)
@@ -21,7 +21,7 @@ import static io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceUtils
 
 import io.fd.honeycomb.v3po.translate.read.ReadContext;
 import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.read.ReaderCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
@@ -53,7 +53,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class VxlanGpeCustomizer extends FutureJVppCustomizer
-        implements ChildReaderCustomizer<VxlanGpe, VxlanGpeBuilder> {
+        implements ReaderCustomizer<VxlanGpe, VxlanGpeBuilder> {
 
     private static final Logger LOG = LoggerFactory.getLogger(VxlanGpeCustomizer.class);
     private NamingContext interfaceContext;
index 8e61627..fa912c0 100644 (file)
@@ -18,7 +18,7 @@ package io.fd.honeycomb.v3po.translate.v3po.interfacesstate.ip;
 
 import io.fd.honeycomb.v3po.translate.read.ReadContext;
 import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.read.ReaderCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface2Builder;
@@ -31,7 +31,7 @@ import org.openvpp.jvpp.future.FutureJVpp;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class Ipv4Customizer extends FutureJVppCustomizer implements ChildReaderCustomizer<Ipv4, Ipv4Builder> {
+public class Ipv4Customizer extends FutureJVppCustomizer implements ReaderCustomizer<Ipv4, Ipv4Builder> {
 
     private static final Logger LOG = LoggerFactory.getLogger(Ipv4Customizer.class);
 
index 37524dd..ada05b7 100644 (file)
@@ -17,7 +17,7 @@ package io.fd.honeycomb.v3po.translate.v3po.interfacesstate.ip;
 
 import io.fd.honeycomb.v3po.translate.read.ReadContext;
 import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.read.ReaderCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import javax.annotation.Nonnull;
@@ -29,7 +29,7 @@ import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.openvpp.jvpp.future.FutureJVpp;
 
-public class Ipv6Customizer extends FutureJVppCustomizer implements ChildReaderCustomizer<Ipv6, Ipv6Builder> {
+public class Ipv6Customizer extends FutureJVppCustomizer implements ReaderCustomizer<Ipv6, Ipv6Builder> {
 
     private final NamingContext interfaceContext;
 
index 22344ba..601a79e 100644 (file)
@@ -20,7 +20,6 @@ import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
 import static io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils.booleanToByte;
 
-import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import io.fd.honeycomb.v3po.translate.spi.write.ListWriterCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
@@ -29,12 +28,9 @@ import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
 import io.fd.honeycomb.v3po.translate.v3po.util.WriteTimeoutException;
 import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
-import java.util.List;
 import javax.annotation.Nonnull;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.BridgeDomains;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainKey;
-import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.openvpp.jvpp.VppBaseCallException;
 import org.openvpp.jvpp.dto.BridgeDomainAddDel;
@@ -57,13 +53,6 @@ public class BridgeDomainCustomizer
         this.bdContext = Preconditions.checkNotNull(bdContext, "bdContext should not be null");
     }
 
-    @Nonnull
-    @Override
-    public Optional<List<BridgeDomain>> extract(@Nonnull final InstanceIdentifier<BridgeDomain> currentId,
-                                                @Nonnull final DataObject parentData) {
-        return Optional.fromNullable(((BridgeDomains) parentData).getBridgeDomain());
-    }
-
     private BridgeDomainAddDelReply addOrUpdateBridgeDomain(@Nonnull final InstanceIdentifier<BridgeDomain> id,
                                                             final int bdId, @Nonnull final BridgeDomain bd)
         throws VppBaseCallException, WriteTimeoutException {
index 3655a48..52bb1ad 100644 (file)
@@ -19,7 +19,6 @@ package io.fd.honeycomb.v3po.translate.v3po.vpp;
 import static io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils.booleanToByte;
 import static io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils.parseMac;
 
-import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.primitives.Longs;
 import io.fd.honeycomb.v3po.translate.spi.write.ListWriterCustomizer;
@@ -29,16 +28,13 @@ import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
 import io.fd.honeycomb.v3po.translate.v3po.util.WriteTimeoutException;
 import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
-import java.util.List;
 import java.util.concurrent.CompletionStage;
 import javax.annotation.Nonnull;
 import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.L2FibFilter;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.fib.attributes.L2FibTable;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.fib.attributes.l2.fib.table.L2FibEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.fib.attributes.l2.fib.table.L2FibEntryKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain;
-import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.openvpp.jvpp.VppBaseCallException;
 import org.openvpp.jvpp.dto.L2FibAddDel;
@@ -66,13 +62,6 @@ public class L2FibEntryCustomizer extends FutureJVppCustomizer
         this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null");
     }
 
-    @Nonnull
-    @Override
-    public Optional<List<L2FibEntry>> extract(@Nonnull final InstanceIdentifier<L2FibEntry> currentId,
-                                              @Nonnull final DataObject parentData) {
-        return Optional.fromNullable(((L2FibTable) parentData).getL2FibEntry());
-    }
-
     @Override
     public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<L2FibEntry> id,
                                        @Nonnull final L2FibEntry dataAfter, @Nonnull final WriteContext writeContext)
index ac964a9..ea183a8 100644 (file)
@@ -21,7 +21,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Preconditions.checkState;
 import static io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils.booleanToByte;
 
-import com.google.common.base.Optional;
 import io.fd.honeycomb.v3po.translate.spi.write.ListWriterCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
@@ -29,7 +28,6 @@ import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
 import io.fd.honeycomb.v3po.translate.v3po.util.WriteTimeoutException;
 import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
-import java.util.List;
 import java.util.concurrent.CompletionStage;
 import javax.annotation.Nonnull;
 import javax.xml.bind.DatatypeConverter;
@@ -38,7 +36,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.clas
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.classify.table.base.attributes.ClassifySessionKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.vpp.classifier.ClassifyTable;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.vpp.classifier.ClassifyTableKey;
-import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.openvpp.jvpp.VppBaseCallException;
 import org.openvpp.jvpp.dto.ClassifyAddDelSession;
@@ -63,13 +60,6 @@ public class ClassifySessionWriter extends FutureJVppCustomizer
         this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null");
     }
 
-    @Nonnull
-    @Override
-    public Optional<List<ClassifySession>> extract(@Nonnull final InstanceIdentifier<ClassifySession> currentId,
-                                                   @Nonnull final DataObject parentData) {
-        return Optional.fromNullable(((ClassifyTable) parentData).getClassifySession());
-    }
-
     @Override
     public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<ClassifySession> id,
                                        @Nonnull final ClassifySession dataAfter,
index 788aac5..c344684 100644 (file)
@@ -21,7 +21,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Preconditions.checkState;
 import static io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils.booleanToByte;
 
-import com.google.common.base.Optional;
 import io.fd.honeycomb.v3po.translate.MappingContext;
 import io.fd.honeycomb.v3po.translate.spi.write.ListWriterCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
@@ -30,14 +29,11 @@ import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
 import io.fd.honeycomb.v3po.translate.v3po.util.WriteTimeoutException;
 import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
-import java.util.List;
 import java.util.concurrent.CompletionStage;
 import javax.annotation.Nonnull;
 import javax.xml.bind.DatatypeConverter;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.VppClassifier;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.vpp.classifier.ClassifyTable;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.vpp.classifier.ClassifyTableKey;
-import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.openvpp.jvpp.VppBaseCallException;
 import org.openvpp.jvpp.dto.ClassifyAddDelTable;
@@ -62,13 +58,6 @@ public class ClassifyTableWriter extends FutureJVppCustomizer
         this.classifyTableContext = checkNotNull(classifyTableContext, "classifyTableContext should not be null");
     }
 
-    @Nonnull
-    @Override
-    public Optional<List<ClassifyTable>> extract(@Nonnull final InstanceIdentifier<ClassifyTable> currentId,
-                                                 @Nonnull final DataObject parentData) {
-        return Optional.fromNullable(((VppClassifier) parentData).getClassifyTable());
-    }
-
     @Override
     public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<ClassifyTable> id,
                                        @Nonnull final ClassifyTable dataAfter, @Nonnull final WriteContext writeContext)
index 83a8995..2032cd8 100644 (file)
@@ -18,7 +18,7 @@ package io.fd.honeycomb.v3po.translate.v3po.vppstate;
 
 import io.fd.honeycomb.v3po.translate.read.ReadContext;
 import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.read.ReaderCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
 import java.util.concurrent.CompletionStage;
@@ -36,7 +36,7 @@ import org.openvpp.jvpp.future.FutureJVpp;
 
 public final class VersionCustomizer
     extends FutureJVppCustomizer
-    implements ChildReaderCustomizer<Version, VersionBuilder> {
+    implements ReaderCustomizer<Version, VersionBuilder> {
 
     /**
      * Default timeout for executing version read
index 64f1e8a..635c77a 100644 (file)
@@ -20,7 +20,7 @@ import io.fd.honeycomb.v3po.translate.v3po.interfaces.ip.Ipv4Customizer;
 import io.fd.honeycomb.v3po.translate.v3po.interfaces.ip.Ipv4NeighbourCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.interfaces.ip.Ipv6Customizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
-import io.fd.honeycomb.v3po.translate.write.ModifiableWriterRegistry;
+import io.fd.honeycomb.v3po.translate.write.registry.ModifiableWriterRegistryBuilder;
 import io.fd.honeycomb.v3po.translate.write.WriterFactory;
 import java.util.Set;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
@@ -106,10 +106,10 @@ public class InterfacesHoneycombWriterModule extends
         }
 
         @Override
-        public void init(final ModifiableWriterRegistry registry) {
+        public void init(final ModifiableWriterRegistryBuilder registry) {
             // Interfaces
             //  Interface =
-            registry.addWriter(new GenericListWriter<>(IFC_ID, new InterfaceCustomizer(jvpp, ifcContext)));
+            registry.add(new GenericListWriter<>(IFC_ID, new InterfaceCustomizer(jvpp, ifcContext)));
             //   VppInterfaceAugmentation
             addVppInterfaceAgmentationWriters(IFC_ID, registry);
             //   Interface1 (ietf-ip augmentation)
@@ -119,65 +119,63 @@ public class InterfacesHoneycombWriterModule extends
         }
 
         private void addInterface1AugmentationWriters(final InstanceIdentifier<Interface> ifcId,
-                                                      final ModifiableWriterRegistry registry) {
+                                                      final ModifiableWriterRegistryBuilder registry) {
             final InstanceIdentifier<Interface1> ifc1AugId = ifcId.augmentation(Interface1.class);
             // Ipv6(after interface) TODO unfinished customizer =
-            registry.addWriterAfter(new GenericWriter<>(ifc1AugId.child(Ipv6.class), new Ipv6Customizer(jvpp)),
-                ifcId);
+            registry.addAfter(new GenericWriter<>(ifc1AugId.child(Ipv6.class), new Ipv6Customizer(jvpp)),
+                    ifcId);
             // Ipv4(after interface)
             final InstanceIdentifier<Ipv4> ipv4Id = ifc1AugId.child(Ipv4.class);
-            registry.addWriterAfter(new GenericWriter<>(ipv4Id, new Ipv4Customizer(jvpp, ifcContext)),
-                ifcId);
+            registry.addAfter(new GenericWriter<>(ipv4Id, new Ipv4Customizer(jvpp, ifcContext)),
+                    ifcId);
             //  Address(after Ipv4) =
             final InstanceIdentifier<Address> ipv4AddressId = ipv4Id.child(Address.class);
-            registry.addWriterAfter(new GenericListWriter<>(ipv4AddressId, new Ipv4AddressCustomizer(jvpp, ifcContext)),
-                ipv4Id);
+            registry.addAfter(new GenericListWriter<>(ipv4AddressId, new Ipv4AddressCustomizer(jvpp, ifcContext)),
+                    ipv4Id);
             //  Neighbor(after ipv4Address)
-            registry.addWriterAfter(
-                new GenericListWriter<>(ipv4Id.child(Neighbor.class), new Ipv4NeighbourCustomizer(jvpp, ifcContext)),
-                ipv4AddressId);
+            registry.addAfter(new GenericListWriter<>(ipv4Id.child(Neighbor.class), new Ipv4NeighbourCustomizer(jvpp, ifcContext)),
+                    ipv4AddressId);
         }
 
         private void addVppInterfaceAgmentationWriters(final InstanceIdentifier<Interface> ifcId,
-                                                       final ModifiableWriterRegistry registry) {
+                                                       final ModifiableWriterRegistryBuilder registry) {
             // VhostUser(Needs to be executed before Interface customizer) =
             final InstanceIdentifier<VhostUser> vhostId = VPP_IFC_AUG_ID.child(VhostUser.class);
-            registry.addWriterBefore(new GenericWriter<>(vhostId, new VhostUserCustomizer(jvpp, ifcContext)),
-                ifcId);
+            registry.addBefore(new GenericWriter<>(vhostId, new VhostUserCustomizer(jvpp, ifcContext)),
+                    ifcId);
             // Vxlan(Needs to be executed before Interface customizer) =
             final InstanceIdentifier<Vxlan> vxlanId = VPP_IFC_AUG_ID.child(Vxlan.class);
-            registry.addWriterBefore(new GenericWriter<>(vxlanId, new VxlanCustomizer(jvpp, ifcContext)),
-                ifcId);
+            registry.addBefore(new GenericWriter<>(vxlanId, new VxlanCustomizer(jvpp, ifcContext)),
+                    ifcId);
             // VxlanGpe(Needs to be executed before Interface customizer) =
             final InstanceIdentifier<VxlanGpe> vxlanGpeId = VPP_IFC_AUG_ID.child(VxlanGpe.class);
-            registry.addWriterBefore(new GenericWriter<>(vxlanGpeId, new VxlanGpeCustomizer(jvpp, ifcContext)),
-                ifcId);
+            registry.addBefore(new GenericWriter<>(vxlanGpeId, new VxlanGpeCustomizer(jvpp, ifcContext)),
+                    ifcId);
             // Tap(Needs to be executed before Interface customizer) =
             final InstanceIdentifier<Tap> tapId = VPP_IFC_AUG_ID.child(Tap.class);
-            registry.addWriterBefore(new GenericWriter<>(tapId, new TapCustomizer(jvpp, ifcContext)),
-                ifcId);
+            registry.addBefore(new GenericWriter<>(tapId, new TapCustomizer(jvpp, ifcContext)),
+                    ifcId);
 
             final Set<InstanceIdentifier<?>> specificIfcTypes = Sets.newHashSet(vhostId, vxlanGpeId, vxlanGpeId, tapId);
 
             // Ethernet(No dependency, customizer not finished TODO) =
-            registry.addWriter(new GenericWriter<>(VPP_IFC_AUG_ID.child(Ethernet.class), new EthernetCustomizer(jvpp)));
+            registry.add(new GenericWriter<>(VPP_IFC_AUG_ID.child(Ethernet.class), new EthernetCustomizer(jvpp)));
             // Routing(Execute only after specific interface customizers) =
-            registry.addWriterAfter(
-                new GenericWriter<>(VPP_IFC_AUG_ID.child(Routing.class), new RoutingCustomizer(jvpp, ifcContext)),
-                specificIfcTypes);
+            registry.addAfter(
+                    new GenericWriter<>(VPP_IFC_AUG_ID.child(Routing.class), new RoutingCustomizer(jvpp, ifcContext)),
+                    specificIfcTypes);
             // Routing(Execute only after specific interface customizers) =
-            registry.addWriterAfter(new GenericWriter<>(L2_ID, new L2Customizer(jvpp, ifcContext, bdContext)),
-                specificIfcTypes);
+            registry.addAfter(new GenericWriter<>(L2_ID, new L2Customizer(jvpp, ifcContext, bdContext)),
+                    specificIfcTypes);
 
             // ACL (execute after classify table and session writers)
             // also handles L2Acl, Ip4Acl and Ip6Acl:
             final InstanceIdentifier<Acl> aclId = InstanceIdentifier.create(Acl.class);
             registry
-                .addSubtreeWriterAfter(
+                .subtreeAddAfter(
                     Sets.newHashSet(aclId.child(L2Acl.class), aclId.child(Ip4Acl.class), aclId.child(Ip6Acl.class)),
                     new GenericWriter<>(ACL_ID, new AclCustomizer(jvpp, ifcContext, classifyTableContext)),
-                    Sets.newHashSet(CLASSIFY_TABLE_ID, CLASSIFY_SESSION_ID)
-                );
+                    Sets.newHashSet(CLASSIFY_TABLE_ID, CLASSIFY_SESSION_ID));
         }
 
     }
index 5c89961..83758d8 100644 (file)
@@ -1,19 +1,10 @@
 package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406;
 
-import static io.fd.honeycomb.v3po.translate.util.RWUtils.emptyAugReaderList;
-import static io.fd.honeycomb.v3po.translate.util.RWUtils.emptyChildReaderList;
-import static io.fd.honeycomb.v3po.translate.util.RWUtils.singletonChildReaderList;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import io.fd.honeycomb.v3po.translate.impl.read.CompositeChildReader;
-import io.fd.honeycomb.v3po.translate.impl.read.CompositeListReader;
-import io.fd.honeycomb.v3po.translate.impl.read.CompositeRootReader;
-import io.fd.honeycomb.v3po.translate.read.ChildReader;
-import io.fd.honeycomb.v3po.translate.util.RWUtils;
-import io.fd.honeycomb.v3po.translate.util.read.CloseableReader;
-import io.fd.honeycomb.v3po.translate.util.read.ReflexiveAugmentReaderCustomizer;
-import io.fd.honeycomb.v3po.translate.util.read.ReflexiveRootReaderCustomizer;
+import com.google.common.collect.Sets;
+import io.fd.honeycomb.v3po.translate.impl.read.GenericListReader;
+import io.fd.honeycomb.v3po.translate.impl.read.GenericReader;
+import io.fd.honeycomb.v3po.translate.read.ReaderFactory;
+import io.fd.honeycomb.v3po.translate.read.registry.ModifiableReaderRegistryBuilder;
 import io.fd.honeycomb.v3po.translate.v3po.interfacesstate.AclCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.interfacesstate.EthernetCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceCustomizer;
@@ -26,13 +17,10 @@ import io.fd.honeycomb.v3po.translate.v3po.interfacesstate.ip.Ipv4AddressCustomi
 import io.fd.honeycomb.v3po.translate.v3po.interfacesstate.ip.Ipv4Customizer;
 import io.fd.honeycomb.v3po.translate.v3po.interfacesstate.ip.Ipv4NeighbourCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.interfacesstate.ip.Ipv6Customizer;
-import java.util.ArrayList;
-import java.util.List;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesStateBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface2;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface2Builder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4;
@@ -41,6 +29,9 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev14061
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.Neighbor;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceStateAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceStateAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.acl.base.attributes.Ip4Acl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.acl.base.attributes.Ip6Acl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.acl.base.attributes.L2Acl;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.Acl;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.Ethernet;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.L2;
@@ -48,11 +39,15 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.VhostUser;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.Vxlan;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.VxlanGpe;
-import org.opendaylight.yangtools.yang.binding.Augmentation;
-import org.opendaylight.yangtools.yang.binding.ChildOf;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.future.FutureJVpp;
 
 public class InterfacesStateHoneycombReaderModule extends
         org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406.AbstractInterfacesStateHoneycombReaderModule {
+
+    public static final InstanceIdentifier<InterfacesState> IFC_STATE_ID = InstanceIdentifier.create(InterfacesState.class);
+    static final InstanceIdentifier<Interface> IFC_ID = IFC_STATE_ID.child(Interface.class);
+
     public InterfacesStateHoneycombReaderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
                                                 org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
         super(identifier, dependencyResolver);
@@ -72,94 +67,93 @@ public class InterfacesStateHoneycombReaderModule extends
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-        final List<ChildReader<? extends Augmentation<Interface>>>
-                interfaceAugReaders = new ArrayList<>();
-        interfaceAugReaders.add(getVppInterfaceStateAugmentationReader());
-        interfaceAugReaders.add(getInterface1AugmentationReader());
-        interfaceAugReaders.add(SubinterfaceStateAugmentationReaderFactory.createInstance(getVppJvppDependency(),
-            getInterfaceContextIfcStateDependency(), getBridgeDomainContextIfcStateDependency(),
-            getClassifyTableContextDependency()));
-
-        final CompositeListReader<Interface, InterfaceKey, InterfaceBuilder> interfaceReader =
-                new CompositeListReader<>(Interface.class,
-                        emptyChildReaderList(),
-                        interfaceAugReaders,
-                        new InterfaceCustomizer(getVppJvppDependency(), getInterfaceContextIfcStateDependency()));
-
-        return new CloseableReader<>(new CompositeRootReader<>(
-                InterfacesState.class,
-                singletonChildReaderList(interfaceReader),
-                emptyAugReaderList(),
-                new ReflexiveRootReaderCustomizer<>(InterfacesStateBuilder.class)));
-    }
-
-    private ChildReader<? extends Augmentation<Interface>> getInterface1AugmentationReader() {
-
-        final ChildReader<Neighbor> neighborReader = new CompositeListReader<>(Neighbor.class,
-                new Ipv4NeighbourCustomizer(getVppJvppDependency()));
-
-        final ChildReader<Address> addressReader = new CompositeListReader<>(Address.class,
-                new Ipv4AddressCustomizer(getVppJvppDependency(),getInterfaceContextIfcStateDependency()));
-
-        final ChildReader<? extends ChildOf<Interface2>> ipv4Reader = new CompositeChildReader<>(Ipv4.class,
-                ImmutableList.of(neighborReader,addressReader),
-                new Ipv4Customizer(getVppJvppDependency()));
-        final ChildReader<? extends ChildOf<Interface2>> ipv6Reader = new CompositeChildReader<>(Ipv6.class,
-                new Ipv6Customizer(getVppJvppDependency(), getInterfaceContextIfcStateDependency()));
-
-        final List<ChildReader<? extends ChildOf<Interface2>>> interface1ChildWriters = Lists.newArrayList();
-        interface1ChildWriters.add(ipv4Reader);
-        interface1ChildWriters.add(ipv6Reader);
-
-        return new CompositeChildReader<>(Interface2.class, interface1ChildWriters,
-                new ReflexiveAugmentReaderCustomizer<>(Interface2Builder.class, Interface2.class));
+        return new VppStateReaderFactory(getVppJvppDependency(),
+                getInterfaceContextIfcStateDependency(),
+                getBridgeDomainContextIfcStateDependency(),
+                getClassifyTableContextDependency());
     }
 
-
-    private ChildReader<? extends Augmentation<Interface>> getVppInterfaceStateAugmentationReader() {
-
-        final ChildReader<? extends ChildOf<VppInterfaceStateAugmentation>> ethernetReader =
-                new CompositeChildReader<>(Ethernet.class,
-                        new EthernetCustomizer(getVppJvppDependency(), getInterfaceContextIfcStateDependency()));
-
-        final ChildReader<? extends ChildOf<VppInterfaceStateAugmentation>> tapReader =
-                new CompositeChildReader<>(Tap.class,
-                        new TapCustomizer(getVppJvppDependency(), getInterfaceContextIfcStateDependency()));
-
-        final ChildReader<? extends ChildOf<VppInterfaceStateAugmentation>> vhostUserReader =
-                new CompositeChildReader<>(VhostUser.class,
-                        new VhostUserCustomizer(getVppJvppDependency(), getInterfaceContextIfcStateDependency()));
-
-        final ChildReader<? extends ChildOf<VppInterfaceStateAugmentation>> vxlanReader =
-                new CompositeChildReader<>(Vxlan.class,
-                        new VxlanCustomizer(getVppJvppDependency(), getInterfaceContextIfcStateDependency()));
-
-        final ChildReader<? extends ChildOf<VppInterfaceStateAugmentation>> vxlanGpeReader =
-                new CompositeChildReader<>(VxlanGpe.class,
-                        new VxlanGpeCustomizer(getVppJvppDependency(), getInterfaceContextIfcStateDependency()));
-
-        final ChildReader<? extends ChildOf<VppInterfaceStateAugmentation>> aclReader =
-                new CompositeChildReader<>(Acl.class,
-                        new AclCustomizer(getVppJvppDependency(), getInterfaceContextIfcStateDependency(), getClassifyTableContextDependency()));
-
-        final ChildReader<? extends ChildOf<VppInterfaceStateAugmentation>> l2Reader =
-                new CompositeChildReader<>(L2.class,
-                        new L2Customizer(getVppJvppDependency(), getInterfaceContextIfcStateDependency(), getBridgeDomainContextIfcStateDependency()));
-
-        final List<ChildReader<? extends ChildOf<VppInterfaceStateAugmentation>>> childReaders = Lists.newArrayList();
-        childReaders.add(ethernetReader);
-        childReaders.add(tapReader);
-        childReaders.add(vhostUserReader);
-        childReaders.add(vxlanReader);
-        childReaders.add(vxlanGpeReader);
-        childReaders.add(l2Reader);
-        childReaders.add(aclReader);
-
-        final ChildReader<VppInterfaceStateAugmentation> vppInterfaceStateAugmentationChildReader =
-                new CompositeChildReader<>(VppInterfaceStateAugmentation.class,
-                        childReaders,
-                        new ReflexiveAugmentReaderCustomizer<>(VppInterfaceStateAugmentationBuilder.class,
-                                VppInterfaceStateAugmentation.class));
-        return vppInterfaceStateAugmentationChildReader;
+    private static final class VppStateReaderFactory implements ReaderFactory, AutoCloseable {
+
+        private NamingContext ifcCtx;
+        private NamingContext bdCtx;
+        private NamingContext classifyCtx;
+        private FutureJVpp jvpp;
+
+        VppStateReaderFactory(final FutureJVpp jvpp,
+                              final NamingContext ifcCtx,
+                              final NamingContext bdCtx,
+                              final NamingContext classifyCtx) {
+            this.jvpp = jvpp;
+            this.ifcCtx = ifcCtx;
+            this.bdCtx = bdCtx;
+            this.classifyCtx = classifyCtx;
+        }
+
+        @Override
+        public void init(final ModifiableReaderRegistryBuilder registry) {
+            // InterfacesState(Structural)
+            registry.addStructuralReader(IFC_STATE_ID, InterfacesStateBuilder.class);
+            //  Interface
+            registry.add(new GenericListReader<>(IFC_ID, new InterfaceCustomizer(jvpp, ifcCtx)));
+
+            // v3po.yang
+            initVppIfcAugmentationReaders(registry, IFC_ID);
+            // ietf-ip.yang
+            initInterface2AugmentationReaders(registry, IFC_ID);
+            // vpp-vlan.yang
+            new SubinterfaceStateAugmentationReaderFactory(jvpp, ifcCtx, bdCtx, classifyCtx).init(registry);
+        }
+
+        private void initInterface2AugmentationReaders(final ModifiableReaderRegistryBuilder registry,
+                                                       final InstanceIdentifier<Interface> ifcId) {
+            //   Interface2Augmentation(Structural)
+            final InstanceIdentifier<Interface2> ifc2AugId = ifcId.augmentation(Interface2.class);
+            registry.addStructuralReader(ifc2AugId, Interface2Builder.class);
+            //    Ipv4
+            // TODO unfinished customizer
+            final InstanceIdentifier<Ipv4> ipv4Id = ifc2AugId.child(Ipv4.class);
+            registry.add(new GenericReader<>(ipv4Id, new Ipv4Customizer(jvpp)));
+            //     Address
+            final InstanceIdentifier<Address> ipv4AddrId = ipv4Id.child(Address.class);
+            registry.add(new GenericListReader<>(ipv4AddrId, new Ipv4AddressCustomizer(jvpp, ifcCtx)));
+            //     Neighbor
+            final InstanceIdentifier<Neighbor> neighborId = ipv4Id.child(Neighbor.class);
+            registry.add(new GenericListReader<>(neighborId, new Ipv4NeighbourCustomizer(jvpp)));
+            //    Ipv6
+            // TODO unfinished customizer
+            final InstanceIdentifier<Ipv6> ipv6Id = ifc2AugId.child(Ipv6.class);
+            registry.add(new GenericReader<>(ipv6Id, new Ipv6Customizer(jvpp, ifcCtx)));
+        }
+
+        private void initVppIfcAugmentationReaders(final ModifiableReaderRegistryBuilder registry,
+                                                   final InstanceIdentifier<Interface> ifcId) {
+            //   VppInterfaceStateAugmentation
+            final InstanceIdentifier<VppInterfaceStateAugmentation> vppIfcAugId = ifcId.augmentation(VppInterfaceStateAugmentation.class);
+            registry.addStructuralReader(vppIfcAugId, VppInterfaceStateAugmentationBuilder.class);
+            //    Ethernet
+            registry.add(new GenericReader<>(vppIfcAugId.child(Ethernet.class), new EthernetCustomizer(jvpp, ifcCtx)));
+            //    Tap
+            registry.add(new GenericReader<>(vppIfcAugId.child(Tap.class), new TapCustomizer(jvpp, ifcCtx)));
+            //    VhostUser
+            registry.add(new GenericReader<>(vppIfcAugId.child(VhostUser.class), new VhostUserCustomizer(jvpp, ifcCtx)));
+            //    Vxlan
+            registry.add(new GenericReader<>(vppIfcAugId.child(Vxlan.class), new VxlanCustomizer(jvpp, ifcCtx)));
+            //    VxlanGpe
+            registry.add(new GenericReader<>(vppIfcAugId.child(VxlanGpe.class), new VxlanGpeCustomizer(jvpp, ifcCtx)));
+            //    L2
+            registry.add(new GenericReader<>(vppIfcAugId.child(L2.class), new L2Customizer(jvpp, ifcCtx, bdCtx)));
+            //    Acl(Subtree)
+            final InstanceIdentifier<Acl> aclIdRelative = InstanceIdentifier.create(Acl.class);
+            registry.subtreeAdd(
+                    Sets.newHashSet(aclIdRelative.child(L2Acl.class), aclIdRelative.child(Ip4Acl.class), aclIdRelative.child(Ip6Acl.class)),
+                    new GenericReader<>(vppIfcAugId.child(Acl.class), new AclCustomizer(jvpp, ifcCtx, classifyCtx)));
+
+        }
+
+        @Override
+        public void close() throws Exception {
+            // unregister not supported
+        }
     }
 }
index 8917105..d6fa377 100644 (file)
@@ -15,6 +15,9 @@ Current order of v3po-api writers is:
 . L2
 . Ethernet
 . Routing
+. ClassifySession
+. ClassifyTable
+. Acl
 . Ipv6
 . Ipv4
 . Address
@@ -22,9 +25,46 @@ Current order of v3po-api writers is:
 . L2FibEntry
 . Rewrite
 . Address
+. Acl
 
 To find out current order in runtime, turn on logging for writer registry:
 
   log:set TRACE io.fd.honeycomb.v3po.translate.util.write.registry
 
-== Readers
\ No newline at end of file
+== Readers
+There is not a strict order for readers, but current configuration produces approx. this order:
+
+Contexts
+. VppState
+. Version
+. BridgeDomains
+. BridgeDomain
+. L2FibTable
+. L2FibEntry
+. InterfacesState
+. Interface
+. VppInterfaceStateAugmentation
+. Ethernet
+. Tap
+. VhostUser
+. Vxlan
+. VxlanGpe
+. L2
+. Acl
+. Interface2
+. Ipv4
+. Address
+. Neighbor
+. Ipv6
+. SubinterfaceStateAugmentation
+. SubInterfaces
+. SubInterface
+. L2
+. Rewrite
+. Ipv4
+. Address
+. Acl
+. VppClassifierState
+. ClassifyTable
+. ClassifySession
+. NetconfState
\ No newline at end of file
index 60a9c2e..0340564 100644 (file)
@@ -28,7 +28,7 @@ import io.fd.honeycomb.v3po.translate.v3po.interfaces.SubInterfaceCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.interfaces.SubInterfaceL2Customizer;
 import io.fd.honeycomb.v3po.translate.v3po.interfaces.ip.SubInterfaceIpv4AddressCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
-import io.fd.honeycomb.v3po.translate.write.ModifiableWriterRegistry;
+import io.fd.honeycomb.v3po.translate.write.registry.ModifiableWriterRegistryBuilder;
 import io.fd.honeycomb.v3po.translate.write.WriterFactory;
 import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.dot1q.tag.or.any.Dot1qTag;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.acl.base.attributes.Ip4Acl;
@@ -74,10 +74,10 @@ final class SubinterfaceAugmentationWriterFactory implements WriterFactory {
     }
 
     @Override
-    public void init(final ModifiableWriterRegistry registry) {
+    public void init(final ModifiableWriterRegistryBuilder registry) {
         // Subinterfaces
         //  Subinterface(Handle only after all interface related stuff gets processed) =
-        registry.addSubtreeWriterAfter(
+        registry.subtreeAddAfter(
                 // TODO this customizer covers quite a lot of complex child nodes (maybe refactor ?)
                 Sets.newHashSet(
                         InstanceIdentifier.create(SubInterface.class).child(Tags.class),
@@ -89,11 +89,11 @@ final class SubinterfaceAugmentationWriterFactory implements WriterFactory {
                 new GenericListWriter<>(SUB_IFC_ID, new SubInterfaceCustomizer(jvpp, ifcContext)),
                 InterfacesHoneycombWriterModule.IFC_ID);
         //   L2 =
-        registry.addWriterAfter(new GenericWriter<>(L2_ID, new SubInterfaceL2Customizer(jvpp, ifcContext, bdContext)),
+        registry.addAfter(new GenericWriter<>(L2_ID, new SubInterfaceL2Customizer(jvpp, ifcContext, bdContext)),
                 SUB_IFC_ID);
         //    Rewrite(also handles pushTags + pushTags/dot1qtag) =
         final InstanceIdentifier<Rewrite> rewriteId = L2_ID.child(Rewrite.class);
-        registry.addSubtreeWriterAfter(
+        registry.subtreeAddAfter(
                 Sets.newHashSet(
                         InstanceIdentifier.create(Rewrite.class).child(PushTags.class),
                         InstanceIdentifier.create(Rewrite.class).child(PushTags.class)
@@ -102,7 +102,7 @@ final class SubinterfaceAugmentationWriterFactory implements WriterFactory {
                 L2_ID);
         //   Ipv4(handled after L2 and L2/rewrite is done) =
         final InstanceIdentifier<Address> ipv4SubifcAddressId = SUB_IFC_ID.child(Ipv4.class).child(Address.class);
-        registry.addWriterAfter(new GenericListWriter<>(ipv4SubifcAddressId,
+        registry.addAfter(new GenericListWriter<>(ipv4SubifcAddressId,
                 new SubInterfaceIpv4AddressCustomizer(jvpp, ifcContext)),
                 rewriteId);
 
@@ -110,11 +110,10 @@ final class SubinterfaceAugmentationWriterFactory implements WriterFactory {
         // also handles L2Acl, Ip4Acl and Ip6Acl:
         final InstanceIdentifier<Acl> aclId = InstanceIdentifier.create(Acl.class);
         registry
-            .addSubtreeWriterAfter(
+            .subtreeAddAfter(
                 Sets.newHashSet(aclId.child(L2Acl.class), aclId.child(Ip4Acl.class), aclId.child(Ip6Acl.class)),
                 new GenericWriter<>(SUBIF_ACL_ID, new SubInterfaceAclCustomizer(jvpp, ifcContext, classifyTableContext)),
-                Sets.newHashSet(CLASSIFY_TABLE_ID, CLASSIFY_SESSION_ID)
-            );
+                Sets.newHashSet(CLASSIFY_TABLE_ID, CLASSIFY_SESSION_ID));
 
     }
 }
index 7dfe4d2..42e8c5b 100644 (file)
 
 package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406;
 
-import static io.fd.honeycomb.v3po.translate.util.RWUtils.singletonChildReaderList;
-
-import io.fd.honeycomb.v3po.translate.impl.read.CompositeChildReader;
-import io.fd.honeycomb.v3po.translate.impl.read.CompositeListReader;
-import io.fd.honeycomb.v3po.translate.read.ChildReader;
-import io.fd.honeycomb.v3po.translate.util.RWUtils;
-import io.fd.honeycomb.v3po.translate.util.read.ReflexiveAugmentReaderCustomizer;
-import io.fd.honeycomb.v3po.translate.util.read.ReflexiveChildReaderCustomizer;
+import com.google.common.collect.Sets;
+import io.fd.honeycomb.v3po.translate.impl.read.GenericListReader;
+import io.fd.honeycomb.v3po.translate.impl.read.GenericReader;
+import io.fd.honeycomb.v3po.translate.read.ReaderFactory;
+import io.fd.honeycomb.v3po.translate.read.registry.ModifiableReaderRegistryBuilder;
 import io.fd.honeycomb.v3po.translate.v3po.interfacesstate.RewriteCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.interfacesstate.SubInterfaceAclCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.interfacesstate.SubInterfaceCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.interfacesstate.SubInterfaceL2Customizer;
 import io.fd.honeycomb.v3po.translate.v3po.interfacesstate.ip.SubInterfaceIpv4AddressCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
-import java.util.ArrayList;
-import java.util.List;
-import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.dot1q.tag.or.any.Dot1qTag;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.acl.base.attributes.Ip4Acl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.acl.base.attributes.Ip6Acl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.acl.base.attributes.L2Acl;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.SubinterfaceStateAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.SubinterfaceStateAugmentationBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces.state._interface.SubInterfaces;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces.state._interface.SubInterfacesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces.state._interface.sub.interfaces.SubInterface;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces.state._interface.sub.interfaces.SubInterfaceBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces.state._interface.sub.interfaces.SubInterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.match.attributes.match.type.vlan.tagged.VlanTagged;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.Acl;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.L2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.Tags;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.l2.Rewrite;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.tags.Tag;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.ip4.attributes.Ipv4;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.ip4.attributes.Ipv4Builder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.ip4.attributes.ipv4.Address;
-import org.opendaylight.yangtools.yang.binding.ChildOf;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.tag.rewrite.PushTags;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.openvpp.jvpp.future.FutureJVpp;
 
-final class SubinterfaceStateAugmentationReaderFactory {
-
-    private SubinterfaceStateAugmentationReaderFactory() {
-    }
+final class SubinterfaceStateAugmentationReaderFactory implements ReaderFactory {
 
-    private static ChildReader<L2> getL2Reader(@Nonnull final FutureJVpp futureJvpp,
-                                                 @Nonnull final NamingContext interfaceContext,
-                                                 @Nonnull final NamingContext bridgeDomainContext) {
-        final ChildReader<Rewrite> rewriteReader = new CompositeChildReader<>(
-            Rewrite.class, new RewriteCustomizer(futureJvpp, interfaceContext));
+    private final FutureJVpp jvpp;
+    private final NamingContext ifcCtx;
+    private final NamingContext bdCtx;
+    private final NamingContext classifyCtx;
 
-        return new CompositeChildReader<>(L2.class,
-                singletonChildReaderList(rewriteReader),
-                new SubInterfaceL2Customizer(futureJvpp, interfaceContext, bridgeDomainContext));
+    SubinterfaceStateAugmentationReaderFactory(final FutureJVpp jvpp, final NamingContext ifcCtx,
+                                               final NamingContext bdCtx, final NamingContext classifyCtx) {
+        this.jvpp = jvpp;
+        this.ifcCtx = ifcCtx;
+        this.bdCtx = bdCtx;
+        this.classifyCtx = classifyCtx;
     }
 
-    private static ChildReader<Ipv4> getIpv4Reader(@Nonnull final FutureJVpp futureJvpp,
-                                                   @Nonnull final NamingContext interfaceContext) {
-
-        final ChildReader<Address> addressReader = new CompositeListReader<>(Address.class,
-            new SubInterfaceIpv4AddressCustomizer(futureJvpp, interfaceContext));
-
-        return new CompositeChildReader<>(
-            Ipv4.class,
-            RWUtils.singletonChildReaderList(addressReader),
-            new ReflexiveChildReaderCustomizer<>(Ipv4Builder.class));
-
-    }
-
-    private static ChildReader<Acl> getAclReader(@Nonnull final FutureJVpp futureJvpp,
-                                                 @Nonnull final NamingContext interfaceContext,
-                                                 @Nonnull final NamingContext classifyTableContext) {
-        return new CompositeChildReader<>(Acl.class,
-            new SubInterfaceAclCustomizer(futureJvpp, interfaceContext, classifyTableContext));
-
-    }
-
-    static ChildReader<SubinterfaceStateAugmentation> createInstance(
-        @Nonnull final FutureJVpp futureJvpp, @Nonnull final NamingContext interfaceContext,
-        @Nonnull final NamingContext bridgeDomainContext,
-        @Nonnull final NamingContext classifyTableContext) {
-
-        List<ChildReader<? extends ChildOf<SubInterface>>> childReaders = new ArrayList<>();
-
-        // TODO can get rid of that cast?
-        childReaders.add((ChildReader) getL2Reader(futureJvpp, interfaceContext, bridgeDomainContext));
-        childReaders.add((ChildReader) getIpv4Reader(futureJvpp, interfaceContext));
-        childReaders.add((ChildReader) getAclReader(futureJvpp, interfaceContext, classifyTableContext));
-
-        final CompositeListReader<SubInterface, SubInterfaceKey, SubInterfaceBuilder> subInterfaceReader =
-            new CompositeListReader<>(SubInterface.class, childReaders, new SubInterfaceCustomizer(futureJvpp,
-                interfaceContext));
-
-        final ChildReader<SubInterfaces> subInterfacesReader = new CompositeChildReader<>(
-            SubInterfaces.class,
-            RWUtils.singletonChildReaderList(subInterfaceReader),
-            new ReflexiveChildReaderCustomizer<>(SubInterfacesBuilder.class));
-
-        final ChildReader<SubinterfaceStateAugmentation> subinterfaceStateAugmentationReader =
-            new CompositeChildReader<>(SubinterfaceStateAugmentation.class,
-                singletonChildReaderList(subInterfacesReader),
-                new ReflexiveAugmentReaderCustomizer<>(
-                    SubinterfaceStateAugmentationBuilder.class,
-                    SubinterfaceStateAugmentation.class));
-
-        return subinterfaceStateAugmentationReader;
+    @Override
+    public void init(final ModifiableReaderRegistryBuilder registry) {
+        // SubinterfaceStateAugmentation(Structural)
+        final InstanceIdentifier<SubinterfaceStateAugmentation> subIfcAugId =
+                InterfacesStateHoneycombReaderModule.IFC_ID.augmentation(SubinterfaceStateAugmentation.class);
+        registry.addStructuralReader(subIfcAugId, SubinterfaceStateAugmentationBuilder.class);
+        //  SubInterfaces(Structural)
+        final InstanceIdentifier<SubInterfaces> subIfcsId = subIfcAugId.child(SubInterfaces.class);
+        registry.addStructuralReader(subIfcsId, SubInterfacesBuilder.class);
+        //   SubInterface(Subtree)
+        final InstanceIdentifier<SubInterface> subIfcId = subIfcsId.child(SubInterface.class);
+        registry.subtreeAdd(Sets.newHashSet(
+                InstanceIdentifier.create(SubInterface.class).child(Tags.class),
+                InstanceIdentifier.create(SubInterface.class).child(Tags.class).child(Tag.class),
+                InstanceIdentifier.create(SubInterface.class).child(Tags.class).child(Tag.class).child(Dot1qTag.class),
+                InstanceIdentifier.create(SubInterface.class).child(Match.class),
+                InstanceIdentifier.create(SubInterface.class).child(Match.class).child(VlanTagged.class)),
+                new GenericListReader<>(subIfcId, new SubInterfaceCustomizer(jvpp, ifcCtx)));
+        //    L2
+        final InstanceIdentifier<L2> l2Id = subIfcId.child(L2.class);
+        registry.add(new GenericReader<>(l2Id, new SubInterfaceL2Customizer(jvpp, ifcCtx, bdCtx)));
+        //     Rewrite(Subtree)
+        registry.subtreeAdd(Sets.newHashSet(
+                InstanceIdentifier.create(Rewrite.class).child(PushTags.class),
+                InstanceIdentifier.create(Rewrite.class).child(PushTags.class)
+                        .child(org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.dot1q.tag.Dot1qTag.class)),
+                new GenericReader<>(l2Id.child(Rewrite.class), new RewriteCustomizer(jvpp, ifcCtx)));
+        //    Ipv4(Structural)
+        final InstanceIdentifier<Ipv4> ipv4Id = subIfcId.child(Ipv4.class);
+        registry.addStructuralReader(ipv4Id, Ipv4Builder.class);
+        //     Address
+        registry.add(new GenericListReader<>(ipv4Id.child(Address.class), new SubInterfaceIpv4AddressCustomizer(jvpp, ifcCtx)));
+        //    Acl(Subtree)
+        final InstanceIdentifier<Acl> aclIdRelative = InstanceIdentifier.create(Acl.class);
+        registry.subtreeAdd(
+                Sets.newHashSet(aclIdRelative.child(L2Acl.class), aclIdRelative.child(Ip4Acl.class), aclIdRelative.child(Ip6Acl.class)),
+                new GenericReader<>(subIfcId.child(Acl.class), new SubInterfaceAclCustomizer(jvpp, ifcCtx, classifyCtx)));
     }
 }
index b2fb545..ca05b39 100644 (file)
@@ -6,8 +6,8 @@ import io.fd.honeycomb.v3po.translate.impl.write.GenericListWriter;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.v3po.vppclassifier.ClassifySessionWriter;
 import io.fd.honeycomb.v3po.translate.v3po.vppclassifier.ClassifyTableWriter;
-import io.fd.honeycomb.v3po.translate.write.ModifiableWriterRegistry;
 import io.fd.honeycomb.v3po.translate.write.WriterFactory;
+import io.fd.honeycomb.v3po.translate.write.registry.ModifiableWriterRegistryBuilder;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.VppClassifier;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.classify.table.base.attributes.ClassifySession;
@@ -66,13 +66,13 @@ public class VppClassifierHoneycombWriterModule extends
         }
 
         @Override
-        public void init(final ModifiableWriterRegistry registry) {
+        public void init(final ModifiableWriterRegistryBuilder registry) {
 
-            registry.addWriterBefore(
+            registry.addBefore(
                 new GenericListWriter<>(CLASSIFY_TABLE_ID, new ClassifyTableWriter(jvpp, classifyTableContext)),
                 ACL_ID);
 
-            registry.addWriterAfter(
+            registry.addBefore(
                 new GenericListWriter<>(CLASSIFY_SESSION_ID, new ClassifySessionWriter(jvpp, classifyTableContext)),
                 CLASSIFY_TABLE_ID);
         }
index bea7e0d..4a91f26 100644 (file)
@@ -1,23 +1,17 @@
 package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406;
 
-import io.fd.honeycomb.v3po.translate.impl.read.CompositeListReader;
-import io.fd.honeycomb.v3po.translate.impl.read.CompositeRootReader;
-import io.fd.honeycomb.v3po.translate.read.ChildReader;
-import io.fd.honeycomb.v3po.translate.util.read.CloseableReader;
-import io.fd.honeycomb.v3po.translate.util.read.ReflexiveRootReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.impl.read.GenericListReader;
+import io.fd.honeycomb.v3po.translate.read.ReaderFactory;
+import io.fd.honeycomb.v3po.translate.read.registry.ModifiableReaderRegistryBuilder;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.v3po.vppclassifier.ClassifySessionReader;
 import io.fd.honeycomb.v3po.translate.v3po.vppclassifier.ClassifyTableReader;
-import java.util.ArrayList;
-import java.util.List;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.VppClassifierState;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.VppClassifierStateBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.classify.table.base.attributes.ClassifySession;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.classify.table.base.attributes.ClassifySessionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.classify.table.base.attributes.ClassifySessionKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.vpp.classifier.state.ClassifyTable;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.vpp.classifier.state.ClassifyTableBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.classifier.rev150603.vpp.classifier.state.ClassifyTableKey;
-import org.opendaylight.yangtools.yang.binding.ChildOf;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.future.FutureJVpp;
 
 public class VppClassifierStateHoneycombReaderModule extends org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406.AbstractVppClassifierStateHoneycombReaderModule {
     public VppClassifierStateHoneycombReaderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
@@ -35,24 +29,36 @@ public class VppClassifierStateHoneycombReaderModule extends org.opendaylight.ya
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-        final CompositeListReader<ClassifySession, ClassifySessionKey, ClassifySessionBuilder> classifySessionReader =
-            new CompositeListReader<>(ClassifySession.class,
-                new ClassifySessionReader(getVppJvppDependency(), getClassifyTableContextDependency()));
-
-        final List<ChildReader<? extends ChildOf<ClassifyTable>>> classifyTableChildReaders = new ArrayList<>();
-        classifyTableChildReaders.add((ChildReader)classifySessionReader);
-        final CompositeListReader<ClassifyTable, ClassifyTableKey, ClassifyTableBuilder> classifyTableReader =
-            new CompositeListReader<>(
-                ClassifyTable.class,
-                classifyTableChildReaders,
-                new ClassifyTableReader(getVppJvppDependency(), getClassifyTableContextDependency()));
-
-        final List<ChildReader<? extends ChildOf<VppClassifierState>>> vppClassifierStateChildReaders = new ArrayList<>();
-        vppClassifierStateChildReaders.add(classifyTableReader);
-        return new CloseableReader<>(new CompositeRootReader<>(
-            VppClassifierState.class,
-            vppClassifierStateChildReaders,
-            new ReflexiveRootReaderCustomizer<>(VppClassifierStateBuilder.class)));
+        return new VppClassifierReaderFactory(getVppJvppDependency(), getClassifyTableContextDependency());
     }
 
+    private static final class VppClassifierReaderFactory implements ReaderFactory, AutoCloseable {
+
+        private final FutureJVpp jvpp;
+        private final NamingContext classifyCtx;
+
+        VppClassifierReaderFactory(final FutureJVpp jvpp,
+                                          final NamingContext classifyCtx) {
+            this.jvpp = jvpp;
+            this.classifyCtx = classifyCtx;
+        }
+
+        @Override
+        public void init(final ModifiableReaderRegistryBuilder registry) {
+            // VppClassifierState
+            final InstanceIdentifier<VppClassifierState> vppStateId = InstanceIdentifier.create(VppClassifierState.class);
+            registry.addStructuralReader(vppStateId, VppClassifierStateBuilder.class);
+            //  ClassifyTable
+            final InstanceIdentifier<ClassifyTable> classTblId = vppStateId.child(ClassifyTable.class);
+            registry.add(new GenericListReader<>(classTblId, new ClassifyTableReader(jvpp, classifyCtx)));
+            //   ClassifySession
+            final InstanceIdentifier<ClassifySession> classSesId = classTblId.child(ClassifySession.class);
+            registry.add(new GenericListReader<>(classSesId, new ClassifySessionReader(jvpp, classifyCtx)));
+        }
+
+        @Override
+        public void close() throws Exception {
+            // Noop, no unregister provided
+        }
+    }
 }
index 922b6f9..ba42cfb 100644 (file)
@@ -5,7 +5,7 @@ import io.fd.honeycomb.v3po.translate.impl.write.GenericListWriter;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.v3po.vpp.BridgeDomainCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.vpp.L2FibEntryCustomizer;
-import io.fd.honeycomb.v3po.translate.write.ModifiableWriterRegistry;
+import io.fd.honeycomb.v3po.translate.write.registry.ModifiableWriterRegistryBuilder;
 import io.fd.honeycomb.v3po.translate.write.WriterFactory;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.Vpp;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.fib.attributes.L2FibTable;
@@ -62,17 +62,17 @@ public class VppHoneycombWriterModule extends
         }
 
         @Override
-        public void init(final ModifiableWriterRegistry registry) {
+        public void init(final ModifiableWriterRegistryBuilder registry) {
             // Vpp has no handlers
             //  BridgeDomains has no handlers
             //   BridgeDomain =
             final InstanceIdentifier<BridgeDomain> bdId =
                     InstanceIdentifier.create(Vpp.class).child(BridgeDomains.class).child(BridgeDomain.class);
-            registry.addWriter(new GenericListWriter<>(bdId, new BridgeDomainCustomizer(jvpp, bdContext)));
+            registry.add(new GenericListWriter<>(bdId, new BridgeDomainCustomizer(jvpp, bdContext)));
             //    L2FibTable has no handlers
             //     L2FibEntry(handled after BridgeDomain and L2 of ifc and subifc) =
             final InstanceIdentifier<L2FibEntry> l2FibEntryId = bdId.child(L2FibTable.class).child(L2FibEntry.class);
-            registry.addWriterAfter(
+            registry.addAfter(
                     new GenericListWriter<>(l2FibEntryId, new L2FibEntryCustomizer(jvpp, bdContext, ifcContext)),
                     Sets.newHashSet(
                             bdId,
index abbde23..4634a5b 100644 (file)
@@ -1,26 +1,22 @@
 package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406;
 
-import io.fd.honeycomb.v3po.translate.impl.read.CompositeChildReader;
-import io.fd.honeycomb.v3po.translate.impl.read.CompositeListReader;
-import io.fd.honeycomb.v3po.translate.impl.read.CompositeRootReader;
-import io.fd.honeycomb.v3po.translate.read.ChildReader;
-import io.fd.honeycomb.v3po.translate.util.KeepaliveReaderWrapper;
-import io.fd.honeycomb.v3po.translate.util.RWUtils;
-import io.fd.honeycomb.v3po.translate.util.read.CloseableReader;
-import io.fd.honeycomb.v3po.translate.util.read.ReflexiveChildReaderCustomizer;
-import io.fd.honeycomb.v3po.translate.util.read.ReflexiveRootReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.impl.read.GenericListReader;
+import io.fd.honeycomb.v3po.translate.impl.read.GenericReader;
+import io.fd.honeycomb.v3po.translate.read.ReaderFactory;
+import io.fd.honeycomb.v3po.translate.read.registry.ModifiableReaderRegistryBuilder;
+import io.fd.honeycomb.v3po.translate.util.read.KeepaliveReaderWrapper;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.v3po.util.ReadTimeoutException;
 import io.fd.honeycomb.v3po.translate.v3po.vppstate.BridgeDomainCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.vppstate.L2FibEntryCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.vppstate.VersionCustomizer;
 import java.lang.management.ManagementFactory;
-import java.util.ArrayList;
-import java.util.List;
 import javax.management.Attribute;
 import javax.management.InstanceNotFoundException;
 import javax.management.ObjectName;
 import org.opendaylight.controller.config.api.ConflictingVersionException;
 import org.opendaylight.controller.config.api.ValidationException;
+import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
 import org.opendaylight.controller.config.util.ConfigRegistryJMXClient;
 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
 import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.jvpp.cfg.rev160406.VppJvppImplModule;
@@ -30,15 +26,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.fib.attributes.L2FibTable;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.fib.attributes.L2FibTableBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.fib.attributes.l2.fib.table.L2FibEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.fib.attributes.l2.fib.table.L2FibEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.fib.attributes.l2.fib.table.L2FibEntryKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.BridgeDomains;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.BridgeDomainsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.Version;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomain;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainKey;
-import org.opendaylight.yangtools.yang.binding.ChildOf;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.openvpp.jvpp.future.FutureJVpp;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -67,55 +59,19 @@ public class VppStateHoneycombReaderModule extends
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-        final FutureJVpp vppApi = getVppJvppDependency();
-
-        ChildReader<Version> versionReader = new CompositeChildReader<>(Version.class, new VersionCustomizer(vppApi));
-        // Wrap with keepalive reader to detect connection issues
-        // TODO keepalive reader wrapper relies on VersionReaderCustomizer (to perform timeout on reads)
-        // Once readers+customizers are asynchronous, pull the timeout to keepalive executor so that keepalive wrapper
-        // is truly generic
-        versionReader = new KeepaliveReaderWrapper<>(versionReader, getKeepaliveExecutorDependency().getExecutor(),
-            ReadTimeoutException.class, 30, () -> reinitializeJVpp(reinitializationCounter));
-
-        final CompositeListReader<L2FibEntry, L2FibEntryKey, L2FibEntryBuilder> l2FibEntryReader =
-            new CompositeListReader<>(L2FibEntry.class,
-                new L2FibEntryCustomizer(vppApi,
-                    getBridgeDomainContextVppStateDependency(), getInterfaceContextVppStateDependency()));
-
-        final ChildReader<L2FibTable> l2FibTableReader = new CompositeChildReader<>(
-            L2FibTable.class,
-            RWUtils.singletonChildReaderList(l2FibEntryReader),
-            new ReflexiveChildReaderCustomizer<>(L2FibTableBuilder.class));
-
-        final CompositeListReader<BridgeDomain, BridgeDomainKey, BridgeDomainBuilder> bridgeDomainReader =
-            new CompositeListReader<>(BridgeDomain.class,
-                RWUtils.singletonChildReaderList((ChildReader) l2FibTableReader),
-                new BridgeDomainCustomizer(vppApi,
-                    getBridgeDomainContextVppStateDependency()));
-
-        final ChildReader<BridgeDomains> bridgeDomainsReader = new CompositeChildReader<>(
-            BridgeDomains.class,
-            RWUtils.singletonChildReaderList(bridgeDomainReader),
-            new ReflexiveChildReaderCustomizer<>(BridgeDomainsBuilder.class));
-
-        final List<ChildReader<? extends ChildOf<VppState>>> childVppReaders = new ArrayList<>();
-        childVppReaders.add(versionReader);
-        childVppReaders.add(bridgeDomainsReader);
-
-        return new CloseableReader<>(new CompositeRootReader<>(
-            VppState.class,
-            childVppReaders,
-            RWUtils.emptyAugReaderList(),
-            new ReflexiveRootReaderCustomizer<>(VppStateBuilder.class)));
+        return new VppStateHoneycombReaderFactory(getVppJvppDependency(),
+                getInterfaceContextVppStateDependency(),
+                getBridgeDomainContextVppStateDependency(),
+                getKeepaliveExecutorDependency());
     }
 
     private static long reinitializationCounter;
     private static final long reinitializationLimit = 10;
 
     /**
-     * In case we detect connection issues with VPP, reinitialize JVpp
+     * In case we detect connection issues with VPP, reinitialize JVpp.
      */
-    private void reinitializeJVpp(final long currentAttempt) {
+    private static void reinitializeJVpp(final long currentAttempt) {
         // FIXME https://jira.fd.io/browse/HONEYCOMB-78 This code correctly re-initializes all the components
         // starting with jvpp, but jvpp reconnect fails. Test in a JVpp test and then from C
         LOG.info("Reinitializing JVpp, attempt: {}", currentAttempt);
@@ -150,8 +106,7 @@ public class VppStateHoneycombReaderModule extends
             LOG.info("JVpp reinitialized successfully");
         } catch (InstanceNotFoundException | ValidationException e) {
             LOG.error("Unable to reinitialize JVpp. Honeycomb will not work properly from now on.", e);
-            throw new IllegalStateException("Unable to find jvpp instance in config subsystem. " +
-                "Unable to reinitialize JVpp", e);
+            throw new IllegalStateException("Unable to find jvpp instance in config subsystem. Unable to reinitialize JVpp", e);
         } catch (ConflictingVersionException e) {
             LOG.debug("Conflict changes occurred, retrying", e);
             // Just retry until there's no conflicting change in progress
@@ -160,4 +115,56 @@ public class VppStateHoneycombReaderModule extends
 
         reinitializationCounter = nextAttempt;
     }
+
+
+    private static final class VppStateHoneycombReaderFactory implements ReaderFactory, AutoCloseable {
+
+        private final FutureJVpp jVpp;
+        private final NamingContext ifcCtx;
+        private final NamingContext bdCtx;
+        private final ScheduledThreadPool keepaliveExecutor;
+
+        public VppStateHoneycombReaderFactory(final FutureJVpp jVpp,
+                                              final NamingContext ifcCtx,
+                                              final NamingContext bdCtx,
+                                              final ScheduledThreadPool keepaliveExecutorDependency) {
+            this.jVpp = jVpp;
+            this.ifcCtx = ifcCtx;
+            this.bdCtx = bdCtx;
+            this.keepaliveExecutor = keepaliveExecutorDependency;
+        }
+
+        @Override
+        public void close() throws Exception {
+            // TODO unregister not available
+        }
+
+        @Override
+        public void init(final ModifiableReaderRegistryBuilder registry) {
+            // VppState(Structural)
+            final InstanceIdentifier<VppState> vppStateId = InstanceIdentifier.create(VppState.class);
+            registry.addStructuralReader(vppStateId, VppStateBuilder.class);
+            //  Version
+            // Wrap with keepalive reader to detect connection issues
+            // TODO keepalive reader wrapper relies on VersionReaderCustomizer (to perform timeout on reads)
+            // Once readers+customizers are asynchronous, pull the timeout to keepalive executor so that keepalive wrapper
+            // is truly generic
+            registry.add(new KeepaliveReaderWrapper<>(
+                    new GenericReader<>(vppStateId.child(Version.class), new VersionCustomizer(jVpp)),
+                    keepaliveExecutor.getExecutor(), ReadTimeoutException.class, 30,
+                    () -> reinitializeJVpp(reinitializationCounter)));
+            //  BridgeDomains(Structural)
+            final InstanceIdentifier<BridgeDomains> bridgeDomainsId = vppStateId.child(BridgeDomains.class);
+            registry.addStructuralReader(bridgeDomainsId, BridgeDomainsBuilder.class);
+            //   BridgeDomain
+            final InstanceIdentifier<BridgeDomain> bridgeDomainId = bridgeDomainsId.child(BridgeDomain.class);
+            registry.add(new GenericListReader<>(bridgeDomainId, new BridgeDomainCustomizer(jVpp, bdCtx)));
+            //    L2FibTable(Structural)
+            final InstanceIdentifier<L2FibTable> l2FibTableId = bridgeDomainId.child(L2FibTable.class);
+            registry.addStructuralReader(l2FibTableId, L2FibTableBuilder.class);
+            //     L2FibEntry
+            registry.add(new GenericListReader<>(l2FibTableId.child(L2FibEntry.class),
+                    new L2FibEntryCustomizer(jVpp, bdCtx, ifcCtx)));
+        }
+    }
 }
index 406dd56..6bc253e 100644 (file)
@@ -22,7 +22,7 @@ module v3po2vpp {
 
     identity vpp-state-honeycomb-reader {
         base config:module-type;
-        config:provided-service tapi:honeycomb-reader;
+        config:provided-service tapi:honeycomb-reader-factory;
     }
 
     augment "/config:modules/config:module/config:configuration" {
@@ -109,7 +109,7 @@ module v3po2vpp {
 
     identity interfaces-state-honeycomb-reader {
         base config:module-type;
-        config:provided-service tapi:honeycomb-reader;
+        config:provided-service tapi:honeycomb-reader-factory;
     }
 
     augment "/config:modules/config:module/config:configuration" {
@@ -157,7 +157,7 @@ module v3po2vpp {
 
     identity vpp-classifier-state-honeycomb-reader {
         base config:module-type;
-        config:provided-service tapi:honeycomb-reader;
+        config:provided-service tapi:honeycomb-reader-factory;
     }
 
     augment "/config:modules/config:module/config:configuration" {
index cea7a2a..21deb91 100644 (file)
@@ -26,14 +26,11 @@ import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.verify;
 import static org.mockito.MockitoAnnotations.initMocks;
 
-import com.google.common.base.Optional;
 import io.fd.honeycomb.v3po.translate.MappingContext;
 import io.fd.honeycomb.v3po.translate.v3po.test.TestHelperUtils;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
-import java.util.Arrays;
-import java.util.List;
 import java.util.concurrent.CompletableFuture;
 import org.junit.Before;
 import org.junit.Test;
@@ -46,7 +43,6 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface1;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4Builder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Address;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.AddressBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.Netmask;
@@ -218,20 +214,6 @@ public class Ipv4AddressCustomizerTest {
         fail("WriteFailedException was expec16ted");
     }
 
-    @Test
-    public void testExtract() {
-        final InstanceIdentifier<Address> id = getAddressId(IFACE_NAME);
-
-        Address address = new AddressBuilder().build();
-        Ipv4 parentData = new Ipv4Builder().setAddress(Arrays.asList(address)).build();
-
-        Optional<List<Address>> addressesOptional = customizer.extract(id, parentData);
-
-        assertEquals(true, addressesOptional.isPresent());
-        assertEquals(1, addressesOptional.get().size());
-        assertEquals(true, addressesOptional.get().contains(address));
-    }
-
     private void testSingleNetmask(final int expectedPrefixLength, final String stringMask) throws Exception {
         final InstanceIdentifier<Address> id = getAddressId(IFACE_NAME);
 
index 5811907..7026ee2 100644 (file)
@@ -17,7 +17,6 @@
 package io.fd.honeycomb.v3po.translate.v3po.interfaces.ip;
 
 import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -29,8 +28,6 @@ import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
 import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
-import java.util.Collections;
-import java.util.List;
 import java.util.concurrent.CompletableFuture;
 import org.junit.Before;
 import org.junit.Test;
@@ -46,7 +43,6 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface1;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4Builder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Neighbor;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.NeighborBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
@@ -148,15 +144,4 @@ public class Ipv4NeighbourCustomizerTest {
         assertEquals(5, request.swIfIndex);
     }
 
-    @Test
-    public void testExtract() {
-        Neighbor data = new NeighborBuilder().build();
-        Ipv4 parentData = new Ipv4Builder().setNeighbor(Collections.singletonList(data)).build();
-
-        Optional<List<Neighbor>> optionalData = new Ipv4NeighbourCustomizer(mock(FutureJVpp.class), null).extract(null,
-                parentData);
-        assertEquals(true, optionalData.isPresent());
-        assertEquals(true, optionalData.get().contains(data));
-    }
-
 }
\ No newline at end of file
index 4e9e5de..09c0e88 100644 (file)
@@ -25,8 +25,8 @@ import static org.mockito.Mockito.verify;
 
 import com.google.common.base.Optional;
 import com.google.common.collect.Lists;
-import io.fd.honeycomb.v3po.translate.spi.read.RootReaderCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.test.ChildReaderCustomizerTest;
+import io.fd.honeycomb.v3po.translate.spi.read.ReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.test.ReaderCustomizerTest;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import java.util.List;
 import java.util.concurrent.CompletableFuture;
@@ -48,7 +48,7 @@ import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
 import org.openvpp.jvpp.dto.ClassifyTableByInterface;
 import org.openvpp.jvpp.dto.ClassifyTableByInterfaceReply;
 
-public class AclCustomizerTest extends ChildReaderCustomizerTest<Acl, AclBuilder> {
+public class AclCustomizerTest extends ReaderCustomizerTest<Acl, AclBuilder> {
 
     private static final String IF_NAME = "local0";
     private static final int IF_INDEX = 1;
@@ -90,7 +90,7 @@ public class AclCustomizerTest extends ChildReaderCustomizerTest<Acl, AclBuilder
     }
 
     @Override
-    protected RootReaderCustomizer<Acl, AclBuilder> initCustomizer() {
+    protected ReaderCustomizer<Acl, AclBuilder> initCustomizer() {
         return new AclCustomizer(api, interfaceContext, classifyTableContext);
     }
 
index dc2d3b6..61df50e 100644 (file)
@@ -31,7 +31,7 @@ import static org.mockito.Mockito.verifyZeroInteractions;
 
 import com.google.common.base.Optional;
 import com.google.common.collect.Lists;
-import io.fd.honeycomb.v3po.translate.spi.read.RootReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.read.ReaderCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.test.ListReaderCustomizerTest;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import java.util.Arrays;
@@ -69,7 +69,7 @@ public class InterfaceCustomizerTest extends
     }
 
     @Override
-    protected RootReaderCustomizer<Interface, InterfaceBuilder> initCustomizer() {
+    protected ReaderCustomizer<Interface, InterfaceBuilder> initCustomizer() {
         final KeyedInstanceIdentifier<Mapping, MappingKey> eth0Id = getMappingIid("eth0", "test-instance");
         final KeyedInstanceIdentifier<Mapping, MappingKey> eth1Id = getMappingIid("eth1", "test-instance");
         final KeyedInstanceIdentifier<Mapping, MappingKey> subEth1Id = getMappingIid("eth1.1", "test-instance");
index b6309d8..c075838 100644 (file)
@@ -26,8 +26,8 @@ import static org.mockito.Mockito.when;
 
 import com.google.common.base.Optional;
 import com.google.common.collect.Lists;
-import io.fd.honeycomb.v3po.translate.spi.read.RootReaderCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.test.ChildReaderCustomizerTest;
+import io.fd.honeycomb.v3po.translate.spi.read.ReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.test.ReaderCustomizerTest;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import java.util.Collections;
 import java.util.HashMap;
@@ -58,7 +58,7 @@ import org.openvpp.jvpp.dto.BridgeDomainDump;
 import org.openvpp.jvpp.dto.BridgeDomainSwIfDetails;
 import org.openvpp.jvpp.dto.SwInterfaceDetails;
 
-public class L2CustomizerTest extends ChildReaderCustomizerTest<L2, L2Builder> {
+public class L2CustomizerTest extends ReaderCustomizerTest<L2, L2Builder> {
 
     private NamingContext interfaceContext;
     private NamingContext bridgeDomainContext;
@@ -74,7 +74,7 @@ public class L2CustomizerTest extends ChildReaderCustomizerTest<L2, L2Builder> {
     }
 
     @Override
-    protected RootReaderCustomizer<L2, L2Builder> initCustomizer() {
+    protected ReaderCustomizer<L2, L2Builder> initCustomizer() {
         return new L2Customizer(api, interfaceContext, bridgeDomainContext);
     }
 
index f7f7bb3..3255826 100644 (file)
@@ -25,8 +25,8 @@ import static org.mockito.Mockito.verify;
 
 import com.google.common.base.Optional;
 import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.spi.read.RootReaderCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.test.ChildReaderCustomizerTest;
+import io.fd.honeycomb.v3po.translate.spi.read.ReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.test.ReaderCustomizerTest;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.v3po.util.TagRewriteOperation;
 import java.util.HashMap;
@@ -52,7 +52,7 @@ import org.opendaylight.yangtools.yang.binding.ChildOf;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.openvpp.jvpp.dto.SwInterfaceDetails;
 
-public class RewriteCustomizerTest extends ChildReaderCustomizerTest<Rewrite, RewriteBuilder> {
+public class RewriteCustomizerTest extends ReaderCustomizerTest<Rewrite, RewriteBuilder> {
 
     public static final String VLAN_IF_NAME = "local0.1";
     public static final int VLAN_IF_ID = 1;
@@ -76,7 +76,7 @@ public class RewriteCustomizerTest extends ChildReaderCustomizerTest<Rewrite, Re
     }
 
     @Override
-    protected RootReaderCustomizer<Rewrite, RewriteBuilder> initCustomizer() {
+    protected ReaderCustomizer<Rewrite, RewriteBuilder> initCustomizer() {
         return new RewriteCustomizer(api, interfacesContext);
     }
 
index effe0db..6419959 100644 (file)
@@ -27,7 +27,7 @@ import static org.mockito.Mockito.verify;
 
 import com.google.common.base.Optional;
 import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.spi.read.RootReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.read.ReaderCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.test.ListReaderCustomizerTest;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import java.util.Collections;
@@ -72,7 +72,7 @@ public class SubInterfaceCustomizerTest extends ListReaderCustomizerTest<SubInte
     }
 
     @Override
-    protected RootReaderCustomizer<SubInterface, SubInterfaceBuilder> initCustomizer() {
+    protected ReaderCustomizer<SubInterface, SubInterfaceBuilder> initCustomizer() {
         return new SubInterfaceCustomizer(api, interfacesContext);
     }
 
index 64c14eb..14830fe 100644 (file)
@@ -27,8 +27,8 @@ import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyZeroInteractions;
 
 import com.google.common.collect.Lists;
-import io.fd.honeycomb.v3po.translate.spi.read.RootReaderCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.test.ChildReaderCustomizerTest;
+import io.fd.honeycomb.v3po.translate.spi.read.ReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.test.ReaderCustomizerTest;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
@@ -49,7 +49,7 @@ import org.openvpp.jvpp.dto.VxlanTunnelDetails;
 import org.openvpp.jvpp.dto.VxlanTunnelDetailsReplyDump;
 import org.openvpp.jvpp.dto.VxlanTunnelDump;
 
-public class VxlanCustomizerTest extends ChildReaderCustomizerTest<Vxlan, VxlanBuilder> {
+public class VxlanCustomizerTest extends ReaderCustomizerTest<Vxlan, VxlanBuilder> {
 
     private NamingContext interfacesContext;
     static final InstanceIdentifier<Vxlan> IID =
@@ -134,7 +134,7 @@ public class VxlanCustomizerTest extends ChildReaderCustomizerTest<Vxlan, VxlanB
     }
 
     @Override
-    protected RootReaderCustomizer<Vxlan, VxlanBuilder> initCustomizer() {
+    protected ReaderCustomizer<Vxlan, VxlanBuilder> initCustomizer() {
         return new VxlanCustomizer(api, interfacesContext);
     }
 }
\ No newline at end of file
index 863951f..323bc7e 100644 (file)
@@ -27,8 +27,8 @@ import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyZeroInteractions;
 
 import com.google.common.collect.Lists;
-import io.fd.honeycomb.v3po.translate.spi.read.RootReaderCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.test.ChildReaderCustomizerTest;
+import io.fd.honeycomb.v3po.translate.spi.read.ReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.test.ReaderCustomizerTest;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
@@ -49,7 +49,7 @@ import org.openvpp.jvpp.dto.VxlanGpeTunnelDetails;
 import org.openvpp.jvpp.dto.VxlanGpeTunnelDetailsReplyDump;
 import org.openvpp.jvpp.dto.VxlanGpeTunnelDump;
 
-public class VxlanGpeCustomizerTest extends ChildReaderCustomizerTest<VxlanGpe, VxlanGpeBuilder> {
+public class VxlanGpeCustomizerTest extends ReaderCustomizerTest<VxlanGpe, VxlanGpeBuilder> {
 
     private NamingContext interfacesContext;
     static final InstanceIdentifier<VxlanGpe> VXLAN_GPE_ID =
@@ -137,7 +137,7 @@ public class VxlanGpeCustomizerTest extends ChildReaderCustomizerTest<VxlanGpe,
     }
 
     @Override
-    protected RootReaderCustomizer<VxlanGpe, VxlanGpeBuilder> initCustomizer() {
+    protected ReaderCustomizer<VxlanGpe, VxlanGpeBuilder> initCustomizer() {
         return new VxlanGpeCustomizer(api, interfacesContext);
     }
 }
index be67771..7d701e4 100644 (file)
@@ -32,7 +32,7 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
 import io.fd.honeycomb.v3po.translate.ModificationCache;
 import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.spi.read.RootReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.read.ReaderCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.test.ListReaderCustomizerTest;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
@@ -83,7 +83,7 @@ public class Ipv4AddressCustomizerTest extends ListReaderCustomizerTest<Address,
     }
 
     @Override
-    protected RootReaderCustomizer<Address, AddressBuilder> initCustomizer() {
+    protected ReaderCustomizer<Address, AddressBuilder> initCustomizer() {
         final KeyedInstanceIdentifier<Mapping, MappingKey> eth0Id = getMappingIid(IFACE_NAME, "test-instance");
         final KeyedInstanceIdentifier<Mapping, MappingKey> eth1Id = getMappingIid(IFACE_2_NAME, "test-instance");
         final Optional<Mapping> eth0 = getMapping(IFACE_NAME, IFACE_ID);
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/ChildReaderCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/ChildReaderCustomizerTest.java
deleted file mode 100644 (file)
index 57369d6..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.v3po.translate.v3po.test;
-
-import static org.junit.Assert.assertNotNull;
-
-import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
-import org.junit.Test;
-import org.opendaylight.yangtools.concepts.Builder;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-/**
- * Generic test for classes implementing {@link ChildReaderCustomizer} interface.
- *
- * @param <D> Specific DataObject derived type (Identifiable), that is handled by this customizer
- * @param <B> Specific Builder for handled type (D)
- */
-public abstract class ChildReaderCustomizerTest<D extends DataObject, B extends Builder<D>> extends RootReaderCustomizerTest<D, B>{
-
-
-    protected ChildReaderCustomizerTest(Class<D> dataObjectClass) {
-        super(dataObjectClass);
-    }
-
-    @Override
-    protected ChildReaderCustomizer<D, B> getCustomizer() {
-        return ChildReaderCustomizer.class.cast(super.getCustomizer());
-    }
-
-    @Test
-    public void testGetBuilder() throws Exception {
-        assertNotNull(getCustomizer().getBuilder(InstanceIdentifier.create(dataObjectClass)));
-    }
-}
index 00cac2d..f2be3de 100644 (file)
@@ -33,7 +33,8 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
  * @param <K> Specific Identifier for handled type (D)
  * @param <B> Specific Builder for handled type (D)
  */
-public abstract class ListReaderCustomizerTest<D extends DataObject & Identifiable<K>, K extends Identifier<D>, B extends Builder<D>> extends RootReaderCustomizerTest<D, B>{
+public abstract class ListReaderCustomizerTest<D extends DataObject & Identifiable<K>, K extends Identifier<D>, B extends Builder<D>> extends
+        ReaderCustomizerTest<D, B> {
 
 
     protected ListReaderCustomizerTest(Class<D> dataObjectClass) {
@@ -23,7 +23,7 @@ import static org.mockito.MockitoAnnotations.initMocks;
 import io.fd.honeycomb.v3po.translate.MappingContext;
 import io.fd.honeycomb.v3po.translate.ModificationCache;
 import io.fd.honeycomb.v3po.translate.read.ReadContext;
-import io.fd.honeycomb.v3po.translate.spi.read.RootReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.read.ReaderCustomizer;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
@@ -33,12 +33,12 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.openvpp.jvpp.future.FutureJVpp;
 
 /**
- * Generic test for classes implementing {@link RootReaderCustomizer} interface.
+ * Generic test for classes implementing {@link ReaderCustomizer} interface.
  *
  * @param <D> Specific DataObject derived type (Identifiable), that is handled by this customizer
  * @param <B> Specific Builder for handled type (D)
  */
-public abstract class RootReaderCustomizerTest<D extends DataObject, B extends Builder<D>> {
+public abstract class ReaderCustomizerTest<D extends DataObject, B extends Builder<D>> {
 
     @Mock
     protected FutureJVpp api;
@@ -49,9 +49,9 @@ public abstract class RootReaderCustomizerTest<D extends DataObject, B extends B
     protected MappingContext mappingContext;
 
     protected final Class<D> dataObjectClass;
-    private RootReaderCustomizer<D, B> customizer;
+    private ReaderCustomizer<D, B> customizer;
 
-    protected RootReaderCustomizerTest(Class<D> dataObjectClass) {
+    protected ReaderCustomizerTest(Class<D> dataObjectClass) {
         this.dataObjectClass = dataObjectClass;
     }
 
@@ -81,9 +81,9 @@ public abstract class RootReaderCustomizerTest<D extends DataObject, B extends B
 
     }
 
-    protected abstract RootReaderCustomizer<D, B> initCustomizer();
+    protected abstract ReaderCustomizer<D, B> initCustomizer();
 
-    protected RootReaderCustomizer<D, B> getCustomizer() {
+    protected ReaderCustomizer<D, B> getCustomizer() {
         return customizer;
     }
 
index ae2373d..701f43e 100644 (file)
@@ -27,7 +27,7 @@ import static org.mockito.Mockito.when;
 import com.google.common.base.Optional;
 import io.fd.honeycomb.v3po.translate.ModificationCache;
 import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.spi.read.RootReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.read.ReaderCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.test.ListReaderCustomizerTest;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import java.util.Arrays;
@@ -73,7 +73,7 @@ public class ClassifySessionReaderTest extends
     }
 
     @Override
-    protected RootReaderCustomizer<ClassifySession, ClassifySessionBuilder> initCustomizer() {
+    protected ReaderCustomizer<ClassifySession, ClassifySessionBuilder> initCustomizer() {
         return new ClassifySessionReader(api, classifyTableContext);
     }
 
index 52429d4..c3c8a5f 100644 (file)
@@ -29,7 +29,7 @@ import static org.mockito.Mockito.verify;
 import com.google.common.base.Optional;
 import com.google.common.collect.Lists;
 import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.spi.read.RootReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.read.ReaderCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.test.ListReaderCustomizerTest;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import java.util.List;
@@ -84,7 +84,7 @@ public class ClassifyTableReaderTest extends
     }
 
     @Override
-    protected RootReaderCustomizer<ClassifyTable, ClassifyTableBuilder> initCustomizer() {
+    protected ReaderCustomizer<ClassifyTable, ClassifyTableBuilder> initCustomizer() {
         return new ClassifyTableReader(api, classifyTableContext);
     }
 
index 7639f48..dc02fda 100644 (file)
@@ -19,7 +19,7 @@ package io.fd.honeycomb.v3po.translate.v3po.vppstate;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
-import io.fd.honeycomb.v3po.translate.spi.read.RootReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.read.ReaderCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.test.ListReaderCustomizerTest;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import java.util.Collections;
@@ -55,7 +55,7 @@ public class BridgeDomainCustomizerTest
     }
 
     @Override
-    protected RootReaderCustomizer<BridgeDomain, BridgeDomainBuilder> initCustomizer() {
+    protected ReaderCustomizer<BridgeDomain, BridgeDomainBuilder> initCustomizer() {
         return new BridgeDomainCustomizer(api, bdContext);
     }
 }
\ No newline at end of file
index 1f668b8..c4be494 100644 (file)
@@ -23,7 +23,7 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import io.fd.honeycomb.v3po.translate.spi.read.RootReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.read.ReaderCustomizer;
 import io.fd.honeycomb.v3po.translate.v3po.test.ListReaderCustomizerTest;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import java.util.Collections;
@@ -69,7 +69,7 @@ public class L2FibEntryCustomizerTest extends ListReaderCustomizerTest<L2FibEntr
     }
 
     @Override
-    protected RootReaderCustomizer<L2FibEntry, L2FibEntryBuilder> initCustomizer() {
+    protected ReaderCustomizer<L2FibEntry, L2FibEntryBuilder> initCustomizer() {
         return new L2FibEntryCustomizer(api, bdContext, interfacesContext);
     }
 
index ed79838..93cd691 100644 (file)
@@ -21,8 +21,8 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
-import io.fd.honeycomb.v3po.translate.v3po.test.ChildReaderCustomizerTest;
+import io.fd.honeycomb.v3po.translate.spi.read.ReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.v3po.test.ReaderCustomizerTest;
 import java.util.concurrent.CompletableFuture;
 import org.junit.Test;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppStateBuilder;
@@ -32,14 +32,14 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.openvpp.jvpp.dto.ShowVersion;
 import org.openvpp.jvpp.dto.ShowVersionReply;
 
-public class VersionCustomizerTest extends ChildReaderCustomizerTest<Version, VersionBuilder> {
+public class VersionCustomizerTest extends ReaderCustomizerTest<Version, VersionBuilder> {
 
     public VersionCustomizerTest() {
         super(Version.class);
     }
 
     @Override
-    protected ChildReaderCustomizer<Version, VersionBuilder> initCustomizer() {
+    protected ReaderCustomizer<Version, VersionBuilder> initCustomizer() {
         return new VersionCustomizer(api);
     }
 
index 7829244..dad991c 100644 (file)
@@ -33,11 +33,9 @@ import com.google.common.collect.Iterables;
 import com.google.common.collect.Multimap;
 import io.fd.honeycomb.v3po.translate.MappingContext;
 import io.fd.honeycomb.v3po.translate.ModificationCache;
-import io.fd.honeycomb.v3po.translate.impl.read.CompositeListReader;
-import io.fd.honeycomb.v3po.translate.impl.read.CompositeRootReader;
+import io.fd.honeycomb.v3po.translate.impl.read.GenericListReader;
 import io.fd.honeycomb.v3po.translate.read.ReadContext;
-import io.fd.honeycomb.v3po.translate.read.Reader;
-import io.fd.honeycomb.v3po.translate.util.read.DelegatingReaderRegistry;
+import io.fd.honeycomb.v3po.translate.read.registry.ReaderRegistry;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
 import java.util.Arrays;
 import java.util.Collections;
@@ -51,7 +49,6 @@ import org.junit.Test;
 import org.mockito.Mock;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppState;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppStateBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.fib.attributes.L2FibTable;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.fib.attributes.l2.fib.table.L2FibEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.fib.attributes.l2.fib.table.L2FibEntryKey;
@@ -86,8 +83,7 @@ public class VppStateTest {
     private NamingContext bdContext;
     private NamingContext interfaceContext;
 
-    private CompositeRootReader<VppState, VppStateBuilder> vppStateReader;
-    private DelegatingReaderRegistry readerRegistry;
+    private ReaderRegistry readerRegistry;
 
     @Before
     public void setUp() throws Exception {
@@ -98,9 +94,7 @@ public class VppStateTest {
 
         bdContext = new NamingContext("generatedBdName", "bd-test-instance");
         interfaceContext = new NamingContext("generatedIfaceName", "ifc-test-instance");
-        vppStateReader = VppStateTestUtils.getVppStateReader(api, bdContext);
-        readerRegistry =
-            new DelegatingReaderRegistry(Collections.<Reader<? extends DataObject>>singletonList(vppStateReader));
+        readerRegistry = VppStateTestUtils.getVppStateReader(api, bdContext);
     }
 
     private static Version getVersion() {
@@ -258,7 +252,7 @@ public class VppStateTest {
 
         VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get();
 
-        final CompositeListReader<BridgeDomain, BridgeDomainKey, BridgeDomainBuilder> bridgeDomainReader =
+        final GenericListReader<BridgeDomain, BridgeDomainKey, BridgeDomainBuilder> bridgeDomainReader =
             VppStateTestUtils.getBridgeDomainReader(api, bdContext);
 
         final List<BridgeDomain> read =
index 27095c7..5afc080 100644 (file)
 
 package io.fd.honeycomb.v3po.translate.v3po.vppstate;
 
-import io.fd.honeycomb.v3po.translate.impl.read.CompositeChildReader;
-import io.fd.honeycomb.v3po.translate.impl.read.CompositeListReader;
-import io.fd.honeycomb.v3po.translate.impl.read.CompositeRootReader;
-import io.fd.honeycomb.v3po.translate.read.ChildReader;
-import io.fd.honeycomb.v3po.translate.util.RWUtils;
-import io.fd.honeycomb.v3po.translate.util.read.ReflexiveChildReaderCustomizer;
-import io.fd.honeycomb.v3po.translate.util.read.ReflexiveRootReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.impl.read.GenericListReader;
+import io.fd.honeycomb.v3po.translate.impl.read.GenericReader;
+import io.fd.honeycomb.v3po.translate.read.registry.ReaderRegistry;
+import io.fd.honeycomb.v3po.translate.util.read.registry.CompositeReaderRegistryBuilder;
 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
-import java.util.ArrayList;
-import java.util.List;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppState;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppStateBuilder;
@@ -35,46 +30,43 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomain;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainKey;
-import org.opendaylight.yangtools.yang.binding.ChildOf;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.openvpp.jvpp.future.FutureJVpp;
 
 final class VppStateTestUtils {
 
+    private static InstanceIdentifier<BridgeDomains> bridgeDomainsId;
+
     public VppStateTestUtils() {
     }
 
     /**
-     * Create root VppState reader with all its children wired
+     * Create root VppState reader with all its children wired.
      */
-    static CompositeRootReader<VppState, VppStateBuilder> getVppStateReader(@Nonnull final FutureJVpp futureJVpp,
-                                                                            @Nonnull final NamingContext bdContext) {
-
-        final ChildReader<Version> versionReader = new CompositeChildReader<>(
-            Version.class, new VersionCustomizer(futureJVpp));
-
-        final CompositeListReader<BridgeDomain, BridgeDomainKey, BridgeDomainBuilder> bridgeDomainReader =
-            getBridgeDomainReader(futureJVpp, bdContext);
-
-        final ChildReader<BridgeDomains> bridgeDomainsReader = new CompositeChildReader<>(
-            BridgeDomains.class,
-            RWUtils.singletonChildReaderList(bridgeDomainReader),
-            new ReflexiveChildReaderCustomizer<>(BridgeDomainsBuilder.class));
-
-        final List<ChildReader<? extends ChildOf<VppState>>> childVppReaders = new ArrayList<>();
-        childVppReaders.add(versionReader);
-        childVppReaders.add(bridgeDomainsReader);
+    static ReaderRegistry getVppStateReader(@Nonnull final FutureJVpp jVpp,
+                                            @Nonnull final NamingContext bdContext) {
+        final CompositeReaderRegistryBuilder registry = new CompositeReaderRegistryBuilder();
 
-        return new CompositeRootReader<>(
-            VppState.class,
-            childVppReaders,
-            RWUtils.<VppState>emptyAugReaderList(),
-            new ReflexiveRootReaderCustomizer<>(VppStateBuilder.class));
+        // VppState(Structural)
+        final InstanceIdentifier<VppState> vppStateId = InstanceIdentifier.create(VppState.class);
+        registry.addStructuralReader(vppStateId, VppStateBuilder.class);
+        //  Version
+        // Wrap with keepalive reader to detect connection issues
+        // TODO keepalive reader wrapper relies on VersionReaderCustomizer (to perform timeout on reads)
+        // Once readers+customizers are asynchronous, pull the timeout to keepalive executor so that keepalive wrapper
+        // is truly generic
+        registry.add(new GenericReader<>(vppStateId.child(Version.class), new VersionCustomizer(jVpp)));
+        //  BridgeDomains(Structural)
+        bridgeDomainsId = vppStateId.child(BridgeDomains.class);
+        registry.addStructuralReader(bridgeDomainsId, BridgeDomainsBuilder.class);
+        //   BridgeDomain
+        registry.add(getBridgeDomainReader(jVpp, bdContext));
+        return registry.build();
     }
 
-    static CompositeListReader<BridgeDomain, BridgeDomainKey, BridgeDomainBuilder> getBridgeDomainReader(
-        final @Nonnull FutureJVpp futureJVpp, @Nonnull final NamingContext bdContext) {
-        return new CompositeListReader<>(
-            BridgeDomain.class,
-            new BridgeDomainCustomizer(futureJVpp, bdContext));
+    static GenericListReader<BridgeDomain, BridgeDomainKey, BridgeDomainBuilder> getBridgeDomainReader(
+            final @Nonnull FutureJVpp jVpp, final @Nonnull NamingContext bdContext) {
+        final InstanceIdentifier<BridgeDomain> bridgeDomainId = bridgeDomainsId.child(BridgeDomain.class);
+        return new GenericListReader<>(bridgeDomainId, new BridgeDomainCustomizer(jVpp, bdContext));
     }
 }
index fd08472..1f2fbd8 100644 (file)
@@ -20,7 +20,7 @@ import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkState;
 
 import com.google.common.base.Optional;
-import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
+import io.fd.honeycomb.v3po.translate.spi.write.WriterCustomizer;
 import io.fd.honeycomb.v3po.translate.write.WriteContext;
 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
 import javax.annotation.Nonnull;
@@ -38,7 +38,7 @@ import org.openvpp.jvpp.future.FutureJVpp;
  * Delete this class when DataTree handles when constraints properly
  */
 public abstract class AbstractInterfaceTypeCustomizer<D extends DataObject>
-    extends FutureJVppCustomizer implements ChildWriterCustomizer<D> {
+    extends FutureJVppCustomizer implements WriterCustomizer<D> {
 
     protected AbstractInterfaceTypeCustomizer(final FutureJVpp futureJvpp) {
         super(futureJvpp);