diff options
Diffstat (limited to 'v3po/impl/src/main/java')
8 files changed, 132 insertions, 90 deletions
diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppOperationalDataTree.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppOperationalDataTree.java index c378365f3..3fddd108c 100644 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppOperationalDataTree.java +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppOperationalDataTree.java @@ -28,7 +28,6 @@ import com.google.common.util.concurrent.CheckedFuture; import com.google.common.util.concurrent.Futures; import io.fd.honeycomb.v3po.impl.trans.r.ReaderRegistry; import java.util.Collection; -import java.util.List; import java.util.Map; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -90,21 +89,17 @@ public final class VppOperationalDataTree implements ReadableVppDataTree { LOG.debug("VppOperationalDataProxy.read(), yangInstanceIdentifier={}", yangInstanceIdentifier); final InstanceIdentifier<?> path = serializer.fromYangInstanceIdentifier(yangInstanceIdentifier); - if (path == null) { - // TODO try to translate wildcarded identifiers here as a workaround if it is expected to be used that way - // Currently its not possible to read list using wildcarded ID. SO we may not need this at all. - } checkNotNull(path, "Invalid instance identifier %s. Cannot create BA equivalent.", yangInstanceIdentifier); LOG.debug("VppOperationalDataProxy.read(), path={}", path); - final List<? extends DataObject> dataObjects = readerRegistry.read(path); + final Optional<? extends DataObject> dataObject = readerRegistry.read(path); - if (dataObjects.isEmpty()) { - return Futures.immediateCheckedFuture(Optional.<NormalizedNode<?, ?>>absent()); + if (dataObject.isPresent()) { + final NormalizedNode<?, ?> value = toNormalizedNodeFunction(path).apply(dataObject.get()); + return Futures.immediateCheckedFuture(Optional.<NormalizedNode<?, ?>>fromNullable(value)); } - final NormalizedNode<?, ?> value = wrapDataObjects(yangInstanceIdentifier, path, dataObjects); - return Futures.immediateCheckedFuture(Optional.<NormalizedNode<?, ?>>fromNullable(value)); + return Futures.immediateCheckedFuture(Optional.<NormalizedNode<?, ?>>absent()); } private DataSchemaNode getSchemaNode(final @Nonnull YangInstanceIdentifier yangInstanceIdentifier) { @@ -175,7 +170,7 @@ public final class VppOperationalDataTree implements ReadableVppDataTree { public NormalizedNode<?, ?> apply(@Nullable final DataObject dataObject) { LOG.trace("VppOperationalDataProxy.toNormalizedNode(), path={}, dataObject={}", path, dataObject); final Map.Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> entry = - serializer.toNormalizedNode(path, dataObject); + serializer.toNormalizedNode(path, dataObject); LOG.trace("VppOperationalDataProxy.toNormalizedNode(), normalizedNodeEntry={}", entry); return entry.getValue(); diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppReaderRegistry.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppReaderRegistry.java index c5d4a8194..df7b6568c 100644 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppReaderRegistry.java +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/data/VppReaderRegistry.java @@ -16,6 +16,7 @@ package io.fd.honeycomb.v3po.impl.data; +import com.google.common.base.Optional; import com.google.common.collect.Multimap; import io.fd.honeycomb.v3po.impl.trans.r.ChildVppReader; import io.fd.honeycomb.v3po.impl.trans.r.ReaderRegistry; @@ -100,7 +101,7 @@ public class VppReaderRegistry implements ReaderRegistry { @Nonnull @Override - public List<? extends DataObject> read(@Nonnull final InstanceIdentifier<? extends DataObject> id) { + public Optional<? extends DataObject> read(@Nonnull final InstanceIdentifier<? extends DataObject> id) { return reader.read(id); } diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/ListVppReader.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/ListVppReader.java new file mode 100644 index 000000000..8a7f29cb3 --- /dev/null +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/ListVppReader.java @@ -0,0 +1,44 @@ +/* + * 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.impl.trans.r; + +import com.google.common.annotations.Beta; +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; + +/** + * List VPP reader, allowing read of all the elements + * + * @param <D> Specific DataObject derived type, that is handled by this reader + */ +@Beta +public interface ListVppReader<D extends DataObject & Identifiable<K>, K extends Identifier<D>> extends VppReader<D> { + + /** + * Read all elements in this list + * + * @param id Wildcarded identifier of list managed by this reader + * + * @return List of all entries in this list + */ + @Nonnull + List<D> readList(@Nonnull final InstanceIdentifier<D> id); +} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/VppReader.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/VppReader.java index 8af493854..1cc76a3a4 100644 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/VppReader.java +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/VppReader.java @@ -17,8 +17,8 @@ package io.fd.honeycomb.v3po.impl.trans.r; import com.google.common.annotations.Beta; +import com.google.common.base.Optional; import io.fd.honeycomb.v3po.impl.trans.SubtreeManager; -import java.util.List; import javax.annotation.Nonnull; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; @@ -44,6 +44,6 @@ public interface VppReader<D extends DataObject> extends SubtreeManager<D> { * @return List of DataObjects identified by id. If the ID points to a single node, it will be wrapped in a list */ @Nonnull - List<? extends DataObject> read(@Nonnull final InstanceIdentifier<? extends DataObject> id); + Optional<? extends DataObject> read(@Nonnull final InstanceIdentifier<? extends DataObject> id); } diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/AbstractCompositeVppReader.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/AbstractCompositeVppReader.java index 511192483..61f318b35 100644 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/AbstractCompositeVppReader.java +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/AbstractCompositeVppReader.java @@ -16,11 +16,12 @@ package io.fd.honeycomb.v3po.impl.trans.r.impl; +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.Collections2; -import com.google.common.collect.Lists; +import com.google.common.collect.Iterables; import io.fd.honeycomb.v3po.impl.trans.r.ChildVppReader; import io.fd.honeycomb.v3po.impl.trans.r.VppReader; import io.fd.honeycomb.v3po.impl.trans.util.ReflectionUtils; @@ -67,7 +68,7 @@ abstract class AbstractCompositeVppReader<D extends DataObject, B extends Builde /** * @param id {@link InstanceIdentifier} pointing to current node. In case of keyed list, key must be present. */ - protected List<D> readCurrent(final InstanceIdentifier<D> id) { + protected Optional<D> readCurrent(final InstanceIdentifier<D> id) { 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 @@ -89,9 +90,9 @@ abstract class AbstractCompositeVppReader<D extends DataObject, B extends Builde // Need to check whether anything was filled in to determine if data is present or not. final D built = builder.build(); - final List<D> read = built.equals(emptyValue) - ? Collections.<D>emptyList() - : Collections.singletonList(built); + final Optional<D> read = built.equals(emptyValue) + ? Optional.<D>absent() + : Optional.of(built); LOG.debug("{}: Current node read successfully. Result: {}", this, read); return read; @@ -100,7 +101,7 @@ abstract class AbstractCompositeVppReader<D extends DataObject, B extends Builde @Nonnull @Override @SuppressWarnings("unchecked") - public List<? extends DataObject> read(@Nonnull final InstanceIdentifier<? extends DataObject> id) { + public Optional<? extends DataObject> read(@Nonnull final InstanceIdentifier<? extends DataObject> id) { LOG.trace("{}: Reading : {}", this, id); if (id.getTargetType().equals(getManagedDataObjectType().getTargetType())) { return readCurrent((InstanceIdentifier<D>) id); @@ -109,7 +110,7 @@ abstract class AbstractCompositeVppReader<D extends DataObject, B extends Builde } } - private List<? extends DataObject> readSubtree(final InstanceIdentifier<? extends DataObject> id) { + private Optional<? extends DataObject> readSubtree(final InstanceIdentifier<? extends DataObject> id) { LOG.debug("{}: Reading subtree: {}", this, id); final Class<? extends DataObject> next = VppRWUtils.getNextId(id, getManagedDataObjectType()).getType(); final ChildVppReader<? extends ChildOf<D>> vppReader = childReaders.get(next); @@ -121,11 +122,11 @@ abstract class AbstractCompositeVppReader<D extends DataObject, B extends Builde 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 = VppRWUtils.cutId(id, getManagedDataObjectType()); - final List<D> current = readCurrent(currentId); + final Optional<D> current = readCurrent(currentId); // then perform post-reading filtering (return only requested sub-node) - final List<? extends DataObject> readSubtree = current.isEmpty() - ? current - : filterSubtree(current, id, getManagedDataObjectType().getTargetType()); + 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; @@ -150,65 +151,59 @@ abstract class AbstractCompositeVppReader<D extends DataObject, B extends Builde // TODO move filtering out of here into a dedicated Filter ifc @Nonnull - private static List<? extends DataObject> filterSubtree(@Nonnull final List<? extends DataObject> built, + private static Optional<? extends DataObject> filterSubtree(@Nonnull final DataObject parent, @Nonnull final InstanceIdentifier<? extends DataObject> absolutPath, @Nonnull final Class<?> managedType) { // TODO is there a better way than reflection ? e.g. convert into NN and filter out with a utility // FIXME this needs to be recursive. right now it expects only 1 additional element in ID + test - List<DataObject> filtered = Lists.newArrayList(); - for (DataObject parent : built) { - final InstanceIdentifier.PathArgument nextId = - VppRWUtils.getNextId(absolutPath, InstanceIdentifier.create(parent.getClass())); + final InstanceIdentifier.PathArgument nextId = + VppRWUtils.getNextId(absolutPath, InstanceIdentifier.create(parent.getClass())); + + Optional<Method> method = ReflectionUtils.findMethodReflex(managedType, "get", + Collections.<Class<?>>emptyList(), nextId.getType()); - 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()) { - filterSingle(filtered, parent, nextId, method); + return filterList(parent, nextId, method.get()); } else { - // List child nodes - method = ReflectionUtils.findMethodReflex(managedType, - "get" + nextId.getType().getSimpleName(), Collections.<Class<?>>emptyList(), List.class); - - if (method.isPresent()) { - filterList(filtered, parent, nextId, method); - } else { - throw new IllegalStateException( - "Unable to filter " + nextId + " from " + parent + " getters not found using reflexion"); - } + throw new IllegalStateException( + "Unable to filter " + nextId + " from " + parent + " getters not found using reflexion"); } } - - return filtered; } @SuppressWarnings("unchecked") - private static void filterList(final List<DataObject> filtered, final DataObject parent, - final InstanceIdentifier.PathArgument nextId, final Optional<Method> method) { - final List<? extends DataObject> invoke = (List<? extends DataObject>)invoke(method.get(), nextId, parent); - - if (nextId instanceof InstanceIdentifier.IdentifiableItem<?, ?>) { - final Identifier key = ((InstanceIdentifier.IdentifiableItem) nextId).getKey(); - filtered.addAll(Collections2.filter(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); - } - })); - } else { - filtered.addAll(invoke); - } + 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 void filterSingle(final List<DataObject> filtered, final DataObject parent, - final InstanceIdentifier.PathArgument nextId, final Optional<Method> method) { - filtered.add(nextId.getType().cast(invoke(method.get(), nextId, parent))); + 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, diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/CompositeChildVppReader.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/CompositeChildVppReader.java index 8f425b09f..a64a72bc4 100644 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/CompositeChildVppReader.java +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/CompositeChildVppReader.java @@ -79,8 +79,7 @@ public final class CompositeChildVppReader<C extends DataObject, B extends Build @Override public final void read(@Nonnull final InstanceIdentifier<? extends DataObject> parentId, @Nonnull final Builder<? extends DataObject> parentBuilder) { - final Optional<C> read = Optional.fromNullable(readCurrent(VppRWUtils.appendTypeToId(parentId, - getManagedDataObjectType())).get(0)); + final Optional<C> read = readCurrent(VppRWUtils.appendTypeToId(parentId, getManagedDataObjectType())); if(read.isPresent()) { customizer.merge(parentBuilder, read.get()); diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/CompositeListVppReader.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/CompositeListVppReader.java index 8d23aa4e0..7e3d8452e 100644 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/CompositeListVppReader.java +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/CompositeListVppReader.java @@ -17,10 +17,11 @@ package io.fd.honeycomb.v3po.impl.trans.r.impl; import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkState; import com.google.common.annotations.Beta; +import com.google.common.base.Optional; import io.fd.honeycomb.v3po.impl.trans.r.ChildVppReader; +import io.fd.honeycomb.v3po.impl.trans.r.ListVppReader; import io.fd.honeycomb.v3po.impl.trans.r.impl.spi.ListVppReaderCustomizer; import io.fd.honeycomb.v3po.impl.trans.util.VppRWUtils; import java.util.ArrayList; @@ -47,7 +48,8 @@ import org.slf4j.LoggerFactory; @Beta @ThreadSafe public final class CompositeListVppReader<C extends DataObject & Identifiable<K>, K extends Identifier<C>, B extends Builder<C>> - extends AbstractCompositeVppReader<C, B> implements ChildVppReader<C> { + extends AbstractCompositeVppReader<C, B> implements ChildVppReader<C>, ListVppReader<C, K> +{ private static final Logger LOG = LoggerFactory.getLogger(CompositeListVppReader.class); @@ -89,11 +91,6 @@ public final class CompositeListVppReader<C extends DataObject & Identifiable<K> } @Override - protected List<C> readCurrent(@Nonnull final InstanceIdentifier<C> id) { - return shouldReadAll(id) ? readList(id) : super.readCurrent(id); - } - - @Override public void read(@Nonnull final InstanceIdentifier<? extends DataObject> id, @Nonnull final Builder<? extends DataObject> parentBuilder) { // Create ID pointing to current node @@ -103,7 +100,9 @@ public final class CompositeListVppReader<C extends DataObject & Identifiable<K> customizer.merge(parentBuilder, ifcs); } - private List<C> readList(@Nonnull final InstanceIdentifier<C> id) { + @Override + @Nonnull + public List<C> readList(@Nonnull final InstanceIdentifier<C> id) { LOG.trace("{}: Reading all list entries", this); final List<K> allIds = customizer.getAllIds(id); LOG.debug("{}: Reading list entries for: {}", this, allIds); @@ -113,20 +112,14 @@ public final class CompositeListVppReader<C extends DataObject & Identifiable<K> final InstanceIdentifier.IdentifiableItem<C, K> currentBdItem = VppRWUtils.getCurrentIdItem(id, key); final InstanceIdentifier<C> keyedId = VppRWUtils.replaceLastInId(id, currentBdItem); - final List<? extends DataObject> read = readCurrent(keyedId); - checkState(read.size() == 1); - final DataObject singleItem = read.get(0); + final Optional<C> read = readCurrent(keyedId); + final DataObject singleItem = read.get(); checkArgument(getManagedDataObjectType().getTargetType().isAssignableFrom(singleItem.getClass())); allEntries.add(getManagedDataObjectType().getTargetType().cast(singleItem)); } return allEntries; } - private boolean shouldReadAll(@Nonnull final InstanceIdentifier<? extends DataObject> id) { - final InstanceIdentifier instanceIdentifier = id.firstIdentifierOf(getManagedDataObjectType().getTargetType()); - return instanceIdentifier == null || instanceIdentifier.isWildcarded(); - } - @Override protected void readCurrentAttributes(@Nonnull final InstanceIdentifier<C> id, @Nonnull final B builder) { customizer.readCurrentAttributes(id, builder); diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/DelegatingReaderRegistry.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/DelegatingReaderRegistry.java index 4e50e5aa8..0777425b2 100644 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/DelegatingReaderRegistry.java +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/DelegatingReaderRegistry.java @@ -18,12 +18,15 @@ package io.fd.honeycomb.v3po.impl.trans.r.util; import static com.google.common.base.Preconditions.checkNotNull; +import com.google.common.base.Optional; import com.google.common.collect.Iterables; import com.google.common.collect.LinkedListMultimap; import com.google.common.collect.Multimap; +import io.fd.honeycomb.v3po.impl.trans.r.ListVppReader; import io.fd.honeycomb.v3po.impl.trans.r.ReaderRegistry; import io.fd.honeycomb.v3po.impl.trans.r.VppReader; import io.fd.honeycomb.v3po.impl.trans.util.VppRWUtils; +import java.util.Collections; import java.util.List; import java.util.Map; import javax.annotation.Nonnull; @@ -62,15 +65,27 @@ public final class DelegatingReaderRegistry implements ReaderRegistry { final Multimap<InstanceIdentifier<? extends DataObject>, DataObject> objects = LinkedListMultimap.create(); for (VppReader<? extends DataObject> rootReader : rootReaders.values()) { LOG.debug("Reading from delegate: {}", rootReader); - final List<? extends DataObject> read = rootReader.read(rootReader.getManagedDataObjectType()); - objects.putAll(rootReader.getManagedDataObjectType(), read); + + if(rootReader instanceof ListVppReader) { + final List<? extends DataObject> listEntries = + ((ListVppReader) rootReader).readList(rootReader.getManagedDataObjectType()); + if(!listEntries.isEmpty()) { + objects.putAll(rootReader.getManagedDataObjectType(), listEntries); + } + } else { + final Optional<? extends DataObject> read = rootReader.read(rootReader.getManagedDataObjectType()); + if(read.isPresent()) { + objects.putAll(rootReader.getManagedDataObjectType(), Collections.singletonList(read.get())); + } + } } + return objects; } @Nonnull @Override - public List<? extends DataObject> read(@Nonnull final InstanceIdentifier<? extends DataObject> id) { + public Optional<? extends DataObject> read(@Nonnull final InstanceIdentifier<? extends DataObject> id) { final InstanceIdentifier.PathArgument first = checkNotNull( Iterables.getFirst(id.getPathArguments(), null), "Empty id"); final VppReader<? extends DataObject> vppReader = rootReaders.get(first.getType()); |