From ec78f178f542369fdfd696fdc6e4bb872780ac87 Mon Sep 17 00:00:00 2001 From: Jan Srnicek Date: Fri, 24 Feb 2017 10:39:55 +0100 Subject: HONEYCOMB-344 - structural reader for list Change-Id: Ia02ed73daaeea547d49c9ec2d4d7d10f4db85b5e Signed-off-by: Jan Srnicek --- .../data/impl/HoneycombReadInfraTest.java | 57 ++++------ .../data/impl/HoneycombSubtreeReadInfraTest.java | 20 +--- .../registry/ModifiableReaderRegistryBuilder.java | 10 ++ .../translate/impl/read/GenericListReader.java | 9 ++ .../registry/CompositeReaderRegistryBuilder.java | 14 ++- infra/translate-utils/pom.xml | 5 + .../util/read/ReflexiveListReaderCustomizer.java | 32 ++++-- .../read/ReflexiveListReaderCustomizerTest.java | 115 +++++++++++++++++++++ .../util/read/ReflexiveReaderCustomizerTest.java | 36 ++----- 9 files changed, 205 insertions(+), 93 deletions(-) create mode 100644 infra/translate-utils/src/test/java/io/fd/honeycomb/translate/util/read/ReflexiveListReaderCustomizerTest.java 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 6d4c9e6f3..143317be0 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,22 +16,6 @@ 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; @@ -47,23 +31,12 @@ import io.fd.honeycomb.translate.read.registry.ReaderRegistry; 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.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.*; 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; @@ -82,6 +55,18 @@ 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 @@ -108,14 +93,14 @@ public class HoneycombReadInfraTest extends AbstractInfraTest { // 2.1 private ListReader listInContainerReader = mockListReader(Ids.LIST_IN_CONTAINER_ID, this::readListInContainer, this::getListInContainerIds, - ListInContainerBuilder.class); + ListInContainerBuilder.class, ctx); // 2.1.1 private Reader containerInListReader = mockReader(Ids.CONTAINER_IN_LIST_ID, this::readContainerInList, ContainerInListBuilder.class); // 2.1.1.1 private ListReader nestedListReader = mockListReader(Ids.NESTED_LIST_ID, this::readNestedList, this::getNestedListIds, - NestedListBuilder.class); + NestedListBuilder.class, ctx); @Override void postSetup() { @@ -293,17 +278,11 @@ public class HoneycombReadInfraTest extends AbstractInfraTest { InstanceIdentifier id, CurrentAttributesReader currentAttributesReader, ListKeysReader listKeysReader, - Class builderClass) { + Class builderClass, + ReadContext ctx) { ListReader reflex = new GenericListReader<>(id, - new ReflexiveListReaderCustomizer(id.getTargetType(), builderClass) { - - @Nonnull - @Override - public List getAllIds(@Nonnull final InstanceIdentifier id, @Nonnull final ReadContext context) - throws ReadFailedException { - return listKeysReader.getAllIds(id, context); - } + new ReflexiveListReaderCustomizer(id.getTargetType(), builderClass, listKeysReader.getAllIds(id, ctx)) { @Override public void readCurrentAttributes(final InstanceIdentifier id, final B builder, 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 1894f4942..b513b5886 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 @@ -33,6 +33,8 @@ import io.fd.honeycomb.translate.read.Reader; import io.fd.honeycomb.translate.read.registry.ReaderRegistry; 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; @@ -61,22 +63,8 @@ public class HoneycombSubtreeReadInfraTest extends AbstractInfraTest { private ListReader listInContainerReader = new GenericListReader<>(Ids.LIST_IN_CONTAINER_ID, - new ReflexiveListReaderCustomizer(Ids.LIST_IN_CONTAINER_ID.getTargetType(), ListInContainerBuilder.class) { - - @Nonnull - @Override - public List getAllIds(@Nonnull final InstanceIdentifier id, - @Nonnull final ReadContext context) - throws ReadFailedException { - // This is the only way of extending subtree reader's list child - // Reflexive list reader has to be used in place of the list(managed by subtree reader perent) - // to enable further children readers. However, it will not work out of the box, because - // reflexive list reader has no way to tell what are the IDs to correctly invoke its children. - // Only way is to override the getAllIds method in reflexive reader and return the same list - // as parent used (this can be done using cache or repeated dump call) - return Lists.newArrayList(new ListInContainerKey(1L), new ListInContainerKey(2L)); - } - + new ReflexiveListReaderCustomizer(Ids.LIST_IN_CONTAINER_ID.getTargetType(), ListInContainerBuilder.class, + Lists.newArrayList(new ListInContainerKey(1L), new ListInContainerKey(2L))) { @Override public void readCurrentAttributes(final InstanceIdentifier id, final ListInContainerBuilder builder, diff --git a/infra/translate-api/src/main/java/io/fd/honeycomb/translate/read/registry/ModifiableReaderRegistryBuilder.java b/infra/translate-api/src/main/java/io/fd/honeycomb/translate/read/registry/ModifiableReaderRegistryBuilder.java index 67029b17c..dc1866d78 100644 --- a/infra/translate-api/src/main/java/io/fd/honeycomb/translate/read/registry/ModifiableReaderRegistryBuilder.java +++ b/infra/translate-api/src/main/java/io/fd/honeycomb/translate/read/registry/ModifiableReaderRegistryBuilder.java @@ -22,8 +22,12 @@ import io.fd.honeycomb.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.Identifiable; +import org.opendaylight.yangtools.yang.binding.Identifier; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import java.util.List; + /** * Mutable registry that allows adding new readers. */ @@ -38,4 +42,10 @@ public interface ModifiableReaderRegistryBuilder */ void addStructuralReader(@Nonnull InstanceIdentifier id, @Nonnull Class> builderType); + /** + * Construct customizer that will always return static list of keys. + * */ + ,K extends Identifier> void addStructuralListReader(@Nonnull InstanceIdentifier id, + @Nonnull Class> builderType, + @Nonnull List staticKeys); } diff --git a/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/read/GenericListReader.java b/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/read/GenericListReader.java index b06ac060f..9e2ccd7e5 100644 --- a/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/read/GenericListReader.java +++ b/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/read/GenericListReader.java @@ -23,12 +23,15 @@ import com.google.common.base.Optional; 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.spi.read.ListReaderCustomizer; import io.fd.honeycomb.translate.util.RWUtils; import java.util.ArrayList; import java.util.List; import javax.annotation.Nonnull; import javax.annotation.concurrent.ThreadSafe; + +import io.fd.honeycomb.translate.util.read.ReflexiveListReaderCustomizer; import org.opendaylight.yangtools.concepts.Builder; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.Identifiable; @@ -97,4 +100,10 @@ public class GenericListReader, K extends public void merge(@Nonnull final Builder builder, @Nonnull final List readData) { ((ListReaderCustomizer) customizer).merge(builder, readData); } + + public static ,K extends Identifier, B extends Builder> Reader createReflexive( + final InstanceIdentifier id, Class builderClass, + final List staticKeys) { + return new GenericListReader<>(id, new ReflexiveListReaderCustomizer<>(id.getTargetType(), builderClass, staticKeys)); + } } 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 dd6a838c6..9163e98de 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 @@ -17,6 +17,7 @@ package io.fd.honeycomb.translate.impl.read.registry; import com.google.common.collect.ImmutableMap; +import io.fd.honeycomb.translate.impl.read.GenericListReader; import io.fd.honeycomb.translate.impl.read.GenericReader; import io.fd.honeycomb.translate.read.InitReader; import io.fd.honeycomb.translate.read.Initializer; @@ -36,6 +37,7 @@ 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; +import org.opendaylight.yangtools.yang.binding.Identifier; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -60,14 +62,18 @@ public final class CompositeReaderRegistryBuilder @Override public void addStructuralReader(@Nonnull InstanceIdentifier id, @Nonnull Class> builderType) { - // TODO https://jira.fd.io/browse/HONEYCOMB-344 provide variant of this method for list nodes // prevent case to submit structural reader for list, which would cause fail because target setter consumes - // List, not Target type. If node is static, customizer that handles it should return static list - // of IDs. - checkArgument(!Identifiable.class.isAssignableFrom(id.getTargetType()), "Structural readers cannot be used for keyed nodes[node type %s]", id.getTargetType()); + // List, not Target type. If node is static list, addStructuralListReader should be used + checkArgument(!Identifiable.class.isAssignableFrom(id.getTargetType()), "Structural readers cannot be used for keyed nodes[node type %s], use addStructuralListReader()", id.getTargetType()); add(GenericReader.createReflexive(id, builderType)); } + @Override + public , K extends Identifier> void addStructuralListReader(@Nonnull InstanceIdentifier id, @Nonnull Class> builderType, @Nonnull List staticKeys) { + checkArgument(Identifiable.class.isAssignableFrom(id.getTargetType()), "Node %s is not keyed, use addStructuralReader()", id.getTargetType()); + add(GenericListReader.createReflexive(id, builderType, staticKeys)); + } + /** * Create {@link CompositeReaderRegistry} with Readers ordered according to submitted relationships. *

diff --git a/infra/translate-utils/pom.xml b/infra/translate-utils/pom.xml index db26ac4c6..d0431505e 100644 --- a/infra/translate-utils/pom.xml +++ b/infra/translate-utils/pom.xml @@ -72,6 +72,11 @@ junit test + + org.hamcrest + hamcrest-all + test + org.mockito mockito-core diff --git a/infra/translate-utils/src/main/java/io/fd/honeycomb/translate/util/read/ReflexiveListReaderCustomizer.java b/infra/translate-utils/src/main/java/io/fd/honeycomb/translate/util/read/ReflexiveListReaderCustomizer.java index 62dbcd6c9..b6430a355 100644 --- a/infra/translate-utils/src/main/java/io/fd/honeycomb/translate/util/read/ReflexiveListReaderCustomizer.java +++ b/infra/translate-utils/src/main/java/io/fd/honeycomb/translate/util/read/ReflexiveListReaderCustomizer.java @@ -16,31 +16,39 @@ package io.fd.honeycomb.translate.util.read; -import static com.google.common.base.Preconditions.checkArgument; - import com.google.common.base.Optional; +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; import io.fd.honeycomb.translate.spi.read.ListReaderCustomizer; import io.fd.honeycomb.translate.util.ReflectionUtils; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -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 javax.annotation.Nonnull; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Collections; +import java.util.List; + +import static com.google.common.base.Preconditions.*; /** * Might be slow. */ -public abstract class ReflexiveListReaderCustomizer, K extends Identifier, B extends Builder> +public class ReflexiveListReaderCustomizer, K extends Identifier, B extends Builder> extends ReflexiveReaderCustomizer implements ListReaderCustomizer { + private final List staticKeys; - public ReflexiveListReaderCustomizer(final Class typeClass, final Class builderClass) { + public ReflexiveListReaderCustomizer(@Nonnull final Class typeClass, @Nonnull final Class builderClass, + @Nonnull final List staticKeys) { super(typeClass, builderClass); + this.staticKeys = checkNotNull(staticKeys, "Static keys cannot be null"); + checkState(!this.staticKeys.isEmpty(), "No static keys provided"); } @Override @@ -62,4 +70,10 @@ public abstract class ReflexiveListReaderCustomizer getAllIds(@Nonnull InstanceIdentifier id, @Nonnull ReadContext context) throws ReadFailedException { + return staticKeys; + } } diff --git a/infra/translate-utils/src/test/java/io/fd/honeycomb/translate/util/read/ReflexiveListReaderCustomizerTest.java b/infra/translate-utils/src/test/java/io/fd/honeycomb/translate/util/read/ReflexiveListReaderCustomizerTest.java new file mode 100644 index 000000000..fe12ff699 --- /dev/null +++ b/infra/translate-utils/src/test/java/io/fd/honeycomb/translate/util/read/ReflexiveListReaderCustomizerTest.java @@ -0,0 +1,115 @@ +/* + * 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.read; + +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.*; + +import java.util.Arrays; +import java.util.List; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.hasSize; + +public class ReflexiveListReaderCustomizerTest { + + static class TestingListObject implements DataObject, Identifiable { + + private final TestingListKey key; + + TestingListObject(final TestingListKey key) { + this.key = key; + } + + @Override + public Class getImplementedInterface() { + return DataObject.class; + } + + @Override + public TestingListKey getKey() { + return key; + } + + static class TestingListKey implements Identifier { + + private final String value; + + TestingListKey(final String value) { + this.value = value; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + TestingListKey that = (TestingListKey) o; + + return value.equals(that.value); + } + + @Override + public int hashCode() { + return value.hashCode(); + } + } + } + + static class TestingListObjectBuilder implements Builder { + + private final TestingListObject.TestingListKey key; + + TestingListObjectBuilder(final TestingListObject.TestingListKey key) { + this.key = key; + } + + @Override + public TestingListObject build() { + return new TestingListObject(key); + } + } + + @Mock + private ReadContext readContext; + + @Before + public void init() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void testStaticKeys() throws ReadFailedException { + final TestingListObject.TestingListKey keyOne = new TestingListObject.TestingListKey("1"); + final TestingListObject.TestingListKey keyTwo = new TestingListObject.TestingListKey("2"); + final List staticKeys = Arrays.asList(keyOne, keyTwo); + + final ReflexiveListReaderCustomizer customizer + = new ReflexiveListReaderCustomizer<>(TestingListObject.class, TestingListObjectBuilder.class, staticKeys); + + final List allIds = customizer.getAllIds(InstanceIdentifier.create(TestingListObject.class), readContext); + + assertThat(allIds, hasSize(2)); + assertThat(allIds, contains(keyOne, keyTwo)); + } +} diff --git a/infra/translate-utils/src/test/java/io/fd/honeycomb/translate/util/read/ReflexiveReaderCustomizerTest.java b/infra/translate-utils/src/test/java/io/fd/honeycomb/translate/util/read/ReflexiveReaderCustomizerTest.java index 7fb67be6e..cf341a74e 100644 --- a/infra/translate-utils/src/test/java/io/fd/honeycomb/translate/util/read/ReflexiveReaderCustomizerTest.java +++ b/infra/translate-utils/src/test/java/io/fd/honeycomb/translate/util/read/ReflexiveReaderCustomizerTest.java @@ -16,26 +16,21 @@ package io.fd.honeycomb.translate.util.read; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verifyZeroInteractions; - import com.google.common.collect.Lists; import io.fd.honeycomb.translate.read.ReadContext; -import io.fd.honeycomb.translate.read.ReadFailedException; -import java.util.Collections; -import java.util.List; -import javax.annotation.Nonnull; import org.junit.Test; import org.mockito.Mock; import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.Augmentation; -import org.opendaylight.yangtools.yang.binding.DataContainer; -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.opendaylight.yangtools.yang.binding.*; + +import javax.annotation.Nonnull; +import java.util.Collections; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verifyZeroInteractions; public class ReflexiveReaderCustomizerTest { @@ -80,16 +75,7 @@ public class ReflexiveReaderCustomizerTest { final ReflexiveListReaderCustomizer reflexReaderCustomizer = new ReflexiveListReaderCustomizer - (TestingListObject.class, TestingListBuilder.class) { - - @Nonnull - @Override - public List getAllIds( - @Nonnull final InstanceIdentifier id, - @Nonnull final ReadContext context) throws ReadFailedException { - return Lists.newArrayList(); - } - }; + (TestingListObject.class, TestingListBuilder.class, Collections.singletonList(new TestingListObject.TestingListKey())); final TestingBuilderParent parentBuilder = new TestingBuilderParent(); final List readValue = Lists.newArrayList(new TestingListObject(), new TestingListObject()); -- cgit 1.2.3-korg