From 691e4695f547b3f12d13f38b730a814414904fb3 Mon Sep 17 00:00:00 2001 From: Maros Marsalek Date: Mon, 21 Mar 2016 15:01:02 +0100 Subject: Add dedicated package for readers Change-Id: Ic85bba0086a58ef53697a1ebf5542b3a7c28be53 Signed-off-by: Maros Marsalek --- .../honeycomb/v3po/impl/trans/ChildVppReader.java | 46 ----- .../honeycomb/v3po/impl/trans/ReaderRegistry.java | 35 ---- .../honeycomb/v3po/impl/trans/SubtreeManager.java | 39 ---- .../io/fd/honeycomb/v3po/impl/trans/VppReader.java | 48 ----- .../trans/impl/AbstractCompositeVppReader.java | 206 --------------------- .../impl/trans/impl/CompositeChildVppReader.java | 100 ---------- .../impl/trans/impl/CompositeListVppReader.java | 134 -------------- .../impl/trans/impl/CompositeRootVppReader.java | 88 --------- .../trans/impl/spi/ChildVppReaderCustomizer.java | 38 ---- .../trans/impl/spi/ListVppReaderCustomizer.java | 47 ----- .../trans/impl/spi/RootVppReaderCustomizer.java | 43 ----- .../v3po/impl/trans/r/ChildVppReader.java | 46 +++++ .../v3po/impl/trans/r/ReaderRegistry.java | 35 ++++ .../v3po/impl/trans/r/SubtreeManager.java | 39 ++++ .../fd/honeycomb/v3po/impl/trans/r/VppReader.java | 48 +++++ .../trans/r/impl/AbstractCompositeVppReader.java | 206 +++++++++++++++++++++ .../impl/trans/r/impl/CompositeChildVppReader.java | 100 ++++++++++ .../impl/trans/r/impl/CompositeListVppReader.java | 134 ++++++++++++++ .../impl/trans/r/impl/CompositeRootVppReader.java | 88 +++++++++ .../trans/r/impl/spi/ChildVppReaderCustomizer.java | 38 ++++ .../trans/r/impl/spi/ListVppReaderCustomizer.java | 47 +++++ .../trans/r/impl/spi/RootVppReaderCustomizer.java | 43 +++++ .../trans/r/util/DelegatingReaderRegistry.java | 82 ++++++++ .../impl/trans/r/util/NoopReaderCustomizer.java | 30 +++ .../v3po/impl/trans/r/util/ReflectionUtils.java | 79 ++++++++ .../r/util/ReflexiveChildReaderCustomizer.java | 56 ++++++ .../r/util/ReflexiveRootReaderCustomizer.java | 42 +++++ .../impl/trans/r/util/VppApiReaderCustomizer.java | 41 ++++ .../v3po/impl/trans/r/util/VppRWUtils.java | 164 ++++++++++++++++ .../impl/trans/util/DelegatingReaderRegistry.java | 82 -------- .../v3po/impl/trans/util/NoopReaderCustomizer.java | 30 --- .../v3po/impl/trans/util/ReflectionUtils.java | 79 -------- .../trans/util/ReflexiveChildReaderCustomizer.java | 56 ------ .../trans/util/ReflexiveRootReaderCustomizer.java | 42 ----- .../impl/trans/util/VppApiReaderCustomizer.java | 41 ---- .../honeycomb/v3po/impl/trans/util/VppRWUtils.java | 164 ---------------- .../v3po/impl/vppstate/BridgeDomainCustomizer.java | 5 +- .../v3po/impl/vppstate/VersionCustomizer.java | 4 +- .../io/fd/honeycomb/v3po/impl/vppstate/BdTest.java | 6 +- .../v3po/impl/vppstate/VppStateUtils.java | 14 +- 40 files changed, 1333 insertions(+), 1332 deletions(-) delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/ChildVppReader.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/ReaderRegistry.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/SubtreeManager.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/VppReader.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/impl/AbstractCompositeVppReader.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/impl/CompositeChildVppReader.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/impl/CompositeListVppReader.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/impl/CompositeRootVppReader.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/impl/spi/ChildVppReaderCustomizer.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/impl/spi/ListVppReaderCustomizer.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/impl/spi/RootVppReaderCustomizer.java create mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/ChildVppReader.java create mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/ReaderRegistry.java create mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/SubtreeManager.java create mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/VppReader.java create mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/AbstractCompositeVppReader.java create mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/CompositeChildVppReader.java create mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/CompositeListVppReader.java create mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/CompositeRootVppReader.java create mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/spi/ChildVppReaderCustomizer.java create mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/spi/ListVppReaderCustomizer.java create mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/spi/RootVppReaderCustomizer.java create mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/DelegatingReaderRegistry.java create mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/NoopReaderCustomizer.java create mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/ReflectionUtils.java create mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/ReflexiveChildReaderCustomizer.java create mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/ReflexiveRootReaderCustomizer.java create mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/VppApiReaderCustomizer.java create mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/VppRWUtils.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/DelegatingReaderRegistry.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/NoopReaderCustomizer.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/ReflectionUtils.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/ReflexiveChildReaderCustomizer.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/ReflexiveRootReaderCustomizer.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/VppApiReaderCustomizer.java delete mode 100644 v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/VppRWUtils.java (limited to 'v3po') diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/ChildVppReader.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/ChildVppReader.java deleted file mode 100644 index 040c8fdef..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/ChildVppReader.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.v3po.impl.trans; - -import com.google.common.annotations.Beta; -import javax.annotation.Nonnull; -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -/** - * Child VPP reader allowing its parent to pass the builder object - * - * @param Specific DataObject derived type, that is handled by this reader - */ -@Beta -public interface ChildVppReader extends VppReader { - - /** - * Reads subtree starting from node managed by this reader and place the subtree within parent builder object if the - * data exists. - * - * @param id Unique identifier pointing to the node managed by this reader. Useful when necessary to - * determine the exact position within more complex subtrees. - * @param parentBuilder Builder of parent DataObject. Objects read on this level (if any) must be placed into the - * parent builder. - */ - void read(@Nonnull final InstanceIdentifier id, - @Nonnull final Builder parentBuilder); - -} - diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/ReaderRegistry.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/ReaderRegistry.java deleted file mode 100644 index 54809c98e..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/ReaderRegistry.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.v3po.impl.trans; - -import com.google.common.annotations.Beta; -import java.util.List; -import javax.annotation.Nonnull; -import org.opendaylight.yangtools.yang.binding.DataObject; - -/** - * Simple delegating reader suitable as a holder for all other root readers, providing readAll feature - */ -@Beta -public interface ReaderRegistry extends VppReader { - - /** - * Perform read on all underlying readers and merge the results into a single list - */ - @Nonnull - List readAll(); -} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/SubtreeManager.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/SubtreeManager.java deleted file mode 100644 index 0aa927cd0..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/SubtreeManager.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.v3po.impl.trans; - -import com.google.common.annotations.Beta; -import javax.annotation.Nonnull; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -/** - * Base identifiable subtree manager(reader, writer etc.) - * - * @param Specific DataObject derived type, that is managed by this manager - */ -@Beta -public interface SubtreeManager { - - /** - * Gets the type of node managed by this reader - * - * @return Class object for node managed by this reader - */ - @Nonnull - InstanceIdentifier getManagedDataObjectType(); -} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/VppReader.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/VppReader.java deleted file mode 100644 index c8c13f65a..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/VppReader.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.v3po.impl.trans; - -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.InstanceIdentifier; - -/** - * Base VPP reader, responsible for translation between DataObjects and VPP APIs - * - * @param Specific DataObject derived type, that is handled by this reader - */ -@Beta -public interface VppReader extends SubtreeManager { - - // TODO add vpp read context that will be shared by all readers during a single read to keep useful information - // preventing possible duplicate reads from VPP - // TODO make async - - /** - * Reads from VPP data identified by id - * - * @param id unique identifier of subtree to be read. The subtree must contain managed data object type. For - * identifiers pointing below node managed by this reader, it's reader's responsibility to filter out the - * right node or to delegate the read to a child reader. - * @return List of DataObjects identified by id. If the ID points to a single node, it will be wrapped in a list - */ - @Nonnull - List read(@Nonnull final InstanceIdentifier id); - -} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/impl/AbstractCompositeVppReader.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/impl/AbstractCompositeVppReader.java deleted file mode 100644 index 121d50dcb..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/impl/AbstractCompositeVppReader.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.v3po.impl.trans.impl; - -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 io.fd.honeycomb.v3po.impl.trans.ChildVppReader; -import io.fd.honeycomb.v3po.impl.trans.VppReader; -import io.fd.honeycomb.v3po.impl.trans.util.ReflectionUtils; -import io.fd.honeycomb.v3po.impl.trans.util.VppRWUtils; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.Augmentation; -import org.opendaylight.yangtools.yang.binding.ChildOf; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.Identifier; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -@Beta -abstract class AbstractCompositeVppReader> implements VppReader { - - // TODO add debug + trace logs here and there - - private final Map, ChildVppReader>> childReaders; - private final Map, ChildVppReader>> augReaders; - private final InstanceIdentifier instanceIdentifier; - - AbstractCompositeVppReader(final Class managedDataObjectType, - final List>> childReaders, - final List>> augReaders) { - this.childReaders = VppRWUtils.uniqueLinkedIndex(childReaders, VppRWUtils.MANAGER_CLASS_FUNCTION); - this.augReaders = VppRWUtils.uniqueLinkedIndex(augReaders, VppRWUtils.MANAGER_CLASS_AUG_FUNCTION); - this.instanceIdentifier = InstanceIdentifier.create(managedDataObjectType); - } - - @Nonnull - @Override - public final InstanceIdentifier getManagedDataObjectType() { - return instanceIdentifier; - } - - /** - * @param id {@link InstanceIdentifier} pointing to current node. In case of keyed list, key must be present. - */ - protected List readCurrent(final InstanceIdentifier id) { - final B builder = getBuilder(id); - // Cache empty value to determine if anything has changed later TODO cache in a field - final D emptyValue = builder.build(); - - readCurrentAttributes(id, builder); - - // TODO expect exceptions from reader - for (ChildVppReader> child : childReaders.values()) { - child.read(id, builder); - } - - for (ChildVppReader> child : augReaders.values()) { - child.read(id, builder); - } - - // Need to check whether anything was filled in to determine if data is present or not. - final D built = builder.build(); - return built.equals(emptyValue) ? Collections.emptyList() : Collections.singletonList(built); - } - - @Nonnull - @Override - @SuppressWarnings("unchecked") - public List read(@Nonnull final InstanceIdentifier id) { - // This is read for one of children, we need to read and then filter, not parent) - - // If this is target, just read - if (id.getTargetType().equals(getManagedDataObjectType().getTargetType())) { - return readCurrent((InstanceIdentifier) id); - } else { - return readSubtree(id); - } - } - - private List readSubtree(final InstanceIdentifier id) { - // Read only specific subtree - final Class next = VppRWUtils.getNextId(id, getManagedDataObjectType()).getType(); - final ChildVppReader> vppReader = childReaders.get(next); - - if (vppReader != null) { - return vppReader.read(id); - } else { - // If there's no dedicated reader, use read current - final InstanceIdentifier currentId = VppRWUtils.cutId(id, getManagedDataObjectType()); - final List current = readCurrent(currentId); - // then perform post-reading filtering (return only requested sub-node) - return current.isEmpty() ? current : filterSubtree(current, id, getManagedDataObjectType().getTargetType()) ; - } - } - - /** - * Fill in current node's attributes - * - * @param id {@link InstanceIdentifier} pointing to current node. In case of keyed list, key must be present. - * @param builder Builder object for current node where the read attributes must be placed - */ - protected abstract void readCurrentAttributes(final InstanceIdentifier id, B builder); - - /** - * Return new instance of a builder object for current node - * - * @param id {@link InstanceIdentifier} pointing to current node. In case of keyed list, key must be present. - * @return Builder object for current node type - */ - protected abstract B getBuilder(InstanceIdentifier id); - - // TODO move filtering out of here into a dedicated Filter ifc - @Nonnull - private static List filterSubtree(@Nonnull final List built, - @Nonnull final InstanceIdentifier 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 filtered = Lists.newArrayList(); - for (DataObject parent : built) { - final InstanceIdentifier.PathArgument nextId = - VppRWUtils.getNextId(absolutPath, InstanceIdentifier.create(parent.getClass())); - - Optional method = ReflectionUtils.findMethodReflex(managedType, "get", - Collections.>emptyList(), nextId.getType()); - - if (method.isPresent()) { - filterSingle(filtered, parent, nextId, method); - } else { - // List child nodes - method = ReflectionUtils.findMethodReflex(managedType, - "get" + nextId.getType().getSimpleName(), Collections.>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"); - } - } - } - - return filtered; - } - - @SuppressWarnings("unchecked") - private static void filterList(final List filtered, final DataObject parent, - final InstanceIdentifier.PathArgument nextId, final Optional method) { - final List invoke = (List)invoke(method.get(), nextId, parent); - - if (nextId instanceof InstanceIdentifier.IdentifiableItem) { - final Identifier key = ((InstanceIdentifier.IdentifiableItem) nextId).getKey(); - filtered.addAll(Collections2.filter(invoke, new Predicate() { - @Override - public boolean apply(@Nullable final DataObject input) { - final Optional keyGetter = - ReflectionUtils.findMethodReflex(nextId.getType(), "get", - Collections.>emptyList(), key.getClass()); - final Object actualKey; - actualKey = invoke(keyGetter.get(), nextId, input); - return key.equals(actualKey); - } - })); - } else { - filtered.addAll(invoke); - } - } - - private static void filterSingle(final List filtered, final DataObject parent, - final InstanceIdentifier.PathArgument nextId, final Optional method) { - filtered.add(nextId.getType().cast(invoke(method.get(), nextId, parent))); - } - - private static Object invoke(final Method method, - final InstanceIdentifier.PathArgument nextId, final DataObject parent) { - try { - return method.invoke(parent); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new IllegalArgumentException("Unable to get " + nextId + " from " + parent, e); - } - } -} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/impl/CompositeChildVppReader.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/impl/CompositeChildVppReader.java deleted file mode 100644 index e1dac48b3..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/impl/CompositeChildVppReader.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.v3po.impl.trans.impl; - -import com.google.common.annotations.Beta; -import com.google.common.base.Optional; -import io.fd.honeycomb.v3po.impl.trans.ChildVppReader; -import io.fd.honeycomb.v3po.impl.trans.impl.spi.ChildVppReaderCustomizer; -import io.fd.honeycomb.v3po.impl.trans.util.VppRWUtils; -import java.util.List; -import javax.annotation.Nonnull; -import javax.annotation.concurrent.ThreadSafe; -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.Augmentation; -import org.opendaylight.yangtools.yang.binding.ChildOf; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -/** - * Composite implementation of {@link ChildVppReader} able to place the read result into - * parent builder object. - */ -@Beta -@ThreadSafe -public final class CompositeChildVppReader> extends AbstractCompositeVppReader - implements ChildVppReader { - - private final ChildVppReaderCustomizer customizer; - - /** - * Create new {@link CompositeChildVppReader} - * - * @param managedDataObjectType Class object for managed data type - * @param childReaders Child nodes(container, list) readers - * @param augReaders Child augmentations readers - * @param customizer Customizer instance to customize this generic reader - * - */ - public CompositeChildVppReader(@Nonnull final Class managedDataObjectType, - @Nonnull final List>> childReaders, - @Nonnull final List>> augReaders, - @Nonnull final ChildVppReaderCustomizer customizer) { - super(managedDataObjectType, childReaders, augReaders); - this.customizer = customizer; - } - - /** - * @see {@link CompositeChildVppReader#CompositeChildVppReader(Class, List, List, ChildVppReaderCustomizer)} - */ - public CompositeChildVppReader(@Nonnull final Class managedDataObjectType, - @Nonnull final List>> childReaders, - @Nonnull final ChildVppReaderCustomizer customizer) { - this(managedDataObjectType, childReaders, VppRWUtils.emptyAugReaderList(), customizer); - } - - /** - * @see {@link CompositeChildVppReader#CompositeChildVppReader(Class, List, List, ChildVppReaderCustomizer)} - */ - public CompositeChildVppReader(@Nonnull final Class managedDataObjectType, - @Nonnull final ChildVppReaderCustomizer customizer) { - this(managedDataObjectType, VppRWUtils.emptyChildReaderList(), VppRWUtils.emptyAugReaderList(), - customizer); - } - - @Override - public final void read(@Nonnull final InstanceIdentifier parentId, - @Nonnull final Builder parentBuilder) { - final Optional read = Optional.fromNullable(readCurrent(VppRWUtils.appendTypeToId(parentId, - getManagedDataObjectType())).get(0)); - - if(read.isPresent()) { - customizer.merge(parentBuilder, read.get()); - } - } - - @Override - protected void readCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final B builder) { - customizer.readCurrentAttributes(id, builder); - } - - @Override - protected B getBuilder(@Nonnull final InstanceIdentifier id) { - return customizer.getBuilder(id); - } - -} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/impl/CompositeListVppReader.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/impl/CompositeListVppReader.java deleted file mode 100644 index d64a83ccc..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/impl/CompositeListVppReader.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.v3po.impl.trans.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.Function; -import com.google.common.collect.Lists; -import io.fd.honeycomb.v3po.impl.trans.ChildVppReader; -import io.fd.honeycomb.v3po.impl.trans.impl.spi.ListVppReaderCustomizer; -import io.fd.honeycomb.v3po.impl.trans.util.VppRWUtils; -import java.util.List; -import javax.annotation.Nonnull; -import javax.annotation.concurrent.ThreadSafe; -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.Augmentation; -import org.opendaylight.yangtools.yang.binding.ChildOf; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.Identifiable; -import org.opendaylight.yangtools.yang.binding.Identifier; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -/** - * Composite implementation of {@link ChildVppReader} able to place the read result into - * parent builder object intended for list node type. - * - * This reader checks if the IDs are wildcarded in which case it performs read of all - * list entries. In case the ID has a key, it reads only the specified value. - */ -@Beta -@ThreadSafe -public final class CompositeListVppReader, K extends Identifier, B extends Builder> - extends AbstractCompositeVppReader implements ChildVppReader { - - private final ListVppReaderCustomizer customizer; - - /** - * Create new {@link CompositeListVppReader} - * - * @param managedDataObjectType Class object for managed data type. Must come from a list node type. - * @param childReaders Child nodes(container, list) readers - * @param augReaders Child augmentations readers - * @param customizer Customizer instance to customize this generic reader - * - */ - public CompositeListVppReader(@Nonnull final Class managedDataObjectType, - @Nonnull final List>> childReaders, - @Nonnull final List>> augReaders, - @Nonnull final ListVppReaderCustomizer customizer) { - super(managedDataObjectType, childReaders, augReaders); - this.customizer = customizer; - } - - /** - * @see {@link CompositeListVppReader#CompositeListVppReader(Class, List, List, ListVppReaderCustomizer)} - */ - public CompositeListVppReader(@Nonnull final Class managedDataObjectType, - @Nonnull final List>> childReaders, - @Nonnull final ListVppReaderCustomizer customizer) { - this(managedDataObjectType, childReaders, VppRWUtils.emptyAugReaderList(), customizer); - } - - /** - * @see {@link CompositeListVppReader#CompositeListVppReader(Class, List, List, ListVppReaderCustomizer)} - */ - public CompositeListVppReader(@Nonnull final Class managedDataObjectType, - @Nonnull final ListVppReaderCustomizer customizer) { - this(managedDataObjectType, VppRWUtils.emptyChildReaderList(), VppRWUtils.emptyAugReaderList(), - customizer); - } - - @Override - protected List readCurrent(@Nonnull final InstanceIdentifier id) { - return shouldReadAll(id) ? readList(id) : super.readCurrent(id); - } - - @Override - public void read(@Nonnull final InstanceIdentifier id, - @Nonnull final Builder parentBuilder) { - // Create ID pointing to current node - final InstanceIdentifier currentId = VppRWUtils.appendTypeToId(id, getManagedDataObjectType()); - // Read all, since current ID is definitely wildcarded - final List ifcs = readList(currentId); - customizer.merge(parentBuilder, ifcs); - } - - private List readList(@Nonnull final InstanceIdentifier id) { - return Lists.transform(customizer.getAllIds(id), new Function() { - @Override - public C apply(final K key) { - final InstanceIdentifier.IdentifiableItem currentBdItem = - VppRWUtils.getCurrentIdItem(id, key); - final InstanceIdentifier keyedId = VppRWUtils.replaceLastInId(id, currentBdItem); - final List read = read(keyedId); - checkState(read.size() == 1); - final DataObject singleItem = read.get(0); - checkArgument(getManagedDataObjectType().getTargetType().isAssignableFrom(singleItem.getClass())); - return getManagedDataObjectType().getTargetType().cast(singleItem); - } - }); - } - - private boolean shouldReadAll(@Nonnull final InstanceIdentifier id) { - final InstanceIdentifier instanceIdentifier = id.firstIdentifierOf(getManagedDataObjectType().getTargetType()); - return instanceIdentifier == null || instanceIdentifier.isWildcarded(); - } - - @Override - protected void readCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final B builder) { - customizer.readCurrentAttributes(id, builder); - } - - @Override - protected B getBuilder(@Nonnull final InstanceIdentifier id) { - return customizer.getBuilder(id); - } - -} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/impl/CompositeRootVppReader.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/impl/CompositeRootVppReader.java deleted file mode 100644 index 1e6b7e93a..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/impl/CompositeRootVppReader.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.v3po.impl.trans.impl; - -import com.google.common.annotations.Beta; -import io.fd.honeycomb.v3po.impl.trans.ChildVppReader; -import io.fd.honeycomb.v3po.impl.trans.VppReader; -import io.fd.honeycomb.v3po.impl.trans.impl.spi.RootVppReaderCustomizer; -import io.fd.honeycomb.v3po.impl.trans.util.VppRWUtils; -import java.util.List; -import javax.annotation.Nonnull; -import javax.annotation.concurrent.ThreadSafe; -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.Augmentation; -import org.opendaylight.yangtools.yang.binding.ChildOf; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -/** - * Composite implementation of {@link VppReader} - */ -@Beta -@ThreadSafe -public final class CompositeRootVppReader> extends AbstractCompositeVppReader - implements VppReader { - - private final RootVppReaderCustomizer customizer; - - /** - * Create new {@link CompositeRootVppReader} - * - * @param managedDataObjectType Class object for managed data type - * @param childReaders Child nodes(container, list) readers - * @param augReaders Child augmentations readers - * @param customizer Customizer instance to customize this generic reader - * - */ - public CompositeRootVppReader(@Nonnull final Class managedDataObjectType, - @Nonnull final List>> childReaders, - @Nonnull final List>> augReaders, - @Nonnull final RootVppReaderCustomizer customizer) { - super(managedDataObjectType, childReaders, augReaders); - this.customizer = customizer; - } - - /** - * @see {@link CompositeRootVppReader#CompositeRootVppReader(Class, List, List, RootVppReaderCustomizer)} - */ - public CompositeRootVppReader(@Nonnull final Class managedDataObjectType, - @Nonnull final List>> childReaders, - @Nonnull final RootVppReaderCustomizer customizer) { - this(managedDataObjectType, childReaders, VppRWUtils.emptyAugReaderList(), customizer); - } - - /** - * @see {@link CompositeRootVppReader#CompositeRootVppReader(Class, List, List, RootVppReaderCustomizer)} - */ - public CompositeRootVppReader(@Nonnull final Class managedDataObjectType, - @Nonnull final RootVppReaderCustomizer customizer) { - this(managedDataObjectType, VppRWUtils.emptyChildReaderList(), VppRWUtils.emptyAugReaderList(), - customizer); - } - - @Override - protected void readCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final B builder) { - customizer.readCurrentAttributes(id, builder); - } - - @Override - protected B getBuilder(@Nonnull final InstanceIdentifier id) { - return customizer.getBuilder(id); - } - -} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/impl/spi/ChildVppReaderCustomizer.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/impl/spi/ChildVppReaderCustomizer.java deleted file mode 100644 index 29cfe3eeb..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/impl/spi/ChildVppReaderCustomizer.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.v3po.impl.trans.impl.spi; - -import com.google.common.annotations.Beta; -import javax.annotation.Nonnull; -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.DataObject; - -/** - * io.fd.honeycomb.v3po.impl.trans.impl.CompositeChildVppReader SPI to customize its behavior - */ -@Beta -public interface ChildVppReaderCustomizer> extends - RootVppReaderCustomizer { - - // FIXME need to capture parent builder type, but that's inconvenient at best, is it ok to leave it Builder and - // cast in specific customizers ? ... probably better than adding another type parameter - - /** - * Merge read data into provided parent builder - */ - void merge(@Nonnull final Builder parentBuilder, @Nonnull final C readValue); -} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/impl/spi/ListVppReaderCustomizer.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/impl/spi/ListVppReaderCustomizer.java deleted file mode 100644 index 8a6812dd6..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/impl/spi/ListVppReaderCustomizer.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.v3po.impl.trans.impl.spi; - -import com.google.common.annotations.Beta; -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; - -/** - * io.fd.honeycomb.v3po.impl.trans.impl.CompositeListVppReader SPI to customize its behavior - */ -@Beta -public interface ListVppReaderCustomizer, K extends Identifier, B extends Builder> - extends RootVppReaderCustomizer { - - /** - * Return list with IDs of all list nodes to be read. - * - * @param id wildcarded ID pointing to list node managed by enclosing reader - */ - @Nonnull - List getAllIds(@Nonnull final InstanceIdentifier id); - - /** - * Merge read data into provided parent builder - */ - void merge(@Nonnull final Builder builder, @Nonnull final List readData); -} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/impl/spi/RootVppReaderCustomizer.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/impl/spi/RootVppReaderCustomizer.java deleted file mode 100644 index 463e4f9d6..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/impl/spi/RootVppReaderCustomizer.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.v3po.impl.trans.impl.spi; - -import com.google.common.annotations.Beta; -import javax.annotation.Nonnull; -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -/** - * io.fd.honeycomb.v3po.impl.trans.impl.CompositeRootVppReader SPI to customize its behavior - */ -@Beta -public interface RootVppReaderCustomizer> { - - // TODO add (un)checked, well defined exception here to indicate issues in the customizer - - /** - * Create new builder that will be used to build read value - */ - @Nonnull - B getBuilder(@Nonnull final InstanceIdentifier id); - - /** - * Add current data (identified by id) to the provided builder - */ - void readCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final B builder); -} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/ChildVppReader.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/ChildVppReader.java new file mode 100644 index 000000000..7f4d6fc4b --- /dev/null +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/ChildVppReader.java @@ -0,0 +1,46 @@ +/* + * 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 javax.annotation.Nonnull; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * Child VPP reader allowing its parent to pass the builder object + * + * @param Specific DataObject derived type, that is handled by this reader + */ +@Beta +public interface ChildVppReader extends VppReader { + + /** + * Reads subtree starting from node managed by this reader and place the subtree within parent builder object if the + * data exists. + * + * @param id Unique identifier pointing to the node managed by this reader. Useful when necessary to + * determine the exact position within more complex subtrees. + * @param parentBuilder Builder of parent DataObject. Objects read on this level (if any) must be placed into the + * parent builder. + */ + void read(@Nonnull final InstanceIdentifier id, + @Nonnull final Builder parentBuilder); + +} + diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/ReaderRegistry.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/ReaderRegistry.java new file mode 100644 index 000000000..49705fe3b --- /dev/null +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/ReaderRegistry.java @@ -0,0 +1,35 @@ +/* + * 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; + +/** + * Simple delegating reader suitable as a holder for all other root readers, providing readAll feature + */ +@Beta +public interface ReaderRegistry extends VppReader { + + /** + * Perform read on all underlying readers and merge the results into a single list + */ + @Nonnull + List readAll(); +} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/SubtreeManager.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/SubtreeManager.java new file mode 100644 index 000000000..fbe17148c --- /dev/null +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/SubtreeManager.java @@ -0,0 +1,39 @@ +/* + * 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 javax.annotation.Nonnull; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * Base identifiable subtree manager(reader, writer etc.) + * + * @param Specific DataObject derived type, that is managed by this manager + */ +@Beta +public interface SubtreeManager { + + /** + * Gets the type of node managed by this reader + * + * @return Class object for node managed by this reader + */ + @Nonnull + InstanceIdentifier getManagedDataObjectType(); +} 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 new file mode 100644 index 000000000..8964aa769 --- /dev/null +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/VppReader.java @@ -0,0 +1,48 @@ +/* + * 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.InstanceIdentifier; + +/** + * Base VPP reader, responsible for translation between DataObjects and VPP APIs + * + * @param Specific DataObject derived type, that is handled by this reader + */ +@Beta +public interface VppReader extends SubtreeManager { + + // TODO add vpp read context that will be shared by all readers during a single read to keep useful information + // preventing possible duplicate reads from VPP + // TODO make async + + /** + * Reads from VPP data identified by id + * + * @param id unique identifier of subtree to be read. The subtree must contain managed data object type. For + * identifiers pointing below node managed by this reader, it's reader's responsibility to filter out the + * right node or to delegate the read to a child reader. + * @return List of DataObjects identified by id. If the ID points to a single node, it will be wrapped in a list + */ + @Nonnull + List read(@Nonnull final InstanceIdentifier 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 new file mode 100644 index 000000000..82a365a42 --- /dev/null +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/AbstractCompositeVppReader.java @@ -0,0 +1,206 @@ +/* + * 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.impl; + +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 io.fd.honeycomb.v3po.impl.trans.r.ChildVppReader; +import io.fd.honeycomb.v3po.impl.trans.r.VppReader; +import io.fd.honeycomb.v3po.impl.trans.r.util.ReflectionUtils; +import io.fd.honeycomb.v3po.impl.trans.r.util.VppRWUtils; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.Augmentation; +import org.opendaylight.yangtools.yang.binding.ChildOf; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.Identifier; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +@Beta +abstract class AbstractCompositeVppReader> implements VppReader { + + // TODO add debug + trace logs here and there + + private final Map, ChildVppReader>> childReaders; + private final Map, ChildVppReader>> augReaders; + private final InstanceIdentifier instanceIdentifier; + + AbstractCompositeVppReader(final Class managedDataObjectType, + final List>> childReaders, + final List>> augReaders) { + this.childReaders = VppRWUtils.uniqueLinkedIndex(childReaders, VppRWUtils.MANAGER_CLASS_FUNCTION); + this.augReaders = VppRWUtils.uniqueLinkedIndex(augReaders, VppRWUtils.MANAGER_CLASS_AUG_FUNCTION); + this.instanceIdentifier = InstanceIdentifier.create(managedDataObjectType); + } + + @Nonnull + @Override + public final InstanceIdentifier getManagedDataObjectType() { + return instanceIdentifier; + } + + /** + * @param id {@link InstanceIdentifier} pointing to current node. In case of keyed list, key must be present. + */ + protected List readCurrent(final InstanceIdentifier id) { + final B builder = getBuilder(id); + // Cache empty value to determine if anything has changed later TODO cache in a field + final D emptyValue = builder.build(); + + readCurrentAttributes(id, builder); + + // TODO expect exceptions from reader + for (ChildVppReader> child : childReaders.values()) { + child.read(id, builder); + } + + for (ChildVppReader> child : augReaders.values()) { + child.read(id, builder); + } + + // Need to check whether anything was filled in to determine if data is present or not. + final D built = builder.build(); + return built.equals(emptyValue) ? Collections.emptyList() : Collections.singletonList(built); + } + + @Nonnull + @Override + @SuppressWarnings("unchecked") + public List read(@Nonnull final InstanceIdentifier id) { + // This is read for one of children, we need to read and then filter, not parent) + + // If this is target, just read + if (id.getTargetType().equals(getManagedDataObjectType().getTargetType())) { + return readCurrent((InstanceIdentifier) id); + } else { + return readSubtree(id); + } + } + + private List readSubtree(final InstanceIdentifier id) { + // Read only specific subtree + final Class next = VppRWUtils.getNextId(id, getManagedDataObjectType()).getType(); + final ChildVppReader> vppReader = childReaders.get(next); + + if (vppReader != null) { + return vppReader.read(id); + } else { + // If there's no dedicated reader, use read current + final InstanceIdentifier currentId = VppRWUtils.cutId(id, getManagedDataObjectType()); + final List current = readCurrent(currentId); + // then perform post-reading filtering (return only requested sub-node) + return current.isEmpty() ? current : filterSubtree(current, id, getManagedDataObjectType().getTargetType()) ; + } + } + + /** + * Fill in current node's attributes + * + * @param id {@link InstanceIdentifier} pointing to current node. In case of keyed list, key must be present. + * @param builder Builder object for current node where the read attributes must be placed + */ + protected abstract void readCurrentAttributes(final InstanceIdentifier id, B builder); + + /** + * Return new instance of a builder object for current node + * + * @param id {@link InstanceIdentifier} pointing to current node. In case of keyed list, key must be present. + * @return Builder object for current node type + */ + protected abstract B getBuilder(InstanceIdentifier id); + + // TODO move filtering out of here into a dedicated Filter ifc + @Nonnull + private static List filterSubtree(@Nonnull final List built, + @Nonnull final InstanceIdentifier 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 filtered = Lists.newArrayList(); + for (DataObject parent : built) { + final InstanceIdentifier.PathArgument nextId = + VppRWUtils.getNextId(absolutPath, InstanceIdentifier.create(parent.getClass())); + + Optional method = ReflectionUtils.findMethodReflex(managedType, "get", + Collections.>emptyList(), nextId.getType()); + + if (method.isPresent()) { + filterSingle(filtered, parent, nextId, method); + } else { + // List child nodes + method = ReflectionUtils.findMethodReflex(managedType, + "get" + nextId.getType().getSimpleName(), Collections.>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"); + } + } + } + + return filtered; + } + + @SuppressWarnings("unchecked") + private static void filterList(final List filtered, final DataObject parent, + final InstanceIdentifier.PathArgument nextId, final Optional method) { + final List invoke = (List)invoke(method.get(), nextId, parent); + + if (nextId instanceof InstanceIdentifier.IdentifiableItem) { + final Identifier key = ((InstanceIdentifier.IdentifiableItem) nextId).getKey(); + filtered.addAll(Collections2.filter(invoke, new Predicate() { + @Override + public boolean apply(@Nullable final DataObject input) { + final Optional keyGetter = + ReflectionUtils.findMethodReflex(nextId.getType(), "get", + Collections.>emptyList(), key.getClass()); + final Object actualKey; + actualKey = invoke(keyGetter.get(), nextId, input); + return key.equals(actualKey); + } + })); + } else { + filtered.addAll(invoke); + } + } + + private static void filterSingle(final List filtered, final DataObject parent, + final InstanceIdentifier.PathArgument nextId, final Optional method) { + filtered.add(nextId.getType().cast(invoke(method.get(), nextId, parent))); + } + + private static Object invoke(final Method method, + final InstanceIdentifier.PathArgument nextId, final DataObject parent) { + try { + return method.invoke(parent); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new IllegalArgumentException("Unable to get " + nextId + " from " + parent, e); + } + } +} 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 new file mode 100644 index 000000000..dd7dbc499 --- /dev/null +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/CompositeChildVppReader.java @@ -0,0 +1,100 @@ +/* + * 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.impl; + +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.impl.spi.ChildVppReaderCustomizer; +import io.fd.honeycomb.v3po.impl.trans.r.util.VppRWUtils; +import java.util.List; +import javax.annotation.Nonnull; +import javax.annotation.concurrent.ThreadSafe; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.Augmentation; +import org.opendaylight.yangtools.yang.binding.ChildOf; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * Composite implementation of {@link ChildVppReader} able to place the read result into + * parent builder object. + */ +@Beta +@ThreadSafe +public final class CompositeChildVppReader> extends AbstractCompositeVppReader + implements ChildVppReader { + + private final ChildVppReaderCustomizer customizer; + + /** + * Create new {@link CompositeChildVppReader} + * + * @param managedDataObjectType Class object for managed data type + * @param childReaders Child nodes(container, list) readers + * @param augReaders Child augmentations readers + * @param customizer Customizer instance to customize this generic reader + * + */ + public CompositeChildVppReader(@Nonnull final Class managedDataObjectType, + @Nonnull final List>> childReaders, + @Nonnull final List>> augReaders, + @Nonnull final ChildVppReaderCustomizer customizer) { + super(managedDataObjectType, childReaders, augReaders); + this.customizer = customizer; + } + + /** + * @see {@link CompositeChildVppReader#CompositeChildVppReader(Class, List, List, ChildVppReaderCustomizer)} + */ + public CompositeChildVppReader(@Nonnull final Class managedDataObjectType, + @Nonnull final List>> childReaders, + @Nonnull final ChildVppReaderCustomizer customizer) { + this(managedDataObjectType, childReaders, VppRWUtils.emptyAugReaderList(), customizer); + } + + /** + * @see {@link CompositeChildVppReader#CompositeChildVppReader(Class, List, List, ChildVppReaderCustomizer)} + */ + public CompositeChildVppReader(@Nonnull final Class managedDataObjectType, + @Nonnull final ChildVppReaderCustomizer customizer) { + this(managedDataObjectType, VppRWUtils.emptyChildReaderList(), VppRWUtils.emptyAugReaderList(), + customizer); + } + + @Override + public final void read(@Nonnull final InstanceIdentifier parentId, + @Nonnull final Builder parentBuilder) { + final Optional read = Optional.fromNullable(readCurrent(VppRWUtils.appendTypeToId(parentId, + getManagedDataObjectType())).get(0)); + + if(read.isPresent()) { + customizer.merge(parentBuilder, read.get()); + } + } + + @Override + protected void readCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final B builder) { + customizer.readCurrentAttributes(id, builder); + } + + @Override + protected B getBuilder(@Nonnull final InstanceIdentifier id) { + return customizer.getBuilder(id); + } + +} 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 new file mode 100644 index 000000000..bc49a8fc7 --- /dev/null +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/CompositeListVppReader.java @@ -0,0 +1,134 @@ +/* + * 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.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.Function; +import com.google.common.collect.Lists; +import io.fd.honeycomb.v3po.impl.trans.r.ChildVppReader; +import io.fd.honeycomb.v3po.impl.trans.r.impl.spi.ListVppReaderCustomizer; +import io.fd.honeycomb.v3po.impl.trans.r.util.VppRWUtils; +import java.util.List; +import javax.annotation.Nonnull; +import javax.annotation.concurrent.ThreadSafe; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.Augmentation; +import org.opendaylight.yangtools.yang.binding.ChildOf; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.Identifiable; +import org.opendaylight.yangtools.yang.binding.Identifier; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * Composite implementation of {@link ChildVppReader} able to place the read result into + * parent builder object intended for list node type. + * + * This reader checks if the IDs are wildcarded in which case it performs read of all + * list entries. In case the ID has a key, it reads only the specified value. + */ +@Beta +@ThreadSafe +public final class CompositeListVppReader, K extends Identifier, B extends Builder> + extends AbstractCompositeVppReader implements ChildVppReader { + + private final ListVppReaderCustomizer customizer; + + /** + * Create new {@link CompositeListVppReader} + * + * @param managedDataObjectType Class object for managed data type. Must come from a list node type. + * @param childReaders Child nodes(container, list) readers + * @param augReaders Child augmentations readers + * @param customizer Customizer instance to customize this generic reader + * + */ + public CompositeListVppReader(@Nonnull final Class managedDataObjectType, + @Nonnull final List>> childReaders, + @Nonnull final List>> augReaders, + @Nonnull final ListVppReaderCustomizer customizer) { + super(managedDataObjectType, childReaders, augReaders); + this.customizer = customizer; + } + + /** + * @see {@link CompositeListVppReader#CompositeListVppReader(Class, List, List, ListVppReaderCustomizer)} + */ + public CompositeListVppReader(@Nonnull final Class managedDataObjectType, + @Nonnull final List>> childReaders, + @Nonnull final ListVppReaderCustomizer customizer) { + this(managedDataObjectType, childReaders, VppRWUtils.emptyAugReaderList(), customizer); + } + + /** + * @see {@link CompositeListVppReader#CompositeListVppReader(Class, List, List, ListVppReaderCustomizer)} + */ + public CompositeListVppReader(@Nonnull final Class managedDataObjectType, + @Nonnull final ListVppReaderCustomizer customizer) { + this(managedDataObjectType, VppRWUtils.emptyChildReaderList(), VppRWUtils.emptyAugReaderList(), + customizer); + } + + @Override + protected List readCurrent(@Nonnull final InstanceIdentifier id) { + return shouldReadAll(id) ? readList(id) : super.readCurrent(id); + } + + @Override + public void read(@Nonnull final InstanceIdentifier id, + @Nonnull final Builder parentBuilder) { + // Create ID pointing to current node + final InstanceIdentifier currentId = VppRWUtils.appendTypeToId(id, getManagedDataObjectType()); + // Read all, since current ID is definitely wildcarded + final List ifcs = readList(currentId); + customizer.merge(parentBuilder, ifcs); + } + + private List readList(@Nonnull final InstanceIdentifier id) { + return Lists.transform(customizer.getAllIds(id), new Function() { + @Override + public C apply(final K key) { + final InstanceIdentifier.IdentifiableItem currentBdItem = + VppRWUtils.getCurrentIdItem(id, key); + final InstanceIdentifier keyedId = VppRWUtils.replaceLastInId(id, currentBdItem); + final List read = read(keyedId); + checkState(read.size() == 1); + final DataObject singleItem = read.get(0); + checkArgument(getManagedDataObjectType().getTargetType().isAssignableFrom(singleItem.getClass())); + return getManagedDataObjectType().getTargetType().cast(singleItem); + } + }); + } + + private boolean shouldReadAll(@Nonnull final InstanceIdentifier id) { + final InstanceIdentifier instanceIdentifier = id.firstIdentifierOf(getManagedDataObjectType().getTargetType()); + return instanceIdentifier == null || instanceIdentifier.isWildcarded(); + } + + @Override + protected void readCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final B builder) { + customizer.readCurrentAttributes(id, builder); + } + + @Override + protected B getBuilder(@Nonnull final InstanceIdentifier id) { + return customizer.getBuilder(id); + } + +} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/CompositeRootVppReader.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/CompositeRootVppReader.java new file mode 100644 index 000000000..ca972e5f8 --- /dev/null +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/CompositeRootVppReader.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.honeycomb.v3po.impl.trans.r.impl; + +import com.google.common.annotations.Beta; +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.r.impl.spi.RootVppReaderCustomizer; +import io.fd.honeycomb.v3po.impl.trans.r.util.VppRWUtils; +import java.util.List; +import javax.annotation.Nonnull; +import javax.annotation.concurrent.ThreadSafe; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.Augmentation; +import org.opendaylight.yangtools.yang.binding.ChildOf; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * Composite implementation of {@link VppReader} + */ +@Beta +@ThreadSafe +public final class CompositeRootVppReader> extends AbstractCompositeVppReader + implements VppReader { + + private final RootVppReaderCustomizer customizer; + + /** + * Create new {@link CompositeRootVppReader} + * + * @param managedDataObjectType Class object for managed data type + * @param childReaders Child nodes(container, list) readers + * @param augReaders Child augmentations readers + * @param customizer Customizer instance to customize this generic reader + * + */ + public CompositeRootVppReader(@Nonnull final Class managedDataObjectType, + @Nonnull final List>> childReaders, + @Nonnull final List>> augReaders, + @Nonnull final RootVppReaderCustomizer customizer) { + super(managedDataObjectType, childReaders, augReaders); + this.customizer = customizer; + } + + /** + * @see {@link CompositeRootVppReader#CompositeRootVppReader(Class, List, List, RootVppReaderCustomizer)} + */ + public CompositeRootVppReader(@Nonnull final Class managedDataObjectType, + @Nonnull final List>> childReaders, + @Nonnull final RootVppReaderCustomizer customizer) { + this(managedDataObjectType, childReaders, VppRWUtils.emptyAugReaderList(), customizer); + } + + /** + * @see {@link CompositeRootVppReader#CompositeRootVppReader(Class, List, List, RootVppReaderCustomizer)} + */ + public CompositeRootVppReader(@Nonnull final Class managedDataObjectType, + @Nonnull final RootVppReaderCustomizer customizer) { + this(managedDataObjectType, VppRWUtils.emptyChildReaderList(), VppRWUtils.emptyAugReaderList(), + customizer); + } + + @Override + protected void readCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final B builder) { + customizer.readCurrentAttributes(id, builder); + } + + @Override + protected B getBuilder(@Nonnull final InstanceIdentifier id) { + return customizer.getBuilder(id); + } + +} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/spi/ChildVppReaderCustomizer.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/spi/ChildVppReaderCustomizer.java new file mode 100644 index 000000000..e462118aa --- /dev/null +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/spi/ChildVppReaderCustomizer.java @@ -0,0 +1,38 @@ +/* + * 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.impl.spi; + +import com.google.common.annotations.Beta; +import javax.annotation.Nonnull; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; + +/** + * io.fd.honeycomb.v3po.impl.trans.r.impl.CompositeChildVppReader SPI to customize its behavior + */ +@Beta +public interface ChildVppReaderCustomizer> extends + RootVppReaderCustomizer { + + // FIXME need to capture parent builder type, but that's inconvenient at best, is it ok to leave it Builder and + // cast in specific customizers ? ... probably better than adding another type parameter + + /** + * Merge read data into provided parent builder + */ + void merge(@Nonnull final Builder parentBuilder, @Nonnull final C readValue); +} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/spi/ListVppReaderCustomizer.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/spi/ListVppReaderCustomizer.java new file mode 100644 index 000000000..5646ab992 --- /dev/null +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/spi/ListVppReaderCustomizer.java @@ -0,0 +1,47 @@ +/* + * 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.impl.spi; + +import com.google.common.annotations.Beta; +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; + +/** + * io.fd.honeycomb.v3po.impl.trans.r.impl.CompositeListVppReader SPI to customize its behavior + */ +@Beta +public interface ListVppReaderCustomizer, K extends Identifier, B extends Builder> + extends RootVppReaderCustomizer { + + /** + * Return list with IDs of all list nodes to be read. + * + * @param id wildcarded ID pointing to list node managed by enclosing reader + */ + @Nonnull + List getAllIds(@Nonnull final InstanceIdentifier id); + + /** + * Merge read data into provided parent builder + */ + void merge(@Nonnull final Builder builder, @Nonnull final List readData); +} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/spi/RootVppReaderCustomizer.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/spi/RootVppReaderCustomizer.java new file mode 100644 index 000000000..b6e1155b3 --- /dev/null +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/impl/spi/RootVppReaderCustomizer.java @@ -0,0 +1,43 @@ +/* + * 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.impl.spi; + +import com.google.common.annotations.Beta; +import javax.annotation.Nonnull; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * io.fd.honeycomb.v3po.impl.trans.r.impl.CompositeRootVppReader SPI to customize its behavior + */ +@Beta +public interface RootVppReaderCustomizer> { + + // TODO add (un)checked, well defined exception here to indicate issues in the customizer + + /** + * Create new builder that will be used to build read value + */ + @Nonnull + B getBuilder(@Nonnull final InstanceIdentifier id); + + /** + * Add current data (identified by id) to the provided builder + */ + void readCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final B 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 new file mode 100644 index 000000000..9e672c92f --- /dev/null +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/DelegatingReaderRegistry.java @@ -0,0 +1,82 @@ +/* + * 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.util; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.collect.Iterables; +import io.fd.honeycomb.v3po.impl.trans.r.ReaderRegistry; +import io.fd.honeycomb.v3po.impl.trans.r.VppReader; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import javax.annotation.Nonnull; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * Simple reader registry able to perform and aggregated read (ROOT read) on top of all + * provided readers. Also able to delegate a specific read to one of the delegate readers. + * + * This could serve as a utility to hold & hide all available readers in upper layers. + */ +public final class DelegatingReaderRegistry implements ReaderRegistry { + + private final Map, VppReader> rootReaders; + + /** + * Create new {@link DelegatingReaderRegistry} + * + * @param rootReaders List of delegate readers + */ + public DelegatingReaderRegistry(@Nonnull final List> rootReaders) { + this.rootReaders = VppRWUtils.uniqueLinkedIndex(checkNotNull(rootReaders), VppRWUtils.MANAGER_CLASS_FUNCTION); + } + + @Override + @Nonnull + public List readAll() { + final List objects = new ArrayList<>(rootReaders.size()); + for (VppReader rootReader : rootReaders.values()) { + final List read = rootReader.read(rootReader.getManagedDataObjectType()); + objects.addAll(read); + } + return objects; + } + + @Nonnull + @Override + public List read(@Nonnull final InstanceIdentifier id) { + final InstanceIdentifier.PathArgument first = checkNotNull( + Iterables.getFirst(id.getPathArguments(), null), "Empty id"); + final VppReader vppReader = rootReaders.get(first.getType()); + checkNotNull(vppReader, + "Unable to read %s. Missing reader. Current readers for: %s", id, rootReaders.keySet()); + return vppReader.read(id); + } + + /** + * @throws UnsupportedOperationException This getter is not supported for reader registry since it does not manage a + * specific node type + */ + @Nonnull + @Override + public InstanceIdentifier getManagedDataObjectType() { + throw new UnsupportedOperationException("Root registry has no type"); + } + +} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/NoopReaderCustomizer.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/NoopReaderCustomizer.java new file mode 100644 index 000000000..1ce09308a --- /dev/null +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/NoopReaderCustomizer.java @@ -0,0 +1,30 @@ +/* + * 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.util; + +import io.fd.honeycomb.v3po.impl.trans.r.impl.spi.RootVppReaderCustomizer; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public abstract class NoopReaderCustomizer> implements RootVppReaderCustomizer { + + @Override + public void readCurrentAttributes(InstanceIdentifier id, final B builder) { + // Noop + } +} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/ReflectionUtils.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/ReflectionUtils.java new file mode 100644 index 000000000..790af8820 --- /dev/null +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/ReflectionUtils.java @@ -0,0 +1,79 @@ +/* + * 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.util; + +import com.google.common.base.Optional; +import java.lang.reflect.Method; +import java.util.List; +import javax.annotation.Nonnull; + +/** + * Reflection based utilities + */ +public final class ReflectionUtils { + + private ReflectionUtils() {} + + /** + * Find a specific method using reflection + * + * @param managedType Class object to find method in + * @param prefix Method name prefix used when finding the method. Case does not matter. + * @param paramTypes List of input argument types + * @param retType Return type + * + * @return Found method or Optional.absent() if there's no such method + */ + @Nonnull + public static Optional findMethodReflex(@Nonnull final Class managedType, + @Nonnull final String prefix, + @Nonnull final List> paramTypes, + @Nonnull final Class retType) { + for (Method method : managedType.getMethods()) { + if(isMethodMatch(prefix, paramTypes, retType, method)) { + return Optional.of(method); + } + } + + return Optional.absent(); + } + + private static boolean isMethodMatch(final @Nonnull String prefix, + final @Nonnull List> paramTypes, + final @Nonnull Class retType, final Method method) { + if (!method.getName().toLowerCase().startsWith(prefix.toLowerCase())) { + return false; + } + + final Class[] parameterTypes = method.getParameterTypes(); + if (parameterTypes.length != paramTypes.size()) { + return false; + } + + for (int i = 0; i < parameterTypes.length; i++) { + if (!parameterTypes[i].isAssignableFrom(paramTypes.get(i))) { + return false; + } + } + + if (!method.getReturnType().equals(retType)) { + return false; + } + + return true; + } +} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/ReflexiveChildReaderCustomizer.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/ReflexiveChildReaderCustomizer.java new file mode 100644 index 000000000..ddef7a94c --- /dev/null +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/ReflexiveChildReaderCustomizer.java @@ -0,0 +1,56 @@ +/* + * 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.util; + +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import io.fd.honeycomb.v3po.impl.trans.r.impl.spi.ChildVppReaderCustomizer; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Collections; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; + +/** + * Might be slow ! + */ +public class ReflexiveChildReaderCustomizer> + extends ReflexiveRootReaderCustomizer + implements ChildVppReaderCustomizer { + + public ReflexiveChildReaderCustomizer(final Class builderClass) { + super(builderClass); + } + + // TODO Could be just a default implementation in interface (making this a mixin) + + @Override + public void merge(final Builder parentBuilder, final C readValue) { + final Optional method = + ReflectionUtils.findMethodReflex(parentBuilder.getClass(), "set", + Collections.>singletonList(readValue.getClass()), parentBuilder.getClass()); + + Preconditions.checkArgument(method.isPresent(), "Unable to set %s to %s", readValue, parentBuilder); + + try { + method.get().invoke(parentBuilder, readValue); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new IllegalArgumentException("Unable to set " + readValue + " to " + parentBuilder, e); + } + } + +} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/ReflexiveRootReaderCustomizer.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/ReflexiveRootReaderCustomizer.java new file mode 100644 index 000000000..b1f776c01 --- /dev/null +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/ReflexiveRootReaderCustomizer.java @@ -0,0 +1,42 @@ +/* + * 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.util; + +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * Might be slow ! + */ +public class ReflexiveRootReaderCustomizer> extends NoopReaderCustomizer { + + private final Class builderClass; + + public ReflexiveRootReaderCustomizer(final Class builderClass) { + this.builderClass = builderClass; + } + + @Override + public B getBuilder(InstanceIdentifier id) { + try { + return builderClass.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + throw new IllegalStateException("Unable to instantiate " + builderClass, e); + } + } +} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/VppApiReaderCustomizer.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/VppApiReaderCustomizer.java new file mode 100644 index 000000000..ddf789c16 --- /dev/null +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/VppApiReaderCustomizer.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.honeycomb.v3po.impl.trans.r.util; + +import com.google.common.annotations.Beta; + +/** + * Abstract utility to hold the vppApi reference. + */ +@Beta +public abstract class VppApiReaderCustomizer { + + private final org.openvpp.vppjapi.vppApi vppApi; + + protected VppApiReaderCustomizer(final org.openvpp.vppjapi.vppApi vppApi) { + this.vppApi = vppApi; + } + + /** + * Get vppApi reference + * + * @return vppApi reference + */ + public org.openvpp.vppjapi.vppApi getVppApi() { + return vppApi; + } +} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/VppRWUtils.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/VppRWUtils.java new file mode 100644 index 000000000..3a765d796 --- /dev/null +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/r/util/VppRWUtils.java @@ -0,0 +1,164 @@ +/* + * 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.util; + +import com.google.common.base.Function; +import com.google.common.base.Preconditions; +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; +import com.google.common.collect.Maps; +import io.fd.honeycomb.v3po.impl.trans.r.ChildVppReader; +import io.fd.honeycomb.v3po.impl.trans.r.SubtreeManager; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import javax.annotation.Nonnull; +import org.opendaylight.yangtools.yang.binding.Augmentation; +import org.opendaylight.yangtools.yang.binding.ChildOf; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.Identifiable; +import org.opendaylight.yangtools.yang.binding.Identifier; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public final class VppRWUtils { + + private VppRWUtils() {} + + /** + * Find next item in ID after provided type + */ + @Nonnull + public static InstanceIdentifier.PathArgument getNextId(@Nonnull final InstanceIdentifier id, + @Nonnull final InstanceIdentifier type) { + // TODO this is inefficient(maybe, depending on actual Iterable type) + final Iterable pathArguments = id.getPathArguments(); + final int i = Iterables.indexOf(pathArguments, new Predicate() { + @Override + public boolean apply(final InstanceIdentifier.PathArgument input) { + return input.getType().isAssignableFrom(type.getTargetType()); + } + }); + Preconditions.checkArgument(i >= 0, "Unable to find %s type in %s", type.getTargetType(), id); + return Iterables.get(pathArguments, i + 1); + } + + public static List>> emptyChildReaderList() { + return Collections.emptyList(); + } + + public static List>> emptyAugReaderList() { + return Collections.emptyList(); + } + + public static List>> singletonAugReaderList( + ChildVppReader> item) { + return Collections.>>singletonList(item); + } + + public static List>> singletonChildReaderList( + ChildVppReader> item) { + return Collections.>>singletonList(item); + } + + /** + * Replace last item in ID with a provided IdentifiableItem of the same type + */ + @SuppressWarnings("unchecked") + @Nonnull + public static , K extends Identifier> InstanceIdentifier replaceLastInId( + @Nonnull final InstanceIdentifier id, final InstanceIdentifier.IdentifiableItem currentBdItem) { + + final Iterable pathArguments = id.getPathArguments(); + final Iterable withoutCurrent = + Iterables.limit(pathArguments, Iterables.size(pathArguments) - 1); + final Iterable concat = + Iterables.concat(withoutCurrent, Collections.singleton(currentBdItem)); + return (InstanceIdentifier) InstanceIdentifier.create(concat); + } + + /** + * Create IdentifiableItem from target type of provided ID with provided key + */ + @Nonnull + public static , K extends Identifier> InstanceIdentifier.IdentifiableItem getCurrentIdItem( + @Nonnull final InstanceIdentifier id, final K key) { + return new InstanceIdentifier.IdentifiableItem<>(id.getTargetType(), key); + } + + /** + * Trim InstanceIdentifier at indexOf(type) + */ + @SuppressWarnings("unchecked") + @Nonnull + public static InstanceIdentifier cutId(@Nonnull final InstanceIdentifier id, + @Nonnull final InstanceIdentifier type) { + final Iterable pathArguments = id.getPathArguments(); + final int i = Iterables.indexOf(pathArguments, new Predicate() { + @Override + public boolean apply(final InstanceIdentifier.PathArgument input) { + return input.getType().equals(type.getTargetType()); + } + }); + Preconditions.checkArgument(i >= 0, "ID %s does not contain %s", id, type); + return (InstanceIdentifier) InstanceIdentifier.create(Iterables.limit(pathArguments, i + 1)); + } + + /** + * Create a map from a collection, checking for duplicity in the process + */ + @Nonnull + public static Map uniqueLinkedIndex(@Nonnull final Collection values, @Nonnull final Function keyFunction) { + final Map objectObjectLinkedHashMap = Maps.newLinkedHashMap(); + for (V value : values) { + final K key = keyFunction.apply(value); + Preconditions.checkArgument(objectObjectLinkedHashMap.put(key, value) == null, + "Duplicate key detected : %s", key); + } + return objectObjectLinkedHashMap; + } + + public static final Function, Class> + MANAGER_CLASS_FUNCTION = new Function, Class>() { + @Override + public Class apply(final SubtreeManager input) { + return input.getManagedDataObjectType().getTargetType(); + } + }; + + public static final Function>, Class> + MANAGER_CLASS_AUG_FUNCTION = new Function>, Class>() { + + @Override + @SuppressWarnings("unchecked") + public Class apply(final SubtreeManager> input) { + final Class> targetType = input.getManagedDataObjectType().getTargetType(); + Preconditions.checkArgument(DataObject.class.isAssignableFrom(targetType)); + return (Class) targetType; + } + }; + + @SuppressWarnings("unchecked") + public static InstanceIdentifier appendTypeToId( + final InstanceIdentifier parentId, final InstanceIdentifier type) { + Preconditions.checkArgument(!parentId.contains(type), + "Unexpected InstanceIdentifier %s, already contains %s", parentId, type); + final InstanceIdentifier.PathArgument t = Iterables.getOnlyElement(type.getPathArguments()); + return (InstanceIdentifier) InstanceIdentifier.create(Iterables.concat( + parentId.getPathArguments(), Collections.singleton(t))); + } +} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/DelegatingReaderRegistry.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/DelegatingReaderRegistry.java deleted file mode 100644 index 5225bab63..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/DelegatingReaderRegistry.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.v3po.impl.trans.util; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.collect.Iterables; -import io.fd.honeycomb.v3po.impl.trans.ReaderRegistry; -import io.fd.honeycomb.v3po.impl.trans.VppReader; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import javax.annotation.Nonnull; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -/** - * Simple reader registry able to perform and aggregated read (ROOT read) on top of all - * provided readers. Also able to delegate a specific read to one of the delegate readers. - * - * This could serve as a utility to hold & hide all available readers in upper layers. - */ -public final class DelegatingReaderRegistry implements ReaderRegistry { - - private final Map, VppReader> rootReaders; - - /** - * Create new {@link DelegatingReaderRegistry} - * - * @param rootReaders List of delegate readers - */ - public DelegatingReaderRegistry(@Nonnull final List> rootReaders) { - this.rootReaders = VppRWUtils.uniqueLinkedIndex(checkNotNull(rootReaders), VppRWUtils.MANAGER_CLASS_FUNCTION); - } - - @Override - @Nonnull - public List readAll() { - final List objects = new ArrayList<>(rootReaders.size()); - for (VppReader rootReader : rootReaders.values()) { - final List read = rootReader.read(rootReader.getManagedDataObjectType()); - objects.addAll(read); - } - return objects; - } - - @Nonnull - @Override - public List read(@Nonnull final InstanceIdentifier id) { - final InstanceIdentifier.PathArgument first = checkNotNull( - Iterables.getFirst(id.getPathArguments(), null), "Empty id"); - final VppReader vppReader = rootReaders.get(first.getType()); - checkNotNull(vppReader, - "Unable to read %s. Missing reader. Current readers for: %s", id, rootReaders.keySet()); - return vppReader.read(id); - } - - /** - * @throws UnsupportedOperationException This getter is not supported for reader registry since it does not manage a - * specific node type - */ - @Nonnull - @Override - public InstanceIdentifier getManagedDataObjectType() { - throw new UnsupportedOperationException("Root registry has no type"); - } - -} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/NoopReaderCustomizer.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/NoopReaderCustomizer.java deleted file mode 100644 index b485a6db4..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/NoopReaderCustomizer.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.v3po.impl.trans.util; - -import io.fd.honeycomb.v3po.impl.trans.impl.spi.RootVppReaderCustomizer; -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public abstract class NoopReaderCustomizer> implements RootVppReaderCustomizer { - - @Override - public void readCurrentAttributes(InstanceIdentifier id, final B builder) { - // Noop - } -} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/ReflectionUtils.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/ReflectionUtils.java deleted file mode 100644 index 6602d750d..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/ReflectionUtils.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.v3po.impl.trans.util; - -import com.google.common.base.Optional; -import java.lang.reflect.Method; -import java.util.List; -import javax.annotation.Nonnull; - -/** - * Reflection based utilities - */ -public final class ReflectionUtils { - - private ReflectionUtils() {} - - /** - * Find a specific method using reflection - * - * @param managedType Class object to find method in - * @param prefix Method name prefix used when finding the method. Case does not matter. - * @param paramTypes List of input argument types - * @param retType Return type - * - * @return Found method or Optional.absent() if there's no such method - */ - @Nonnull - public static Optional findMethodReflex(@Nonnull final Class managedType, - @Nonnull final String prefix, - @Nonnull final List> paramTypes, - @Nonnull final Class retType) { - for (Method method : managedType.getMethods()) { - if(isMethodMatch(prefix, paramTypes, retType, method)) { - return Optional.of(method); - } - } - - return Optional.absent(); - } - - private static boolean isMethodMatch(final @Nonnull String prefix, - final @Nonnull List> paramTypes, - final @Nonnull Class retType, final Method method) { - if (!method.getName().toLowerCase().startsWith(prefix.toLowerCase())) { - return false; - } - - final Class[] parameterTypes = method.getParameterTypes(); - if (parameterTypes.length != paramTypes.size()) { - return false; - } - - for (int i = 0; i < parameterTypes.length; i++) { - if (!parameterTypes[i].isAssignableFrom(paramTypes.get(i))) { - return false; - } - } - - if (!method.getReturnType().equals(retType)) { - return false; - } - - return true; - } -} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/ReflexiveChildReaderCustomizer.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/ReflexiveChildReaderCustomizer.java deleted file mode 100644 index d67a3afbb..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/ReflexiveChildReaderCustomizer.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.v3po.impl.trans.util; - -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import io.fd.honeycomb.v3po.impl.trans.impl.spi.ChildVppReaderCustomizer; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Collections; -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.DataObject; - -/** - * Might be slow ! - */ -public class ReflexiveChildReaderCustomizer> - extends ReflexiveRootReaderCustomizer - implements ChildVppReaderCustomizer { - - public ReflexiveChildReaderCustomizer(final Class builderClass) { - super(builderClass); - } - - // TODO Could be just a default implementation in interface (making this a mixin) - - @Override - public void merge(final Builder parentBuilder, final C readValue) { - final Optional method = - ReflectionUtils.findMethodReflex(parentBuilder.getClass(), "set", - Collections.>singletonList(readValue.getClass()), parentBuilder.getClass()); - - Preconditions.checkArgument(method.isPresent(), "Unable to set %s to %s", readValue, parentBuilder); - - try { - method.get().invoke(parentBuilder, readValue); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new IllegalArgumentException("Unable to set " + readValue + " to " + parentBuilder, e); - } - } - -} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/ReflexiveRootReaderCustomizer.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/ReflexiveRootReaderCustomizer.java deleted file mode 100644 index 2568f9886..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/ReflexiveRootReaderCustomizer.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.v3po.impl.trans.util; - -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -/** - * Might be slow ! - */ -public class ReflexiveRootReaderCustomizer> extends NoopReaderCustomizer { - - private final Class builderClass; - - public ReflexiveRootReaderCustomizer(final Class builderClass) { - this.builderClass = builderClass; - } - - @Override - public B getBuilder(InstanceIdentifier id) { - try { - return builderClass.newInstance(); - } catch (InstantiationException | IllegalAccessException e) { - throw new IllegalStateException("Unable to instantiate " + builderClass, e); - } - } -} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/VppApiReaderCustomizer.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/VppApiReaderCustomizer.java deleted file mode 100644 index 1ca898c8c..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/VppApiReaderCustomizer.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.v3po.impl.trans.util; - -import com.google.common.annotations.Beta; - -/** - * Abstract utility to hold the vppApi reference. - */ -@Beta -public abstract class VppApiReaderCustomizer { - - private final org.openvpp.vppjapi.vppApi vppApi; - - protected VppApiReaderCustomizer(final org.openvpp.vppjapi.vppApi vppApi) { - this.vppApi = vppApi; - } - - /** - * Get vppApi reference - * - * @return vppApi reference - */ - public org.openvpp.vppjapi.vppApi getVppApi() { - return vppApi; - } -} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/VppRWUtils.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/VppRWUtils.java deleted file mode 100644 index 1cc0dfe92..000000000 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/trans/util/VppRWUtils.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.v3po.impl.trans.util; - -import com.google.common.base.Function; -import com.google.common.base.Preconditions; -import com.google.common.base.Predicate; -import com.google.common.collect.Iterables; -import com.google.common.collect.Maps; -import io.fd.honeycomb.v3po.impl.trans.ChildVppReader; -import io.fd.honeycomb.v3po.impl.trans.SubtreeManager; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import javax.annotation.Nonnull; -import org.opendaylight.yangtools.yang.binding.Augmentation; -import org.opendaylight.yangtools.yang.binding.ChildOf; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.Identifiable; -import org.opendaylight.yangtools.yang.binding.Identifier; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public final class VppRWUtils { - - private VppRWUtils() {} - - /** - * Find next item in ID after provided type - */ - @Nonnull - public static InstanceIdentifier.PathArgument getNextId(@Nonnull final InstanceIdentifier id, - @Nonnull final InstanceIdentifier type) { - // TODO this is inefficient(maybe, depending on actual Iterable type) - final Iterable pathArguments = id.getPathArguments(); - final int i = Iterables.indexOf(pathArguments, new Predicate() { - @Override - public boolean apply(final InstanceIdentifier.PathArgument input) { - return input.getType().isAssignableFrom(type.getTargetType()); - } - }); - Preconditions.checkArgument(i >= 0, "Unable to find %s type in %s", type.getTargetType(), id); - return Iterables.get(pathArguments, i + 1); - } - - public static List>> emptyChildReaderList() { - return Collections.emptyList(); - } - - public static List>> emptyAugReaderList() { - return Collections.emptyList(); - } - - public static List>> singletonAugReaderList( - ChildVppReader> item) { - return Collections.>>singletonList(item); - } - - public static List>> singletonChildReaderList( - ChildVppReader> item) { - return Collections.>>singletonList(item); - } - - /** - * Replace last item in ID with a provided IdentifiableItem of the same type - */ - @SuppressWarnings("unchecked") - @Nonnull - public static , K extends Identifier> InstanceIdentifier replaceLastInId( - @Nonnull final InstanceIdentifier id, final InstanceIdentifier.IdentifiableItem currentBdItem) { - - final Iterable pathArguments = id.getPathArguments(); - final Iterable withoutCurrent = - Iterables.limit(pathArguments, Iterables.size(pathArguments) - 1); - final Iterable concat = - Iterables.concat(withoutCurrent, Collections.singleton(currentBdItem)); - return (InstanceIdentifier) InstanceIdentifier.create(concat); - } - - /** - * Create IdentifiableItem from target type of provided ID with provided key - */ - @Nonnull - public static , K extends Identifier> InstanceIdentifier.IdentifiableItem getCurrentIdItem( - @Nonnull final InstanceIdentifier id, final K key) { - return new InstanceIdentifier.IdentifiableItem<>(id.getTargetType(), key); - } - - /** - * Trim InstanceIdentifier at indexOf(type) - */ - @SuppressWarnings("unchecked") - @Nonnull - public static InstanceIdentifier cutId(@Nonnull final InstanceIdentifier id, - @Nonnull final InstanceIdentifier type) { - final Iterable pathArguments = id.getPathArguments(); - final int i = Iterables.indexOf(pathArguments, new Predicate() { - @Override - public boolean apply(final InstanceIdentifier.PathArgument input) { - return input.getType().equals(type.getTargetType()); - } - }); - Preconditions.checkArgument(i >= 0, "ID %s does not contain %s", id, type); - return (InstanceIdentifier) InstanceIdentifier.create(Iterables.limit(pathArguments, i + 1)); - } - - /** - * Create a map from a collection, checking for duplicity in the process - */ - @Nonnull - public static Map uniqueLinkedIndex(@Nonnull final Collection values, @Nonnull final Function keyFunction) { - final Map objectObjectLinkedHashMap = Maps.newLinkedHashMap(); - for (V value : values) { - final K key = keyFunction.apply(value); - Preconditions.checkArgument(objectObjectLinkedHashMap.put(key, value) == null, - "Duplicate key detected : %s", key); - } - return objectObjectLinkedHashMap; - } - - public static final Function, Class> - MANAGER_CLASS_FUNCTION = new Function, Class>() { - @Override - public Class apply(final SubtreeManager input) { - return input.getManagedDataObjectType().getTargetType(); - } - }; - - public static final Function>, Class> - MANAGER_CLASS_AUG_FUNCTION = new Function>, Class>() { - - @Override - @SuppressWarnings("unchecked") - public Class apply(final SubtreeManager> input) { - final Class> targetType = input.getManagedDataObjectType().getTargetType(); - Preconditions.checkArgument(DataObject.class.isAssignableFrom(targetType)); - return (Class) targetType; - } - }; - - @SuppressWarnings("unchecked") - public static InstanceIdentifier appendTypeToId( - final InstanceIdentifier parentId, final InstanceIdentifier type) { - Preconditions.checkArgument(!parentId.contains(type), - "Unexpected InstanceIdentifier %s, already contains %s", parentId, type); - final InstanceIdentifier.PathArgument t = Iterables.getOnlyElement(type.getPathArguments()); - return (InstanceIdentifier) InstanceIdentifier.create(Iterables.concat( - parentId.getPathArguments(), Collections.singleton(t))); - } -} diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/vppstate/BridgeDomainCustomizer.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/vppstate/BridgeDomainCustomizer.java index 97d1867c2..041d9eb55 100644 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/vppstate/BridgeDomainCustomizer.java +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/vppstate/BridgeDomainCustomizer.java @@ -17,8 +17,9 @@ package io.fd.honeycomb.v3po.impl.vppstate; import com.google.common.collect.Lists; -import io.fd.honeycomb.v3po.impl.trans.impl.spi.ListVppReaderCustomizer; -import io.fd.honeycomb.v3po.impl.trans.util.VppApiReaderCustomizer; +import io.fd.honeycomb.v3po.impl.trans.r.impl.spi.ListVppReaderCustomizer; +import io.fd.honeycomb.v3po.impl.trans.r.util.VppApiReaderCustomizer; +import io.fd.honeycomb.v3po.impl.trans.r.util.VppRWUtils; import java.util.ArrayList; import java.util.List; import javax.annotation.Nonnull; diff --git a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/vppstate/VersionCustomizer.java b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/vppstate/VersionCustomizer.java index 641d61805..de596994d 100644 --- a/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/vppstate/VersionCustomizer.java +++ b/v3po/impl/src/main/java/io/fd/honeycomb/v3po/impl/vppstate/VersionCustomizer.java @@ -16,8 +16,8 @@ package io.fd.honeycomb.v3po.impl.vppstate; -import io.fd.honeycomb.v3po.impl.trans.impl.spi.ChildVppReaderCustomizer; -import io.fd.honeycomb.v3po.impl.trans.util.VppApiReaderCustomizer; +import io.fd.honeycomb.v3po.impl.trans.r.impl.spi.ChildVppReaderCustomizer; +import io.fd.honeycomb.v3po.impl.trans.r.util.VppApiReaderCustomizer; import javax.annotation.Nonnull; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppStateBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.Version; diff --git a/v3po/impl/src/test/java/io/fd/honeycomb/v3po/impl/vppstate/BdTest.java b/v3po/impl/src/test/java/io/fd/honeycomb/v3po/impl/vppstate/BdTest.java index 7439bcd30..f50a70a69 100644 --- a/v3po/impl/src/test/java/io/fd/honeycomb/v3po/impl/vppstate/BdTest.java +++ b/v3po/impl/src/test/java/io/fd/honeycomb/v3po/impl/vppstate/BdTest.java @@ -22,9 +22,9 @@ import static org.mockito.Matchers.anyString; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; -import io.fd.honeycomb.v3po.impl.trans.VppReader; -import io.fd.honeycomb.v3po.impl.trans.impl.CompositeRootVppReader; -import io.fd.honeycomb.v3po.impl.trans.util.DelegatingReaderRegistry; +import io.fd.honeycomb.v3po.impl.trans.r.VppReader; +import io.fd.honeycomb.v3po.impl.trans.r.impl.CompositeRootVppReader; +import io.fd.honeycomb.v3po.impl.trans.r.util.DelegatingReaderRegistry; import java.util.Collections; import java.util.List; import org.junit.Before; diff --git a/v3po/impl/src/test/java/io/fd/honeycomb/v3po/impl/vppstate/VppStateUtils.java b/v3po/impl/src/test/java/io/fd/honeycomb/v3po/impl/vppstate/VppStateUtils.java index e28e5b092..f32a45379 100644 --- a/v3po/impl/src/test/java/io/fd/honeycomb/v3po/impl/vppstate/VppStateUtils.java +++ b/v3po/impl/src/test/java/io/fd/honeycomb/v3po/impl/vppstate/VppStateUtils.java @@ -16,13 +16,13 @@ package io.fd.honeycomb.v3po.impl.vppstate; -import io.fd.honeycomb.v3po.impl.trans.ChildVppReader; -import io.fd.honeycomb.v3po.impl.trans.impl.CompositeChildVppReader; -import io.fd.honeycomb.v3po.impl.trans.impl.CompositeListVppReader; -import io.fd.honeycomb.v3po.impl.trans.impl.CompositeRootVppReader; -import io.fd.honeycomb.v3po.impl.trans.util.ReflexiveChildReaderCustomizer; -import io.fd.honeycomb.v3po.impl.trans.util.ReflexiveRootReaderCustomizer; -import io.fd.honeycomb.v3po.impl.trans.util.VppRWUtils; +import io.fd.honeycomb.v3po.impl.trans.r.ChildVppReader; +import io.fd.honeycomb.v3po.impl.trans.r.impl.CompositeChildVppReader; +import io.fd.honeycomb.v3po.impl.trans.r.impl.CompositeListVppReader; +import io.fd.honeycomb.v3po.impl.trans.r.impl.CompositeRootVppReader; +import io.fd.honeycomb.v3po.impl.trans.r.util.ReflexiveChildReaderCustomizer; +import io.fd.honeycomb.v3po.impl.trans.r.util.ReflexiveRootReaderCustomizer; +import io.fd.honeycomb.v3po.impl.trans.r.util.VppRWUtils; import java.util.ArrayList; import java.util.List; import javax.annotation.Nonnull; -- cgit 1.2.3-korg