diff options
Diffstat (limited to 'v3po')
143 files changed, 2514 insertions, 2519 deletions
diff --git a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeDelegator.java b/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeDelegator.java index 77aa12aba..2c2581ec0 100644 --- a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeDelegator.java +++ b/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeDelegator.java @@ -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; diff --git a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ReadableDataTreeDelegator.java b/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ReadableDataTreeDelegator.java index 8dc7f8f1c..aff023ebc 100644 --- a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ReadableDataTreeDelegator.java +++ b/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ReadableDataTreeDelegator.java @@ -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; diff --git a/v3po/data-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/data/impl/rev160411/OperationalDataTreeModule.java b/v3po/data-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/data/impl/rev160411/OperationalDataTreeModule.java index 2e49cb7ec..1526fddca 100644 --- a/v3po/data-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/data/impl/rev160411/OperationalDataTreeModule.java +++ b/v3po/data-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/data/impl/rev160411/OperationalDataTreeModule.java @@ -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 { diff --git a/v3po/data-impl/src/main/yang/data-impl.yang b/v3po/data-impl/src/main/yang/data-impl.yang index 922846371..ee485538b 100644 --- a/v3po/data-impl/src/main/yang/data-impl.yang +++ b/v3po/data-impl/src/main/yang/data-impl.yang @@ -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; } } } diff --git a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeDelegatorTest.java b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeDelegatorTest.java index c2653661a..915d738e9 100644 --- a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeDelegatorTest.java +++ b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeDelegatorTest.java @@ -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; diff --git a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ReadableDataTreeDelegatorTest.java b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ReadableDataTreeDelegatorTest.java index c8d4fe4e5..e1b0720e7 100644 --- a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ReadableDataTreeDelegatorTest.java +++ b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ReadableDataTreeDelegatorTest.java @@ -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 = diff --git a/v3po/impl/src/main/config/context-datatree-config.xml b/v3po/impl/src/main/config/context-datatree-config.xml index 02d2f61d4..2c17de15e 100644 --- a/v3po/impl/src/main/config/context-datatree-config.xml +++ b/v3po/impl/src/main/config/context-datatree-config.xml @@ -102,10 +102,10 @@ <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 --> @@ -122,7 +122,7 @@ <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> diff --git a/v3po/impl/src/main/config/default-config.xml b/v3po/impl/src/main/config/default-config.xml index cc6c7c6e2..63f40c624 100644 --- a/v3po/impl/src/main/config/default-config.xml +++ b/v3po/impl/src/main/config/default-config.xml @@ -105,10 +105,10 @@ <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> diff --git a/v3po/impl/src/main/config/netconf-north-config.xml b/v3po/impl/src/main/config/netconf-north-config.xml index ef500c68c..35bd5ff04 100644 --- a/v3po/impl/src/main/config/netconf-north-config.xml +++ b/v3po/impl/src/main/config/netconf-north-config.xml @@ -331,10 +331,10 @@ <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. --> @@ -364,7 +364,7 @@ </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> diff --git a/v3po/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/v3po/impl/rev141210/ContextReaderModule.java b/v3po/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/v3po/impl/rev141210/ContextReaderModule.java index df22a2bea..c15fe525c 100644 --- a/v3po/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/v3po/impl/rev141210/ContextReaderModule.java +++ b/v3po/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/v3po/impl/rev141210/ContextReaderModule.java @@ -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 + } + } } diff --git a/v3po/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/v3po/impl/rev141210/NetconfMonitoringReaderModule.java b/v3po/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/v3po/impl/rev141210/NetconfMonitoringReaderModule.java index feb7768a2..455751858 100644 --- a/v3po/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/v3po/impl/rev141210/NetconfMonitoringReaderModule.java +++ b/v3po/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/v3po/impl/rev141210/NetconfMonitoringReaderModule.java @@ -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 + } + } } diff --git a/v3po/impl/src/main/yang/v3po-impl.yang b/v3po/impl/src/main/yang/v3po-impl.yang index 40b00ec96..065e99fbb 100644 --- a/v3po/impl/src/main/yang/v3po-impl.yang +++ b/v3po/impl/src/main/yang/v3po-impl.yang @@ -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"; } diff --git a/v3po/it/it-test/src/test/java/io/fd/honeycomb/v3po/data/impl/HoneycombWriteInfraTest.java b/v3po/it/it-test/src/test/java/io/fd/honeycomb/v3po/data/impl/HoneycombWriteInfraTest.java index f65b3e186..51fc22744 100644 --- a/v3po/it/it-test/src/test/java/io/fd/honeycomb/v3po/data/impl/HoneycombWriteInfraTest.java +++ b/v3po/it/it-test/src/test/java/io/fd/honeycomb/v3po/data/impl/HoneycombWriteInfraTest.java @@ -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 index 000000000..591a9e9bb --- /dev/null +++ b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/ModifiableSubtreeManagerRegistryBuilder.java @@ -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); +} diff --git a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/SubtreeManager.java b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/SubtreeManager.java index 39e403642..40842763d 100644 --- a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/SubtreeManager.java +++ b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/SubtreeManager.java @@ -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(); diff --git a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/WriterRegistryBuilder.java b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/SubtreeManagerRegistryBuilder.java index 55ef66ec6..2434deddb 100644 --- a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/WriterRegistryBuilder.java +++ b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/SubtreeManagerRegistryBuilder.java @@ -14,12 +14,9 @@ * 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 index 02b6b8d26..000000000 --- a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/ChildReader.java +++ /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; - -} - diff --git a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/ListReader.java b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/ListReader.java index faf6f0a19..13a7a55da 100644 --- a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/ListReader.java +++ b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/ListReader.java @@ -17,23 +17,26 @@ 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)); + } } diff --git a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/Reader.java b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/Reader.java index 122263cb3..d0bf0dea1 100644 --- a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/Reader.java +++ b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/Reader.java @@ -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 index 000000000..6d6d52acc --- /dev/null +++ b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/ReaderFactory.java @@ -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 index 000000000..c2eba4f72 --- /dev/null +++ b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/registry/ModifiableReaderRegistryBuilder.java @@ -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); +} diff --git a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/ReaderRegistry.java b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/registry/ReaderRegistry.java index f34455a27..308ec238d 100644 --- a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/ReaderRegistry.java +++ b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/registry/ReaderRegistry.java @@ -14,10 +14,13 @@ * 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; } diff --git a/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/TraversalType.java b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/registry/ReaderRegistryBuilder.java index 3fa0f8d24..ff95d6248 100644 --- a/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/TraversalType.java +++ b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/registry/ReaderRegistryBuilder.java @@ -14,24 +14,14 @@ * 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 index 000000000..f29289d2d --- /dev/null +++ b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/ListWriter.java @@ -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 index 71ecbb806..000000000 --- a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/ModifiableWriterRegistry.java +++ /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); -} diff --git a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/WriterFactory.java b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/WriterFactory.java index 4287964db..dfcffa47f 100644 --- a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/WriterFactory.java +++ b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/WriterFactory.java @@ -17,12 +17,17 @@ 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 index 000000000..8670a5059 --- /dev/null +++ b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/registry/ModifiableWriterRegistryBuilder.java @@ -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>> { + +} diff --git a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/WriterRegistry.java b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/registry/WriterRegistry.java index 64735017f..439a85410 100644 --- a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/WriterRegistry.java +++ b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/registry/WriterRegistry.java @@ -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 index 000000000..3f0289ece --- /dev/null +++ b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/registry/WriterRegistryBuilder.java @@ -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> { +} diff --git a/v3po/translate-api/src/main/yang/translate-api.yang b/v3po/translate-api/src/main/yang/translate-api.yang index 414ee20e1..796632dd2 100644 --- a/v3po/translate-api/src/main/yang/translate-api.yang +++ b/v3po/translate-api/src/main/yang/translate-api.yang @@ -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 index c99e0edc4..000000000 --- a/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/AbstractCompositeReader.java +++ /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 index 89f9f5675..000000000 --- a/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/CompositeChildReader.java +++ /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 index 7c438f669..000000000 --- a/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/CompositeListReader.java +++ /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 index ea157aafd..000000000 --- a/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/CompositeRootReader.java +++ /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 index 000000000..54dad5517 --- /dev/null +++ b/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/GenericListReader.java @@ -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 index 000000000..eace7fa89 --- /dev/null +++ b/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/GenericReader.java @@ -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); + } + +} diff --git a/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/write/GenericListWriter.java b/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/write/GenericListWriter.java index b61fb51f7..32daf5975 100644 --- a/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/write/GenericListWriter.java +++ b/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/write/GenericListWriter.java @@ -17,10 +17,12 @@ 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) { diff --git a/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/write/GenericWriter.java b/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/write/GenericWriter.java index 6ca80ca37..65c192ffa 100644 --- a/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/write/GenericWriter.java +++ b/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/write/GenericWriter.java @@ -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; } diff --git a/v3po/translate-impl/src/test/java/io/fd/honeycomb/v3po/translate/impl/write/GenericWriterTest.java b/v3po/translate-impl/src/test/java/io/fd/honeycomb/v3po/translate/impl/write/GenericWriterTest.java index 919072bcb..87f18965b 100644 --- a/v3po/translate-impl/src/test/java/io/fd/honeycomb/v3po/translate/impl/write/GenericWriterTest.java +++ b/v3po/translate-impl/src/test/java/io/fd/honeycomb/v3po/translate/impl/write/GenericWriterTest.java @@ -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 index 8acc54db9..000000000 --- a/v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/read/ChildReaderCustomizer.java +++ /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); -} diff --git a/v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/read/ListReaderCustomizer.java b/v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/read/ListReaderCustomizer.java index 4a2e02cfb..59557554f 100644 --- a/v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/read/ListReaderCustomizer.java +++ b/v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/read/ListReaderCustomizer.java @@ -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)); + } } diff --git a/v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/read/RootReaderCustomizer.java b/v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/read/ReaderCustomizer.java index f0cb76860..270da8beb 100644 --- a/v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/read/RootReaderCustomizer.java +++ b/v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/read/ReaderCustomizer.java @@ -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 index e8f248495..000000000 --- a/v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/write/ChildWriterCustomizer.java +++ /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); - -} diff --git a/v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/write/ListWriterCustomizer.java b/v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/write/ListWriterCustomizer.java index ecc591191..41cdb94b6 100644 --- a/v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/write/ListWriterCustomizer.java +++ b/v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/write/ListWriterCustomizer.java @@ -17,32 +17,18 @@ 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 diff --git a/v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/write/RootWriterCustomizer.java b/v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/write/WriterCustomizer.java index 0ada8e9e5..06ce3f814 100644 --- a/v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/write/RootWriterCustomizer.java +++ b/v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/write/WriterCustomizer.java @@ -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 index 000000000..23a66337f --- /dev/null +++ b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/AbstractSubtreeManagerRegistryBuilderBuilder.java @@ -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 {} +} diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/RWUtils.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/RWUtils.java index 55ae9ecf0..ba9d8e16f 100644 --- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/RWUtils.java +++ b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/RWUtils.java @@ -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) { diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/TransactionMappingContext.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/TransactionMappingContext.java index 60f4282f5..6abc3b1eb 100644 --- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/TransactionMappingContext.java +++ b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/TransactionMappingContext.java @@ -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 index 000000000..9bfbc2450 --- /dev/null +++ b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/AbstractGenericReader.java @@ -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()); + } +} diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/BindingBrokerReader.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/BindingBrokerReader.java index 58695cf8b..68aa3956e 100644 --- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/BindingBrokerReader.java +++ b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/BindingBrokerReader.java @@ -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 index 5492062e3..000000000 --- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/CloseableReader.java +++ /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 - } -} diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/KeepaliveReaderWrapper.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/KeepaliveReaderWrapper.java index d59111faa..d782bcc7f 100644 --- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/KeepaliveReaderWrapper.java +++ b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/KeepaliveReaderWrapper.java @@ -14,15 +14,15 @@ * 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(); } diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/NoopReaderCustomizer.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/NoopReaderCustomizer.java index cf494efbe..a4de9febb 100644 --- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/NoopReaderCustomizer.java +++ b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/NoopReaderCustomizer.java @@ -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 index 38107edff..000000000 --- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveAugmentReaderCustomizer.java +++ /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 index 3d5f9f4e8..000000000 --- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveChildReaderCustomizer.java +++ /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 index 000000000..51725e728 --- /dev/null +++ b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveReader.java @@ -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 index 000000000..f9efca3dc --- /dev/null +++ b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveReaderCustomizer.java @@ -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 index 029f359bb..000000000 --- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveRootReaderCustomizer.java +++ /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 index 000000000..64ecaf095 --- /dev/null +++ b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/CompositeReader.java @@ -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); + } + } + +} diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/DelegatingReaderRegistry.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/CompositeReaderRegistry.java index 387f3cc7c..0a948c7a8 100644 --- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/DelegatingReaderRegistry.java +++ b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/CompositeReaderRegistry.java @@ -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 index 000000000..3adda713d --- /dev/null +++ b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/CompositeReaderRegistryBuilder.java @@ -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 index 000000000..98fcac673 --- /dev/null +++ b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/SubtreeReader.java @@ -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 index 000000000..005e3bc8d --- /dev/null +++ b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/TypeHierarchy.java @@ -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{} +} diff --git a/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/write/AbstractCompositeWriter.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/AbstractGenericWriter.java index 5f1391c74..44b36edae 100644 --- a/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/write/AbstractCompositeWriter.java +++ b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/AbstractGenericWriter.java @@ -14,10 +14,11 @@ * 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 index 3442f8370..000000000 --- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/CloseableWriter.java +++ /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 { - - } -} diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/NoopWriterRegistry.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/NoopWriterRegistry.java index 236ad8917..7c45fcd82 100644 --- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/NoopWriterRegistry.java +++ b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/NoopWriterRegistry.java @@ -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 diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/registry/FlatWriterRegistry.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/registry/FlatWriterRegistry.java index 4abad23a6..7433de813 100644 --- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/registry/FlatWriterRegistry.java +++ b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/registry/FlatWriterRegistry.java @@ -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; @@ -91,15 +90,6 @@ final class FlatWriterRegistry implements WriterRegistry { } @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 { if (updates.isEmpty()) { @@ -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 { diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/registry/FlatWriterRegistryBuilder.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/registry/FlatWriterRegistryBuilder.java index f5d218f55..bfac2eedd 100644 --- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/registry/FlatWriterRegistryBuilder.java +++ b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/registry/FlatWriterRegistryBuilder.java @@ -17,20 +17,16 @@ 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 {} } diff --git a/v3po/translate-utils/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/translate/utils/rev160406/DelegatingReaderRegistryModule.java b/v3po/translate-utils/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/translate/utils/rev160406/DelegatingReaderRegistryModule.java index fccd6b1c2..e1f04ebe2 100644 --- a/v3po/translate-utils/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/translate/utils/rev160406/DelegatingReaderRegistryModule.java +++ b/v3po/translate-utils/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/translate/utils/rev160406/DelegatingReaderRegistryModule.java @@ -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; } } diff --git a/v3po/translate-utils/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/translate/utils/rev160406/NoopWriterRegistryModule.java b/v3po/translate-utils/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/translate/utils/rev160406/NoopWriterRegistryModule.java index fedd069f1..0f72df9da 100644 --- a/v3po/translate-utils/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/translate/utils/rev160406/NoopWriterRegistryModule.java +++ b/v3po/translate-utils/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/translate/utils/rev160406/NoopWriterRegistryModule.java @@ -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) { diff --git a/v3po/translate-utils/src/main/yang/translate-utils.yang b/v3po/translate-utils/src/main/yang/translate-utils.yang index 2c00bb548..b543bba0d 100644 --- a/v3po/translate-utils/src/main/yang/translate-utils.yang +++ b/v3po/translate-utils/src/main/yang/translate-utils.yang @@ -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 index 3edc001a8..000000000 --- a/v3po/translate-utils/src/test/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveAugmentReaderCustomizerTest.java +++ /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 index 000000000..92449af28 --- /dev/null +++ b/v3po/translate-utils/src/test/java/io/fd/honeycomb/v3po/translate/util/read/registry/TypeHierarchyTest.java @@ -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); + } + } + } +} + diff --git a/v3po/translate-utils/src/test/java/io/fd/honeycomb/v3po/translate/util/write/registry/FlatWriterRegistryBuilderTest.java b/v3po/translate-utils/src/test/java/io/fd/honeycomb/v3po/translate/util/write/registry/FlatWriterRegistryBuilderTest.java index ec407b685..da7ac0947 100644 --- a/v3po/translate-utils/src/test/java/io/fd/honeycomb/v3po/translate/util/write/registry/FlatWriterRegistryBuilderTest.java +++ b/v3po/translate-utils/src/test/java/io/fd/honeycomb/v3po/translate/util/write/registry/FlatWriterRegistryBuilderTest.java @@ -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)); diff --git a/v3po/translate-utils/src/test/java/io/fd/honeycomb/v3po/translate/util/write/registry/FlatWriterRegistryTest.java b/v3po/translate-utils/src/test/java/io/fd/honeycomb/v3po/translate/util/write/registry/FlatWriterRegistryTest.java index df3296557..1b4a059ea 100644 --- a/v3po/translate-utils/src/test/java/io/fd/honeycomb/v3po/translate/util/write/registry/FlatWriterRegistryTest.java +++ b/v3po/translate-utils/src/test/java/io/fd/honeycomb/v3po/translate/util/write/registry/FlatWriterRegistryTest.java @@ -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; @@ -49,19 +49,6 @@ public class FlatWriterRegistryTest { } @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 = new FlatWriterRegistry(ImmutableMap.of(DataObject1.IID, writer1, DataObject2.IID, writer2)); @@ -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); } diff --git a/v3po/v3po2vpp/src/main/config/default-config.xml b/v3po/v3po2vpp/src/main/config/default-config.xml index 435edd029..6a671382c 100644 --- a/v3po/v3po2vpp/src/main/config/default-config.xml +++ b/v3po/v3po2vpp/src/main/config/default-config.xml @@ -187,18 +187,18 @@ <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> @@ -221,7 +221,7 @@ <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'] diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/initializers/VppInitializer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/initializers/VppInitializer.java index 8c90c5051..8db903d8a 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/initializers/VppInitializer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/initializers/VppInitializer.java @@ -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(); diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/AclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/AclCustomizer.java index 4e681f60a..cb8eed233 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/AclCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/AclCustomizer.java @@ -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 { diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/EthernetCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/EthernetCustomizer.java index dd3a85628..27081b1b2 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/EthernetCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/EthernetCustomizer.java @@ -16,15 +16,12 @@ 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) { diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterfaceCustomizer.java index de07bdcc1..ac57ab4da 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterfaceCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterfaceCustomizer.java @@ -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 { diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/L2Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/L2Customizer.java index dd40fbdd0..83b522b63 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/L2Customizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/L2Customizer.java @@ -16,23 +16,20 @@ 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) diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RewriteCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RewriteCustomizer.java index 9fa57830a..54c6971a8 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RewriteCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RewriteCustomizer.java @@ -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) diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RoutingCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RoutingCustomizer.java index 9d41afd0c..1e8102133 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RoutingCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RoutingCustomizer.java @@ -16,18 +16,17 @@ 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) diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceAclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceAclCustomizer.java index 9cba9c724..eb433dc37 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceAclCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceAclCustomizer.java @@ -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 { diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceCustomizer.java index 57676c85b..c4971867c 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceCustomizer.java @@ -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) diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceL2Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceL2Customizer.java index 8ab3e2c12..567122d31 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceL2Customizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceL2Customizer.java @@ -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) diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/TapCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/TapCustomizer.java index d0e5179e2..6de3bc457 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/TapCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/TapCustomizer.java @@ -16,29 +16,30 @@ 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; diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VhostUserCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VhostUserCustomizer.java index 60df2cf37..d087f30f5 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VhostUserCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VhostUserCustomizer.java @@ -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; diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizer.java index 382348012..82c572864 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizer.java @@ -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; diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanGpeCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanGpeCustomizer.java index 9b7e4bdbd..ebe7bfeab 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanGpeCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanGpeCustomizer.java @@ -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: {}", diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4AddressCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4AddressCustomizer.java index a05bd8f08..26d05546b 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4AddressCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4AddressCustomizer.java @@ -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 { diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4Customizer.java index cee64742b..7eb45b2e4 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4Customizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4Customizer.java @@ -16,23 +16,20 @@ 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) diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4NeighbourCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4NeighbourCustomizer.java index 99267ddff..426d81fbc 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4NeighbourCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4NeighbourCustomizer.java @@ -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 { diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv6Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv6Customizer.java index 0fe86435e..d43bc90d5 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv6Customizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv6Customizer.java @@ -16,20 +16,17 @@ 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) { diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/SubInterfaceIpv4AddressCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/SubInterfaceIpv4AddressCustomizer.java index ccdcc6ce2..3d41b899f 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/SubInterfaceIpv4AddressCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/SubInterfaceIpv4AddressCustomizer.java @@ -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 { diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/AclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/AclCustomizer.java index d8d2d8e30..c5b17e5b9 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/AclCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/AclCustomizer.java @@ -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; diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/EthernetCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/EthernetCustomizer.java index 5bbf33935..a2643e408 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/EthernetCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/EthernetCustomizer.java @@ -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; diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2Customizer.java index e1496e36b..e7c6b2aa1 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2Customizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2Customizer.java @@ -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; diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/RewriteCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/RewriteCustomizer.java index 9bb12da82..e76ed7662 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/RewriteCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/RewriteCustomizer.java @@ -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; diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceAclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceAclCustomizer.java index a00485f49..276849ba4 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceAclCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceAclCustomizer.java @@ -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; diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceL2Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceL2Customizer.java index 0c6d50b76..6e9b16719 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceL2Customizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceL2Customizer.java @@ -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; diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/TapCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/TapCustomizer.java index 3f79e5517..c9a592e30 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/TapCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/TapCustomizer.java @@ -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"; diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VhostUserCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VhostUserCustomizer.java index 23e1a6efd..878eb3179 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VhostUserCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VhostUserCustomizer.java @@ -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"; diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizer.java index 3d82820a4..b57274a88 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizer.java @@ -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); diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanGpeCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanGpeCustomizer.java index de05dc4bc..2e45a2b64 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanGpeCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanGpeCustomizer.java @@ -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; diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/ip/Ipv4Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/ip/Ipv4Customizer.java index 8e6162784..fa912c05e 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/ip/Ipv4Customizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/ip/Ipv4Customizer.java @@ -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); diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/ip/Ipv6Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/ip/Ipv6Customizer.java index 37524dde6..ada05b72f 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/ip/Ipv6Customizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/ip/Ipv6Customizer.java @@ -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; diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizer.java index 22344baa6..601a79eba 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizer.java @@ -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 { diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vpp/L2FibEntryCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vpp/L2FibEntryCustomizer.java index 3655a48f1..52bb1ad61 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vpp/L2FibEntryCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vpp/L2FibEntryCustomizer.java @@ -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) diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppclassifier/ClassifySessionWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppclassifier/ClassifySessionWriter.java index ac964a9b8..ea183a839 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppclassifier/ClassifySessionWriter.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppclassifier/ClassifySessionWriter.java @@ -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, diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppclassifier/ClassifyTableWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppclassifier/ClassifyTableWriter.java index 788aac59c..c34468458 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppclassifier/ClassifyTableWriter.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppclassifier/ClassifyTableWriter.java @@ -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) diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizer.java index 83a8995f7..2032cd811 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizer.java @@ -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 diff --git a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesHoneycombWriterModule.java b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesHoneycombWriterModule.java index 64f1e8a7c..635c77a0b 100644 --- a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesHoneycombWriterModule.java +++ b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesHoneycombWriterModule.java @@ -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)); } } diff --git a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesStateHoneycombReaderModule.java b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesStateHoneycombReaderModule.java index 5c89961b9..83758d828 100644 --- a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesStateHoneycombReaderModule.java +++ b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesStateHoneycombReaderModule.java @@ -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 + } } } diff --git a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/Readme.adoc b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/Readme.adoc index 8917105f5..d6fa3770d 100644 --- a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/Readme.adoc +++ b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/Readme.adoc @@ -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 diff --git a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/SubinterfaceAugmentationWriterFactory.java b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/SubinterfaceAugmentationWriterFactory.java index 60a9c2e2c..034056425 100644 --- a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/SubinterfaceAugmentationWriterFactory.java +++ b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/SubinterfaceAugmentationWriterFactory.java @@ -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)); } } diff --git a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/SubinterfaceStateAugmentationReaderFactory.java b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/SubinterfaceStateAugmentationReaderFactory.java index 7dfe4d289..42e8c5b34 100644 --- a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/SubinterfaceStateAugmentationReaderFactory.java +++ b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/SubinterfaceStateAugmentationReaderFactory.java @@ -16,104 +16,91 @@ 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))); } } diff --git a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppClassifierHoneycombWriterModule.java b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppClassifierHoneycombWriterModule.java index b2fb5454a..ca05b392b 100644 --- a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppClassifierHoneycombWriterModule.java +++ b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppClassifierHoneycombWriterModule.java @@ -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); } diff --git a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppClassifierStateHoneycombReaderModule.java b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppClassifierStateHoneycombReaderModule.java index bea7e0d13..4a91f2679 100644 --- a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppClassifierStateHoneycombReaderModule.java +++ b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppClassifierStateHoneycombReaderModule.java @@ -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 + } + } } diff --git a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppHoneycombWriterModule.java b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppHoneycombWriterModule.java index 922b6f9cd..ba42cfba5 100644 --- a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppHoneycombWriterModule.java +++ b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppHoneycombWriterModule.java @@ -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, diff --git a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppStateHoneycombReaderModule.java b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppStateHoneycombReaderModule.java index abbde23ab..4634a5b59 100644 --- a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppStateHoneycombReaderModule.java +++ b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppStateHoneycombReaderModule.java @@ -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))); + } + } } diff --git a/v3po/v3po2vpp/src/main/yang/v3po2vpp.yang b/v3po/v3po2vpp/src/main/yang/v3po2vpp.yang index 406dd56d6..6bc253e48 100644 --- a/v3po/v3po2vpp/src/main/yang/v3po2vpp.yang +++ b/v3po/v3po2vpp/src/main/yang/v3po2vpp.yang @@ -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" { diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4AddressCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4AddressCustomizerTest.java index cea7a2a23..21deb9135 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4AddressCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4AddressCustomizerTest.java @@ -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); diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4NeighbourCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4NeighbourCustomizerTest.java index 5811907a4..7026ee2a4 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4NeighbourCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4NeighbourCustomizerTest.java @@ -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 diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/AclCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/AclCustomizerTest.java index 4e9e5dea4..09c0e8815 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/AclCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/AclCustomizerTest.java @@ -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); } diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizerTest.java index dc2d3b675..61df50e4b 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizerTest.java @@ -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"); diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2CustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2CustomizerTest.java index b6309d86b..c07583857 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2CustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2CustomizerTest.java @@ -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); } diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/RewriteCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/RewriteCustomizerTest.java index f7f7bb377..3255826d1 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/RewriteCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/RewriteCustomizerTest.java @@ -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); } diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceCustomizerTest.java index effe0dbfb..641995991 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceCustomizerTest.java @@ -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); } diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizerTest.java index 64c14ebff..14830fe45 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizerTest.java @@ -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 diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanGpeCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanGpeCustomizerTest.java index 863951fad..323bc7e2a 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanGpeCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanGpeCustomizerTest.java @@ -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); } } diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/ip/Ipv4AddressCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/ip/Ipv4AddressCustomizerTest.java index be67771de..7d701e453 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/ip/Ipv4AddressCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/ip/Ipv4AddressCustomizerTest.java @@ -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 index 57369d665..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/ChildReaderCustomizerTest.java +++ /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))); - } -} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/ListReaderCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/ListReaderCustomizerTest.java index 00cac2d5d..f2be3dec9 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/ListReaderCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/ListReaderCustomizerTest.java @@ -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) { diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/RootReaderCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/ReaderCustomizerTest.java index 8500acece..29d365ca2 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/RootReaderCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/ReaderCustomizerTest.java @@ -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; } diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppclassifier/ClassifySessionReaderTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppclassifier/ClassifySessionReaderTest.java index ae2373def..701f43eb0 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppclassifier/ClassifySessionReaderTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppclassifier/ClassifySessionReaderTest.java @@ -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); } diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppclassifier/ClassifyTableReaderTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppclassifier/ClassifyTableReaderTest.java index 52429d4c7..c3c8a5f0a 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppclassifier/ClassifyTableReaderTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppclassifier/ClassifyTableReaderTest.java @@ -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); } diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizerTest.java index 7639f4849..dc02fdac5 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizerTest.java @@ -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 diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/L2FibEntryCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/L2FibEntryCustomizerTest.java index 1f668b817..c4be494c3 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/L2FibEntryCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/L2FibEntryCustomizerTest.java @@ -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); } diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizerTest.java index ed79838b4..93cd6913e 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizerTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizerTest.java @@ -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); } diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateTest.java index 782924490..dad991c13 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateTest.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateTest.java @@ -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 = diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateTestUtils.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateTestUtils.java index 27095c7d9..5afc080d6 100644 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateTestUtils.java +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateTestUtils.java @@ -16,16 +16,11 @@ 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)); } } diff --git a/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/AbstractInterfaceTypeCustomizer.java b/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/AbstractInterfaceTypeCustomizer.java index fd08472d7..1f2fbd838 100644 --- a/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/AbstractInterfaceTypeCustomizer.java +++ b/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/AbstractInterfaceTypeCustomizer.java @@ -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); |