summaryrefslogtreecommitdiffstats
path: root/v3po/translate-api
diff options
context:
space:
mode:
Diffstat (limited to 'v3po/translate-api')
-rw-r--r--v3po/translate-api/pom.xml2
-rw-r--r--v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/ChildWriter.java66
-rw-r--r--v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/DataObjectUpdate.java114
-rw-r--r--v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/ModifiableWriterRegistry.java78
-rw-r--r--v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/WriterFactory.java28
-rw-r--r--v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/WriterRegistry.java131
-rw-r--r--v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/WriterRegistryBuilder.java25
-rw-r--r--v3po/translate-api/src/main/yang/translate-api.yang11
8 files changed, 363 insertions, 92 deletions
diff --git a/v3po/translate-api/pom.xml b/v3po/translate-api/pom.xml
index 8e244fa8d..1b08e85e8 100644
--- a/v3po/translate-api/pom.xml
+++ b/v3po/translate-api/pom.xml
@@ -19,7 +19,7 @@
<groupId>io.fd.honeycomb.common</groupId>
<artifactId>impl-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
- <relativePath>../../common/api-parent</relativePath>
+ <relativePath>../../common/impl-parent</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
diff --git a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/ChildWriter.java b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/ChildWriter.java
deleted file mode 100644
index b38f26983..000000000
--- a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/ChildWriter.java
+++ /dev/null
@@ -1,66 +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.write;
-
-import com.google.common.annotations.Beta;
-import javax.annotation.Nonnull;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-/**
- * Child writer allowing its parent to pass the builder object
- *
- * @param <D> Specific DataObject derived type, that is handled by this writer
- */
-@Beta
-public interface ChildWriter<D extends DataObject> extends Writer<D> {
-
- /**
- * Extract data object managed by this writer from parent data and perform write.
- *
- * @param parentId Id of parent node
- * @param parentDataAfter Parent data from modification to extract data object from
- * @param ctx Write context for current modification
- */
- void writeChild(@Nonnull final InstanceIdentifier<? extends DataObject> parentId,
- @Nonnull final DataObject parentDataAfter,
- @Nonnull final WriteContext ctx) throws WriteFailedException;
-
- /**
- * Extract data object managed by this writer(if necessary) from parent data and perform delete.
- *
- * @param parentId Id of parent node
- * @param parentDataBefore Parent data before modification to extract data object from
- * @param ctx Write context for current modification
- */
- void deleteChild(@Nonnull final InstanceIdentifier<? extends DataObject> parentId,
- @Nonnull final DataObject parentDataBefore,
- @Nonnull final WriteContext ctx) throws WriteFailedException;
-
- /**
- * Extract data object managed by this writer(if necessary) from parent data and perform delete.
- *
- * @param parentId Id of parent node
- * @param parentDataBefore Parent data before modification to extract data object from
- * @param parentDataAfter Parent data from modification to extract data object from
- * @param ctx Write context for current modification
- */
- void updateChild(@Nonnull final InstanceIdentifier<? extends DataObject> parentId,
- @Nonnull final DataObject parentDataBefore,
- @Nonnull final DataObject parentDataAfter,
- @Nonnull final WriteContext ctx) throws WriteFailedException;
-}
diff --git a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/DataObjectUpdate.java b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/DataObjectUpdate.java
new file mode 100644
index 000000000..0d891ecba
--- /dev/null
+++ b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/DataObjectUpdate.java
@@ -0,0 +1,114 @@
+/*
+ * 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.write;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Simple wrapper for BA id + data before and after state. Does not allow both before and after to be null.
+ */
+public class DataObjectUpdate {
+
+ @Nonnull
+ private final InstanceIdentifier<?> id;
+ @Nullable
+ private final DataObject dataBefore;
+ @Nullable
+ private final DataObject dataAfter;
+
+ private DataObjectUpdate(@Nonnull final InstanceIdentifier<?> id,
+ @Nullable final DataObject dataBefore,
+ @Nullable final DataObject dataAfter) {
+ this.id = checkNotNull(id);
+ this.dataAfter = dataAfter;
+ this.dataBefore = dataBefore;
+ }
+
+ public DataObject getDataBefore() {
+ return dataBefore;
+ }
+
+ public DataObject getDataAfter() {
+ return dataAfter;
+ }
+
+ public InstanceIdentifier<?> getId() {
+ return id;
+ }
+
+ public static DataObjectUpdate create(@Nonnull final InstanceIdentifier<?> id,
+ @Nullable final DataObject dataBefore,
+ @Nullable final DataObject dataAfter) {
+ checkArgument(!(dataBefore == null && dataAfter == null), "Both before and after data are null");
+ if (dataBefore != null) {
+ checkArgument(id.getTargetType().isAssignableFrom(dataBefore.getClass()));
+ }
+ if (dataAfter != null) {
+ checkArgument(id.getTargetType().isAssignableFrom(dataAfter.getClass()));
+ }
+
+ return dataAfter == null
+ ? new DataObjectDelete(id, dataBefore)
+ : new DataObjectUpdate(id, dataBefore, dataAfter);
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ final DataObjectUpdate that = (DataObjectUpdate) o;
+
+ return id.equals(that.id);
+
+ }
+
+ @Override
+ public int hashCode() {
+ return id.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return "DataObjectUpdate{" + "id=" + id
+ + ", dataBefore=" + dataBefore
+ + ", dataAfter=" + dataAfter
+ + '}';
+ }
+
+ public DataObjectUpdate reverse() {
+ return DataObjectUpdate.create(id, dataAfter, dataBefore);
+ }
+
+ public static class DataObjectDelete extends DataObjectUpdate {
+
+ private DataObjectDelete(@Nonnull final InstanceIdentifier<?> id,
+ @Nullable final DataObject dataBefore) {
+ super(id, dataBefore, null);
+ }
+ }
+}
diff --git a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/ModifiableWriterRegistry.java b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/ModifiableWriterRegistry.java
new file mode 100644
index 000000000..71ecbb806
--- /dev/null
+++ b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/ModifiableWriterRegistry.java
@@ -0,0 +1,78 @@
+/*
+ * 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.write;
+
+import com.google.common.annotations.Beta;
+import java.util.Collection;
+import java.util.Set;
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Mutable registry that allows adding new writers.
+ */
+@Beta
+public interface ModifiableWriterRegistry {
+
+ /**
+ * Add a writer responsible for writing only a single complex node.
+ */
+ ModifiableWriterRegistry addWriter(@Nonnull Writer<? extends DataObject> writer);
+
+ /**
+ * Add a writer responsible for writing multiple complex nodes within a subtree its responsible for.
+ * Identifiers for subtree nodes handled by a single writer have to be relative from {@link DataObject} that
+ * represents subtree root.
+ */
+ ModifiableWriterRegistry addSubtreeWriter(@Nonnull Set<InstanceIdentifier<?>> handledChildren,
+ @Nonnull Writer<? extends DataObject> writer);
+
+ /**
+ * Add a writer and make sure it will be executed before writer identifier by relatedType is executed.
+ */
+ ModifiableWriterRegistry addWriterBefore(@Nonnull Writer<? extends DataObject> writer,
+ @Nonnull InstanceIdentifier<?> relatedType);
+
+ ModifiableWriterRegistry addSubtreeWriterBefore(@Nonnull Set<InstanceIdentifier<?>> handledChildren,
+ @Nonnull Writer<? extends DataObject> writer,
+ @Nonnull InstanceIdentifier<?> relatedType);
+
+ ModifiableWriterRegistry addWriterBefore(@Nonnull Writer<? extends DataObject> writer,
+ @Nonnull Collection<InstanceIdentifier<?>> relatedTypes);
+
+ ModifiableWriterRegistry addSubtreeWriterBefore(@Nonnull Set<InstanceIdentifier<?>> handledChildren,
+ @Nonnull Writer<? extends DataObject> writer,
+ @Nonnull Collection<InstanceIdentifier<?>> relatedTypes);
+
+ /**
+ * Add a writer and make sure it will be executed after writer identifier by relatedType is executed.
+ */
+ ModifiableWriterRegistry addWriterAfter(@Nonnull Writer<? extends DataObject> writer,
+ @Nonnull InstanceIdentifier<?> relatedType);
+
+ ModifiableWriterRegistry addSubtreeWriterAfter(@Nonnull Set<InstanceIdentifier<?>> handledChildren,
+ @Nonnull Writer<? extends DataObject> writer,
+ @Nonnull InstanceIdentifier<?> relatedType);
+
+ ModifiableWriterRegistry addWriterAfter(@Nonnull Writer<? extends DataObject> writer,
+ @Nonnull Collection<InstanceIdentifier<?>> relatedTypes);
+
+ ModifiableWriterRegistry addSubtreeWriterAfter(@Nonnull Set<InstanceIdentifier<?>> handledChildren,
+ @Nonnull Writer<? extends DataObject> writer,
+ @Nonnull Collection<InstanceIdentifier<?>> relatedTypes);
+}
diff --git a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/WriterFactory.java b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/WriterFactory.java
new file mode 100644
index 000000000..4287964db
--- /dev/null
+++ b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/WriterFactory.java
@@ -0,0 +1,28 @@
+/*
+ * 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.write;
+
+import com.google.common.annotations.Beta;
+
+@Beta
+public interface WriterFactory {
+
+ /**
+ * Initialize 1 or more writers and add them to provided registry.
+ */
+ void init(ModifiableWriterRegistry registry);
+}
diff --git a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/WriterRegistry.java b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/WriterRegistry.java
index d30f06d13..64735017f 100644
--- a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/WriterRegistry.java
+++ b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/WriterRegistry.java
@@ -19,47 +19,131 @@ package io.fd.honeycomb.v3po.translate.write;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.Beta;
-import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Sets;
import io.fd.honeycomb.v3po.translate.TranslationException;
-import java.util.List;
-import java.util.Map;
+import java.util.Set;
import javax.annotation.Nonnull;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
/**
- * Special {@link Writer} capable of performing bulk updates
+ * Special {@link Writer} capable of performing bulk updates.
*/
@Beta
public interface WriterRegistry extends Writer<DataObject> {
/**
- * Performs bulk update
+ * Performs bulk update.
*
* @throws BulkUpdateException in case bulk update fails
- * @throws TranslationException in case some other error occurs while processing update request
+ * @throws TranslationException in case some other error occurs while processing update request
*/
- void update(@Nonnull final Map<InstanceIdentifier<?>, DataObject> dataBefore,
- @Nonnull final Map<InstanceIdentifier<?>, DataObject> dataAfter,
- @Nonnull final WriteContext ctx) throws TranslationException;
+ void update(@Nonnull DataObjectUpdates updates,
+ @Nonnull WriteContext ctx) throws TranslationException;
+
+ /**
+ * Simple DTO containing updates for {@link WriterRegistry}. Currently only deletes and updates (create + update)
+ * are distinguished.
+ */
+ @Beta
+ final class DataObjectUpdates {
+
+ private final Multimap<InstanceIdentifier<?>, DataObjectUpdate> updates;
+ private final Multimap<InstanceIdentifier<?>, DataObjectUpdate.DataObjectDelete> deletes;
+
+ /**
+ * Create new instance.
+ *
+ * @param updates All updates indexed by their unkeyed {@link InstanceIdentifier}
+ * @param deletes All deletes indexed by their unkeyed {@link InstanceIdentifier}
+ */
+ public DataObjectUpdates(@Nonnull final Multimap<InstanceIdentifier<?>, DataObjectUpdate> updates,
+ @Nonnull final Multimap<InstanceIdentifier<?>, DataObjectUpdate.DataObjectDelete> deletes) {
+ this.deletes = deletes;
+ this.updates = updates;
+ }
+
+ public Multimap<InstanceIdentifier<?>, DataObjectUpdate> getUpdates() {
+ return updates;
+ }
+
+ public Multimap<InstanceIdentifier<?>, DataObjectUpdate.DataObjectDelete> getDeletes() {
+ return deletes;
+ }
+
+ public boolean isEmpty() {
+ return updates.isEmpty() && deletes.isEmpty();
+ }
+
+ @Override
+ public String toString() {
+ return "DataObjectUpdates{" + "updates=" + updates + ", deletes=" + deletes + '}';
+ }
+
+ /**
+ * Get a {@link Set} containing all update types from both updates as well as deletes.
+ */
+ public Set<InstanceIdentifier<?>> getTypeIntersection() {
+ return Sets.union(deletes.keySet(), updates.keySet());
+ }
+
+ /**
+ * Check whether there is only a single type of data object to be updated.
+ *
+ * @return true if there is only a single type of updates (update + delete)
+ */
+ public boolean containsOnlySingleType() {
+ return getTypeIntersection().size() == 1;
+ }
+
+ @Override
+ public boolean equals(final Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (other == null || getClass() != other.getClass()) {
+ return false;
+ }
+
+ final DataObjectUpdates that = (DataObjectUpdates) other;
+
+ if (!updates.equals(that.updates)) {
+ return false;
+ }
+ return deletes.equals(that.deletes);
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = updates.hashCode();
+ result = 31 * result + deletes.hashCode();
+ return result;
+ }
+
+ }
/**
* Thrown when bulk update failed.
*/
@Beta
- class BulkUpdateException extends WriteFailedException {
+ class BulkUpdateException extends TranslationException {
private final Reverter reverter;
+ private final Set<InstanceIdentifier<?>> failedIds;
/**
* Constructs an BulkUpdateException.
- *
- * @param failedId instance identifier of the data object that caused bulk update to fail.
- * @param cause the cause of bulk update failure
+ * @param failedIds instance identifiers of the data objects that were not processed during bulk update.
+ * @param cause the cause of bulk update failure
*/
- public BulkUpdateException(@Nonnull final InstanceIdentifier<?> failedId, @Nonnull final Reverter reverter,
- final Throwable cause) {
- super(failedId, "Bulk update failed at " + failedId, cause);
+ public BulkUpdateException(@Nonnull final Set<InstanceIdentifier<?>> failedIds,
+ @Nonnull final Reverter reverter,
+ @Nonnull final Throwable cause) {
+ super("Bulk update failed at: " + failedIds, cause);
+ this.failedIds = failedIds;
this.reverter = checkNotNull(reverter, "reverter should not be null");
}
@@ -72,10 +156,13 @@ public interface WriterRegistry extends Writer<DataObject> {
reverter.revert();
}
+ public Set<InstanceIdentifier<?>> getFailedIds() {
+ return failedIds;
+ }
}
/**
- * Abstraction over revert mechanism in case of a bulk update failure
+ * Abstraction over revert mechanism in case of a bulk update failure.
*/
@Beta
interface Reverter {
@@ -95,19 +182,19 @@ public interface WriterRegistry extends Writer<DataObject> {
class RevertFailedException extends TranslationException {
// TODO change to list of VppDataModifications to make debugging easier
- private final List<InstanceIdentifier<?>> notRevertedChanges;
+ private final Set<InstanceIdentifier<?>> notRevertedChanges;
/**
- * Constructs an RevertFailedException with the list of changes that were not reverted.
+ * Constructs a RevertFailedException with the list of changes that were not reverted.
*
* @param notRevertedChanges list of changes that were not reverted
* @param cause the cause of revert failure
*/
- public RevertFailedException(@Nonnull final List<InstanceIdentifier<?>> notRevertedChanges,
+ public RevertFailedException(@Nonnull final Set<InstanceIdentifier<?>> notRevertedChanges,
final Throwable cause) {
super(cause);
checkNotNull(notRevertedChanges, "notRevertedChanges should not be null");
- this.notRevertedChanges = ImmutableList.copyOf(notRevertedChanges);
+ this.notRevertedChanges = ImmutableSet.copyOf(notRevertedChanges);
}
/**
@@ -116,7 +203,7 @@ public interface WriterRegistry extends Writer<DataObject> {
* @return list of changes that were not reverted
*/
@Nonnull
- public List<InstanceIdentifier<?>> getNotRevertedChanges() {
+ public Set<InstanceIdentifier<?>> getNotRevertedChanges() {
return notRevertedChanges;
}
}
diff --git a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/WriterRegistryBuilder.java b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/WriterRegistryBuilder.java
new file mode 100644
index 000000000..55ef66ec6
--- /dev/null
+++ b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/WriterRegistryBuilder.java
@@ -0,0 +1,25 @@
+/*
+ * 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.write;
+
+/**
+ * Builder for writer registries.
+ */
+public interface WriterRegistryBuilder {
+
+ WriterRegistry build();
+}
diff --git a/v3po/translate-api/src/main/yang/translate-api.yang b/v3po/translate-api/src/main/yang/translate-api.yang
index 4a8093ab8..414ee20e1 100644
--- a/v3po/translate-api/src/main/yang/translate-api.yang
+++ b/v3po/translate-api/src/main/yang/translate-api.yang
@@ -24,14 +24,19 @@ module translate-api {
config:java-class io.fd.honeycomb.v3po.translate.read.ReaderRegistry;
}
- identity honeycomb-writer {
+ identity honeycomb-writer-factory {
base "config:service-type";
- config:java-class io.fd.honeycomb.v3po.translate.write.Writer;
+ config:java-class io.fd.honeycomb.v3po.translate.write.WriterFactory;
}
identity honeycomb-writer-registry {
base "config:service-type";
- config:java-class io.fd.honeycomb.v3po.translate.write.WriterRegistry;
+ config:java-class io.fd.honeycomb.v3po.translate.write.ModifiableWriterRegistry;
+ }
+
+ identity honeycomb-writer-registry-builder {
+ base "config:service-type";
+ config:java-class io.fd.honeycomb.v3po.translate.write.WriterRegistryBuilder;
}
identity honeycomb-mapping-context {