summaryrefslogtreecommitdiffstats
path: root/v3po/translate-utils/src/main/java/io
diff options
context:
space:
mode:
Diffstat (limited to 'v3po/translate-utils/src/main/java/io')
-rw-r--r--v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/AbstractSubtreeManagerRegistryBuilderBuilder.java213
-rw-r--r--v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/JsonUtils.java102
-rw-r--r--v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/RWUtils.java186
-rw-r--r--v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/ReflectionUtils.java79
-rw-r--r--v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/TransactionMappingContext.java75
-rw-r--r--v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/AbstractGenericReader.java90
-rw-r--r--v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/BindingBrokerReader.java96
-rw-r--r--v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/KeepaliveReaderWrapper.java173
-rw-r--r--v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/NoopReaderCustomizer.java34
-rw-r--r--v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveListReaderCustomizer.java65
-rw-r--r--v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveReader.java57
-rw-r--r--v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveReaderCustomizer.java103
-rw-r--r--v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/CompositeReader.java202
-rw-r--r--v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/CompositeReaderRegistry.java117
-rw-r--r--v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/CompositeReaderRegistryBuilder.java109
-rw-r--r--v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/SubtreeReader.java250
-rw-r--r--v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/TypeHierarchy.java101
-rw-r--r--v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/AbstractGenericWriter.java137
-rw-r--r--v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/NoopWriterRegistry.java40
-rw-r--r--v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/TransactionWriteContext.java121
-rw-r--r--v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/registry/FlatWriterRegistry.java315
-rw-r--r--v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/registry/FlatWriterRegistryBuilder.java71
-rw-r--r--v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/registry/SubtreeWriter.java85
23 files changed, 0 insertions, 2821 deletions
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/AbstractSubtreeManagerRegistryBuilderBuilder.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/AbstractSubtreeManagerRegistryBuilderBuilder.java
deleted file mode 100644
index 23a66337f..000000000
--- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/AbstractSubtreeManagerRegistryBuilderBuilder.java
+++ /dev/null
@@ -1,213 +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.translate.util;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Sets;
-import io.fd.honeycomb.v3po.translate.ModifiableSubtreeManagerRegistryBuilder;
-import io.fd.honeycomb.v3po.translate.SubtreeManager;
-import io.fd.honeycomb.v3po.translate.SubtreeManagerRegistryBuilder;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import javax.annotation.Nonnull;
-import org.jgrapht.experimental.dag.DirectedAcyclicGraph;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-public abstract class AbstractSubtreeManagerRegistryBuilderBuilder<S extends SubtreeManager<? extends DataObject>, R>
- implements ModifiableSubtreeManagerRegistryBuilder<S>, SubtreeManagerRegistryBuilder<R>, AutoCloseable {
-
- // Using directed acyclic graph to represent the ordering relationships between writers
- private final DirectedAcyclicGraph<InstanceIdentifier<?>, Order>
- handlersRelations = new DirectedAcyclicGraph<>((sourceVertex, targetVertex) -> new Order());
- private final Map<InstanceIdentifier<?>, S> handlersMap = new HashMap<>();
-
- /**
- * Add handler without any special relationship to any other type.
- */
- @Override
- public AbstractSubtreeManagerRegistryBuilderBuilder<S, R> add(@Nonnull final S handler) {
- // Make IID wildcarded just in case
- // + the way InstanceIdentifier.create + equals work for Identifiable items is unexpected, meaning updates would
- // not be matched to writers in registry
- final InstanceIdentifier<?> targetType = RWUtils.makeIidWildcarded(handler.getManagedDataObjectType());
- checkWriterNotPresentYet(targetType);
- handlersRelations.addVertex(targetType);
- handlersMap.put(targetType, handler);
- return this;
- }
-
- /**
- * Add handler without any special relationship to any other type.
- */
- @Override
- public AbstractSubtreeManagerRegistryBuilderBuilder<S, R> subtreeAdd(@Nonnull final Set<InstanceIdentifier<?>> handledChildren,
- @Nonnull final S handler) {
- add(getSubtreeHandler(handledChildren, handler));
- return this;
- }
-
- private void checkWriterNotPresentYet(final InstanceIdentifier<?> targetType) {
- Preconditions.checkArgument(!handlersMap.containsKey(targetType),
- "Writer for type: %s already present: %s", targetType, handlersMap.get(targetType));
- }
-
- /**
- * Add handler with relationship: to be executed before handler handling relatedType.
- */
- @Override
- public AbstractSubtreeManagerRegistryBuilderBuilder<S, R> addBefore(@Nonnull final S handler,
- @Nonnull final InstanceIdentifier<?> relatedType) {
- final InstanceIdentifier<?> targetType = RWUtils.makeIidWildcarded(handler.getManagedDataObjectType());
- final InstanceIdentifier<?> wildcardedRelatedType = RWUtils.makeIidWildcarded(relatedType);
- checkWriterNotPresentYet(targetType);
- handlersRelations.addVertex(targetType);
- handlersRelations.addVertex(wildcardedRelatedType);
- addEdge(targetType, wildcardedRelatedType);
- handlersMap.put(targetType, handler);
- return this;
- }
-
- @Override
- public AbstractSubtreeManagerRegistryBuilderBuilder<S, R> addBefore(@Nonnull final S handler,
- @Nonnull final Collection<InstanceIdentifier<?>> relatedTypes) {
- final InstanceIdentifier<?> targetType = RWUtils.makeIidWildcarded(handler.getManagedDataObjectType());
- checkWriterNotPresentYet(targetType);
- handlersRelations.addVertex(targetType);
- relatedTypes.stream()
- .map(RWUtils::makeIidWildcarded)
- .forEach(handlersRelations::addVertex);
- relatedTypes.stream()
- .map(RWUtils::makeIidWildcarded)
- .forEach(type -> addEdge(targetType, type));
- handlersMap.put(targetType, handler);
- return this;
- }
-
- @Override
- public AbstractSubtreeManagerRegistryBuilderBuilder<S, R> subtreeAddBefore(
- @Nonnull final Set<InstanceIdentifier<?>> handledChildren,
- @Nonnull final S handler,
- @Nonnull final InstanceIdentifier<?> relatedType) {
- return addBefore(getSubtreeHandler(handledChildren, handler), relatedType);
- }
-
- @Override
- public AbstractSubtreeManagerRegistryBuilderBuilder<S, R> subtreeAddBefore(
- @Nonnull final Set<InstanceIdentifier<?>> handledChildren,
- @Nonnull final S handler,
- @Nonnull final Collection<InstanceIdentifier<?>> relatedTypes) {
- return addBefore(getSubtreeHandler(handledChildren, handler), relatedTypes);
- }
-
- protected abstract S getSubtreeHandler(@Nonnull final Set<InstanceIdentifier<?>> handledChildren,
- @Nonnull final S handler);
-
- /**
- * Add handler with relationship: to be executed after handler handling relatedType.
- */
- @Override
- public AbstractSubtreeManagerRegistryBuilderBuilder<S, R> addAfter(@Nonnull final S handler,
- @Nonnull final InstanceIdentifier<?> relatedType) {
- final InstanceIdentifier<?> targetType = RWUtils.makeIidWildcarded(handler.getManagedDataObjectType());
- final InstanceIdentifier<?> wildcardedRelatedType = RWUtils.makeIidWildcarded(relatedType);
- checkWriterNotPresentYet(targetType);
- handlersRelations.addVertex(targetType);
- handlersRelations.addVertex(wildcardedRelatedType);
- // set edge to indicate before relationship, just reversed
- addEdge(wildcardedRelatedType, targetType);
- handlersMap.put(targetType, handler);
- return this;
- }
-
- @Override
- public AbstractSubtreeManagerRegistryBuilderBuilder<S, R> addAfter(@Nonnull final S handler,
- @Nonnull final Collection<InstanceIdentifier<?>> relatedTypes) {
- final InstanceIdentifier<?> targetType = RWUtils.makeIidWildcarded(handler.getManagedDataObjectType());
- checkWriterNotPresentYet(targetType);
- handlersRelations.addVertex(targetType);
- relatedTypes.stream()
- .map(RWUtils::makeIidWildcarded)
- .forEach(handlersRelations::addVertex);
- // set edge to indicate before relationship, just reversed
- relatedTypes.stream()
- .map(RWUtils::makeIidWildcarded)
- .forEach(type -> addEdge(type, targetType));
- handlersMap.put(targetType, handler);
- return this;
- }
-
- @Override
- public AbstractSubtreeManagerRegistryBuilderBuilder<S, R> subtreeAddAfter(
- @Nonnull final Set<InstanceIdentifier<?>> handledChildren,
- @Nonnull final S handler,
- @Nonnull final InstanceIdentifier<?> relatedType) {
- return addAfter(getSubtreeHandler(handledChildren, handler), relatedType);
- }
-
- @Override
- public AbstractSubtreeManagerRegistryBuilderBuilder<S, R> subtreeAddAfter(
- @Nonnull final Set<InstanceIdentifier<?>> handledChildren,
- @Nonnull final S handler,
- @Nonnull final Collection<InstanceIdentifier<?>> relatedTypes) {
- return addAfter(getSubtreeHandler(handledChildren, handler), relatedTypes);
- }
-
-
- private void addEdge(final InstanceIdentifier<?> targetType,
- final InstanceIdentifier<?> relatedType) {
- try {
- handlersRelations.addDagEdge(targetType, relatedType);
- } catch (DirectedAcyclicGraph.CycleFoundException e) {
- throw new IllegalArgumentException(String.format(
- "Unable to add writer with relation: %s -> %s. Loop detected", targetType, relatedType), e);
- }
- }
-
- protected ImmutableMap<InstanceIdentifier<?>, S> getMappedHandlers() {
- final ImmutableMap.Builder<InstanceIdentifier<?>, S> builder = ImmutableMap.builder();
- // Iterate writer types according to their relationships from graph
- handlersRelations.iterator()
- .forEachRemaining(writerType -> {
- // There might be types stored just for relationship sake, no real writer, ignoring those
- if (handlersMap.containsKey(writerType)) {
- builder.put(writerType, handlersMap.get(writerType));
- }
- });
-
- // TODO we could optimize subtree handlers, if there is a dedicated handler for a node managed by a subtree
- // handler, recreate the subtree handler with a subset of handled child nodes
- // This way it is not necessary to change the configuration of subtree writer, just to add a dedicated child
- // writer. This will be needed if we ever switch to annotations for reader/writer hierarchy initialization
-
- return builder.build();
- }
-
- @Override
- public void close() throws Exception {
- handlersMap.clear();
- // Wrap sets into another set to avoid concurrent modification ex in graph
- handlersRelations.removeAllEdges(Sets.newHashSet(handlersRelations.edgeSet()));
- handlersRelations.removeAllVertices(Sets.newHashSet(handlersRelations.vertexSet()));
- }
-
- // Represents edges in graph
- private class Order {}
-}
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/JsonUtils.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/JsonUtils.java
deleted file mode 100644
index d9798d07d..000000000
--- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/JsonUtils.java
+++ /dev/null
@@ -1,102 +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.translate.util;
-
-import com.google.common.base.Charsets;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import javax.annotation.Nonnull;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
-import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactory;
-import org.opendaylight.yangtools.yang.data.codec.gson.JSONNormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.codec.gson.JsonParserStream;
-import org.opendaylight.yangtools.yang.data.codec.gson.JsonWriterFactory;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-
-public final class JsonUtils {
-
- private JsonUtils() {}
-
- /**
- * Serialize normalized node root structure into provided output stream
- *
- * @throws IOException if serialized data cannot be written into provided output stream
- */
- public static void writeJsonRoot(@Nonnull final NormalizedNode<?, ?> rootData,
- @Nonnull final SchemaContext schemaContext,
- @Nonnull final OutputStream outputStream) throws IOException {
- final JsonWriter
- jsonWriter = createJsonWriter(outputStream, true);
- final NormalizedNodeStreamWriter streamWriter = JSONNormalizedNodeStreamWriter
- .createNestedWriter(JSONCodecFactory.create(schemaContext), SchemaPath.ROOT, null, jsonWriter);
- final NormalizedNodeWriter normalizedNodeWriter =
- NormalizedNodeWriter.forStreamWriter(streamWriter, true);
- jsonWriter.beginObject();
- writeChildren(normalizedNodeWriter,(ContainerNode) rootData);
- jsonWriter.endObject();
- jsonWriter.flush();
- }
-
- /**
- * Read json serialized normalized node root structure and parse them into normalized nodes
- *
- * @return artificial normalized node holding all the top level nodes from provided stream as children. In case
- * the stream is empty, empty artificial normalized node is returned
- *
- * @throws IllegalArgumentException if content in the provided input stream is not restore-able
- */
- public static ContainerNode readJsonRoot(@Nonnull final SchemaContext schemaContext,
- @Nonnull final InputStream stream) {
- final DataContainerNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifier, ContainerNode> builder =
- Builders.containerBuilder().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(schemaContext.getQName()));
- final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(builder);
-
- final JsonParserStream jsonParser = JsonParserStream.create(writer, schemaContext);
- final JsonReader reader = new JsonReader(new InputStreamReader(stream, Charsets.UTF_8));
- jsonParser.parse(reader);
-
- return builder.build();
- }
-
- private static void writeChildren(final NormalizedNodeWriter nnWriter, final ContainerNode data) throws IOException {
- for(final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> child : data.getValue()) {
- nnWriter.write(child);
- }
- }
-
- private static JsonWriter createJsonWriter(final OutputStream entityStream, boolean prettyPrint) {
- if (prettyPrint) {
- return JsonWriterFactory.createJsonWriter(new OutputStreamWriter(entityStream, Charsets.UTF_8), 2);
- } else {
- return JsonWriterFactory.createJsonWriter(new OutputStreamWriter(entityStream, Charsets.UTF_8));
- }
- }
-}
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/RWUtils.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/RWUtils.java
deleted file mode 100644
index 2a565d9f2..000000000
--- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/RWUtils.java
+++ /dev/null
@@ -1,186 +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.translate.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.translate.SubtreeManager;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collector;
-import java.util.stream.Collectors;
-import java.util.stream.StreamSupport;
-import javax.annotation.Nonnull;
-import org.opendaylight.yangtools.yang.binding.Augmentation;
-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 RWUtils {
-
- private RWUtils() {}
-
- /**
- * Collector expecting only a single resulting item from a stream
- */
- public static<T> Collector<T,?,T> singleItemCollector() {
- return Collectors.collectingAndThen(
- Collectors.toList(),
- list -> {
- if (list.size() != 1) {
- throw new IllegalStateException("Unexpected size of list: " + list + ". Single item expected");
- }
- return list.get(0);
- }
- );
- }
-
- /**
- * Find next item in ID after provided type
- */
- @Nonnull
- public static InstanceIdentifier.PathArgument getNextId(@Nonnull final InstanceIdentifier<? extends DataObject> id,
- @Nonnull final InstanceIdentifier<? extends DataObject> type) {
- // TODO this is inefficient(maybe, depending on actual Iterable type)
- final Iterable<InstanceIdentifier.PathArgument> pathArguments = id.getPathArguments();
- final int i = Iterables.indexOf(pathArguments, new Predicate<InstanceIdentifier.PathArgument>() {
- @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);
- }
-
- /**
- * Replace last item in ID with a provided IdentifiableItem of the same type
- */
- @SuppressWarnings("unchecked")
- @Nonnull
- public static <D extends DataObject & Identifiable<K>, K extends Identifier<D>> InstanceIdentifier<D> replaceLastInId(
- @Nonnull final InstanceIdentifier<D> id, final InstanceIdentifier.IdentifiableItem<D, K> currentBdItem) {
-
- final Iterable<InstanceIdentifier.PathArgument> pathArguments = id.getPathArguments();
- final Iterable<InstanceIdentifier.PathArgument> withoutCurrent =
- Iterables.limit(pathArguments, Iterables.size(pathArguments) - 1);
- final Iterable<InstanceIdentifier.PathArgument> concat =
- Iterables.concat(withoutCurrent, Collections.singleton(currentBdItem));
- return (InstanceIdentifier<D>) InstanceIdentifier.create(concat);
- }
-
- /**
- * Create IdentifiableItem from target type of provided ID with provided key
- */
- @Nonnull
- public static <D extends DataObject & Identifiable<K>, K extends Identifier<D>> InstanceIdentifier.IdentifiableItem<D, K> getCurrentIdItem(
- @Nonnull final InstanceIdentifier<D> id, final K key) {
- return new InstanceIdentifier.IdentifiableItem<>(id.getTargetType(), key);
- }
-
- /**
- * Trim InstanceIdentifier at indexOf(type)
- */
- @SuppressWarnings("unchecked")
- @Nonnull
- public static <D extends DataObject> InstanceIdentifier<D> cutId(@Nonnull final InstanceIdentifier<? extends DataObject> id,
- @Nonnull final InstanceIdentifier<D> type) {
- final Iterable<InstanceIdentifier.PathArgument> pathArguments = id.getPathArguments();
- final int i = Iterables.indexOf(pathArguments, new Predicate<InstanceIdentifier.PathArgument>() {
- @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<D>) InstanceIdentifier.create(Iterables.limit(pathArguments, i + 1));
- }
-
- /**
- * Create an ordered map from a collection, checking for duplicity in the process.
- */
- @Nonnull
- public static <K, V> Map<K, V> uniqueLinkedIndex(@Nonnull final Collection<V> values, @Nonnull final Function<? super V, K> keyFunction) {
- final Map<K, V> 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<SubtreeManager<? extends DataObject>, Class<? extends DataObject>>
- MANAGER_CLASS_FUNCTION = new Function<SubtreeManager<? extends DataObject>, Class<? extends DataObject>>() {
- @Override
- public Class<? extends DataObject> apply(final SubtreeManager<? extends DataObject> input) {
- return input.getManagedDataObjectType().getTargetType();
- }
- };
-
- public static final Function<SubtreeManager<? extends Augmentation<?>>, Class<? extends DataObject>>
- MANAGER_CLASS_AUG_FUNCTION = new Function<SubtreeManager<? extends Augmentation<?>>, Class<? extends DataObject>>() {
-
- @Override
- @SuppressWarnings("unchecked")
- public Class<? extends DataObject> apply(final SubtreeManager<? extends Augmentation<?>> input) {
- final Class<? extends Augmentation<?>> targetType = input.getManagedDataObjectType().getTargetType();
- Preconditions.checkArgument(DataObject.class.isAssignableFrom(targetType));
- return (Class<? extends DataObject>) targetType;
- }
- };
-
- /**
- * Transform a keyed instance identifier into a wildcarded one.
- * <p/>
- * ! This has to be called also for wildcarded List instance identifiers
- * due to weird behavior of equals in InstanceIdentifier !
- */
- @SuppressWarnings("unchecked")
- public static <D extends DataObject> InstanceIdentifier<D> makeIidWildcarded(final InstanceIdentifier<D> id) {
- final List<InstanceIdentifier.PathArgument> transformedPathArguments =
- StreamSupport.stream(id.getPathArguments().spliterator(), false)
- .map(RWUtils::cleanPathArgumentFromKeys)
- .collect(Collectors.toList());
- return (InstanceIdentifier<D>) InstanceIdentifier.create(transformedPathArguments);
- }
-
- /**
- * Transform a keyed instance identifier into a wildcarded one, keeping keys except the last item.
- */
- @SuppressWarnings("unchecked")
- public static <D extends DataObject> InstanceIdentifier<D> makeIidLastWildcarded(final InstanceIdentifier<D> id) {
- final InstanceIdentifier.Item<D> wildcardedItem = new InstanceIdentifier.Item<>(id.getTargetType());
- final Iterable<InstanceIdentifier.PathArgument> pathArguments = id.getPathArguments();
- return (InstanceIdentifier<D>) InstanceIdentifier.create(
- Iterables.concat(
- Iterables.limit(pathArguments, Iterables.size(pathArguments) - 1),
- Collections.singleton(wildcardedItem)));
- }
-
- private static InstanceIdentifier.PathArgument cleanPathArgumentFromKeys(final InstanceIdentifier.PathArgument pathArgument) {
- return pathArgument instanceof InstanceIdentifier.IdentifiableItem<?, ?>
- ? new InstanceIdentifier.Item<>(pathArgument.getType())
- : pathArgument;
- }
-}
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/ReflectionUtils.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/ReflectionUtils.java
deleted file mode 100644
index 728c4f80d..000000000
--- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/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.translate.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<Method> findMethodReflex(@Nonnull final Class<?> managedType,
- @Nonnull final String prefix,
- @Nonnull final List<Class<?>> 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<Class<?>> 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/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/TransactionMappingContext.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/TransactionMappingContext.java
deleted file mode 100644
index 6abc3b1eb..000000000
--- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/TransactionMappingContext.java
+++ /dev/null
@@ -1,75 +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.translate.util;
-
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
-import io.fd.honeycomb.v3po.translate.MappingContext;
-import javax.annotation.Nonnull;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-/**
- * Binding Transaction backed mapping context.
- */
-public class TransactionMappingContext implements MappingContext {
-
- private final ReadWriteTransaction readWriteTransaction;
-
- // TODO make async
-
- public TransactionMappingContext(final ReadWriteTransaction readWriteTransaction) {
- this.readWriteTransaction = readWriteTransaction;
- }
-
- @Override
- public <T extends DataObject> Optional<T> read(@Nonnull final InstanceIdentifier<T> currentId) {
- try {
- return readWriteTransaction.read(LogicalDatastoreType.OPERATIONAL, currentId).checkedGet();
- } catch (ReadFailedException e) {
- throw new IllegalStateException("Unable to perform read", e);
- }
- }
-
- @Override
- public void delete(final InstanceIdentifier<?> path) {
- readWriteTransaction.delete(LogicalDatastoreType.OPERATIONAL, path);
- }
-
- @Override
- public <T extends DataObject> void merge(final InstanceIdentifier<T> path, T data) {
- readWriteTransaction.merge(LogicalDatastoreType.OPERATIONAL, path, data, true);
- }
-
- @Override
- public <T extends DataObject> void put(final InstanceIdentifier<T> path, T data) {
- readWriteTransaction.put(LogicalDatastoreType.OPERATIONAL, path, data, true);
- }
-
- public CheckedFuture<Void, TransactionCommitFailedException> submit() {
- return readWriteTransaction.submit();
- }
-
- @Override
- public void close() {
- readWriteTransaction.cancel();
- }
-}
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/AbstractGenericReader.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/AbstractGenericReader.java
deleted file mode 100644
index 9bfbc2450..000000000
--- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/AbstractGenericReader.java
+++ /dev/null
@@ -1,90 +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.translate.util.read;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Optional;
-import io.fd.honeycomb.v3po.translate.read.ReadContext;
-import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.read.Reader;
-import io.fd.honeycomb.v3po.translate.util.RWUtils;
-import javax.annotation.Nonnull;
-import org.opendaylight.yangtools.concepts.Builder;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Beta
-public abstract class AbstractGenericReader<D extends DataObject, B extends Builder<D>> implements Reader<D, B> {
-
- private static final Logger LOG = LoggerFactory.getLogger(AbstractGenericReader.class);
-
- private final InstanceIdentifier<D> instanceIdentifier;
-
- protected AbstractGenericReader(final InstanceIdentifier<D> managedDataObjectType) {
- this.instanceIdentifier = RWUtils.makeIidWildcarded(managedDataObjectType);
- }
-
- @Nonnull
- @Override
- public final InstanceIdentifier<D> getManagedDataObjectType() {
- return instanceIdentifier;
- }
-
- /**
- * @param id {@link InstanceIdentifier} pointing to current node. In case of keyed list, key must be present.
- *
- */
- protected Optional<D> readCurrent(@Nonnull final InstanceIdentifier<D> id,
- @Nonnull final ReadContext ctx) throws ReadFailedException {
- LOG.debug("{}: Reading current: {}", this, id);
- final B builder = getBuilder(id);
- // Cache empty value to determine if anything has changed later TODO cache in a field
- final D emptyValue = builder.build();
-
- LOG.trace("{}: Reading current attributes", this);
- readCurrentAttributes(id, builder, ctx);
-
- // Need to check whether anything was filled in to determine if data is present or not.
- final D built = builder.build();
- final Optional<D> read = built.equals(emptyValue)
- ? Optional.absent()
- : Optional.of(built);
-
- LOG.debug("{}: Current node read successfully. Result: {}", this, read);
- return read;
- }
-
- @Nonnull
- @Override
- @SuppressWarnings("unchecked")
- public Optional<? extends DataObject> read(@Nonnull final InstanceIdentifier<? extends DataObject> id,
- @Nonnull final ReadContext ctx)
- throws ReadFailedException {
- LOG.trace("{}: Reading : {}", this, id);
- checkArgument(id.getTargetType().equals(getManagedDataObjectType().getTargetType()));
- return readCurrent((InstanceIdentifier<D>) id, ctx);
- }
-
- @Override
- public String toString() {
- return String.format("Reader[%s]", getManagedDataObjectType().getTargetType().getSimpleName());
- }
-}
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/BindingBrokerReader.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/BindingBrokerReader.java
deleted file mode 100644
index 68aa3956e..000000000
--- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/BindingBrokerReader.java
+++ /dev/null
@@ -1,96 +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.translate.util.read;
-
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
-import io.fd.honeycomb.v3po.translate.read.ReadContext;
-import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.read.Reader;
-import javax.annotation.Nonnull;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.yangtools.concepts.Builder;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-/**
- * Simple DataBroker backed reader allowing to delegate reads to different brokers.
- */
-public final class BindingBrokerReader<D extends DataObject, B extends Builder<D>>
- implements Reader<D, B>, AutoCloseable {
-
- private final InstanceIdentifier<D> instanceIdentifier;
- private final DataBroker dataBroker;
- private final LogicalDatastoreType datastoreType;
- private final ReflexiveReaderCustomizer<D, B> reflexiveReaderCustomizer;
-
- public BindingBrokerReader(final InstanceIdentifier<D> instanceIdentifier,
- final DataBroker dataBroker,
- final LogicalDatastoreType datastoreType,
- final Class<B> builderClass) {
- this.reflexiveReaderCustomizer = new ReflexiveReaderCustomizer<>(instanceIdentifier.getTargetType(), builderClass);
- this.instanceIdentifier = instanceIdentifier;
- this.dataBroker = dataBroker;
- this.datastoreType = datastoreType;
- }
-
- @Nonnull
- @Override
- public Optional<? extends DataObject> read(@Nonnull final InstanceIdentifier<? extends DataObject> id,
- @Nonnull final ReadContext ctx) throws ReadFailedException {
- try (final ReadOnlyTransaction readOnlyTransaction = dataBroker.newReadOnlyTransaction()) {
- final CheckedFuture<? extends Optional<? extends DataObject>, org.opendaylight.controller.md.sal.common.api.data.ReadFailedException>
- read = readOnlyTransaction.read(datastoreType, id);
- try {
- return read.checkedGet();
- } catch (org.opendaylight.controller.md.sal.common.api.data.ReadFailedException e) {
- throw new ReadFailedException(id, e);
- }
- }
- }
-
- @Override
- public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, @Nonnull final D readValue) {
- reflexiveReaderCustomizer.merge(parentBuilder, readValue);
- }
-
- @Nonnull
- @Override
- public B getBuilder(final InstanceIdentifier<D> id) {
- return reflexiveReaderCustomizer.getBuilder(id);
- }
-
- @Override
- public void readCurrentAttributes(@Nonnull final InstanceIdentifier<D> id,
- @Nonnull final B builder,
- @Nonnull final ReadContext ctx) throws ReadFailedException {
- throw new UnsupportedOperationException("Not supported");
- }
-
- @Nonnull
- @Override
- public InstanceIdentifier<D> getManagedDataObjectType() {
- return instanceIdentifier;
- }
-
- @Override
- public void close() throws Exception {
- // Noop
- }
-}
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/KeepaliveReaderWrapper.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/KeepaliveReaderWrapper.java
deleted file mode 100644
index d782bcc7f..000000000
--- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/KeepaliveReaderWrapper.java
+++ /dev/null
@@ -1,173 +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.translate.util.read;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import io.fd.honeycomb.v3po.translate.MappingContext;
-import io.fd.honeycomb.v3po.translate.ModificationCache;
-import io.fd.honeycomb.v3po.translate.read.ReadContext;
-import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.read.Reader;
-import java.io.Closeable;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
-import javax.annotation.Nonnegative;
-import javax.annotation.Nonnull;
-import org.opendaylight.yangtools.concepts.Builder;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Reader wrapper that periodically invokes a read to determine whether reads are still fully functional.
- * In case a specific error occurs, Keep-alive failure listener gets notified.
- */
-public final class KeepaliveReaderWrapper<D extends DataObject, B extends Builder<D>> implements Reader<D, B>, Runnable, Closeable {
-
- private static final Logger LOG = LoggerFactory.getLogger(KeepaliveReaderWrapper.class);
-
- private static final NoopReadContext CTX = new NoopReadContext();
-
- private final Reader<D, B> delegate;
- private final Class<? extends Exception> exceptionType;
- private final KeepaliveFailureListener failureListener;
- private final ScheduledFuture<?> scheduledFuture;
-
- /**
- * Create new Keepalive wrapper
- *
- * @param delegate underlying reader performing actual reads
- * @param executor scheduled executor service to schedule keepalive calls
- * @param exception type of exception used to differentiate keepalive exception from other exceptions
- * @param delayInSeconds number of seconds to wait between keepalive calls
- * @param failureListener listener to be called whenever a keepalive failure is detected
- */
- public KeepaliveReaderWrapper(@Nonnull final Reader<D, B> delegate,
- @Nonnull final ScheduledExecutorService executor,
- @Nonnull final Class<? extends Exception> exception,
- @Nonnegative final int delayInSeconds,
- @Nonnull final KeepaliveFailureListener failureListener) {
- this.delegate = delegate;
- this.exceptionType = exception;
- this.failureListener = failureListener;
- Preconditions.checkArgument(delayInSeconds > 0, "Delay cannot be < 0");
- LOG.debug("Starting keep-alive execution on top of: {} with delay of: {} seconds", delegate, delayInSeconds);
- scheduledFuture = executor.scheduleWithFixedDelay(this, delayInSeconds, delayInSeconds, TimeUnit.SECONDS);
- }
-
- @Nonnull
- public Optional<? extends DataObject> read(@Nonnull final InstanceIdentifier id,
- @Nonnull final ReadContext ctx) throws ReadFailedException {
- return delegate.read(id, ctx);
- }
-
- public void readCurrentAttributes(@Nonnull final InstanceIdentifier<D> id,
- @Nonnull final B builder,
- @Nonnull final ReadContext ctx) throws ReadFailedException {
- delegate.readCurrentAttributes(id, builder, ctx);
- }
-
- @Nonnull
- public B getBuilder(final InstanceIdentifier<D> id) {
- return delegate.getBuilder(id);
- }
-
- public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder,
- @Nonnull final D readValue) {
- delegate.merge(parentBuilder, readValue);
- }
-
- @Nonnull
- @Override
- public InstanceIdentifier<D> getManagedDataObjectType() {
- return delegate.getManagedDataObjectType();
- }
-
- @Override
- public void run() {
- LOG.trace("Invoking keepalive");
- try {
- final Optional<? extends DataObject> read = read(delegate.getManagedDataObjectType(), CTX);
- LOG.debug("Keepalive executed successfully with data: {}", read);
- } catch (Exception e) {
- if (exceptionType.isAssignableFrom(e.getClass())) {
- LOG.warn("Keepalive failed. Notifying listener", e);
- failureListener.onKeepaliveFailure();
- }
- LOG.warn("Keepalive failed unexpectedly", e);
- throw new IllegalArgumentException("Unexpected failure during keep-alive execution", e);
- }
- }
-
- @Override
- public void close() {
- // Do not interrupt, it's not our executor
- scheduledFuture.cancel(false);
- }
-
- /**
- * Listener that gets called whenever keepalive fails as expected
- */
- public interface KeepaliveFailureListener {
-
- void onKeepaliveFailure();
- }
-
- private static final class NoopMappingContext implements MappingContext {
- @Override
- public <T extends DataObject> Optional<T> read(@Nonnull final InstanceIdentifier<T> currentId) {
- return Optional.absent();
- }
-
- @Override
- public void delete(final InstanceIdentifier<?> path) {}
-
- @Override
- public <T extends DataObject> void merge(final InstanceIdentifier<T> path, final T data) {}
-
- @Override
- public <T extends DataObject> void put(final InstanceIdentifier<T> path, final T data) {}
-
- @Override
- public void close() {}
- }
-
- private static class NoopReadContext implements ReadContext {
-
- private final ModificationCache modificationCache = new ModificationCache();
-
- @Nonnull
- @Override
- public ModificationCache getModificationCache() {
- return modificationCache;
- }
-
- @Nonnull
- @Override
- public MappingContext getMappingContext() {
- return new NoopMappingContext();
- }
-
- @Override
- public void close() {
-
- }
- }
-}
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/NoopReaderCustomizer.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/NoopReaderCustomizer.java
deleted file mode 100644
index a4de9febb..000000000
--- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/NoopReaderCustomizer.java
+++ /dev/null
@@ -1,34 +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.translate.util.read;
-
-import io.fd.honeycomb.v3po.translate.read.ReadContext;
-import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.spi.read.ReaderCustomizer;
-import org.opendaylight.yangtools.concepts.Builder;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-public abstract class NoopReaderCustomizer<C extends DataObject, B extends Builder<C>> implements
- ReaderCustomizer<C, B> {
-
- @Override
- public void readCurrentAttributes(InstanceIdentifier<C> id, final B builder, final ReadContext context) throws
- ReadFailedException {
- // Noop
- }
-}
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveListReaderCustomizer.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveListReaderCustomizer.java
deleted file mode 100644
index 8ad323cc3..000000000
--- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveListReaderCustomizer.java
+++ /dev/null
@@ -1,65 +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.translate.util.read;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import com.google.common.base.Optional;
-import io.fd.honeycomb.v3po.translate.spi.read.ListReaderCustomizer;
-import io.fd.honeycomb.v3po.translate.util.ReflectionUtils;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Collections;
-import java.util.List;
-import javax.annotation.Nonnull;
-import org.opendaylight.yangtools.concepts.Builder;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.Identifiable;
-import org.opendaylight.yangtools.yang.binding.Identifier;
-
-/**
- * Might be slow !
- */
-public abstract class ReflexiveListReaderCustomizer<C extends DataObject & Identifiable<K>, K extends Identifier<C>, B extends Builder<C>>
- extends ReflexiveReaderCustomizer<C, B>
- implements ListReaderCustomizer<C, K, B> {
-
-
- public ReflexiveListReaderCustomizer(final Class<C> typeClass, final Class<B> builderClass) {
- super(typeClass, builderClass);
- }
-
- @Override
- public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, @Nonnull final C readValue) {
- merge(parentBuilder, Collections.singletonList(readValue));
- }
-
- @Override
- public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, @Nonnull final List<C> readData) {
- final Optional<Method> method =
- ReflectionUtils.findMethodReflex(parentBuilder.getClass(), "set" + getTypeClass().getSimpleName(),
- Collections.singletonList(List.class), parentBuilder.getClass());
-
- checkArgument(method.isPresent(), "Unable to set %s to %s", readData, parentBuilder);
-
- try {
- method.get().invoke(parentBuilder, readData);
- } catch (IllegalAccessException | InvocationTargetException e) {
- throw new IllegalArgumentException("Unable to set " + readData + " to " + parentBuilder, e);
- }
- }
-}
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveReader.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveReader.java
deleted file mode 100644
index 2b2d9300b..000000000
--- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveReader.java
+++ /dev/null
@@ -1,57 +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.translate.util.read;
-
-import io.fd.honeycomb.v3po.translate.read.ReadContext;
-import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import javax.annotation.Nonnull;
-import org.opendaylight.yangtools.concepts.Builder;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-/**
- * Reader that performs no read operation on its own, just fills in the hierarchy.
- * <p/>
- * Might be slow due to reflection !
- */
-public class ReflexiveReader<C extends DataObject, B extends Builder<C>> extends AbstractGenericReader<C, B> {
-
- private final ReflexiveReaderCustomizer<C, B> customizer;
-
- public ReflexiveReader(final InstanceIdentifier<C> identifier, final Class<B> builderClass) {
- super(identifier);
- this.customizer = new ReflexiveReaderCustomizer<>(identifier.getTargetType(), builderClass);
- }
-
- @Override
- public void readCurrentAttributes(@Nonnull final InstanceIdentifier<C> id, @Nonnull final B builder,
- @Nonnull final ReadContext ctx)
- throws ReadFailedException {
- customizer.readCurrentAttributes(id, builder, ctx);
- }
-
- @Nonnull
- @Override
- public B getBuilder(final InstanceIdentifier<C> id) {
- return customizer.getBuilder(id);
- }
-
- @Override
- public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, @Nonnull final C readValue) {
- customizer.merge(parentBuilder, readValue);
- }
-}
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveReaderCustomizer.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveReaderCustomizer.java
deleted file mode 100644
index a6b9bf08e..000000000
--- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/ReflexiveReaderCustomizer.java
+++ /dev/null
@@ -1,103 +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.translate.util.read;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import com.google.common.base.Optional;
-import com.google.common.collect.Lists;
-import io.fd.honeycomb.v3po.translate.util.ReflectionUtils;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Collections;
-import javax.annotation.Nonnull;
-import org.opendaylight.yangtools.concepts.Builder;
-import org.opendaylight.yangtools.yang.binding.Augmentation;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-/**
- * Might be slow !
- */
-class ReflexiveReaderCustomizer<C extends DataObject, B extends Builder<C>> extends NoopReaderCustomizer<C, B> {
-
- private final Class<C> typeClass;
- private final Class<B> builderClass;
-
- public ReflexiveReaderCustomizer(final Class<C> typeClass, final Class<B> builderClass) {
- this.typeClass = typeClass;
- this.builderClass = builderClass;
- }
-
- protected Class<C> getTypeClass() {
- return typeClass;
- }
-
- protected Class<B> getBuilderClass() {
- return builderClass;
- }
-
- @Nonnull
- @Override
- public B getBuilder(@Nonnull InstanceIdentifier<C> id) {
- try {
- return builderClass.newInstance();
- } catch (InstantiationException | IllegalAccessException e) {
- throw new IllegalStateException("Unable to instantiate " + builderClass, e);
- }
- }
-
- @Override
- public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, @Nonnull final C readValue) {
- if (Augmentation.class.isAssignableFrom(typeClass)) {
- mergeAugmentation(parentBuilder, (Class<? extends Augmentation<?>>) typeClass, readValue);
- } else {
- mergeRegular(parentBuilder, readValue);
- }
- }
-
- private static void mergeRegular(@Nonnull final Builder<? extends DataObject> parentBuilder,
- @Nonnull final DataObject readValue) {
- final Optional<Method> method =
- ReflectionUtils.findMethodReflex(parentBuilder.getClass(), "set",
- Collections.singletonList(readValue.getClass()), parentBuilder.getClass());
-
- 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);
- }
- }
-
- private static void mergeAugmentation(@Nonnull final Builder<? extends DataObject> parentBuilder,
- @Nonnull final Class<? extends Augmentation<?>> typeClass,
- @Nonnull final DataObject readValue) {
- final Optional<Method> method =
- ReflectionUtils.findMethodReflex(parentBuilder.getClass(), "addAugmentation",
- Lists.newArrayList(Class.class, Augmentation.class), parentBuilder.getClass());
-
- checkArgument(method.isPresent(), "Not possible to add augmentations to builder: %s", parentBuilder);
- try {
- method.get().invoke(parentBuilder, typeClass, readValue);
- } catch (IllegalAccessException | InvocationTargetException e) {
- throw new IllegalArgumentException("Unable to set " + readValue + " to " + parentBuilder, e);
- }
- }
-
-}
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/CompositeReader.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/CompositeReader.java
deleted file mode 100644
index aa9b2dc92..000000000
--- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/CompositeReader.java
+++ /dev/null
@@ -1,202 +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.translate.util.read.registry;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-import io.fd.honeycomb.v3po.translate.read.ListReader;
-import io.fd.honeycomb.v3po.translate.read.ReadContext;
-import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.read.Reader;
-import io.fd.honeycomb.v3po.translate.util.RWUtils;
-import io.fd.honeycomb.v3po.translate.util.read.AbstractGenericReader;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import javax.annotation.Nonnull;
-import org.opendaylight.yangtools.concepts.Builder;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.Identifiable;
-import org.opendaylight.yangtools.yang.binding.Identifier;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-class CompositeReader<D extends DataObject, B extends Builder<D>> extends AbstractGenericReader<D, B> {
-
- private static final Logger LOG = LoggerFactory.getLogger(CompositeReader.class);
-
- private final Reader<D, B> delegate;
- private final ImmutableMap<Class<?>, Reader<? extends DataObject, ? extends Builder<?>>> childReaders;
-
- private CompositeReader(final Reader<D, B> reader,
- final ImmutableMap<Class<?>, Reader<? extends DataObject, ? extends Builder<?>>> childReaders) {
- super(reader.getManagedDataObjectType());
- this.delegate = reader;
- this.childReaders = childReaders;
- }
-
- @VisibleForTesting
- ImmutableMap<Class<?>, Reader<? extends DataObject, ? extends Builder<?>>> getChildReaders() {
- return childReaders;
- }
-
- @SuppressWarnings("unchecked")
- public static <D extends DataObject> InstanceIdentifier<D> appendTypeToId(
- final InstanceIdentifier<? extends DataObject> parentId, final InstanceIdentifier<D> type) {
- final InstanceIdentifier.PathArgument t = new InstanceIdentifier.Item<>(type.getTargetType());
- return (InstanceIdentifier<D>) InstanceIdentifier.create(Iterables.concat(
- parentId.getPathArguments(), Collections.singleton(t)));
- }
-
- @Nonnull
- @Override
- public Optional<? extends DataObject> read(@Nonnull final InstanceIdentifier<? extends DataObject> id,
- @Nonnull final ReadContext ctx) throws ReadFailedException {
- if (shouldReadCurrent(id)) {
- LOG.trace("{}: Reading current: {}", this, id);
- return readCurrent((InstanceIdentifier<D>) id, ctx);
- } else if (shouldDelegateToChild(id)) {
- LOG.trace("{}: Reading child: {}", this, id);
- return readSubtree(id, ctx);
- } else {
- // Fallback
- LOG.trace("{}: Delegating read: {}", this, id);
- return delegate.read(id, ctx);
- }
- }
-
- private boolean shouldReadCurrent(@Nonnull final InstanceIdentifier<? extends DataObject> id) {
- return id.getTargetType().equals(getManagedDataObjectType().getTargetType());
- }
-
- private boolean shouldDelegateToChild(@Nonnull final InstanceIdentifier<? extends DataObject> id) {
- return childReaders.containsKey(RWUtils.getNextId(id, getManagedDataObjectType()).getType());
- }
-
- private Optional<? extends DataObject> readSubtree(final InstanceIdentifier<? extends DataObject> id,
- final ReadContext ctx) throws ReadFailedException {
- final InstanceIdentifier.PathArgument nextId = RWUtils.getNextId(id, getManagedDataObjectType());
- final Reader<?, ? extends Builder<?>> nextReader = childReaders.get(nextId.getType());
- checkArgument(nextReader != null, "Unable to read: %s. No delegate present, available readers at next level: %s",
- id, childReaders.keySet());
- return nextReader.read(id, ctx);
- }
-
- @SuppressWarnings("unchecked")
- private void readChildren(final InstanceIdentifier<D> id, @Nonnull final ReadContext ctx, final B builder)
- throws ReadFailedException {
- LOG.debug("{}: Reading children: {}", this, childReaders.keySet());
- for (Reader child : childReaders.values()) {
- final InstanceIdentifier childId = appendTypeToId(id, child.getManagedDataObjectType());
-
- LOG.debug("{}: Reading child from: {}", this, child);
- if (child instanceof ListReader) {
- final List<? extends DataObject> list = ((ListReader) child).readList(childId, ctx);
- ((ListReader) child).merge(builder, list);
- } else {
- final Optional<? extends DataObject> read = child.read(childId, ctx);
- if (read.isPresent()) {
- child.merge(builder, read.get());
- }
- }
- }
- }
-
- @Override
- public void readCurrentAttributes(@Nonnull final InstanceIdentifier<D> id, @Nonnull final B builder,
- @Nonnull final ReadContext ctx)
- throws ReadFailedException {
- delegate.readCurrentAttributes(id, builder, ctx);
- readChildren(id, ctx, builder);
- }
-
- @Nonnull
- @Override
- public B getBuilder(final InstanceIdentifier<D> id) {
- return delegate.getBuilder(id);
- }
-
- @Override
- public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, @Nonnull final D readValue) {
- delegate.merge(parentBuilder, readValue);
- }
-
- /**
- * Wrap a Reader as a Composite Reader.
- */
- static <D extends DataObject, B extends Builder<D>> Reader<D, B> createForReader(
- @Nonnull final Reader<D, B> reader,
- @Nonnull final ImmutableMap<Class<?>, Reader<?, ? extends Builder<?>>> childReaders) {
-
- return (reader instanceof ListReader)
- ? new CompositeListReader<>((ListReader) reader, childReaders)
- : new CompositeReader<>(reader, childReaders);
- }
-
- private static class CompositeListReader<D extends DataObject & Identifiable<K>, B extends Builder<D>, K extends Identifier<D>>
- extends CompositeReader<D, B>
- implements ListReader<D, K, B> {
-
- private final ListReader<D, K, B> delegate;
-
- private CompositeListReader(final ListReader<D, K, B> reader,
- final ImmutableMap<Class<?>, Reader<? extends DataObject, ? extends Builder<?>>> childReaders) {
- super(reader, childReaders);
- this.delegate = reader;
- }
-
- @Nonnull
- @Override
- public List<D> readList(@Nonnull final InstanceIdentifier<D> id, @Nonnull final ReadContext ctx)
- throws ReadFailedException {
- LOG.trace("{}: Reading all list entries", this);
- final List<K> allIds = delegate.getAllIds(id, ctx);
- LOG.debug("{}: Reading list entries for: {}", this, allIds);
-
- // Override read list in order to perform readCurrent + readChildren here
- final ArrayList<D> allEntries = new ArrayList<>(allIds.size());
- for (K key : allIds) {
- final InstanceIdentifier.IdentifiableItem<D, K> currentBdItem = RWUtils.getCurrentIdItem(id, key);
- final InstanceIdentifier<D> keyedId = RWUtils.replaceLastInId(id, currentBdItem);
- final Optional<D> read = readCurrent(keyedId, ctx);
- if (read.isPresent()) {
- final DataObject singleItem = read.get();
- checkArgument(getManagedDataObjectType().getTargetType().isAssignableFrom(singleItem.getClass()));
- allEntries.add(getManagedDataObjectType().getTargetType().cast(singleItem));
- }
- }
- return allEntries;
- }
-
- @Override
- public void merge(@Nonnull final Builder<? extends DataObject> builder, @Nonnull final List<D> readData) {
- delegate.merge(builder, readData);
- }
-
- @Override
- public List<K> getAllIds(@Nonnull final InstanceIdentifier<D> id,
- @Nonnull final ReadContext ctx) throws ReadFailedException {
- return delegate.getAllIds(id, ctx);
- }
- }
-
-}
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/CompositeReaderRegistry.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/CompositeReaderRegistry.java
deleted file mode 100644
index a9f606ae2..000000000
--- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/CompositeReaderRegistry.java
+++ /dev/null
@@ -1,117 +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.translate.util.read.registry;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Optional;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.LinkedListMultimap;
-import com.google.common.collect.Multimap;
-import io.fd.honeycomb.v3po.translate.read.ListReader;
-import io.fd.honeycomb.v3po.translate.read.ReadContext;
-import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.read.Reader;
-import io.fd.honeycomb.v3po.translate.read.registry.ReaderRegistry;
-import io.fd.honeycomb.v3po.translate.util.RWUtils;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-import javax.annotation.Nonnull;
-import org.opendaylight.yangtools.concepts.Builder;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * 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.
- * <p/>
- * This could serve as a utility to hold & hide all available readers in upper layers.
- */
-public final class CompositeReaderRegistry implements ReaderRegistry {
-
- private static final Logger LOG = LoggerFactory.getLogger(CompositeReaderRegistry.class);
-
- private final Map<Class<? extends DataObject>, Reader<? extends DataObject, ? extends Builder<?>>> rootReaders;
-
- /**
- * Create new {@link CompositeReaderRegistry}.
- *
- * @param rootReaders List of delegate readers
- */
- public CompositeReaderRegistry(@Nonnull final List<Reader<? extends DataObject, ? extends Builder<?>>> rootReaders) {
- this.rootReaders = RWUtils.uniqueLinkedIndex(checkNotNull(rootReaders), RWUtils.MANAGER_CLASS_FUNCTION);
- }
-
- @VisibleForTesting
- Map<Class<? extends DataObject>, Reader<? extends DataObject, ? extends Builder<?>>> getRootReaders() {
- return rootReaders;
- }
-
- @Override
- @Nonnull
- public Multimap<InstanceIdentifier<? extends DataObject>, ? extends DataObject> readAll(
- @Nonnull final ReadContext ctx) throws ReadFailedException {
-
- LOG.debug("Reading from all delegates: {}", this);
- LOG.trace("Reading from all delegates: {}", rootReaders.values());
-
- final Multimap<InstanceIdentifier<? extends DataObject>, DataObject> objects = LinkedListMultimap.create();
- for (Reader<? extends DataObject, ? extends Builder<?>> rootReader : rootReaders.values()) {
- LOG.debug("Reading from delegate: {}", rootReader);
-
- if (rootReader instanceof ListReader) {
- final List<? extends DataObject> listEntries =
- ((ListReader) rootReader).readList(rootReader.getManagedDataObjectType(), ctx);
- if (!listEntries.isEmpty()) {
- objects.putAll(rootReader.getManagedDataObjectType(), listEntries);
- }
- } else {
- final Optional<? extends DataObject> read = rootReader.read(rootReader.getManagedDataObjectType(), ctx);
- if (read.isPresent()) {
- objects.putAll(rootReader.getManagedDataObjectType(), Collections.singletonList(read.get()));
- }
- }
- }
-
- return objects;
- }
-
- @Nonnull
- @Override
- public Optional<? extends DataObject> read(@Nonnull final InstanceIdentifier<? extends DataObject> id,
- @Nonnull final ReadContext ctx)
- throws ReadFailedException {
- final InstanceIdentifier.PathArgument first = checkNotNull(
- Iterables.getFirst(id.getPathArguments(), null), "Empty id");
- final Reader<? extends DataObject, ? extends Builder<?>> reader = rootReaders.get(first.getType());
- checkNotNull(reader,
- "Unable to read %s. Missing reader. Current readers for: %s", id, rootReaders.keySet());
- LOG.debug("Reading from delegate: {}", reader);
- return reader.read(id, ctx);
- }
-
- @Override
- public String toString() {
- return getClass().getSimpleName()
- + rootReaders.keySet().stream().map(Class::getSimpleName).collect(Collectors.toList());
- }
-}
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/CompositeReaderRegistryBuilder.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/CompositeReaderRegistryBuilder.java
deleted file mode 100644
index 3adda713d..000000000
--- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/CompositeReaderRegistryBuilder.java
+++ /dev/null
@@ -1,109 +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.translate.util.read.registry;
-
-import com.google.common.collect.ImmutableMap;
-import io.fd.honeycomb.v3po.translate.read.Reader;
-import io.fd.honeycomb.v3po.translate.read.registry.ModifiableReaderRegistryBuilder;
-import io.fd.honeycomb.v3po.translate.read.registry.ReaderRegistry;
-import io.fd.honeycomb.v3po.translate.read.registry.ReaderRegistryBuilder;
-import io.fd.honeycomb.v3po.translate.util.AbstractSubtreeManagerRegistryBuilderBuilder;
-import io.fd.honeycomb.v3po.translate.util.read.ReflexiveReader;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
-import javax.annotation.Nonnull;
-import javax.annotation.concurrent.NotThreadSafe;
-import org.opendaylight.yangtools.concepts.Builder;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@NotThreadSafe
-public final class CompositeReaderRegistryBuilder
- extends AbstractSubtreeManagerRegistryBuilderBuilder<Reader<? extends DataObject, ? extends Builder<?>>, ReaderRegistry>
- implements ModifiableReaderRegistryBuilder, ReaderRegistryBuilder {
-
- private static final Logger LOG = LoggerFactory.getLogger(CompositeReaderRegistryBuilder.class);
-
- @Override
- protected Reader<? extends DataObject, ? extends Builder<?>> getSubtreeHandler(@Nonnull final Set<InstanceIdentifier<?>> handledChildren,
- @Nonnull final Reader<? extends DataObject, ? extends Builder<?>> reader) {
- return SubtreeReader.createForReader(handledChildren, reader);
- }
-
- @Override
- public <D extends DataObject> void addStructuralReader(@Nonnull InstanceIdentifier<D> id,
- @Nonnull Class<? extends Builder<D>> builderType) {
- add(new ReflexiveReader<>(id, builderType));
- }
-
- /**
- * Create {@link CompositeReaderRegistry} with Readers ordered according to submitted relationships.
- * <p/>
- * Note: The ordering only applies between nodes on the same level, inter-level and inter-subtree relationships are
- * ignored.
- */
- @Override
- public ReaderRegistry build() {
- ImmutableMap<InstanceIdentifier<?>, Reader<? extends DataObject, ? extends Builder<?>>> mappedReaders =
- getMappedHandlers();
- LOG.debug("Building Reader registry with Readers: {}",
- mappedReaders.keySet().stream()
- .map(InstanceIdentifier::getTargetType)
- .map(Class::getSimpleName)
- .collect(Collectors.joining(", ")));
-
- LOG.trace("Building Reader registry with Readers: {}", mappedReaders);
- final List<InstanceIdentifier<?>> readerOrder = new ArrayList<>(mappedReaders.keySet());
-
- // Wrap readers into composite readers recursively, collect roots and create registry
- final TypeHierarchy typeHierarchy = TypeHierarchy.create(mappedReaders.keySet());
- final List<Reader<? extends DataObject, ? extends Builder<?>>> orderedRootReaders =
- typeHierarchy.getRoots().stream()
- .map(rootId -> toCompositeReader(rootId, mappedReaders, typeHierarchy))
- .collect(Collectors.toList());
-
- // We are violating the ordering from mappedReaders, since we are forming a composite structure
- // but at least order root writers
- orderedRootReaders.sort((reader1, reader2) -> readerOrder.indexOf(reader1.getManagedDataObjectType())
- - readerOrder.indexOf(reader2.getManagedDataObjectType()));
-
- return new CompositeReaderRegistry(orderedRootReaders);
- }
-
- private Reader<? extends DataObject, ? extends Builder<?>> toCompositeReader(
- final InstanceIdentifier<?> instanceIdentifier,
- final ImmutableMap<InstanceIdentifier<?>, Reader<? extends DataObject, ? extends Builder<?>>> mappedReaders,
- final TypeHierarchy typeHierarchy) {
-
- // Order child readers according to the mappedReadersCollection
- final ImmutableMap.Builder<Class<?>, Reader<?, ? extends Builder<?>>> childReadersMapB = ImmutableMap.builder();
- for (InstanceIdentifier<?> childId : mappedReaders.keySet()) {
- if (typeHierarchy.getDirectChildren(instanceIdentifier).contains(childId)) {
- childReadersMapB.put(childId.getTargetType(), toCompositeReader(childId, mappedReaders, typeHierarchy));
- }
- }
-
- final ImmutableMap<Class<?>, Reader<?, ? extends Builder<?>>> childReadersMap = childReadersMapB.build();
- return childReadersMap.isEmpty()
- ? mappedReaders.get(instanceIdentifier)
- : CompositeReader.createForReader(mappedReaders.get(instanceIdentifier), childReadersMap);
- }
-}
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/SubtreeReader.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/SubtreeReader.java
deleted file mode 100644
index 50a20656e..000000000
--- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/SubtreeReader.java
+++ /dev/null
@@ -1,250 +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.translate.util.read.registry;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterables;
-import io.fd.honeycomb.v3po.translate.read.ListReader;
-import io.fd.honeycomb.v3po.translate.read.ReadContext;
-import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.read.Reader;
-import io.fd.honeycomb.v3po.translate.util.RWUtils;
-import io.fd.honeycomb.v3po.translate.util.ReflectionUtils;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import org.opendaylight.yangtools.concepts.Builder;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.Identifiable;
-import org.opendaylight.yangtools.yang.binding.Identifier;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Simple Reader delegate for subtree Readers (Readers handling also children nodes) providing a list of all the
- * children nodes being handled.
- */
-class SubtreeReader<D extends DataObject, B extends Builder<D>> implements Reader<D, B> {
-
- private static final Logger LOG = LoggerFactory.getLogger(SubtreeReader.class);
-
- private final Reader<D, B> delegate;
- private final Set<InstanceIdentifier<?>> handledChildTypes = new HashSet<>();
-
- private SubtreeReader(final Reader<D, B> delegate, Set<InstanceIdentifier<?>> handledTypes) {
- this.delegate = delegate;
- for (InstanceIdentifier<?> handledType : handledTypes) {
- // Iid has to start with Reader's handled root type
- checkArgument(delegate.getManagedDataObjectType().getTargetType().equals(
- handledType.getPathArguments().iterator().next().getType()),
- "Handled node from subtree has to be identified by an instance identifier starting from: %s."
- + "Instance identifier was: %s", getManagedDataObjectType().getTargetType(), handledType);
- checkArgument(Iterables.size(handledType.getPathArguments()) > 1,
- "Handled node from subtree identifier too short: %s", handledType);
- handledChildTypes.add(InstanceIdentifier.create(Iterables.concat(
- getManagedDataObjectType().getPathArguments(), Iterables.skip(handledType.getPathArguments(), 1))));
- }
- }
-
- /**
- * Return set of types also handled by this Reader. All of the types are children of the type managed by this Reader
- * excluding the type of this Reader.
- */
- Set<InstanceIdentifier<?>> getHandledChildTypes() {
- return handledChildTypes;
- }
-
- @Override
- @Nonnull
- public Optional<? extends DataObject> read(
- @Nonnull final InstanceIdentifier<? extends DataObject> id,
- @Nonnull final ReadContext ctx) throws ReadFailedException {
- final InstanceIdentifier<?> wildcarded = RWUtils.makeIidWildcarded(id);
-
- // Reading entire subtree and filtering if is current reader responsible
- if (getHandledChildTypes().contains(wildcarded)) {
- LOG.debug("{}: Subtree node managed by this writer requested: {}. Reading current and filtering", this, id);
- // If there's no dedicated reader, use read current
- final InstanceIdentifier<D> currentId = RWUtils.cutId(id, getManagedDataObjectType());
- final Optional<? extends DataObject> current = delegate.read(currentId, ctx);
- // then perform post-reading filtering (return only requested sub-node)
- final Optional<? extends DataObject> readSubtree = current.isPresent()
- ? filterSubtree(current.get(), id, getManagedDataObjectType().getTargetType())
- : current;
-
- LOG.debug("{}: Subtree: {} read successfully. Result: {}", this, id, readSubtree);
- return readSubtree;
-
- // Fallback solution, try delegate, maybe it can read the ID
- } else {
- return delegate.read(id, ctx);
- }
- }
-
- @Override
- public void readCurrentAttributes(@Nonnull final InstanceIdentifier<D> id, @Nonnull final B builder,
- @Nonnull final ReadContext ctx)
- throws ReadFailedException {
- delegate.readCurrentAttributes(id, builder, ctx);
- }
-
- @Nonnull
- @Override
- public B getBuilder(final InstanceIdentifier<D> id) {
- return delegate.getBuilder(id);
- }
-
- @Override
- public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, @Nonnull final D readValue) {
- delegate.merge(parentBuilder, readValue);
- }
-
- @Nonnull
- private static Optional<? extends DataObject> filterSubtree(@Nonnull final DataObject parent,
- @Nonnull final InstanceIdentifier<? extends DataObject> absolutPath,
- @Nonnull final Class<?> managedType) {
- final InstanceIdentifier.PathArgument nextId =
- RWUtils.getNextId(absolutPath, InstanceIdentifier.create(parent.getClass()));
-
- final Optional<? extends DataObject> nextParent = findNextParent(parent, nextId, managedType);
-
- if (Iterables.getLast(absolutPath.getPathArguments()).equals(nextId)) {
- return nextParent; // we found the dataObject identified by absolutePath
- } else if (nextParent.isPresent()) {
- return filterSubtree(nextParent.get(), absolutPath, nextId.getType());
- } else {
- return nextParent; // we can't go further, return Optional.absent()
- }
- }
-
- private static Optional<? extends DataObject> findNextParent(@Nonnull final DataObject parent,
- @Nonnull final InstanceIdentifier.PathArgument nextId,
- @Nonnull final Class<?> managedType) {
- // TODO is there a better way than reflection ? e.g. convert into NN and filter out with a utility
- Optional<Method> method = ReflectionUtils.findMethodReflex(managedType, "get",
- Collections.emptyList(), nextId.getType());
-
- if (method.isPresent()) {
- return Optional.fromNullable(filterSingle(parent, nextId, method.get()));
- } else {
- // List child nodes
- method = ReflectionUtils.findMethodReflex(managedType,
- "get" + nextId.getType().getSimpleName(), Collections.emptyList(), List.class);
-
- if (method.isPresent()) {
- return filterList(parent, nextId, method.get());
- } else {
- throw new IllegalStateException(
- "Unable to filter " + nextId + " from " + parent + " getters not found using reflexion");
- }
- }
- }
-
- @SuppressWarnings("unchecked")
- private static Optional<? extends DataObject> filterList(final DataObject parent,
- final InstanceIdentifier.PathArgument nextId,
- final Method method) {
- final List<? extends DataObject> invoke = (List<? extends DataObject>) invoke(method, nextId, parent);
-
- checkArgument(nextId instanceof InstanceIdentifier.IdentifiableItem<?, ?>,
- "Unable to perform wildcarded read for %s", nextId);
- final Identifier key = ((InstanceIdentifier.IdentifiableItem) nextId).getKey();
- // TODO replace with stream().filter().findFirst() when we switch to using java's Optional instead of Guava's
- // because now we would have to do awkward Optional transformation since findFirstReturns guava's optional
- return Iterables.tryFind(invoke, new Predicate<DataObject>() {
-
- @Override
- public boolean apply(@Nullable final DataObject input) {
- final Optional<Method> keyGetter = ReflectionUtils.findMethodReflex(nextId.getType(), "get",
- Collections.emptyList(), key.getClass());
- final Object actualKey;
- actualKey = invoke(keyGetter.get(), nextId, input);
- return key.equals(actualKey);
- }
- });
- }
-
- private static DataObject filterSingle(final DataObject parent,
- final InstanceIdentifier.PathArgument nextId, final Method method) {
- return nextId.getType().cast(invoke(method, nextId, parent));
- }
-
- private static Object invoke(final Method method,
- 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);
- }
- }
-
- @Override
- @Nonnull
- public InstanceIdentifier<D> getManagedDataObjectType() {
- return delegate.getManagedDataObjectType();
- }
-
- /**
- * Wrap a Reader as a subtree Reader.
- */
- static <D extends DataObject, B extends Builder<D>> Reader<D, B> createForReader(@Nonnull final Set<InstanceIdentifier<?>> handledChildren,
- @Nonnull final Reader<D, B> reader) {
- return (reader instanceof ListReader)
- ? new SubtreeListReader<>((ListReader) reader, handledChildren)
- : new SubtreeReader<>(reader, handledChildren);
- }
-
- private static final class SubtreeListReader<D extends DataObject & Identifiable<K>, B extends Builder<D>, K extends Identifier<D>>
- extends SubtreeReader<D, B> implements ListReader<D, K, B> {
-
- private final ListReader<D, K, B> delegate;
-
- private SubtreeListReader(final ListReader<D, K, B> delegate,
- final Set<InstanceIdentifier<?>> handledTypes) {
- super(delegate, handledTypes);
- this.delegate = delegate;
- }
-
- @Nonnull
- @Override
- public List<D> readList(@Nonnull final InstanceIdentifier<D> id, @Nonnull final ReadContext ctx)
- throws ReadFailedException {
- return delegate.readList(id, ctx);
- }
-
- @Override
- public void merge(@Nonnull final Builder<? extends DataObject> builder, @Nonnull final List<D> readData) {
- delegate.merge(builder, readData);
- }
-
- @Override
- public List<K> getAllIds(@Nonnull final InstanceIdentifier<D> id,
- @Nonnull final ReadContext ctx) throws ReadFailedException {
- return delegate.getAllIds(id, ctx);
- }
- }
-
-}
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/TypeHierarchy.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/TypeHierarchy.java
deleted file mode 100644
index 005e3bc8d..000000000
--- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/registry/TypeHierarchy.java
+++ /dev/null
@@ -1,101 +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.translate.util.read.registry;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import com.google.common.collect.Iterables;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
-import javax.annotation.Nonnull;
-import org.jgrapht.experimental.dag.DirectedAcyclicGraph;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-final class TypeHierarchy {
- private final DirectedAcyclicGraph<InstanceIdentifier<?>, Parent> hierarchy;
-
- private TypeHierarchy(@Nonnull final DirectedAcyclicGraph<InstanceIdentifier<?>, Parent> hierarchy) {
- this.hierarchy = hierarchy;
- }
-
- Set<InstanceIdentifier<?>> getAllChildren(InstanceIdentifier<?> id) {
- final HashSet<InstanceIdentifier<?>> instanceIdentifiers = new HashSet<>();
- for (InstanceIdentifier<?> childId : getDirectChildren(id)) {
- instanceIdentifiers.add(childId);
- instanceIdentifiers.addAll(getAllChildren(childId));
- }
- return instanceIdentifiers;
- }
-
- Set<InstanceIdentifier<?>> getDirectChildren(InstanceIdentifier<?> id) {
- checkArgument(hierarchy.vertexSet().contains(id),
- "Unknown reader: %s. Known readers: %s", id, hierarchy.vertexSet());
-
- return hierarchy.outgoingEdgesOf(id).stream()
- .map(hierarchy::getEdgeTarget)
- .collect(Collectors.toSet());
- }
-
- Set<InstanceIdentifier<?>> getRoots() {
- return hierarchy.vertexSet().stream()
- .filter(vertex -> hierarchy.incomingEdgesOf(vertex).size() == 0)
- .collect(Collectors.toSet());
- }
-
- /**
- * Create reader hierarchy from a flat set of instance identifiers.
- *
- * @param allIds Set of unkeyed instance identifiers
- */
- static TypeHierarchy create(@Nonnull Set<InstanceIdentifier<?>> allIds) {
- final DirectedAcyclicGraph<InstanceIdentifier<?>, Parent>
- readersHierarchy = new DirectedAcyclicGraph<>((sourceVertex, targetVertex) -> new Parent());
-
- for (InstanceIdentifier<?> allId : allIds) {
- checkArgument(!Iterables.isEmpty(allId.getPathArguments()), "Empty ID detected");
-
- if (Iterables.size(allId.getPathArguments()) == 1) {
- readersHierarchy.addVertex(allId);
- }
-
- List<InstanceIdentifier.PathArgument> pathArgs = new LinkedList<>();
- pathArgs.add(allId.getPathArguments().iterator().next());
-
- for (InstanceIdentifier.PathArgument pathArgument : Iterables.skip(allId.getPathArguments(), 1)) {
- final InstanceIdentifier<?> previous = InstanceIdentifier.create(pathArgs);
- pathArgs.add(pathArgument);
- final InstanceIdentifier<?> current = InstanceIdentifier.create(pathArgs);
-
- readersHierarchy.addVertex(previous);
- readersHierarchy.addVertex(current);
-
- try {
- readersHierarchy.addDagEdge(previous, current);
- } catch (DirectedAcyclicGraph.CycleFoundException e) {
- throw new IllegalArgumentException("Loop in hierarchy detected", e);
- }
- }
- }
-
- return new TypeHierarchy(readersHierarchy);
- }
-
- private static final class Parent{}
-}
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/AbstractGenericWriter.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/AbstractGenericWriter.java
deleted file mode 100644
index 44b36edae..000000000
--- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/AbstractGenericWriter.java
+++ /dev/null
@@ -1,137 +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.translate.util.write;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import io.fd.honeycomb.v3po.translate.util.RWUtils;
-import io.fd.honeycomb.v3po.translate.write.WriteContext;
-import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
-import io.fd.honeycomb.v3po.translate.write.Writer;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public abstract class AbstractGenericWriter<D extends DataObject> implements Writer<D> {
-
- private static final Logger LOG = LoggerFactory.getLogger(AbstractGenericWriter.class);
-
- private final InstanceIdentifier<D> instanceIdentifier;
-
- protected AbstractGenericWriter(final InstanceIdentifier<D> type) {
- this.instanceIdentifier = RWUtils.makeIidWildcarded(type);
- }
-
- protected void writeCurrent(final InstanceIdentifier<D> id, final D data, final WriteContext ctx)
- throws WriteFailedException {
- LOG.debug("{}: Writing current: {} data: {}", this, id, data);
- writeCurrentAttributes(id, data, ctx);
- LOG.debug("{}: Current node written successfully", this);
- }
-
- protected void updateCurrent(final InstanceIdentifier<D> id, final D dataBefore, final D dataAfter,
- final WriteContext ctx) throws WriteFailedException {
- LOG.debug("{}: Updating current: {} dataBefore: {}, datAfter: {}", this, id, dataBefore, dataAfter);
-
- if (dataBefore.equals(dataAfter)) {
- LOG.debug("{}: Skipping current(no update): {}", this, id);
- // No change, ignore
- return;
- }
- updateCurrentAttributes(id, dataBefore, dataAfter, ctx);
- LOG.debug("{}: Current node updated successfully", this);
- }
-
- protected void deleteCurrent(final InstanceIdentifier<D> id, final D dataBefore, final WriteContext ctx)
- throws WriteFailedException {
- LOG.debug("{}: Deleting current: {} dataBefore: {}", this, id, dataBefore);
- deleteCurrentAttributes(id, dataBefore, ctx);
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public void update(@Nonnull final InstanceIdentifier<? extends DataObject> id,
- @Nullable final DataObject dataBefore,
- @Nullable final DataObject dataAfter,
- @Nonnull final WriteContext ctx) throws WriteFailedException {
- LOG.debug("{}: Updating : {}", this, id);
- LOG.trace("{}: Updating : {}, from: {} to: {}", this, id, dataBefore, dataAfter);
-
- checkArgument(idPointsToCurrent(id), "Cannot handle data: %s. Only: %s can be handled by writer: %s",
- id, getManagedDataObjectType(), this);
-
- if (isWrite(dataBefore, dataAfter)) {
- writeCurrent((InstanceIdentifier<D>) id, castToManaged(dataAfter), ctx);
- } else if (isDelete(dataBefore, dataAfter)) {
- deleteCurrent((InstanceIdentifier<D>) id, castToManaged(dataBefore), ctx);
- } else {
- checkArgument(dataBefore != null && dataAfter != null, "No data to process");
- updateCurrent((InstanceIdentifier<D>) id, castToManaged(dataBefore), castToManaged(dataAfter), ctx);
- }
- }
-
- private void checkDataType(@Nonnull final DataObject dataAfter) {
- checkArgument(getManagedDataObjectType().getTargetType().isAssignableFrom(dataAfter.getClass()));
- }
-
- private D castToManaged(final DataObject data) {
- checkDataType(data);
- return getManagedDataObjectType().getTargetType().cast(data);
- }
-
- private static boolean isWrite(final DataObject dataBefore,
- final DataObject dataAfter) {
- return dataBefore == null && dataAfter != null;
- }
-
- private static boolean isDelete(final DataObject dataBefore,
- final DataObject dataAfter) {
- return dataAfter == null && dataBefore != null;
- }
-
- private boolean idPointsToCurrent(final @Nonnull InstanceIdentifier<? extends DataObject> id) {
- return id.getTargetType().equals(getManagedDataObjectType().getTargetType());
- }
-
- protected abstract void writeCurrentAttributes(@Nonnull final InstanceIdentifier<D> id,
- @Nonnull final D data,
- @Nonnull final WriteContext ctx) throws WriteFailedException;
-
- protected abstract void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<D> id,
- @Nonnull final D dataBefore,
- @Nonnull final WriteContext ctx) throws WriteFailedException;
-
- protected abstract void updateCurrentAttributes(@Nonnull final InstanceIdentifier<D> id,
- @Nonnull final D dataBefore,
- @Nonnull final D dataAfter,
- @Nonnull final WriteContext ctx) throws WriteFailedException;
-
- @Nonnull
- @Override
- public InstanceIdentifier<D> getManagedDataObjectType() {
- return instanceIdentifier;
- }
-
-
- @Override
- public String toString() {
- return String.format("Writer[%s]", getManagedDataObjectType().getTargetType().getSimpleName());
- }
-}
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/NoopWriterRegistry.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/NoopWriterRegistry.java
deleted file mode 100644
index 7c45fcd82..000000000
--- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/NoopWriterRegistry.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco and/or its affiliates.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.fd.honeycomb.v3po.translate.util.write;
-
-import io.fd.honeycomb.v3po.translate.TranslationException;
-import io.fd.honeycomb.v3po.translate.write.WriteContext;
-import io.fd.honeycomb.v3po.translate.write.registry.WriterRegistry;
-import javax.annotation.Nonnull;
-
-/**
- * Empty registry that does not perform any changes. Can be used in data layer, if we want to disable passing data to
- * translation layer.
- */
-public class NoopWriterRegistry implements WriterRegistry, AutoCloseable {
-
- @Override
- public void update(@Nonnull final DataObjectUpdates updates,
- @Nonnull final WriteContext ctx) throws TranslationException {
- // NOOP
- }
-
- @Override
- public void close() throws Exception {
- // NOOP
- }
-}
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/TransactionWriteContext.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/TransactionWriteContext.java
deleted file mode 100644
index 47498f594..000000000
--- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/TransactionWriteContext.java
+++ /dev/null
@@ -1,121 +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.translate.util.write;
-
-import static com.google.common.base.Preconditions.checkState;
-
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
-import io.fd.honeycomb.v3po.translate.MappingContext;
-import io.fd.honeycomb.v3po.translate.ModificationCache;
-import io.fd.honeycomb.v3po.translate.write.WriteContext;
-import java.util.Map;
-import javax.annotation.Nonnull;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
-import org.opendaylight.yangtools.binding.data.codec.api.BindingNormalizedNodeSerializer;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-/**
- * Transaction based WriteContext
- */
-public final class TransactionWriteContext implements WriteContext {
-
- private final DOMDataReadOnlyTransaction beforeTx;
- private final DOMDataReadOnlyTransaction afterTx;
- private final ModificationCache ctx;
- private final BindingNormalizedNodeSerializer serializer;
- private final MappingContext mappingContext;
-
- public TransactionWriteContext(final BindingNormalizedNodeSerializer serializer,
- final DOMDataReadOnlyTransaction beforeTx,
- final DOMDataReadOnlyTransaction afterTx,
- final MappingContext mappingContext) {
- this.serializer = serializer;
- // TODO do we have a BA transaction adapter ? If so, use it here and don't pass serializer
- this.beforeTx = beforeTx;
- this.afterTx = afterTx;
- this.mappingContext = mappingContext;
- this.ctx = new ModificationCache();
- }
-
- // TODO make this asynchronous
-
- @Override
- public <T extends DataObject> Optional<T> readBefore(@Nonnull final InstanceIdentifier<T> currentId) {
- return read(currentId, beforeTx);
- }
-
- @Override
- public <T extends DataObject> Optional<T> readAfter(@Nonnull final InstanceIdentifier<T> currentId) {
- return read(currentId, afterTx);
- }
-
-
- private <T extends DataObject> Optional<T> read(final InstanceIdentifier<T> currentId,
- final DOMDataReadOnlyTransaction tx) {
- final YangInstanceIdentifier path = serializer.toYangInstanceIdentifier(currentId);
-
- final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read =
- tx.read(LogicalDatastoreType.CONFIGURATION, path);
-
- try {
- // TODO once the APIs are asynchronous use just Futures.transform
- final Optional<NormalizedNode<?, ?>> optional = read.checkedGet();
-
- if (!optional.isPresent()) {
- return Optional.absent();
- }
-
- final NormalizedNode<?, ?> data = optional.get();
- final Map.Entry<InstanceIdentifier<?>, DataObject> entry = serializer.fromNormalizedNode(path, data);
-
- final Class<T> targetType = currentId.getTargetType();
- checkState(targetType.isAssignableFrom(entry.getValue().getClass()),
- "Unexpected data object type, should be: %s, but was: %s", targetType, entry.getValue().getClass());
- return Optional.of(targetType.cast(entry.getValue()));
- } catch (ReadFailedException e) {
- throw new IllegalStateException("Unable to perform read", e);
- }
- }
-
- @Nonnull
- @Override
- public ModificationCache getModificationCache() {
- return ctx;
- }
-
- @Nonnull
- @Override
- public MappingContext getMappingContext() {
- return mappingContext;
- }
-
- /**
- * Does not close the transactions
- */
- @Override
- public void close() {
- ctx.close();
- beforeTx.close();
- afterTx.close();
- }
-}
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/registry/FlatWriterRegistry.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/registry/FlatWriterRegistry.java
deleted file mode 100644
index 7433de813..000000000
--- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/registry/FlatWriterRegistry.java
+++ /dev/null
@@ -1,315 +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.translate.util.write.registry;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import com.google.common.base.Optional;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Sets;
-import io.fd.honeycomb.v3po.translate.TranslationException;
-import io.fd.honeycomb.v3po.translate.util.RWUtils;
-import io.fd.honeycomb.v3po.translate.write.DataObjectUpdate;
-import io.fd.honeycomb.v3po.translate.write.WriteContext;
-import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
-import io.fd.honeycomb.v3po.translate.write.Writer;
-import io.fd.honeycomb.v3po.translate.write.registry.WriterRegistry;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.ThreadSafe;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Flat writer registry, delegating updates to writers in the order writers were submitted.
- */
-@ThreadSafe
-final class FlatWriterRegistry implements WriterRegistry {
-
- private static final Logger LOG = LoggerFactory.getLogger(FlatWriterRegistry.class);
-
- // All types handled by writers directly or as children
- private final ImmutableSet<InstanceIdentifier<?>> handledTypes;
-
- private final Set<InstanceIdentifier<?>> writersOrderReversed;
- private final Set<InstanceIdentifier<?>> writersOrder;
- private final Map<InstanceIdentifier<?>, Writer<?>> writers;
-
- /**
- * Create flat registry instance.
- *
- * @param writers immutable, ordered map of writers to use to process updates. Order of the writers has to be
- * one in which create and update operations should be handled. Deletes will be handled in reversed
- * order. All deletes are handled before handling all the updates.
- */
- FlatWriterRegistry(@Nonnull final ImmutableMap<InstanceIdentifier<?>, Writer<?>> writers) {
- this.writers = writers;
- this.writersOrderReversed = Sets.newLinkedHashSet(Lists.reverse(Lists.newArrayList(writers.keySet())));
- this.writersOrder = writers.keySet();
- this.handledTypes = getAllHandledTypes(writers);
- }
-
- private static ImmutableSet<InstanceIdentifier<?>> getAllHandledTypes(
- @Nonnull final ImmutableMap<InstanceIdentifier<?>, Writer<?>> writers) {
- final ImmutableSet.Builder<InstanceIdentifier<?>> handledTypesBuilder = ImmutableSet.builder();
- for (Map.Entry<InstanceIdentifier<?>, Writer<?>> writerEntry : writers.entrySet()) {
- final InstanceIdentifier<?> writerType = writerEntry.getKey();
- final Writer<?> writer = writerEntry.getValue();
- handledTypesBuilder.add(writerType);
- if (writer instanceof SubtreeWriter) {
- handledTypesBuilder.addAll(((SubtreeWriter<?>) writer).getHandledChildTypes());
- }
- }
- return handledTypesBuilder.build();
- }
-
- @Override
- public void update(@Nonnull final DataObjectUpdates updates,
- @Nonnull final WriteContext ctx) throws TranslationException {
- if (updates.isEmpty()) {
- return;
- }
-
- // Optimization
- if (updates.containsOnlySingleType()) {
- // First process delete
- singleUpdate(updates.getDeletes(), ctx);
- // Next is update
- singleUpdate(updates.getUpdates(), ctx);
- } else {
- // First process deletes
- bulkUpdate(updates.getDeletes(), ctx, true, writersOrderReversed);
- // Next are updates
- bulkUpdate(updates.getUpdates(), ctx, true, writersOrder);
- }
-
- LOG.debug("Update successful for types: {}", updates.getTypeIntersection());
- LOG.trace("Update successful for: {}", updates);
- }
-
- private void singleUpdate(@Nonnull final Multimap<InstanceIdentifier<?>, ? extends DataObjectUpdate> updates,
- @Nonnull final WriteContext ctx) throws WriteFailedException {
- if (updates.isEmpty()) {
- return;
- }
-
- final InstanceIdentifier<?> singleType = updates.keySet().iterator().next();
- LOG.debug("Performing single type update for: {}", singleType);
- Collection<? extends DataObjectUpdate> singleTypeUpdates = updates.get(singleType);
- Writer<?> writer = getWriter(singleType);
-
- if (writer == null) {
- // This node must be handled by a subtree writer, find it and call it or else fail
- checkArgument(handledTypes.contains(singleType), "Unable to process update. Missing writers for: %s",
- singleType);
- writer = getSubtreeWriterResponsible(singleType);
- singleTypeUpdates = getParentDataObjectUpdate(ctx, updates, writer);
- }
-
- LOG.trace("Performing single type update with writer: {}", writer);
- for (DataObjectUpdate singleUpdate : singleTypeUpdates) {
- writer.update(singleUpdate.getId(), singleUpdate.getDataBefore(), singleUpdate.getDataAfter(), ctx);
- }
- }
-
- private Writer<?> getSubtreeWriterResponsible(final InstanceIdentifier<?> singleType) {
- final Writer<?> writer;// This is slow ( minor TODO-perf )
- writer = writers.values().stream()
- .filter(w -> w instanceof SubtreeWriter)
- .filter(w -> ((SubtreeWriter<?>) w).getHandledChildTypes().contains(singleType))
- .findFirst()
- .get();
- return writer;
- }
-
- private Collection<DataObjectUpdate> getParentDataObjectUpdate(final WriteContext ctx,
- final Multimap<InstanceIdentifier<?>, ? extends DataObjectUpdate> updates,
- final Writer<?> writer) {
- // Now read data for subtree reader root, but first keyed ID is needed and that ID can be cut from updates
- InstanceIdentifier<?> firstAffectedChildId = ((SubtreeWriter<?>) writer).getHandledChildTypes().stream()
- .filter(updates::containsKey)
- .map(unkeyedId -> updates.get(unkeyedId))
- .flatMap(doUpdates -> doUpdates.stream())
- .map(DataObjectUpdate::getId)
- .findFirst()
- .get();
-
- final InstanceIdentifier<?> parentKeyedId =
- RWUtils.cutId(firstAffectedChildId, writer.getManagedDataObjectType());
-
- final Optional<? extends DataObject> parentBefore = ctx.readBefore(parentKeyedId);
- final Optional<? extends DataObject> parentAfter = ctx.readAfter(parentKeyedId);
- return Collections.singleton(
- DataObjectUpdate.create(parentKeyedId, parentBefore.orNull(), parentAfter.orNull()));
- }
-
- private void bulkUpdate(@Nonnull final Multimap<InstanceIdentifier<?>, ? extends DataObjectUpdate> updates,
- @Nonnull final WriteContext ctx,
- final boolean attemptRevert,
- @Nonnull final Set<InstanceIdentifier<?>> writersOrder) throws BulkUpdateException {
- if (updates.isEmpty()) {
- return;
- }
-
- LOG.debug("Performing bulk update with revert attempt: {} for: {}", attemptRevert, updates.keySet());
-
- // Check that all updates can be handled
- checkAllTypesCanBeHandled(updates);
-
- // Capture all changes successfully processed in case revert is needed
- final Set<InstanceIdentifier<?>> processedNodes = new HashSet<>();
-
- // Iterate over all writers and call update if there are any related updates
- for (InstanceIdentifier<?> writerType : writersOrder) {
- Collection<? extends DataObjectUpdate> writersData = updates.get(writerType);
- final Writer<?> writer = getWriter(writerType);
-
- if (writersData.isEmpty()) {
- // If there are no data for current writer, but it is a SubtreeWriter and there are updates to
- // its children, still invoke it with its root data
- if (writer instanceof SubtreeWriter<?> && isAffected(((SubtreeWriter<?>) writer), updates)) {
- // Provide parent data for SubtreeWriter for further processing
- writersData = getParentDataObjectUpdate(ctx, updates, writer);
- } else {
- // Skipping unaffected writer
- // Alternative to this would be modification sort according to the order of writers
- continue;
- }
- }
-
- LOG.debug("Performing update for: {}", writerType);
- LOG.trace("Performing update with writer: {}", writer);
-
- for (DataObjectUpdate singleUpdate : writersData) {
- try {
- writer.update(singleUpdate.getId(), singleUpdate.getDataBefore(), singleUpdate.getDataAfter(), ctx);
- processedNodes.add(singleUpdate.getId());
- LOG.trace("Update successful for type: {}", writerType);
- LOG.debug("Update successful for: {}", singleUpdate);
- } catch (Exception e) {
- LOG.error("Error while processing data change of: {} (updates={})", writerType, writersData, e);
-
- final Reverter reverter = attemptRevert
- ? new ReverterImpl(processedNodes, updates, writersOrder, ctx)
- : () -> {}; // NOOP reverter
-
- // Find out which changes left unprocessed
- final Set<InstanceIdentifier<?>> unprocessedChanges = updates.values().stream()
- .map(DataObjectUpdate::getId)
- .filter(id -> !processedNodes.contains(id))
- .collect(Collectors.toSet());
- throw new BulkUpdateException(unprocessedChanges, reverter, e);
- }
- }
- }
- }
-
- private void checkAllTypesCanBeHandled(
- @Nonnull final Multimap<InstanceIdentifier<?>, ? extends DataObjectUpdate> updates) {
- if (!handledTypes.containsAll(updates.keySet())) {
- final Sets.SetView<InstanceIdentifier<?>> missingWriters = Sets.difference(updates.keySet(), handledTypes);
- LOG.warn("Unable to process update. Missing writers for: {}", missingWriters);
- throw new IllegalArgumentException("Unable to process update. Missing writers for: " + missingWriters);
- }
- }
-
- /**
- * Check whether {@link SubtreeWriter} is affected by the updates.
- *
- * @return true if there are any updates to SubtreeWriter's child nodes (those marked by SubtreeWriter
- * as being taken care of)
- * */
- private static boolean isAffected(final SubtreeWriter<?> writer,
- final Multimap<InstanceIdentifier<?>, ? extends DataObjectUpdate> updates) {
- return !Sets.intersection(writer.getHandledChildTypes(), updates.keySet()).isEmpty();
- }
-
- @Nullable
- private Writer<?> getWriter(@Nonnull final InstanceIdentifier<?> singleType) {
- return writers.get(singleType);
- }
-
- // FIXME unit test
- private final class ReverterImpl implements Reverter {
-
- private final Collection<InstanceIdentifier<?>> processedNodes;
- private final Multimap<InstanceIdentifier<?>, ? extends DataObjectUpdate> updates;
- private final Set<InstanceIdentifier<?>> revertDeleteOrder;
- private final WriteContext ctx;
-
- ReverterImpl(final Collection<InstanceIdentifier<?>> processedNodes,
- final Multimap<InstanceIdentifier<?>, ? extends DataObjectUpdate> updates,
- final Set<InstanceIdentifier<?>> writersOrderOriginal,
- final WriteContext ctx) {
- this.processedNodes = processedNodes;
- this.updates = updates;
- // Use opposite ordering when executing revert
- this.revertDeleteOrder = writersOrderOriginal == FlatWriterRegistry.this.writersOrder
- ? FlatWriterRegistry.this.writersOrderReversed
- : FlatWriterRegistry.this.writersOrder;
- this.ctx = ctx;
- }
-
- @Override
- public void revert() throws RevertFailedException {
- Multimap<InstanceIdentifier<?>, DataObjectUpdate> updatesToRevert =
- filterAndRevertProcessed(updates, processedNodes);
-
- LOG.info("Attempting revert for changes: {}", updatesToRevert);
- try {
- // Perform reversed bulk update without revert attempt
- bulkUpdate(updatesToRevert, ctx, true, revertDeleteOrder);
- LOG.info("Revert successful");
- } catch (BulkUpdateException e) {
- LOG.error("Revert failed", e);
- throw new RevertFailedException(e.getFailedIds(), e);
- }
- }
-
- /**
- * Create new updates map, but only keep already processed changes. Switching before and after data for each
- * update.
- */
- private Multimap<InstanceIdentifier<?>, DataObjectUpdate> filterAndRevertProcessed(
- final Multimap<InstanceIdentifier<?>, ? extends DataObjectUpdate> updates,
- final Collection<InstanceIdentifier<?>> processedNodes) {
- final Multimap<InstanceIdentifier<?>, DataObjectUpdate> filtered = HashMultimap.create();
- for (InstanceIdentifier<?> processedNode : processedNodes) {
- final InstanceIdentifier<?> wildcardedIid = RWUtils.makeIidWildcarded(processedNode);
- if (updates.containsKey(wildcardedIid)) {
- updates.get(wildcardedIid).stream()
- .filter(dataObjectUpdate -> processedNode.contains(dataObjectUpdate.getId()))
- .forEach(dataObjectUpdate -> filtered.put(processedNode, dataObjectUpdate.reverse()));
- }
- }
- return filtered;
- }
- }
-
-}
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/registry/FlatWriterRegistryBuilder.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/registry/FlatWriterRegistryBuilder.java
deleted file mode 100644
index bfac2eedd..000000000
--- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/registry/FlatWriterRegistryBuilder.java
+++ /dev/null
@@ -1,71 +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.translate.util.write.registry;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.ImmutableMap;
-import io.fd.honeycomb.v3po.translate.util.AbstractSubtreeManagerRegistryBuilderBuilder;
-import io.fd.honeycomb.v3po.translate.write.Writer;
-import io.fd.honeycomb.v3po.translate.write.registry.ModifiableWriterRegistryBuilder;
-import io.fd.honeycomb.v3po.translate.write.registry.WriterRegistry;
-import io.fd.honeycomb.v3po.translate.write.registry.WriterRegistryBuilder;
-import java.util.Set;
-import java.util.stream.Collectors;
-import javax.annotation.Nonnull;
-import javax.annotation.concurrent.NotThreadSafe;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Builder for {@link FlatWriterRegistry} allowing users to specify inter-writer relationships.
- */
-@NotThreadSafe
-public final class FlatWriterRegistryBuilder
- extends AbstractSubtreeManagerRegistryBuilderBuilder<Writer<? extends DataObject>, WriterRegistry>
- implements ModifiableWriterRegistryBuilder, WriterRegistryBuilder {
-
- private static final Logger LOG = LoggerFactory.getLogger(FlatWriterRegistryBuilder.class);
-
- @Override
- protected Writer<? extends DataObject> getSubtreeHandler(final @Nonnull Set<InstanceIdentifier<?>> handledChildren,
- final @Nonnull Writer<? extends DataObject> writer) {
- return SubtreeWriter.createForWriter(handledChildren, writer);
- }
-
- /**
- * Create FlatWriterRegistry with writers ordered according to submitted relationships.
- */
- @Override
- public WriterRegistry build() {
- final ImmutableMap<InstanceIdentifier<?>, Writer<?>> mappedWriters = getMappedHandlers();
- LOG.debug("Building writer registry with writers: {}",
- mappedWriters.keySet().stream()
- .map(InstanceIdentifier::getTargetType)
- .map(Class::getSimpleName)
- .collect(Collectors.joining(", ")));
- LOG.trace("Building writer registry with writers: {}", mappedWriters);
- return new FlatWriterRegistry(mappedWriters);
- }
-
- @VisibleForTesting
- @Override
- protected ImmutableMap<InstanceIdentifier<?>, Writer<? extends DataObject>> getMappedHandlers() {
- return super.getMappedHandlers();
- }
-}
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/registry/SubtreeWriter.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/registry/SubtreeWriter.java
deleted file mode 100644
index e395b29da..000000000
--- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/registry/SubtreeWriter.java
+++ /dev/null
@@ -1,85 +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.translate.util.write.registry;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import com.google.common.collect.Iterables;
-import io.fd.honeycomb.v3po.translate.write.WriteContext;
-import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
-import io.fd.honeycomb.v3po.translate.write.Writer;
-import java.util.HashSet;
-import java.util.Set;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-/**
- * Simple writer delegate for subtree writers (writers handling also children nodes) providing a list of all the
- * children nodes being handled.
- */
-final class SubtreeWriter<D extends DataObject> implements Writer<D> {
-
- private final Writer<D> delegate;
- private final Set<InstanceIdentifier<?>> handledChildTypes = new HashSet<>();
-
- private SubtreeWriter(final Writer<D> delegate, Set<InstanceIdentifier<?>> handledTypes) {
- this.delegate = delegate;
- for (InstanceIdentifier<?> handledType : handledTypes) {
- // Iid has to start with writer's handled root type
- checkArgument(delegate.getManagedDataObjectType().getTargetType().equals(
- handledType.getPathArguments().iterator().next().getType()),
- "Handled node from subtree has to be identified by an instance identifier starting from: %s."
- + "Instance identifier was: %s", getManagedDataObjectType().getTargetType(), handledType);
- checkArgument(Iterables.size(handledType.getPathArguments()) > 1,
- "Handled node from subtree identifier too short: %s", handledType);
- handledChildTypes.add(InstanceIdentifier.create(Iterables.concat(
- getManagedDataObjectType().getPathArguments(), Iterables.skip(handledType.getPathArguments(), 1))));
- }
- }
-
- /**
- * Return set of types also handled by this writer. All of the types are children of the type managed by this
- * writer excluding the type of this writer.
- */
- Set<InstanceIdentifier<?>> getHandledChildTypes() {
- return handledChildTypes;
- }
-
- @Override
- public void update(
- @Nonnull final InstanceIdentifier<? extends DataObject> id,
- @Nullable final DataObject dataBefore,
- @Nullable final DataObject dataAfter, @Nonnull final WriteContext ctx) throws WriteFailedException {
- delegate.update(id, dataBefore, dataAfter, ctx);
- }
-
- @Override
- @Nonnull
- public InstanceIdentifier<D> getManagedDataObjectType() {
- return delegate.getManagedDataObjectType();
- }
-
- /**
- * Wrap a writer as a subtree writer.
- */
- static Writer<?> createForWriter(@Nonnull final Set<InstanceIdentifier<?>> handledChildren,
- @Nonnull final Writer<? extends DataObject> writer) {
- return new SubtreeWriter<>(writer, handledChildren);
- }
-}