try {
final DataObject dataObject = normalizedNode.isPresent() ? codec.toBinding(path,
normalizedNode.get()) : null;
- if(dataObject != null) {
+ if (dataObject != null) {
updateCache(store, path, dataObject);
}
return Optional.fromNullable(dataObject);
.toNormalizedNode(path, data);
org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalizedPath = normalized.getKey();
+ ensureParentsByMerge(writeTransaction, store, normalized.getKey(), path);
+ LOG.debug("Tx: {} : Putting data {}",getDelegate().getIdentifier(),normalized.getKey());
+ writeTransaction.put(store, normalized.getKey(), normalized.getValue());
+ }
+
+ protected void doMergeWithEnsureParents(final DOMDataReadWriteTransaction writeTransaction,
+ final LogicalDatastoreType store, final InstanceIdentifier<?> path, final DataObject data) {
+ invalidateCache(store, path);
+ final Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>> normalized = codec
+ .toNormalizedNode(path, data);
+
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalizedPath = normalized.getKey();
+ ensureParentsByMerge(writeTransaction, store, normalized.getKey(), path);
+ LOG.debug("Tx: {} : Merge data {}",getDelegate().getIdentifier(),normalized.getKey());
+ writeTransaction.merge(store, normalized.getKey(), normalized.getValue());
+ }
+
+ private void ensureParentsByMerge(final DOMDataReadWriteTransaction writeTransaction,
+ final LogicalDatastoreType store,
+ final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalizedPath,
+ final InstanceIdentifier<?> path) {
List<PathArgument> currentArguments = new ArrayList<>();
DataNormalizationOperation<?> currentOp = codec.getDataNormalizer().getRootOperation();
Iterator<PathArgument> iterator = normalizedPath.getPath().iterator();
writeTransaction.merge(store, currentPath, currentOp.createDefault(currentArg));
}
}
- //LOG .info("Tx: {} : Putting data {}",getDelegate().getIdentifier(),normalized.getKey());
- writeTransaction.put(store, normalized.getKey(), normalized.getValue());
}
protected void doMerge(final DOMDataWriteTransaction writeTransaction, final LogicalDatastoreType store,
private class ForwardedBackwardsCompatibleTransacion extends
AbstractForwardedTransaction<DOMDataReadWriteTransaction> implements DataModificationTransaction {
+ private final ListenerRegistry<DataTransactionListener> listeners = ListenerRegistry.create();
private final Map<InstanceIdentifier<? extends DataObject>, DataObject> updated = new HashMap<>();
private final Map<InstanceIdentifier<? extends DataObject>, DataObject> created = new HashMap<>();
private final Set<InstanceIdentifier<? extends DataObject>> removed = new HashSet<>();
@Override
public void putOperationalData(final InstanceIdentifier<? extends DataObject> path, final DataObject data) {
- posponedRemovedOperational.remove(path);
- doPutWithEnsureParents(getDelegate(), LogicalDatastoreType.OPERATIONAL, path, data);
+ boolean previouslyRemoved = posponedRemovedOperational.remove(path);
+ if(previouslyRemoved) {
+ doPutWithEnsureParents(getDelegate(), LogicalDatastoreType.OPERATIONAL, path, data);
+ } else {
+ doMergeWithEnsureParents(getDelegate(), LogicalDatastoreType.OPERATIONAL, path, data);
+ }
}
@Override
public void putConfigurationData(final InstanceIdentifier<? extends DataObject> path, final DataObject data) {
- posponedRemovedConfiguration.remove(path);
+ boolean previouslyRemoved = posponedRemovedConfiguration.remove(path);
DataObject originalObj = readConfigurationData(path);
if (originalObj != null) {
original.put(path, originalObj);
created.put(path, data);
}
updated.put(path, data);
- doPutWithEnsureParents(getDelegate(), LogicalDatastoreType.CONFIGURATION, path, data);
+ if(previouslyRemoved) {
+ doPutWithEnsureParents(getDelegate(), LogicalDatastoreType.CONFIGURATION, path, data);
+ } else {
+ doMergeWithEnsureParents(getDelegate(), LogicalDatastoreType.CONFIGURATION, path, data);
+ }
}
@Override
private void changeStatus(final TransactionStatus status) {
LOG.trace("Transaction {} changed status to {}", getIdentifier(), status);
this.status = status;
+
+ for(ListenerRegistration<DataTransactionListener> listener : listeners) {
+ try {
+ listener.getInstance().onStatusUpdated(this, status);
+ } catch (Exception e) {
+ LOG.error("Error during invoking transaction listener {}",listener.getInstance(),e);
+ }
+ }
}
@Override
doDelete(getDelegate(), LogicalDatastoreType.OPERATIONAL, path);
}
- final ListenableFuture<RpcResult<TransactionStatus>> f = ForwardedBackwardsCompatibleDataBroker.this.commit(this);
-
changeStatus(TransactionStatus.SUBMITED);
+ final ListenableFuture<RpcResult<TransactionStatus>> f = ForwardedBackwardsCompatibleDataBroker.this.commit(this);
+
Futures.addCallback(f, new FutureCallback<RpcResult<TransactionStatus>>() {
@Override
public void onSuccess(final RpcResult<TransactionStatus> result) {
@Override
public ListenerRegistration<DataTransactionListener> registerListener(final DataTransactionListener listener) {
- throw new UnsupportedOperationException();
+ return listeners.register(listener);
}
}
Builder eventBuilder = builder(potentialScope) //
.setBefore(beforeCont) //
- .setAfter(afterCont);
+ .setAfter(afterCont)
+ .addUpdated(path, beforeCont, afterCont);
for (DOMImmutableDataChangeEvent childChange : childChanges) {
eventBuilder.merge(childChange);
}
final Collection<Node> listeners, final NormalizedNode<PathArgument, ?> node,
final SimpleEventFactory eventFactory) {
- DOMImmutableDataChangeEvent event = eventFactory.create(path, node);
-
- if (!listeners.isEmpty()) {
+ final DOMImmutableDataChangeEvent event = eventFactory.create(path, node);
+ DOMImmutableDataChangeEvent propagateEvent = event;
// We have listeners for this node or it's children, so we will try
// to do additional processing
- if (node instanceof NormalizedNodeContainer<?, ?, ?>) {
- // Node has children, so we will try to resolve it's children
- // changes.
- @SuppressWarnings("unchecked")
- NormalizedNodeContainer<?, PathArgument, NormalizedNode<PathArgument, ?>> container = (NormalizedNodeContainer<?, PathArgument, NormalizedNode<PathArgument, ?>>) node;
- for (NormalizedNode<PathArgument, ?> child : container.getValue()) {
- PathArgument childId = child.getIdentifier();
- Collection<Node> childListeners = getListenerChildrenWildcarded(listeners, childId);
- if (!childListeners.isEmpty()) {
- resolveSameEventRecursivelly(append(path, childId), childListeners, child, eventFactory);
- }
- }
+ if (node instanceof NormalizedNodeContainer<?, ?, ?>) {
+ Builder eventBuilder = builder(DataChangeScope.BASE);
+ eventBuilder.merge(event);
+ eventBuilder.setBefore(event.getOriginalSubtree());
+ eventBuilder.setAfter(event.getUpdatedSubtree());
+
+ // Node has children, so we will try to resolve it's children
+ // changes.
+ @SuppressWarnings("unchecked")
+ NormalizedNodeContainer<?, PathArgument, NormalizedNode<PathArgument, ?>> container = (NormalizedNodeContainer<?, PathArgument, NormalizedNode<PathArgument, ?>>) node;
+ for (NormalizedNode<PathArgument, ?> child : container.getValue()) {
+ PathArgument childId = child.getIdentifier();
+ Collection<Node> childListeners = getListenerChildrenWildcarded(listeners, childId);
+ eventBuilder.merge(resolveSameEventRecursivelly(append(path, childId), childListeners, child, eventFactory));
}
+ propagateEvent = eventBuilder.build();
+ } else {
+ // We do not dispatch leaf events since Binding Aware components do not support them.
+ propagateEvent = builder(DataChangeScope.BASE).build();
+ }
+ if (!listeners.isEmpty()) {
addPartialTask(listeners, event);
}
- return event;
+ return propagateEvent;
}
private DOMImmutableDataChangeEvent resolveSubtreeChangeEvent(final InstanceIdentifier path,
Builder one = builder(DataChangeScope.ONE).setBefore(before.getData()).setAfter(after.getData());
- Builder subtree = builder(DataChangeScope.SUBTREE);
+ Builder subtree = builder(DataChangeScope.SUBTREE).setBefore(before.getData()).setAfter(after.getData());
for (NodeModification childMod : modification.getModifications()) {
PathArgument childId = childMod.getIdentifier();
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableOrderedLeafSetNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableOrderedMapNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUnkeyedListEntryNodeBuilder;
import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
} else if (schemaNode instanceof ChoiceNode) {
return new ChoiceModificationStrategy((ChoiceNode) schemaNode);
} else if (schemaNode instanceof LeafListSchemaNode) {
- return new LeafSetEntryModificationStrategy((LeafListSchemaNode) schemaNode);
+ return fromLeafListSchemaNode((LeafListSchemaNode) schemaNode);
} else if (schemaNode instanceof LeafSchemaNode) {
return new LeafModificationStrategy((LeafSchemaNode) schemaNode);
}
return new UnorderedMapModificationStrategy(schemaNode);
}
+ private static SchemaAwareApplyOperation fromLeafListSchemaNode(final LeafListSchemaNode schemaNode) {
+ if(schemaNode.isUserOrdered()) {
+ return new OrderedLeafSetModificationStrategy(schemaNode);
+ } else {
+ return new UnorderedLeafSetModificationStrategy(schemaNode);
+ }
+ }
+
+
public static SchemaAwareApplyOperation from(final DataNodeContainer resolvedTree,
final AugmentationTarget augSchemas, final AugmentationIdentifier identifier) {
AugmentationSchema augSchema = null;
}
- public static class LeafSetModificationStrategy extends NormalizedNodeContainerModificationStrategy {
+ public static class UnorderedLeafSetModificationStrategy extends NormalizedNodeContainerModificationStrategy {
private final Optional<ModificationApplyOperation> entryStrategy;
@SuppressWarnings({ "unchecked", "rawtypes" })
- protected LeafSetModificationStrategy(final LeafListSchemaNode schema) {
+ protected UnorderedLeafSetModificationStrategy(final LeafListSchemaNode schema) {
super((Class) LeafSetNode.class);
entryStrategy = Optional.<ModificationApplyOperation> of(new LeafSetEntryModificationStrategy(schema));
}
}
+ public static class OrderedLeafSetModificationStrategy extends NormalizedNodeContainerModificationStrategy {
+
+ private final Optional<ModificationApplyOperation> entryStrategy;
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ protected OrderedLeafSetModificationStrategy(final LeafListSchemaNode schema) {
+ super((Class) LeafSetNode.class);
+ entryStrategy = Optional.<ModificationApplyOperation> of(new LeafSetEntryModificationStrategy(schema));
+ }
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ protected NormalizedNodeContainerBuilder createBuilder(final PathArgument identifier) {
+ return ImmutableOrderedLeafSetNodeBuilder.create().withNodeIdentifier((NodeIdentifier) identifier);
+ }
+
+ @Override
+ public Optional<ModificationApplyOperation> getChild(final PathArgument identifier) {
+ if (identifier instanceof NodeWithValue) {
+ return entryStrategy;
+ }
+ return Optional.absent();
+ }
+
+ }
+
public static class UnkeyedListModificationStrategy extends SchemaAwareApplyOperation {
private final Optional<ModificationApplyOperation> entryStrategy;