import java.util.List;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataPreconditionFailedException;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.ConflictingModificationAppliedException;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataValidationFailedException;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.IncorrectDataStructureException;
import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType;
import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.DataNodeContainerModificationStrategy.ContainerModificationStrategy;
import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.DataNodeContainerModificationStrategy.UnkeyedListItemModificationStrategy;
import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.NormalizedNodeContainerModificationStrategy.OrderedMapModificationStrategy;
import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.NormalizedNodeContainerModificationStrategy.UnorderedLeafSetModificationStrategy;
import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.ValueNodeModificationStrategy.LeafModificationStrategy;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNodeFactory;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.Version;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
-import com.google.common.primitives.UnsignedLong;
abstract class SchemaAwareApplyOperation implements ModificationApplyOperation {
private static final Logger LOG = LoggerFactory.getLogger(SchemaAwareApplyOperation.class);
return null;
}
+ public static boolean checkConflicting(final InstanceIdentifier path, final boolean condition, final String message) throws ConflictingModificationAppliedException {
+ if(!condition) {
+ throw new ConflictingModificationAppliedException(path, message);
+ }
+ return condition;
+ }
+
private static SchemaAwareApplyOperation fromListSchemaNode(final ListSchemaNode schemaNode) {
List<QName> keyDefinition = schemaNode.getKeyDefinition();
if (keyDefinition == null || keyDefinition.isEmpty()) {
}
}
- private static final void checkNotConflicting(final InstanceIdentifier path,final StoreMetadataNode original, final StoreMetadataNode current) throws DataPreconditionFailedException {
- checkDataPrecondition(path, original.getNodeVersion().equals(current.getNodeVersion()),"Node was replaced by other transaction.");
- checkDataPrecondition(path,original.getSubtreeVersion().equals(current.getSubtreeVersion()), "Node children was modified by other transaction");
+ private static final void checkNotConflicting(final InstanceIdentifier path, final TreeNode original, final TreeNode current) throws ConflictingModificationAppliedException {
+ checkConflicting(path, original.getVersion().equals(current.getVersion()),
+ "Node was replaced by other transaction.");
+ checkConflicting(path, original.getSubtreeVersion().equals(current.getSubtreeVersion()),
+ "Node children was modified by other transaction");
}
protected final ModificationApplyOperation resolveChildOperation(final PathArgument child) {
}
@Override
- public void verifyStructure(final NodeModification modification) throws IllegalArgumentException {
- if (modification.getModificationType() == ModificationType.WRITE) {
+ public void verifyStructure(final ModifiedNode modification) throws IllegalArgumentException {
+ if (modification.getType() == ModificationType.WRITE) {
verifyWrittenStructure(modification.getWrittenValue());
}
}
@Override
- public void checkApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional<StoreMetadataNode> current) throws DataPreconditionFailedException {
- switch (modification.getModificationType()) {
+ public final void checkApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional<TreeNode> current) throws DataValidationFailedException {
+ switch (modification.getType()) {
case DELETE:
checkDeleteApplicable(modification, current);
case SUBTREE_MODIFIED:
- checkSubtreeModificationApplicable(path,modification, current);
+ checkSubtreeModificationApplicable(path, modification, current);
return;
case WRITE:
- checkWriteApplicable(path,modification, current);
+ checkWriteApplicable(path, modification, current);
return;
case MERGE:
- checkMergeApplicable(path,modification,current);
+ checkMergeApplicable(path, modification, current);
return;
case UNMODIFIED:
return;
default:
- throw new UnsupportedOperationException("Suplied modification type "+modification.getModificationType()+ "is not supported.");
+ throw new UnsupportedOperationException("Suplied modification type "+ modification.getType()+ "is not supported.");
}
}
- protected void checkMergeApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional<StoreMetadataNode> current) throws DataPreconditionFailedException {
- Optional<StoreMetadataNode> original = modification.getOriginal();
+ protected void checkMergeApplicable(final InstanceIdentifier path, final NodeModification modification, final Optional<TreeNode> current) throws DataValidationFailedException {
+ Optional<TreeNode> original = modification.getOriginal();
if (original.isPresent() && current.isPresent()) {
/*
* We need to do conflict detection only and only if the value of leaf changed
* leads to same data.
*/
if(!original.get().getData().equals(current.get().getData())) {
-
- checkNotConflicting(path,original.get(), current.get());
+ checkNotConflicting(path, original.get(), current.get());
}
}
}
- protected void checkWriteApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional<StoreMetadataNode> current) throws DataPreconditionFailedException {
- Optional<StoreMetadataNode> original = modification.getOriginal();
+ protected void checkWriteApplicable(final InstanceIdentifier path, final NodeModification modification, final Optional<TreeNode> current) throws DataValidationFailedException {
+ Optional<TreeNode> original = modification.getOriginal();
if (original.isPresent() && current.isPresent()) {
- checkNotConflicting(path,original.get(), current.get());
+ checkNotConflicting(path, original.get(), current.get());
} else if(original.isPresent()) {
- throw new DataPreconditionFailedException(path,"Node was deleted by other transaction.");
+ throw new ConflictingModificationAppliedException(path,"Node was deleted by other transaction.");
}
}
- private void checkDeleteApplicable(final NodeModification modification, final Optional<StoreMetadataNode> current) {
+ private void checkDeleteApplicable(final NodeModification modification, final Optional<TreeNode> current) {
// Delete is always applicable, we do not expose it to subclasses
if (current.isPresent()) {
LOG.trace("Delete operation turned to no-op on missing node {}", modification);
}
@Override
- public final Optional<StoreMetadataNode> apply(final NodeModification modification,
- final Optional<StoreMetadataNode> currentMeta, final UnsignedLong subtreeVersion) {
+ public final Optional<TreeNode> apply(final ModifiedNode modification,
+ final Optional<TreeNode> currentMeta, final Version version) {
- switch (modification.getModificationType()) {
+ switch (modification.getType()) {
case DELETE:
- return modification.storeSnapshot(Optional.<StoreMetadataNode> absent());
+ return modification.storeSnapshot(Optional.<TreeNode> absent());
case SUBTREE_MODIFIED:
Preconditions.checkArgument(currentMeta.isPresent(), "Metadata not available for modification",
modification);
return modification.storeSnapshot(Optional.of(applySubtreeChange(modification, currentMeta.get(),
- subtreeVersion)));
+ version)));
case MERGE:
if(currentMeta.isPresent()) {
- return modification.storeSnapshot(Optional.of(applyMerge(modification,currentMeta.get(),subtreeVersion)));
+ return modification.storeSnapshot(Optional.of(applyMerge(modification,currentMeta.get(), version)));
} // Fallback to write is intentional - if node is not preexisting merge is same as write
case WRITE:
- return modification.storeSnapshot(Optional.of(applyWrite(modification, currentMeta, subtreeVersion)));
+ return modification.storeSnapshot(Optional.of(applyWrite(modification, currentMeta, version)));
case UNMODIFIED:
return currentMeta;
default:
}
}
- protected abstract StoreMetadataNode applyMerge(NodeModification modification,
- StoreMetadataNode currentMeta, UnsignedLong subtreeVersion);
+ protected abstract TreeNode applyMerge(ModifiedNode modification,
+ TreeNode currentMeta, Version version);
- protected abstract StoreMetadataNode applyWrite(NodeModification modification,
- Optional<StoreMetadataNode> currentMeta, UnsignedLong subtreeVersion);
+ protected abstract TreeNode applyWrite(ModifiedNode modification,
+ Optional<TreeNode> currentMeta, Version version);
- protected abstract StoreMetadataNode applySubtreeChange(NodeModification modification,
- StoreMetadataNode currentMeta, UnsignedLong subtreeVersion);
+ protected abstract TreeNode applySubtreeChange(ModifiedNode modification,
+ TreeNode currentMeta, Version version);
- protected abstract void checkSubtreeModificationApplicable(InstanceIdentifier path,final NodeModification modification,
- final Optional<StoreMetadataNode> current) throws DataPreconditionFailedException;
+ /**
+ *
+ * Checks is supplied {@link NodeModification} is applicable for Subtree Modification.
+ *
+ * @param path Path to current node
+ * @param modification Node modification which should be applied.
+ * @param current Current state of data tree
+ * @throws ConflictingModificationAppliedException If subtree was changed in conflicting way
+ * @throws IncorrectDataStructureException If subtree modification is not applicable (e.g. leaf node).
+ */
+ protected abstract void checkSubtreeModificationApplicable(InstanceIdentifier path, final NodeModification modification,
+ final Optional<TreeNode> current) throws DataValidationFailedException;
protected abstract void verifyWrittenStructure(NormalizedNode<?, ?> writtenValue);
}
@Override
- protected StoreMetadataNode applyMerge(final NodeModification modification, final StoreMetadataNode currentMeta,
- final UnsignedLong subtreeVersion) {
- return applyWrite(modification, Optional.of(currentMeta), subtreeVersion);
+ protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta,
+ final Version version) {
+ return applyWrite(modification, Optional.of(currentMeta), version);
}
@Override
- protected StoreMetadataNode applySubtreeChange(final NodeModification modification,
- final StoreMetadataNode currentMeta, final UnsignedLong subtreeVersion) {
+ protected TreeNode applySubtreeChange(final ModifiedNode modification,
+ final TreeNode currentMeta, final Version version) {
throw new UnsupportedOperationException("UnkeyedList does not support subtree change.");
}
@Override
- protected StoreMetadataNode applyWrite(final NodeModification modification,
- final Optional<StoreMetadataNode> currentMeta, final UnsignedLong subtreeVersion) {
- return StoreMetadataNode.createRecursively(modification.getWrittenValue(), subtreeVersion);
+ protected TreeNode applyWrite(final ModifiedNode modification,
+ final Optional<TreeNode> currentMeta, final Version version) {
+ return TreeNodeFactory.createTreeNode(modification.getWrittenValue(), version);
}
@Override
}
@Override
- protected void checkSubtreeModificationApplicable(final InstanceIdentifier path,final NodeModification modification,
- final Optional<StoreMetadataNode> current) throws DataPreconditionFailedException {
- throw new DataPreconditionFailedException(path, "Subtree modification is not allowed.");
+ protected void checkSubtreeModificationApplicable(final InstanceIdentifier path, final NodeModification modification,
+ final Optional<TreeNode> current) throws IncorrectDataStructureException {
+ throw new IncorrectDataStructureException(path, "Subtree modification is not allowed.");
}
}
-
- public static boolean checkDataPrecondition(final InstanceIdentifier path, final boolean condition, final String message) throws DataPreconditionFailedException {
- if(!condition) {
- throw new DataPreconditionFailedException(path, message);
- }
- return condition;
- }
-
}