From 130c716105017c7b20b4779973b915968b3dc322 Mon Sep 17 00:00:00 2001 From: Jan Srnicek Date: Wed, 16 Aug 2017 09:21:24 +0200 Subject: HONEYCOMB-386 - Make update optional If customizer does not support update directly, updates for its handled nodes are broken up to delete + create pairs. Change-Id: I2929109e8c9a1db0bef108367cf7d839135ce173 Signed-off-by: Jan Srnicek --- .../translate/impl/write/GenericListWriter.java | 4 +++- .../translate/impl/write/GenericWriter.java | 24 +++++++++++++++++++++- .../impl/write/registry/FlatWriterRegistry.java | 22 +++++++++++++++----- .../impl/write/registry/SubtreeWriter.java | 9 ++++++-- 4 files changed, 50 insertions(+), 9 deletions(-) (limited to 'infra/translate-impl/src/main/java/io') 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 4e05ce018..6fbef8e84 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 @@ -16,6 +16,8 @@ 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.util.RWUtils; import io.fd.honeycomb.translate.util.write.AbstractGenericWriter; @@ -39,7 +41,7 @@ public final class GenericListWriter, K e public GenericListWriter(@Nonnull final InstanceIdentifier type, @Nonnull final ListWriterCustomizer customizer) { - super(type); + super(type, isUpdateSupported(customizer)); this.customizer = customizer; } 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 30d15e370..086936e38 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 @@ -23,18 +23,40 @@ import io.fd.honeycomb.translate.write.WriteFailedException; import javax.annotation.Nonnull; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Generic writer with customizable behavior thanks to injected customizer. */ public final class GenericWriter extends AbstractGenericWriter { + private static final Logger LOG = LoggerFactory.getLogger(GenericWriter.class); + private static final String UPDATE_M = "updateCurrentAttributes"; private final WriterCustomizer customizer; public GenericWriter(@Nonnull final InstanceIdentifier type, @Nonnull final WriterCustomizer customizer) { - super(type); + super(type, isUpdateSupported(customizer)); this.customizer = customizer; + + } + + static boolean isUpdateSupported(final @Nonnull WriterCustomizer customizer) { + try { + // if customizer overrides updateCurrentAttributes method, it will be used, otherwise updates will be broken into individual + // delete + create pairs + final Class customizerClass = customizer.getClass(); + final Class updateDeclaringClass = customizerClass + .getMethod(UPDATE_M, InstanceIdentifier.class, DataObject.class, DataObject.class, WriteContext.class) + .getDeclaringClass(); + final boolean supportsUpdate = !WriterCustomizer.class.equals(updateDeclaringClass); + LOG.debug("Customizer {} update support : {}|Update declaring class {}", customizerClass, supportsUpdate, + updateDeclaringClass); + return supportsUpdate; + } catch (NoSuchMethodException e) { + throw new IllegalStateException("Unable to detect if customizer supports update", e); + } } @Override 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 418f4b4b7..e21297aa3 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 @@ -92,8 +92,8 @@ final class FlatWriterRegistry implements WriterRegistry { } @Override - public void update(@Nonnull final DataObjectUpdates updates, - @Nonnull final WriteContext ctx) throws TranslationException { + public void processModifications(@Nonnull final DataObjectUpdates updates, + @Nonnull final WriteContext ctx) throws TranslationException { if (updates.isEmpty()) { return; } @@ -115,6 +115,17 @@ final class FlatWriterRegistry implements WriterRegistry { LOG.trace("Update successful for: {}", updates); } + @Override + public boolean writerSupportsUpdate(@Nonnull final InstanceIdentifier type) { + Writer writer = getWriter(type); + + if(writer == null){ + writer = getSubtreeWriterResponsible(type); + } + + return checkNotNull(writer, "Unable to find writer for %s", type).supportsDirectUpdate(); + } + private void singleUpdate(@Nonnull final Multimap, ? extends DataObjectUpdate> updates, @Nonnull final WriteContext ctx) throws WriteFailedException { if (updates.isEmpty()) { @@ -136,16 +147,17 @@ final class FlatWriterRegistry implements WriterRegistry { LOG.trace("Performing single type update with writer: {}", writer); for (DataObjectUpdate singleUpdate : singleTypeUpdates) { - writer.update(singleUpdate.getId(), singleUpdate.getDataBefore(), singleUpdate.getDataAfter(), ctx); + writer.processModification(singleUpdate.getId(), singleUpdate.getDataBefore(), singleUpdate.getDataAfter(), ctx); } } + @Nullable private Writer getSubtreeWriterResponsible(final InstanceIdentifier singleType) { return writers.values().stream() .filter(w -> w instanceof SubtreeWriter) .filter(w -> ((SubtreeWriter) w).getHandledChildTypes().contains(singleType)) .findFirst() - .get(); + .orElse(null); } private Collection getParentDataObjectUpdate(final WriteContext ctx, @@ -208,7 +220,7 @@ final class FlatWriterRegistry implements WriterRegistry { for (DataObjectUpdate singleUpdate : writersData) { try { - writer.update(singleUpdate.getId(), singleUpdate.getDataBefore(), singleUpdate.getDataAfter(), ctx); + writer.processModification(singleUpdate.getId(), singleUpdate.getDataBefore(), singleUpdate.getDataAfter(), ctx); processedNodes.add(singleUpdate.getId()); LOG.trace("Update successful for type: {}", writerType); LOG.debug("Update successful for: {}", singleUpdate); 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 fc6ecc67e..b2a571b40 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 @@ -62,11 +62,16 @@ final class SubtreeWriter implements Writer { } @Override - public void update( + public void processModification( @Nonnull final InstanceIdentifier id, @Nullable final DataObject dataBefore, @Nullable final DataObject dataAfter, @Nonnull final WriteContext ctx) throws WriteFailedException { - delegate.update(id, dataBefore, dataAfter, ctx); + delegate.processModification(id, dataBefore, dataAfter, ctx); + } + + @Override + public boolean supportsDirectUpdate() { + return delegate.supportsDirectUpdate(); } @Override -- cgit 1.2.3-korg