summaryrefslogtreecommitdiffstats
path: root/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl
diff options
context:
space:
mode:
Diffstat (limited to 'infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl')
-rw-r--r--infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/GenericListWriter.java21
-rw-r--r--infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/GenericWriter.java9
-rw-r--r--infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/registry/FlatWriterRegistry.java69
-rw-r--r--infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/registry/SubtreeWriter.java8
4 files changed, 85 insertions, 22 deletions
diff --git a/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/GenericListWriter.java b/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/GenericListWriter.java
index 92467a8e8..5121eb793 100644
--- a/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/GenericListWriter.java
+++ b/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/GenericListWriter.java
@@ -19,12 +19,13 @@ package io.fd.honeycomb.translate.impl.write;
import static io.fd.honeycomb.translate.impl.write.GenericWriter.isUpdateSupported;
import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer;
+import io.fd.honeycomb.translate.spi.write.WriterCustomizer;
import io.fd.honeycomb.translate.util.RWUtils;
import io.fd.honeycomb.translate.util.write.AbstractGenericWriter;
import io.fd.honeycomb.translate.write.ListWriter;
+import io.fd.honeycomb.translate.write.Validator;
import io.fd.honeycomb.translate.write.WriteContext;
import io.fd.honeycomb.translate.write.WriteFailedException;
-import io.fd.honeycomb.translate.spi.write.WriterCustomizer;
import javax.annotation.Nonnull;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.Identifiable;
@@ -45,6 +46,13 @@ public final class GenericListWriter<D extends DataObject & Identifiable<K>, K e
this.customizer = customizer;
}
+ public GenericListWriter(@Nonnull final InstanceIdentifier<D> type,
+ @Nonnull final ListWriterCustomizer<D, K> customizer,
+ @Nonnull final Validator<D> validator) {
+ super(type, isUpdateSupported(customizer), validator);
+ this.customizer = customizer;
+ }
+
@Override
protected void writeCurrentAttributes(@Nonnull final InstanceIdentifier<D> id, @Nonnull final D data,
@Nonnull final WriteContext ctx) throws WriteFailedException {
@@ -79,22 +87,25 @@ public final class GenericListWriter<D extends DataObject & Identifiable<K>, K e
@Override
protected void writeCurrent(final InstanceIdentifier<D> id, final D data, final WriteContext ctx)
throws WriteFailedException {
- super.writeCurrent(getId(id, data), data, ctx);
+ super.writeCurrent(getManagedId(id, data), data, ctx);
}
@Override
protected void updateCurrent(final InstanceIdentifier<D> id, final D dataBefore, final D dataAfter,
final WriteContext ctx) throws WriteFailedException {
- super.updateCurrent(getId(id, dataBefore), dataBefore, dataAfter, ctx);
+ super.updateCurrent(getManagedId(id, dataBefore), dataBefore, dataAfter, ctx);
}
@Override
protected void deleteCurrent(final InstanceIdentifier<D> id, final D dataBefore, final WriteContext ctx)
throws WriteFailedException {
- super.deleteCurrent(getId(id, dataBefore), dataBefore, ctx);
+ super.deleteCurrent(getManagedId(id, dataBefore), dataBefore, ctx);
}
- private InstanceIdentifier<D> getId(final InstanceIdentifier<D> id, final D current) {
+ @Override
+ protected InstanceIdentifier<D> getManagedId(@Nonnull final InstanceIdentifier<? extends DataObject> currentId,
+ @Nonnull final D current) {
+ final InstanceIdentifier<D> id = (InstanceIdentifier<D>) currentId;
// Make sure the key is present
if (isWildcarded(id)) {
return getSpecificId(id, current);
diff --git a/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/GenericWriter.java b/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/GenericWriter.java
index 086936e38..bfdf072c0 100644
--- a/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/GenericWriter.java
+++ b/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/GenericWriter.java
@@ -16,9 +16,10 @@
package io.fd.honeycomb.translate.impl.write;
-import io.fd.honeycomb.translate.write.WriteContext;
import io.fd.honeycomb.translate.spi.write.WriterCustomizer;
import io.fd.honeycomb.translate.util.write.AbstractGenericWriter;
+import io.fd.honeycomb.translate.write.Validator;
+import io.fd.honeycomb.translate.write.WriteContext;
import io.fd.honeycomb.translate.write.WriteFailedException;
import javax.annotation.Nonnull;
import org.opendaylight.yangtools.yang.binding.DataObject;
@@ -39,7 +40,13 @@ public final class GenericWriter<D extends DataObject> extends AbstractGenericWr
@Nonnull final WriterCustomizer<D> customizer) {
super(type, isUpdateSupported(customizer));
this.customizer = customizer;
+ }
+ public GenericWriter(@Nonnull final InstanceIdentifier<D> type,
+ @Nonnull final WriterCustomizer<D> customizer,
+ @Nonnull final Validator<D> validator) {
+ super(type, isUpdateSupported(customizer), validator);
+ this.customizer = customizer;
}
static boolean isUpdateSupported(final @Nonnull WriterCustomizer<?> customizer) {
diff --git a/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/registry/FlatWriterRegistry.java b/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/registry/FlatWriterRegistry.java
index 67a5da32a..9e36e593f 100644
--- a/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/registry/FlatWriterRegistry.java
+++ b/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/registry/FlatWriterRegistry.java
@@ -28,12 +28,14 @@ import com.google.common.collect.Sets;
import io.fd.honeycomb.translate.TranslationException;
import io.fd.honeycomb.translate.util.RWUtils;
import io.fd.honeycomb.translate.write.DataObjectUpdate;
+import io.fd.honeycomb.translate.write.DataValidationFailedException;
import io.fd.honeycomb.translate.write.WriteContext;
import io.fd.honeycomb.translate.write.Writer;
import io.fd.honeycomb.translate.write.registry.UpdateFailedException;
import io.fd.honeycomb.translate.write.registry.WriterRegistry;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -76,6 +78,33 @@ final class FlatWriterRegistry implements WriterRegistry {
}
@Override
+ public void validateModifications(@Nonnull final DataObjectUpdates updates, @Nonnull final WriteContext ctx)
+ throws DataValidationFailedException {
+ // Optimization: validation order is not relevant, so do not merge deletes and updates.
+ validateModifications(updates.getDeletes(), ctx);
+ validateModifications(updates.getUpdates(), ctx);
+ }
+
+ private void validateModifications(
+ @Nonnull final Multimap<InstanceIdentifier<?>, ? extends DataObjectUpdate> updates,
+ @Nonnull final WriteContext ctx) throws DataValidationFailedException {
+ if (updates.isEmpty()) {
+ return;
+ }
+ // Fail early if some handlers are missing.
+ checkAllTypesCanBeHandled(updates);
+
+ // Validators do not modify anything, so order of validators is not important.
+ // We iterate over writersOrder instead of modifications for consistent handling of subtree writers case.
+ for (InstanceIdentifier<?> writerType : writersOrder) {
+ final Writer<?> writer = getWriter(writerType);
+ for (DataObjectUpdate singleUpdate : getWritersData(updates, writer, writerType, ctx)) {
+ writer.validate(singleUpdate.getId(), singleUpdate.getDataBefore(), singleUpdate.getDataAfter(), ctx);
+ }
+ }
+ }
+
+ @Override
public void processModifications(@Nonnull final DataObjectUpdates updates,
@Nonnull final WriteContext ctx) throws TranslationException {
if (updates.isEmpty()) {
@@ -207,26 +236,11 @@ final class FlatWriterRegistry implements WriterRegistry {
LOG.debug("Performing bulk update for: {}", updates.keySet());
// 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) {
+ for (DataObjectUpdate singleUpdate : getWritersData(updates, writer, writerType, ctx)) {
try {
writer.processModification(singleUpdate.getId(), singleUpdate.getDataBefore(),
singleUpdate.getDataAfter(), ctx);
@@ -240,6 +254,29 @@ final class FlatWriterRegistry implements WriterRegistry {
}
}
+ private Collection<? extends DataObjectUpdate> getWritersData(
+ final Multimap<InstanceIdentifier<?>, ? extends DataObjectUpdate> updates, final Writer<?> writer,
+ final InstanceIdentifier<?> writerType, final WriteContext ctx) {
+ Collection<? extends DataObjectUpdate> writersData = updates.get(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.
+ // Notice that child updates will be ignored if the set of all modifications
+ // contain both parent update and child updates. But this is ok, since all changes are already expressed in
+ // the parent update.
+ 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
+ return Collections.emptyList();
+ }
+ }
+ return writersData;
+ }
+
private void checkAllTypesCanBeHandled(
@Nonnull final Multimap<InstanceIdentifier<?>, ? extends DataObjectUpdate> updates) {
diff --git a/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/registry/SubtreeWriter.java b/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/registry/SubtreeWriter.java
index a1a5f3fd0..e510bc33c 100644
--- a/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/registry/SubtreeWriter.java
+++ b/infra/translate-impl/src/main/java/io/fd/honeycomb/translate/impl/write/registry/SubtreeWriter.java
@@ -19,6 +19,7 @@ package io.fd.honeycomb.translate.impl.write.registry;
import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.collect.Iterables;
+import io.fd.honeycomb.translate.write.DataValidationFailedException;
import io.fd.honeycomb.translate.write.WriteContext;
import io.fd.honeycomb.translate.write.WriteFailedException;
import io.fd.honeycomb.translate.write.Writer;
@@ -68,6 +69,13 @@ final class SubtreeWriter<D extends DataObject> implements Writer<D> {
}
@Override
+ public void validate(@Nonnull final InstanceIdentifier<? extends DataObject> id,
+ @Nullable final DataObject dataBefore, @Nullable final DataObject dataAfter,
+ @Nonnull final WriteContext ctx) throws DataValidationFailedException {
+ delegate.validate(id, dataBefore, dataAfter, ctx);
+ }
+
+ @Override
public void processModification(
@Nonnull final InstanceIdentifier<? extends DataObject> id,
@Nullable final DataObject dataBefore,