diff options
Diffstat (limited to 'infra/translate-impl/src/main')
4 files changed, 86 insertions, 48 deletions
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 f8290f166..4f7e1e140 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,8 +16,6 @@ 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; @@ -29,12 +27,6 @@ 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; @@ -43,6 +35,15 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.Nonnull; +import javax.annotation.concurrent.NotThreadSafe; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import static com.google.common.base.Preconditions.checkArgument; + @NotThreadSafe public final class CompositeReaderRegistryBuilder extends AbstractSubtreeManagerRegistryBuilderBuilder<Reader<? extends DataObject, ? extends Builder<?>>, ReaderRegistry> @@ -63,6 +64,11 @@ public final class CompositeReaderRegistryBuilder } @Override + protected Reader<? extends DataObject, ? extends Builder<?>> getWildcardedSubtreeHandler(@Nonnull Reader<? extends DataObject, ? extends Builder<?>> handler) { + throw new UnsupportedOperationException("Wildcarded readers are not supported"); + } + + @Override public <D extends DataObject> void addStructuralReader(@Nonnull InstanceIdentifier<D> id, @Nonnull Class<? extends Builder<D>> builderType) { // prevent case to submit structural reader for list, which would cause fail because target setter consumes diff --git a/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/registry/FlatWriterRegistry.java b/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/registry/FlatWriterRegistry.java index 146ddb9c5..c3bc1ee0e 100644 --- a/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/registry/FlatWriterRegistry.java +++ b/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/registry/FlatWriterRegistry.java @@ -21,7 +21,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.base.Optional; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; import com.google.common.collect.Multimap; import com.google.common.collect.Sets; @@ -32,12 +31,15 @@ import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.Writer; import io.fd.honeycomb.translate.write.registry.UpdateFailedException; import io.fd.honeycomb.translate.write.registry.WriterRegistry; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.annotation.concurrent.ThreadSafe; @@ -54,39 +56,23 @@ final class FlatWriterRegistry implements WriterRegistry { private static final Logger LOG = LoggerFactory.getLogger(FlatWriterRegistry.class); - // All types handled by writers directly or as children - private final ImmutableSet<InstanceIdentifier<?>> handledTypes; - private final Set<InstanceIdentifier<?>> writersOrderReversed; private final Set<InstanceIdentifier<?>> writersOrder; - private final Map<InstanceIdentifier<?>, Writer<?>> writers; + private final Map<InstanceIdentifier<?>, Writer<?>> writersById; + private final Set<? extends Writer<?>> writers; /** * Create flat registry instance. * - * @param writers immutable, ordered map of writers to use to process updates. Order of the writers has to be one in + * @param writersById immutable, ordered map of writers to use to process updates. Order of the writers has to be one in * which create and update operations should be handled. Deletes will be handled in reversed order. * All deletes are handled before handling all the updates. */ - FlatWriterRegistry(@Nonnull final ImmutableMap<InstanceIdentifier<?>, Writer<?>> writers) { - this.writers = writers; - this.writersOrderReversed = Sets.newLinkedHashSet(Lists.reverse(Lists.newArrayList(writers.keySet()))); - this.writersOrder = writers.keySet(); - this.handledTypes = getAllHandledTypes(writers); - } - - private static ImmutableSet<InstanceIdentifier<?>> getAllHandledTypes( - @Nonnull final ImmutableMap<InstanceIdentifier<?>, Writer<?>> writers) { - final ImmutableSet.Builder<InstanceIdentifier<?>> handledTypesBuilder = ImmutableSet.builder(); - for (Map.Entry<InstanceIdentifier<?>, Writer<?>> writerEntry : writers.entrySet()) { - final InstanceIdentifier<?> writerType = writerEntry.getKey(); - final Writer<?> writer = writerEntry.getValue(); - handledTypesBuilder.add(writerType); - if (writer instanceof SubtreeWriter) { - handledTypesBuilder.addAll(((SubtreeWriter<?>) writer).getHandledChildTypes()); - } - } - return handledTypesBuilder.build(); + FlatWriterRegistry(@Nonnull final ImmutableMap<InstanceIdentifier<?>, Writer<?>> writersById) { + this.writersById = writersById; + this.writersOrderReversed = Sets.newLinkedHashSet(Lists.reverse(Lists.newArrayList(writersById.keySet()))); + this.writersOrder = writersById.keySet(); + this.writers = writersById.entrySet().stream().map(Map.Entry::getValue).collect(Collectors.toSet()); } @Override @@ -145,9 +131,9 @@ final class FlatWriterRegistry implements WriterRegistry { if (writer == null) { // This node must be handled by a subtree writer, find it and call it or else fail - checkArgument(handledTypes.contains(singleType), "Unable to process update. Missing writers for: %s", - singleType); writer = getSubtreeWriterResponsible(singleType); + checkArgument(writer != null, "Unable to process update. Missing writers for: %s", + singleType); singleTypeUpdates = getParentDataObjectUpdate(ctx, updates, writer); } @@ -168,9 +154,9 @@ final class FlatWriterRegistry implements WriterRegistry { @Nullable private Writer<?> getSubtreeWriterResponsible(final InstanceIdentifier<?> singleType) { - return writers.values().stream() + return writersById.values().stream() .filter(w -> w instanceof SubtreeWriter) - .filter(w -> ((SubtreeWriter<?>) w).getHandledChildTypes().contains(singleType)) + .filter(w -> w.canProcess(singleType)) .findFirst() .orElse(null); } @@ -249,10 +235,23 @@ final class FlatWriterRegistry implements WriterRegistry { private void checkAllTypesCanBeHandled( @Nonnull final Multimap<InstanceIdentifier<?>, ? extends DataObjectUpdate> updates) { - if (!handledTypes.containsAll(updates.keySet())) { - final Sets.SetView<InstanceIdentifier<?>> missingWriters = Sets.difference(updates.keySet(), handledTypes); - LOG.warn("Unable to process update. Missing writers for: {}", missingWriters); - throw new IllegalArgumentException("Unable to process update. Missing writers for: " + missingWriters); + + List<InstanceIdentifier<?>> noWriterNodes = new ArrayList<>(); + for (InstanceIdentifier<?> id : updates.keySet()) { + // either there is direct writer for the iid + if (writersById.containsKey(id)) { + continue; + } else { + // or subtree one + if (writers.stream().anyMatch(o -> o.canProcess(id))) { + continue; + } + } + noWriterNodes.add(id); + } + + if (!noWriterNodes.isEmpty()) { + throw new IllegalArgumentException("Unable to process update. Missing writers for: " + noWriterNodes); } } @@ -269,7 +268,7 @@ final class FlatWriterRegistry implements WriterRegistry { @Nullable private Writer<?> getWriter(@Nonnull final InstanceIdentifier<?> singleType) { - return writers.get(singleType); + return writersById.get(singleType); } } 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 0c6d0a1b4..43606064e 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 @@ -24,15 +24,16 @@ 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; -import javax.annotation.concurrent.NotThreadSafe; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.Nonnull; +import javax.annotation.concurrent.NotThreadSafe; +import java.util.Set; +import java.util.stream.Collectors; + /** * Builder for {@link FlatWriterRegistry} allowing users to specify inter-writer relationships. */ @@ -53,6 +54,11 @@ public final class FlatWriterRegistryBuilder return SubtreeWriter.createForWriter(handledChildren, writer); } + @Override + protected Writer<? extends DataObject> getWildcardedSubtreeHandler(@Nonnull Writer<? extends DataObject> handler) { + return SubtreeWriter.createWildcardedForWriter(handler); + } + /** * Create FlatWriterRegistry with writers ordered according to submitted relationships. */ diff --git a/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/registry/SubtreeWriter.java b/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/registry/SubtreeWriter.java index b2a571b40..a1a5f3fd0 100644 --- a/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/registry/SubtreeWriter.java +++ b/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/registry/SubtreeWriter.java @@ -37,15 +37,16 @@ final class SubtreeWriter<D extends DataObject> implements Writer<D> { private final Writer<D> delegate; private final Set<InstanceIdentifier<?>> handledChildTypes = new HashSet<>(); + private boolean isWildcarded = false; - private SubtreeWriter(final Writer<D> delegate, Set<InstanceIdentifier<?>> handledTypes) { + private SubtreeWriter(final Writer<D> delegate, final Set<InstanceIdentifier<?>> handledTypes) { this.delegate = delegate; for (InstanceIdentifier<?> handledType : handledTypes) { // Iid has to start with writer'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); + + "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( @@ -53,6 +54,11 @@ final class SubtreeWriter<D extends DataObject> implements Writer<D> { } } + private SubtreeWriter(final Writer<D> delegate) { + this.delegate = delegate; + this.isWildcarded = true; + } + /** * Return set of types also handled by this writer. All of the types are children of the type managed by this * writer excluding the type of this writer. @@ -75,6 +81,20 @@ final class SubtreeWriter<D extends DataObject> implements Writer<D> { } @Override + public boolean canProcess(@Nonnull InstanceIdentifier<?> instanceIdentifier) { + if (isWildcarded) { + final Class<D> parent = delegate.getManagedDataObjectType().getTargetType(); + for (InstanceIdentifier.PathArgument pathArgument : instanceIdentifier.getPathArguments()) { + if (pathArgument.getType().equals(parent)) { + return true; + } + } + return false; + } + return handledChildTypes.contains(instanceIdentifier); + } + + @Override @Nonnull public InstanceIdentifier<D> getManagedDataObjectType() { return delegate.getManagedDataObjectType(); @@ -87,4 +107,11 @@ final class SubtreeWriter<D extends DataObject> implements Writer<D> { @Nonnull final Writer<? extends DataObject> writer) { return new SubtreeWriter<>(writer, handledChildren); } + + /** + * Wrap a writer as a subtree writer. + */ + static Writer<?> createWildcardedForWriter(@Nonnull final Writer<? extends DataObject> writer) { + return new SubtreeWriter<>(writer); + } } |