2 * Copyright (c) 2016 Cisco and/or its affiliates.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package io.fd.honeycomb.translate.write.registry;
19 import static com.google.common.base.Preconditions.checkNotNull;
21 import com.google.common.annotations.Beta;
22 import com.google.common.collect.ImmutableSet;
23 import com.google.common.collect.Multimap;
24 import com.google.common.collect.Sets;
25 import io.fd.honeycomb.translate.TranslationException;
26 import io.fd.honeycomb.translate.write.DataObjectUpdate;
27 import io.fd.honeycomb.translate.write.WriteContext;
28 import io.fd.honeycomb.translate.write.Writer;
30 import javax.annotation.Nonnull;
31 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
34 * Special {@link Writer} capable of performing bulk updates.
37 public interface WriterRegistry {
40 * Performs bulk update.
42 * @throws BulkUpdateException in case bulk update fails
43 * @throws TranslationException in case some other error occurs while processing update request
45 void update(@Nonnull DataObjectUpdates updates,
46 @Nonnull WriteContext ctx) throws TranslationException;
49 * Simple DTO containing updates for {@link WriterRegistry}. Currently only deletes and updates (create + update)
53 final class DataObjectUpdates {
55 private final Multimap<InstanceIdentifier<?>, DataObjectUpdate> updates;
56 private final Multimap<InstanceIdentifier<?>, DataObjectUpdate.DataObjectDelete> deletes;
59 * Create new instance.
61 * @param updates All updates indexed by their unkeyed {@link InstanceIdentifier}
62 * @param deletes All deletes indexed by their unkeyed {@link InstanceIdentifier}
64 public DataObjectUpdates(@Nonnull final Multimap<InstanceIdentifier<?>, DataObjectUpdate> updates,
65 @Nonnull final Multimap<InstanceIdentifier<?>, DataObjectUpdate.DataObjectDelete> deletes) {
66 this.deletes = deletes;
67 this.updates = updates;
70 public Multimap<InstanceIdentifier<?>, DataObjectUpdate> getUpdates() {
74 public Multimap<InstanceIdentifier<?>, DataObjectUpdate.DataObjectDelete> getDeletes() {
78 public boolean isEmpty() {
79 return updates.isEmpty() && deletes.isEmpty();
83 public String toString() {
84 return "DataObjectUpdates{" + "updates=" + updates + ", deletes=" + deletes + '}';
88 * Get a {@link Set} containing all update types from both updates as well as deletes.
90 public Set<InstanceIdentifier<?>> getTypeIntersection() {
91 return Sets.union(deletes.keySet(), updates.keySet());
95 * Check whether there is only a single type of data object to be updated.
97 * @return true if there is only a single type of updates (update + delete)
99 public boolean containsOnlySingleType() {
100 return getTypeIntersection().size() == 1;
104 public boolean equals(final Object other) {
108 if (other == null || getClass() != other.getClass()) {
112 final DataObjectUpdates that = (DataObjectUpdates) other;
114 if (!updates.equals(that.updates)) {
117 return deletes.equals(that.deletes);
122 public int hashCode() {
123 int result = updates.hashCode();
124 result = 31 * result + deletes.hashCode();
131 * Thrown when bulk update failed.
134 class BulkUpdateException extends TranslationException {
136 private final Reverter reverter;
137 private final Set<InstanceIdentifier<?>> failedIds;
140 * Constructs an BulkUpdateException.
141 * @param failedIds instance identifiers of the data objects that were not processed during bulk update.
142 * @param cause the cause of bulk update failure
144 public BulkUpdateException(@Nonnull final Set<InstanceIdentifier<?>> failedIds,
145 @Nonnull final Reverter reverter,
146 @Nonnull final Throwable cause) {
147 super("Bulk update failed at: " + failedIds, cause);
148 this.failedIds = failedIds;
149 this.reverter = checkNotNull(reverter, "reverter should not be null");
153 * Reverts changes that were successfully applied during bulk update before failure occurred.
155 * @throws Reverter.RevertFailedException if revert fails
157 public void revertChanges() throws Reverter.RevertFailedException {
161 public Set<InstanceIdentifier<?>> getFailedIds() {
167 * Abstraction over revert mechanism in case of a bulk update failure.
173 * Reverts changes that were successfully applied during bulk update before failure occurred. Changes are
174 * reverted in reverse order they were applied.
176 * @throws RevertFailedException if not all of applied changes were successfully reverted
178 void revert() throws RevertFailedException;
181 * Thrown when some of the changes applied during bulk update were not reverted.
184 class RevertFailedException extends TranslationException {
186 // TODO change to list of VppDataModifications to make debugging easier
187 private final Set<InstanceIdentifier<?>> notRevertedChanges;
190 * Constructs a RevertFailedException with the list of changes that were not reverted.
192 * @param notRevertedChanges list of changes that were not reverted
193 * @param cause the cause of revert failure
195 public RevertFailedException(@Nonnull final Set<InstanceIdentifier<?>> notRevertedChanges,
196 final Throwable cause) {
198 checkNotNull(notRevertedChanges, "notRevertedChanges should not be null");
199 this.notRevertedChanges = ImmutableSet.copyOf(notRevertedChanges);
203 * Returns the list of changes that were not reverted.
205 * @return list of changes that were not reverted
208 public Set<InstanceIdentifier<?>> getNotRevertedChanges() {
209 return notRevertedChanges;