diff options
14 files changed, 226 insertions, 125 deletions
diff --git a/infra/it/it-test/src/test/java/io/fd/honeycomb/data/impl/HoneycombReadInfraTest.java b/infra/it/it-test/src/test/java/io/fd/honeycomb/data/impl/HoneycombReadInfraTest.java index 143317be0..53fd2e922 100644 --- a/infra/it/it-test/src/test/java/io/fd/honeycomb/data/impl/HoneycombReadInfraTest.java +++ b/infra/it/it-test/src/test/java/io/fd/honeycomb/data/impl/HoneycombReadInfraTest.java @@ -16,6 +16,22 @@ package io.fd.honeycomb.data.impl; +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 static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyListOf; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.atMost; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; + import com.google.common.base.Optional; import com.google.common.collect.Lists; import com.google.common.collect.Multimap; @@ -28,15 +44,27 @@ import io.fd.honeycomb.translate.read.ReadContext; import io.fd.honeycomb.translate.read.ReadFailedException; import io.fd.honeycomb.translate.read.Reader; import io.fd.honeycomb.translate.read.registry.ReaderRegistry; +import io.fd.honeycomb.translate.util.YangDAG; import io.fd.honeycomb.translate.util.RWUtils; import io.fd.honeycomb.translate.util.read.ReflexiveListReaderCustomizer; import io.fd.honeycomb.translate.util.read.ReflexiveReaderCustomizer; +import java.lang.reflect.InvocationTargetException; +import java.util.List; +import java.util.stream.Collectors; +import javax.annotation.Nonnull; import org.junit.Test; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.exceptions.misusing.MockitoConfigurationException; import org.mockito.invocation.InvocationOnMock; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.*; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.ComplexAugment; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.ComplexAugmentBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.ContainerWithList; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.ContainerWithListBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.SimpleAugment; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.SimpleAugmentBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.SimpleContainer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.SimpleContainerBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.container.with.list.ListInContainer; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.container.with.list.ListInContainerBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.container.with.list.ListInContainerKey; @@ -55,20 +83,7 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; -import javax.annotation.Nonnull; -import java.lang.reflect.InvocationTargetException; -import java.util.List; -import java.util.stream.Collectors; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.*; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyListOf; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.*; - public class HoneycombReadInfraTest extends AbstractInfraTest { - @Mock private ReadContext ctx; private ReaderRegistry registry; @@ -108,7 +123,7 @@ public class HoneycombReadInfraTest extends AbstractInfraTest { } private void initReaderRegistry() { - registry = new CompositeReaderRegistryBuilder() + registry = new CompositeReaderRegistryBuilder(new YangDAG()) .add(containerWithListReader) // 2 .addBefore(simpleContainerReader, Ids.CONTAINER_WITH_LIST_ID) // 1 .add(simpleAugmentReader) // 1.1 diff --git a/infra/it/it-test/src/test/java/io/fd/honeycomb/data/impl/HoneycombSubtreeReadInfraTest.java b/infra/it/it-test/src/test/java/io/fd/honeycomb/data/impl/HoneycombSubtreeReadInfraTest.java index b513b5886..b586a186c 100644 --- a/infra/it/it-test/src/test/java/io/fd/honeycomb/data/impl/HoneycombSubtreeReadInfraTest.java +++ b/infra/it/it-test/src/test/java/io/fd/honeycomb/data/impl/HoneycombSubtreeReadInfraTest.java @@ -26,18 +26,15 @@ import com.google.common.collect.Multimap; import com.google.common.collect.Sets; import com.google.common.util.concurrent.CheckedFuture; import io.fd.honeycomb.translate.impl.read.GenericListReader; +import io.fd.honeycomb.translate.impl.read.registry.CompositeReaderRegistryBuilder; import io.fd.honeycomb.translate.read.ListReader; import io.fd.honeycomb.translate.read.ReadContext; import io.fd.honeycomb.translate.read.ReadFailedException; import io.fd.honeycomb.translate.read.Reader; import io.fd.honeycomb.translate.read.registry.ReaderRegistry; +import io.fd.honeycomb.translate.util.YangDAG; import io.fd.honeycomb.translate.util.read.ReflexiveListReaderCustomizer; -import io.fd.honeycomb.translate.impl.read.registry.CompositeReaderRegistryBuilder; - -import java.util.Collections; -import java.util.List; import java.util.stream.Collectors; -import javax.annotation.Nonnull; import org.junit.Test; import org.mockito.Mock; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.ContainerWithList; @@ -85,7 +82,7 @@ public class HoneycombSubtreeReadInfraTest extends AbstractInfraTest { } private void initReaderRegistry() { - registry = new CompositeReaderRegistryBuilder() + registry = new CompositeReaderRegistryBuilder(new YangDAG()) // Subtree reader handling its child list .subtreeAdd(Sets.newHashSet(Ids.LIST_IN_CONTAINER_ID), containerWithListReader) // Reflexive diff --git a/infra/it/it-test/src/test/java/io/fd/honeycomb/data/impl/HoneycombWriteInfraTest.java b/infra/it/it-test/src/test/java/io/fd/honeycomb/data/impl/HoneycombWriteInfraTest.java index bd51e39de..b98c91214 100644 --- a/infra/it/it-test/src/test/java/io/fd/honeycomb/data/impl/HoneycombWriteInfraTest.java +++ b/infra/it/it-test/src/test/java/io/fd/honeycomb/data/impl/HoneycombWriteInfraTest.java @@ -30,8 +30,9 @@ import com.google.common.collect.Lists; import com.google.common.collect.Sets; import io.fd.honeycomb.data.DataModification; import io.fd.honeycomb.translate.impl.write.registry.FlatWriterRegistryBuilder; -import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.honeycomb.translate.util.YangDAG; import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; import io.fd.honeycomb.translate.write.Writer; import io.fd.honeycomb.translate.write.registry.WriterRegistry; import java.util.ArrayList; @@ -116,7 +117,7 @@ public class HoneycombWriteInfraTest extends AbstractInfraTest { } private void initWriterRegistry() { - writerRegistry = new FlatWriterRegistryBuilder() + writerRegistry = new FlatWriterRegistryBuilder(new YangDAG()) .add(complexAugmentWriter) // unordered .add(nestedListWriter) // 6 .addAfter(listInContainerWriter, Ids.NESTED_LIST_ID) // 7 @@ -473,7 +474,7 @@ public class HoneycombWriteInfraTest extends AbstractInfraTest { @Test public void testSubtreeWriter() throws Exception { - writerRegistry = new FlatWriterRegistryBuilder() + writerRegistry = new FlatWriterRegistryBuilder(new YangDAG()) // Handles also container from grouping .subtreeAdd(Sets.newHashSet(Ids.CONTAINER_FROM_GROUPING_ID), containerWithChoiceWriter) .build(); diff --git a/infra/it/it-test/src/test/java/io/fd/honeycomb/data/impl/NestedAugmentationWriteTest.java b/infra/it/it-test/src/test/java/io/fd/honeycomb/data/impl/NestedAugmentationWriteTest.java index 351b88e4a..3b7d4a1cb 100644 --- a/infra/it/it-test/src/test/java/io/fd/honeycomb/data/impl/NestedAugmentationWriteTest.java +++ b/infra/it/it-test/src/test/java/io/fd/honeycomb/data/impl/NestedAugmentationWriteTest.java @@ -25,6 +25,7 @@ import static org.mockito.Mockito.when; import io.fd.honeycomb.data.DataModification; import io.fd.honeycomb.translate.impl.write.registry.FlatWriterRegistryBuilder; +import io.fd.honeycomb.translate.util.YangDAG; import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.Writer; import io.fd.honeycomb.translate.write.registry.WriterRegistry; @@ -132,7 +133,7 @@ public class NestedAugmentationWriteTest extends AbstractInfraTest { } private void initWriterRegistry() { - writerRegistry = new FlatWriterRegistryBuilder() + writerRegistry = new FlatWriterRegistryBuilder(new YangDAG()) .add(augTargetWriter) .add(fromAugmentWriter) .add(listFromAugmentWriter) diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/config/WriterRegistryProvider.java b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/config/WriterRegistryProvider.java index e368266b7..6546ba2d2 100644 --- a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/config/WriterRegistryProvider.java +++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/config/WriterRegistryProvider.java @@ -19,6 +19,7 @@ package io.fd.honeycomb.infra.distro.data.config; import com.google.inject.Inject; import io.fd.honeycomb.infra.distro.ProviderTrait; import io.fd.honeycomb.translate.impl.write.registry.FlatWriterRegistryBuilder; +import io.fd.honeycomb.translate.util.YangDAG; import io.fd.honeycomb.translate.write.WriterFactory; import io.fd.honeycomb.translate.write.registry.WriterRegistry; import java.util.HashSet; @@ -31,7 +32,7 @@ public final class WriterRegistryProvider extends ProviderTrait<WriterRegistry> @Override protected WriterRegistry create() { - final FlatWriterRegistryBuilder builder = new FlatWriterRegistryBuilder(); + final FlatWriterRegistryBuilder builder = new FlatWriterRegistryBuilder(new YangDAG()); writerFactories .stream() .forEach(it -> it.init(builder)); diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/oper/ReaderRegistryBuilderProvider.java b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/oper/ReaderRegistryBuilderProvider.java deleted file mode 100644 index ab967e164..000000000 --- a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/oper/ReaderRegistryBuilderProvider.java +++ /dev/null @@ -1,40 +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.infra.distro.data.oper; - -import com.google.inject.Inject; -import io.fd.honeycomb.infra.distro.ProviderTrait; -import io.fd.honeycomb.translate.read.ReaderFactory; -import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder; -import io.fd.honeycomb.translate.impl.read.registry.CompositeReaderRegistryBuilder; -import java.util.HashSet; -import java.util.Set; - -public final class ReaderRegistryBuilderProvider extends ProviderTrait<ModifiableReaderRegistryBuilder> { - - @Inject(optional = true) - private Set<ReaderFactory> readerFactories = new HashSet<>(); - - @Override - protected CompositeReaderRegistryBuilder create() { - final CompositeReaderRegistryBuilder builder = new CompositeReaderRegistryBuilder(); - readerFactories.stream() - .forEach(it -> it.init(builder)); - return builder; - } - -} diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/oper/ReaderRegistryProvider.java b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/oper/ReaderRegistryProvider.java index 86a5ff858..8f6bb0e6e 100644 --- a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/oper/ReaderRegistryProvider.java +++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/data/oper/ReaderRegistryProvider.java @@ -21,6 +21,7 @@ import io.fd.honeycomb.infra.distro.ProviderTrait; import io.fd.honeycomb.translate.impl.read.registry.CompositeReaderRegistryBuilder; import io.fd.honeycomb.translate.read.ReaderFactory; import io.fd.honeycomb.translate.read.registry.ReaderRegistry; +import io.fd.honeycomb.translate.util.YangDAG; import java.util.HashSet; import java.util.Set; @@ -31,7 +32,7 @@ public final class ReaderRegistryProvider extends ProviderTrait<ReaderRegistry> @Override protected ReaderRegistry create() { - final CompositeReaderRegistryBuilder builder = new CompositeReaderRegistryBuilder(); + final CompositeReaderRegistryBuilder builder = new CompositeReaderRegistryBuilder(new YangDAG()); readerFactories.stream() .forEach(it -> it.init(builder)); return builder.build(); diff --git a/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/read/registry/CompositeReaderRegistryBuilder.java b/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/read/registry/CompositeReaderRegistryBuilder.java index 9163e98de..f8290f166 100644 --- a/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/read/registry/CompositeReaderRegistryBuilder.java +++ b/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/read/registry/CompositeReaderRegistryBuilder.java @@ -16,6 +16,8 @@ package io.fd.honeycomb.translate.impl.read.registry; +import static com.google.common.base.Preconditions.checkArgument; + import com.google.common.collect.ImmutableMap; import io.fd.honeycomb.translate.impl.read.GenericListReader; import io.fd.honeycomb.translate.impl.read.GenericReader; @@ -26,14 +28,13 @@ import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder; import io.fd.honeycomb.translate.read.registry.ReaderRegistry; import io.fd.honeycomb.translate.read.registry.ReaderRegistryBuilder; import io.fd.honeycomb.translate.util.AbstractSubtreeManagerRegistryBuilderBuilder; - +import io.fd.honeycomb.translate.util.YangDAG; 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.Identifiable; @@ -42,8 +43,6 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import static com.google.common.base.Preconditions.checkArgument; - @NotThreadSafe public final class CompositeReaderRegistryBuilder extends AbstractSubtreeManagerRegistryBuilderBuilder<Reader<? extends DataObject, ? extends Builder<?>>, ReaderRegistry> @@ -51,6 +50,10 @@ public final class CompositeReaderRegistryBuilder private static final Logger LOG = LoggerFactory.getLogger(CompositeReaderRegistryBuilder.class); + public CompositeReaderRegistryBuilder(@Nonnull final YangDAG yangDAG) { + super(yangDAG); + } + @Override protected Reader<? extends DataObject, ? extends Builder<?>> getSubtreeHandler(@Nonnull final Set<InstanceIdentifier<?>> handledChildren, @Nonnull final Reader<? extends DataObject, ? extends Builder<?>> reader) { diff --git a/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/registry/FlatWriterRegistryBuilder.java b/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/registry/FlatWriterRegistryBuilder.java index 936aa3c1e..0c6d0a1b4 100644 --- a/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/registry/FlatWriterRegistryBuilder.java +++ b/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/registry/FlatWriterRegistryBuilder.java @@ -18,11 +18,12 @@ package io.fd.honeycomb.translate.impl.write.registry; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableMap; -import io.fd.honeycomb.translate.write.registry.WriterRegistryBuilder; import io.fd.honeycomb.translate.util.AbstractSubtreeManagerRegistryBuilderBuilder; +import io.fd.honeycomb.translate.util.YangDAG; import io.fd.honeycomb.translate.write.Writer; import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder; import io.fd.honeycomb.translate.write.registry.WriterRegistry; +import io.fd.honeycomb.translate.write.registry.WriterRegistryBuilder; import java.util.Set; import java.util.stream.Collectors; import javax.annotation.Nonnull; @@ -42,6 +43,10 @@ public final class FlatWriterRegistryBuilder private static final Logger LOG = LoggerFactory.getLogger(FlatWriterRegistryBuilder.class); + public FlatWriterRegistryBuilder(@Nonnull final YangDAG yangDAG) { + super(yangDAG); + } + @Override protected Writer<? extends DataObject> getSubtreeHandler(final @Nonnull Set<InstanceIdentifier<?>> handledChildren, final @Nonnull Writer<? extends DataObject> writer) { diff --git a/infra/translate-impl/src/test/java/io/fd/honeycomb/translate/impl/read/registry/CompositeReaderRegistryBuilderTest.java b/infra/translate-impl/src/test/java/io/fd/honeycomb/translate/impl/read/registry/CompositeReaderRegistryBuilderTest.java index 0c7c71eac..1858f222a 100644 --- a/infra/translate-impl/src/test/java/io/fd/honeycomb/translate/impl/read/registry/CompositeReaderRegistryBuilderTest.java +++ b/infra/translate-impl/src/test/java/io/fd/honeycomb/translate/impl/read/registry/CompositeReaderRegistryBuilderTest.java @@ -26,6 +26,7 @@ import com.google.common.collect.Lists; import io.fd.honeycomb.translate.read.Reader; import io.fd.honeycomb.translate.read.registry.ReaderRegistry; import io.fd.honeycomb.translate.util.DataObjects; +import io.fd.honeycomb.translate.util.YangDAG; import java.util.List; import java.util.Map; import org.junit.Test; @@ -68,12 +69,12 @@ public class CompositeReaderRegistryBuilderTest { @Test(expected = IllegalArgumentException.class) public void testPreventStructuralReaderForList() { - new CompositeReaderRegistryBuilder().addStructuralReader(InstanceIdentifier.create(DataObjects.DataObjectK.class), DataObjects.DataObjectKBuilder.class); + new CompositeReaderRegistryBuilder(new YangDAG()).addStructuralReader(InstanceIdentifier.create(DataObjects.DataObjectK.class), DataObjects.DataObjectKBuilder.class); } @Test public void testCompositeStructure() throws Exception { - final CompositeReaderRegistryBuilder compositeReaderRegistryBuilder = new CompositeReaderRegistryBuilder(); + final CompositeReaderRegistryBuilder compositeReaderRegistryBuilder = new CompositeReaderRegistryBuilder(new YangDAG()); /* Composite reader structure ordered left from right diff --git a/infra/translate-impl/src/test/java/io/fd/honeycomb/translate/impl/write/registry/FlatWriterRegistryBuilderTest.java b/infra/translate-impl/src/test/java/io/fd/honeycomb/translate/impl/write/registry/FlatWriterRegistryBuilderTest.java index 3a6767265..feaba726c 100644 --- a/infra/translate-impl/src/test/java/io/fd/honeycomb/translate/impl/write/registry/FlatWriterRegistryBuilderTest.java +++ b/infra/translate-impl/src/test/java/io/fd/honeycomb/translate/impl/write/registry/FlatWriterRegistryBuilderTest.java @@ -32,6 +32,7 @@ import com.google.common.collect.Lists; import com.google.common.collect.Multimaps; import com.google.common.collect.Sets; import io.fd.honeycomb.translate.util.DataObjects; +import io.fd.honeycomb.translate.util.YangDAG; import io.fd.honeycomb.translate.write.DataObjectUpdate; import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.Writer; @@ -45,10 +46,9 @@ import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; public class FlatWriterRegistryBuilderTest { - @Test public void testRelationsBefore() throws Exception { - final FlatWriterRegistryBuilder flatWriterRegistryBuilder = new FlatWriterRegistryBuilder(); + final FlatWriterRegistryBuilder flatWriterRegistryBuilder = new FlatWriterRegistryBuilder(new YangDAG()); /* 1 -> 2 -> 3 -> 4 @@ -70,7 +70,7 @@ public class FlatWriterRegistryBuilderTest { @Test public void testBuild() throws Exception { - final FlatWriterRegistryBuilder flatWriterRegistryBuilder = new FlatWriterRegistryBuilder(); + final FlatWriterRegistryBuilder flatWriterRegistryBuilder = new FlatWriterRegistryBuilder(new YangDAG()); final Writer<? extends DataObject> writer = mockWriter(DataObjects.DataObject3.class); flatWriterRegistryBuilder.add(writer); final WriterRegistry build = flatWriterRegistryBuilder.build(); @@ -94,7 +94,7 @@ public class FlatWriterRegistryBuilderTest { @Test(expected = IllegalArgumentException.class) public void testBuildUnknownWriter() throws Exception { - final FlatWriterRegistryBuilder flatWriterRegistryBuilder = new FlatWriterRegistryBuilder(); + final FlatWriterRegistryBuilder flatWriterRegistryBuilder = new FlatWriterRegistryBuilder(new YangDAG()); final Writer<? extends DataObject> writer = mockWriter(DataObjects.DataObject3.class); flatWriterRegistryBuilder.add(writer); final WriterRegistry build = flatWriterRegistryBuilder.build(); @@ -109,7 +109,7 @@ public class FlatWriterRegistryBuilderTest { @Test public void testRelationsAfter() throws Exception { - final FlatWriterRegistryBuilder flatWriterRegistryBuilder = new FlatWriterRegistryBuilder(); + final FlatWriterRegistryBuilder flatWriterRegistryBuilder = new FlatWriterRegistryBuilder(new YangDAG()); /* 1 -> 2 -> 3 -> 4 @@ -131,7 +131,7 @@ public class FlatWriterRegistryBuilderTest { @Test(expected = IllegalArgumentException.class) public void testRelationsLoop() throws Exception { - final FlatWriterRegistryBuilder flatWriterRegistryBuilder = new FlatWriterRegistryBuilder(); + final FlatWriterRegistryBuilder flatWriterRegistryBuilder = new FlatWriterRegistryBuilder(new YangDAG()); /* 1 -> 2 -> 1 */ @@ -142,14 +142,14 @@ public class FlatWriterRegistryBuilderTest { @Test(expected = IllegalArgumentException.class) public void testAddWriterTwice() throws Exception { - final FlatWriterRegistryBuilder flatWriterRegistryBuilder = new FlatWriterRegistryBuilder(); + final FlatWriterRegistryBuilder flatWriterRegistryBuilder = new FlatWriterRegistryBuilder(new YangDAG()); flatWriterRegistryBuilder.add(mockWriter(DataObjects.DataObject1.class)); flatWriterRegistryBuilder.add(mockWriter(DataObjects.DataObject1.class)); } @Test public void testAddSubtreeWriter() throws Exception { - final FlatWriterRegistryBuilder flatWriterRegistryBuilder = new FlatWriterRegistryBuilder(); + final FlatWriterRegistryBuilder flatWriterRegistryBuilder = new FlatWriterRegistryBuilder(new YangDAG()); flatWriterRegistryBuilder.subtreeAdd( Sets.newHashSet(DataObjects.DataObject4.DataObject41.IID, DataObjects.DataObject4.DataObject41.IID), diff --git a/infra/translate-utils/src/main/java/io/fd/honeycomb/translate/util/AbstractSubtreeManagerRegistryBuilderBuilder.java b/infra/translate-utils/src/main/java/io/fd/honeycomb/translate/util/AbstractSubtreeManagerRegistryBuilderBuilder.java index 6a19ed220..fe2f1178f 100644 --- a/infra/translate-utils/src/main/java/io/fd/honeycomb/translate/util/AbstractSubtreeManagerRegistryBuilderBuilder.java +++ b/infra/translate-utils/src/main/java/io/fd/honeycomb/translate/util/AbstractSubtreeManagerRegistryBuilderBuilder.java @@ -18,7 +18,6 @@ package io.fd.honeycomb.translate.util; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Sets; import io.fd.honeycomb.translate.ModifiableSubtreeManagerRegistryBuilder; import io.fd.honeycomb.translate.SubtreeManager; import io.fd.honeycomb.translate.SubtreeManagerRegistryBuilder; @@ -27,17 +26,18 @@ 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 { + implements ModifiableSubtreeManagerRegistryBuilder<S>, SubtreeManagerRegistryBuilder<R> { - // 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<>(); + private final YangDAG dag; + + protected AbstractSubtreeManagerRegistryBuilderBuilder(@Nonnull final YangDAG yangDAG) { + this.dag = Preconditions.checkNotNull(yangDAG, "yangDAG should not be null"); + } /** * Add handler without any special relationship to any other type. @@ -49,7 +49,7 @@ public abstract class AbstractSubtreeManagerRegistryBuilderBuilder<S extends Sub // not be matched to writers in registry final InstanceIdentifier<?> targetType = RWUtils.makeIidWildcarded(handler.getManagedDataObjectType()); checkWriterNotPresentYet(targetType); - handlersRelations.addVertex(targetType); + dag.addVertex(targetType); handlersMap.put(targetType, handler); return this; } @@ -78,9 +78,9 @@ public abstract class AbstractSubtreeManagerRegistryBuilderBuilder<S extends Sub final InstanceIdentifier<?> targetType = RWUtils.makeIidWildcarded(handler.getManagedDataObjectType()); final InstanceIdentifier<?> wildcardedRelatedType = RWUtils.makeIidWildcarded(relatedType); checkWriterNotPresentYet(targetType); - handlersRelations.addVertex(targetType); - handlersRelations.addVertex(wildcardedRelatedType); - addEdge(targetType, wildcardedRelatedType); + dag.addVertex(targetType); + dag.addVertex(wildcardedRelatedType); + dag.addEdge(targetType, wildcardedRelatedType); handlersMap.put(targetType, handler); return this; } @@ -90,13 +90,13 @@ public abstract class AbstractSubtreeManagerRegistryBuilderBuilder<S extends Sub @Nonnull final Collection<InstanceIdentifier<?>> relatedTypes) { final InstanceIdentifier<?> targetType = RWUtils.makeIidWildcarded(handler.getManagedDataObjectType()); checkWriterNotPresentYet(targetType); - handlersRelations.addVertex(targetType); + dag.addVertex(targetType); relatedTypes.stream() .map(RWUtils::makeIidWildcarded) - .forEach(handlersRelations::addVertex); + .forEach(dag::addVertex); relatedTypes.stream() .map(RWUtils::makeIidWildcarded) - .forEach(type -> addEdge(targetType, type)); + .forEach(type -> dag.addEdge(targetType, type)); handlersMap.put(targetType, handler); return this; } @@ -129,10 +129,10 @@ public abstract class AbstractSubtreeManagerRegistryBuilderBuilder<S extends Sub final InstanceIdentifier<?> targetType = RWUtils.makeIidWildcarded(handler.getManagedDataObjectType()); final InstanceIdentifier<?> wildcardedRelatedType = RWUtils.makeIidWildcarded(relatedType); checkWriterNotPresentYet(targetType); - handlersRelations.addVertex(targetType); - handlersRelations.addVertex(wildcardedRelatedType); + dag.addVertex(targetType); + dag.addVertex(wildcardedRelatedType); // set edge to indicate before relationship, just reversed - addEdge(wildcardedRelatedType, targetType); + dag.addEdge(wildcardedRelatedType, targetType); handlersMap.put(targetType, handler); return this; } @@ -142,14 +142,14 @@ public abstract class AbstractSubtreeManagerRegistryBuilderBuilder<S extends Sub @Nonnull final Collection<InstanceIdentifier<?>> relatedTypes) { final InstanceIdentifier<?> targetType = RWUtils.makeIidWildcarded(handler.getManagedDataObjectType()); checkWriterNotPresentYet(targetType); - handlersRelations.addVertex(targetType); + dag.addVertex(targetType); relatedTypes.stream() .map(RWUtils::makeIidWildcarded) - .forEach(handlersRelations::addVertex); + .forEach(dag::addVertex); // set edge to indicate before relationship, just reversed relatedTypes.stream() .map(RWUtils::makeIidWildcarded) - .forEach(type -> addEdge(type, targetType)); + .forEach(type -> dag.addEdge(type, targetType)); handlersMap.put(targetType, handler); return this; } @@ -170,22 +170,10 @@ public abstract class AbstractSubtreeManagerRegistryBuilderBuilder<S extends Sub 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(handlerType -> { + dag.iterator().forEachRemaining(handlerType -> { // There might be types stored just for relationship sake, no real writer, ignoring those if (handlersMap.containsKey(handlerType)) { builder.put(handlerType, handlersMap.get(handlerType)); @@ -199,15 +187,4 @@ public abstract class AbstractSubtreeManagerRegistryBuilderBuilder<S extends Sub 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/infra/translate-utils/src/main/java/io/fd/honeycomb/translate/util/YangDAG.java b/infra/translate-utils/src/main/java/io/fd/honeycomb/translate/util/YangDAG.java new file mode 100644 index 000000000..2269adbff --- /dev/null +++ b/infra/translate-utils/src/main/java/io/fd/honeycomb/translate/util/YangDAG.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.honeycomb.translate.util; + +import java.util.Iterator; +import org.jgrapht.experimental.dag.DirectedAcyclicGraph; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * Directed acyclic graph representing ordering relationships between schema nodes represented as wildcarded + * InstanceIdentifiers. Maintains topological order of vertices. Feature is used by translation layer if more nodes are + * affected in single read/write transaction. + */ +public final class YangDAG { + + private final DirectedAcyclicGraph<InstanceIdentifier<?>, Edge> + dag = new DirectedAcyclicGraph<>((sourceVertex, targetVertex) -> new Edge()); + + /** + * Adds the vertex if it wasn't already in the graph. + * + * @param vertex vertex to be added + */ + public void addVertex(final InstanceIdentifier<?> vertex) { + dag.addVertex(vertex); + } + + /** + * Adds edge between source and target vertices. + * + * @param source source vertex of the edge + * @param target target vertex of the edge + * @throws IllegalArgumentException if the edge would induce a cycle in the graph + */ + public void addEdge(final InstanceIdentifier<?> source, final InstanceIdentifier<?> target) { + try { + dag.addDagEdge(source, target); + } catch (DirectedAcyclicGraph.CycleFoundException e) { + throw new IllegalArgumentException(String.format( + "Unable to add writer with relation: %s -> %s. Loop detected", source, target), e); + } + } + + /** + * Traverses schema nodes in topological order. + * + * @return an iterator that will traverse the graph in topological order. + */ + public Iterator<InstanceIdentifier<?>> iterator() { + return dag.iterator(); + } + + private static final class Edge { + } +} diff --git a/infra/translate-utils/src/test/java/io/fd/honeycomb/translate/util/YangDAGTest.java b/infra/translate-utils/src/test/java/io/fd/honeycomb/translate/util/YangDAGTest.java new file mode 100644 index 000000000..1c8fb5442 --- /dev/null +++ b/infra/translate-utils/src/test/java/io/fd/honeycomb/translate/util/YangDAGTest.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.honeycomb.translate.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.Iterator; +import org.jgrapht.experimental.dag.DirectedAcyclicGraph; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class YangDAGTest { + + private static final InstanceIdentifier<DataObjects.DataObject1> VERTEX_A = DataObjects.DataObject1.IID; + private static final InstanceIdentifier<DataObjects.DataObject2> VERTEX_B = DataObjects.DataObject2.IID; + + private YangDAG dag; + + @Before + public void setUp() { + dag = new YangDAG(); + } + @Test + public void testAddVertex() { + dag.addVertex(VERTEX_A); + final Iterator<InstanceIdentifier<?>> it = dag.iterator(); + assertEquals(VERTEX_A, it.next()); + assertFalse(it.hasNext()); + } + + @Test + public void testAddEdge() { + dag.addVertex(VERTEX_A); + dag.addVertex(VERTEX_B); + dag.addEdge(VERTEX_A, VERTEX_B); + final Iterator<InstanceIdentifier<?>> it = dag.iterator(); + assertEquals(VERTEX_A, it.next()); + assertEquals(VERTEX_B, it.next()); + assertFalse(it.hasNext()); + } + + @Test + public void testAddCycleFails() { + dag.addVertex(VERTEX_A); + dag.addVertex(VERTEX_B); + dag.addEdge(VERTEX_A, VERTEX_B); + try { + dag.addEdge(VERTEX_B, VERTEX_A); + } catch (IllegalArgumentException e) { + assertTrue(e.getCause() instanceof DirectedAcyclicGraph.CycleFoundException); + } + } +}
\ No newline at end of file |