From: Tony Tkacik Date: Fri, 23 May 2014 15:06:17 +0000 (+0000) Subject: Merge "BUG-770: NumberFormatException for input string on switch OFPT_HELLO" X-Git-Tag: autorelease-tag-v20140601202136_82eb3f9~27 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=290b7c23512204074fcd0fb7163b0adea48823fd;hp=d3e6c92c1f8bf92d60c4a0ec2ee8fc734806ff5d Merge "BUG-770: NumberFormatException for input string on switch OFPT_HELLO" --- diff --git a/opendaylight/commons/opendaylight/pom.xml b/opendaylight/commons/opendaylight/pom.xml index 89fd22d5a2..e1e3164f71 100644 --- a/opendaylight/commons/opendaylight/pom.xml +++ b/opendaylight/commons/opendaylight/pom.xml @@ -17,8 +17,8 @@ 1.0.0 0.4.2-SNAPSHOT - 1.1.0 + 0.5.2-SNAPSHOT 4.1 @@ -78,6 +78,7 @@ 0.4.2-SNAPSHOT 0.4.2-SNAPSHOT 2010.09.24.4-SNAPSHOT + 2013.10.19.1-SNAPSHOT 2013.10.21.2-SNAPSHOT 2010.09.24.4-SNAPSHOT 2.3.2 @@ -1470,6 +1471,11 @@ ietf-inet-types ${ietf-inet-types.version} + + org.opendaylight.yangtools.model + ietf-restconf + ${ietf-restconf.version} + org.opendaylight.yangtools.model ietf-topology @@ -1485,6 +1491,11 @@ ietf-yang-types ${ietf-yang-types.version} + + org.opendaylight.yangtools.model + ietf-yang-types-20130715 + 2013.07.15.1-SNAPSHOT + org.opendaylight.yangtools.model opendaylight-l2-types diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/CodecRegistryProvider.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/CodecRegistryProvider.java index 9d0fbd85dc..ec46219aaf 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/CodecRegistryProvider.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/CodecRegistryProvider.java @@ -8,6 +8,7 @@ package org.opendaylight.controller.config.manager.impl.osgi.mapping; import javassist.ClassPool; + import org.opendaylight.controller.config.manager.impl.util.OsgiRegistrationUtil; import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy; import org.opendaylight.yangtools.sal.binding.generator.impl.RuntimeGeneratedMappingServiceImpl; @@ -27,10 +28,8 @@ public class CodecRegistryProvider implements AutoCloseable { private final RuntimeGeneratedMappingServiceImpl service; private final AutoCloseable registration; - public CodecRegistryProvider(ClassLoadingStrategy classLoadingStrategy, BundleContext context) { - service = new RuntimeGeneratedMappingServiceImpl(classLoadingStrategy); - service.setPool(CLASS_POOL); - service.init(); + public CodecRegistryProvider(final ClassLoadingStrategy classLoadingStrategy, final BundleContext context) { + service = new RuntimeGeneratedMappingServiceImpl(CLASS_POOL, classLoadingStrategy); registration = OsgiRegistrationUtil.registerService(context, service, SchemaServiceListener.class, BindingIndependentMappingService.class); } diff --git a/opendaylight/distribution/opendaylight/pom.xml b/opendaylight/distribution/opendaylight/pom.xml index 48e661f196..52aa6d276b 100644 --- a/opendaylight/distribution/opendaylight/pom.xml +++ b/opendaylight/distribution/opendaylight/pom.xml @@ -1187,6 +1187,10 @@ org.opendaylight.yangtools.model ietf-inet-types + + org.opendaylight.yangtools.model + ietf-restconf + org.opendaylight.yangtools.model ietf-topology @@ -1195,6 +1199,10 @@ org.opendaylight.yangtools.model ietf-yang-types + + org.opendaylight.yangtools.model + ietf-yang-types-20130715 + org.opendaylight.yangtools.model opendaylight-l2-types diff --git a/opendaylight/dummy-console/pom.xml b/opendaylight/dummy-console/pom.xml index 6d90eb39da..8901c2e0b5 100644 --- a/opendaylight/dummy-console/pom.xml +++ b/opendaylight/dummy-console/pom.xml @@ -16,7 +16,6 @@ org.apache.felix maven-bundle-plugin - ${bundle.plugin.version} true diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/RuntimeMappingModule.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/RuntimeMappingModule.java index 750defc0e9..0f0ce0dc9d 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/RuntimeMappingModule.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/RuntimeMappingModule.java @@ -26,6 +26,8 @@ import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException; import org.opendaylight.yangtools.yang.model.api.SchemaServiceListener; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.google.common.base.Optional; import com.google.common.base.Preconditions; @@ -36,6 +38,8 @@ import com.google.common.base.Preconditions; public final class RuntimeMappingModule extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractRuntimeMappingModule { + private static final Logger LOG = LoggerFactory.getLogger(RuntimeMappingModule.class); + private BundleContext bundleContext; public RuntimeMappingModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, @@ -163,10 +167,17 @@ public final class RuntimeMappingModule extends } @Override - public void close() throws Exception { + public void close() { if(delegate != null) { delegate = null; - bundleContext.ungetService(reference); + + try { + bundleContext.ungetService(reference); + } catch (IllegalStateException e) { + // Indicates the BundleContext is no longer valid which can happen normally on shutdown. + LOG.debug( "Error unregistering service", e ); + } + bundleContext= null; reference = null; } diff --git a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizer.java b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizer.java index 33a9869a6b..f30c8ddcaa 100644 --- a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizer.java +++ b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizer.java @@ -92,11 +92,11 @@ public class DataNormalizer { } // Write Augmentation data resolution - if (legacyData.getChildren().size() == 1) { + if (legacyData.getValue().size() == 1) { final DataNormalizationOperation potentialOp; try { - final QName childType = legacyData.getChildren().get(0).getNodeType(); + final QName childType = legacyData.getValue().get(0).getNodeType(); potentialOp = currentOp.getChild(childType); } catch (DataNormalizationException e) { throw new IllegalArgumentException(String.format("Failed to get child operation for %s", legacyData), e); diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/SchemaServiceImplSingletonModule.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/SchemaServiceImplSingletonModule.java index ba7414d42e..93284c98e1 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/SchemaServiceImplSingletonModule.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/SchemaServiceImplSingletonModule.java @@ -16,6 +16,8 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.SchemaServiceListener; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @@ -23,6 +25,8 @@ import org.osgi.framework.ServiceReference; public final class SchemaServiceImplSingletonModule extends org.opendaylight.controller.config.yang.md.sal.dom.impl.AbstractSchemaServiceImplSingletonModule { + private static final Logger LOG = LoggerFactory.getLogger(SchemaServiceImplSingletonModule.class); + BundleContext bundleContext; public SchemaServiceImplSingletonModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, @@ -83,28 +87,41 @@ public final class SchemaServiceImplSingletonModule extends public void close() throws Exception { if (delegate != null) { delegate = null; - bundleContext.ungetService(reference); + + try { + bundleContext.ungetService(reference); + } catch (IllegalStateException e) { + // Indicates the service was already unregistered which can happen normally + // on shutdown. + LOG.debug( "Error unregistering service", e ); + } + reference = null; bundleContext = null; } } + @Override public void addModule(Module arg0) { delegate.addModule(arg0); } + @Override public SchemaContext getGlobalContext() { return delegate.getGlobalContext(); } + @Override public SchemaContext getSessionContext() { return delegate.getSessionContext(); } + @Override public ListenerRegistration registerSchemaServiceListener(SchemaServiceListener arg0) { return delegate.registerSchemaServiceListener(arg0); } + @Override public void removeModule(Module arg0) { delegate.removeModule(arg0); } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/TranslatingDataChangeEvent.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/TranslatingDataChangeEvent.java index 827e4ca63d..3de07fc2ab 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/TranslatingDataChangeEvent.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/TranslatingDataChangeEvent.java @@ -23,7 +23,7 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import com.google.common.collect.Maps; public abstract class TranslatingDataChangeEvent implements - DataChangeEvent { +DataChangeEvent { private TranslatingDataChangeEvent() { } @@ -98,7 +98,6 @@ public abstract class TranslatingDataChangeEvent implements return null; } - @SuppressWarnings({ "rawtypes", "unchecked" }) private final static class OperationalChangeEvent extends TranslatingDataChangeEvent { private final AsyncDataChangeEvent> delegate; @@ -106,7 +105,7 @@ public abstract class TranslatingDataChangeEvent implements private Map updatedCache; public OperationalChangeEvent(final AsyncDataChangeEvent> change, - final DataNormalizer normalizer) { + final DataNormalizer normalizer) { this.delegate = change; this.normalizer = normalizer; } @@ -179,7 +178,7 @@ public abstract class TranslatingDataChangeEvent implements private Map updatedCache; public ConfigurationChangeEvent(final AsyncDataChangeEvent> change, - final DataNormalizer normalizer) { + final DataNormalizer normalizer) { this.delegate = change; this.normalizer = normalizer; } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMDataStore.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMDataStore.java index 9e11fc70fc..00df6580ef 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMDataStore.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMDataStore.java @@ -335,12 +335,8 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable, Sch @Override public ListenableFuture abort() { - if (candidate != null) { - candidate.close(); - candidate = null; - } - - return Futures. immediateFuture(null); + candidate = null; + return Futures.immediateFuture(null); } @Override @@ -360,7 +356,7 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable, Sch } } - return Futures. immediateFuture(null); + return Futures.immediateFuture(null); } } } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java index db9bb0fef2..b36ef3dd7c 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java @@ -23,11 +23,11 @@ import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataCh import org.opendaylight.controller.md.sal.dom.store.impl.DOMImmutableDataChangeEvent.Builder; import org.opendaylight.controller.md.sal.dom.store.impl.DOMImmutableDataChangeEvent.SimpleEventFactory; import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeCandidate; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeCandidateNode; import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerTree; import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerTree.Node; import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerTree.Walker; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.NodeModification; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.StoreMetadataNode; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates; @@ -73,9 +73,9 @@ final class ResolveDataChangeEventsTask implements Callable call() { try (final Walker w = listenerRoot.getWalker()) { - resolveAnyChangeEvent(candidate.getRootPath(), Collections.singleton(w.getRootNode()), - candidate.getModificationRoot(), Optional.fromNullable(candidate.getBeforeRoot()), - Optional.fromNullable(candidate.getAfterRoot())); + resolveAnyChangeEvent(candidate.getRootPath(), Collections.singleton(w.getRootNode()), candidate.getRootNode()); return createNotificationTasks(); } } @@ -256,29 +254,38 @@ final class ResolveDataChangeEventsTask implements Callable listeners, final NodeModification modification, - final Optional before, final Optional after) { - // No listeners are present in listener registration subtree - // no before and after state is present - if (!before.isPresent() && !after.isPresent()) { + final Collection listeners, final DataTreeCandidateNode node) { + + if (node.getModificationType() != ModificationType.UNMODIFIED && + !node.getDataAfter().isPresent() && !node.getDataBefore().isPresent()) { + LOG.debug("Modification at {} has type {}, but no before- and after-data. Assuming unchanged.", + path, node.getModificationType()); return NO_CHANGE; } - switch (modification.getModificationType()) { + + // no before and after state is present + + switch (node.getModificationType()) { case SUBTREE_MODIFIED: - return resolveSubtreeChangeEvent(path, listeners, modification, before.get(), after.get()); + return resolveSubtreeChangeEvent(path, listeners, node); case MERGE: case WRITE: - if (before.isPresent()) { - return resolveReplacedEvent(path, listeners, before.get().getData(), after.get().getData()); + Preconditions.checkArgument(node.getDataAfter().isPresent(), + "Modification at {} has type {} but no after-data", path, node.getModificationType()); + if (node.getDataBefore().isPresent()) { + return resolveReplacedEvent(path, listeners, node.getDataBefore().get(), node.getDataAfter().get()); } else { - return resolveCreateEvent(path, listeners, after.get()); + return resolveCreateEvent(path, listeners, node.getDataAfter().get()); } case DELETE: - return resolveDeleteEvent(path, listeners, before.get()); - default: + Preconditions.checkArgument(node.getDataBefore().isPresent(), + "Modification at {} has type {} but no before-data", path, node.getModificationType()); + return resolveDeleteEvent(path, listeners, node.getDataBefore().get()); + case UNMODIFIED: return NO_CHANGE; } + throw new IllegalStateException(String.format("Unhandled node state %s at %s", node.getModificationType(), path)); } private DOMImmutableDataChangeEvent resolveReplacedEvent(final InstanceIdentifier path, @@ -313,7 +320,7 @@ final class ResolveDataChangeEventsTask implements Callable listeners, final NormalizedNodeContainer> beforeCont, - final NormalizedNodeContainer> afterCont) { + final NormalizedNodeContainer> afterCont) { final Set alreadyProcessed = new HashSet<>(); final List childChanges = new LinkedList<>(); @@ -388,17 +395,17 @@ final class ResolveDataChangeEventsTask implements Callable listeners, final StoreMetadataNode afterState) { + final Collection listeners, final NormalizedNode afterState) { @SuppressWarnings({ "unchecked", "rawtypes" }) - final NormalizedNode node = (NormalizedNode) afterState.getData(); + final NormalizedNode node = (NormalizedNode) afterState; return resolveSameEventRecursivelly(path, listeners, node, DOMImmutableDataChangeEvent.getCreateEventFactory()); } private DOMImmutableDataChangeEvent resolveDeleteEvent(final InstanceIdentifier path, - final Collection listeners, final StoreMetadataNode beforeState) { + final Collection listeners, final NormalizedNode beforeState) { @SuppressWarnings({ "unchecked", "rawtypes" }) - final NormalizedNode node = (NormalizedNode) beforeState.getData(); + final NormalizedNode node = (NormalizedNode) beforeState; return resolveSameEventRecursivelly(path, listeners, node, DOMImmutableDataChangeEvent.getRemoveEventFactory()); } @@ -408,7 +415,7 @@ final class ResolveDataChangeEventsTask implements Callable) { LOG.trace("Resolving subtree recursive event for {}, type {}", path, eventFactory); @@ -439,30 +446,31 @@ final class ResolveDataChangeEventsTask implements Callable listeners, final NodeModification modification, - final StoreMetadataNode before, final StoreMetadataNode after) { + final Collection listeners, final DataTreeCandidateNode modification) { - Builder one = builder(DataChangeScope.ONE).setBefore(before.getData()).setAfter(after.getData()); + Preconditions.checkArgument(modification.getDataBefore().isPresent(), "Subtree change with before-data not present at path %s", path); + Preconditions.checkArgument(modification.getDataAfter().isPresent(), "Subtree change with after-data not present at path %s", path); - Builder subtree = builder(DataChangeScope.SUBTREE).setBefore(before.getData()).setAfter(after.getData()); + Builder one = builder(DataChangeScope.ONE). + setBefore(modification.getDataBefore().get()). + setAfter(modification.getDataAfter().get()); + Builder subtree = builder(DataChangeScope.SUBTREE). + setBefore(modification.getDataBefore().get()). + setAfter(modification.getDataAfter().get()); - for (NodeModification childMod : modification.getModifications()) { + for (DataTreeCandidateNode childMod : modification.getChildNodes()) { PathArgument childId = childMod.getIdentifier(); InstanceIdentifier childPath = append(path, childId); Collection childListeners = getListenerChildrenWildcarded(listeners, childId); - Optional childBefore = before.getChild(childId); - Optional childAfter = after.getChild(childId); - switch (childMod.getModificationType()) { case WRITE: case MERGE: case DELETE: - one.merge(resolveAnyChangeEvent(childPath, childListeners, childMod, childBefore, childAfter)); + one.merge(resolveAnyChangeEvent(childPath, childListeners, childMod)); break; case SUBTREE_MODIFIED: - subtree.merge(resolveSubtreeChangeEvent(childPath, childListeners, childMod, childBefore.get(), - childAfter.get())); + subtree.merge(resolveSubtreeChangeEvent(childPath, childListeners, childMod)); break; case UNMODIFIED: // no-op @@ -514,7 +522,7 @@ final class ResolveDataChangeEventsTask implements Callable getChildNodes(); + + ModificationType getModificationType(); + Optional> getDataAfter(); + Optional> getDataBefore(); +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationType.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ModificationType.java similarity index 91% rename from opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationType.java rename to opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ModificationType.java index 9d2e965ff7..b16e907120 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationType.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ModificationType.java @@ -5,7 +5,7 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; +package org.opendaylight.controller.md.sal.dom.store.impl.tree; public enum ModificationType { diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/AbstractDataTreeCandidate.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/AbstractDataTreeCandidate.java index b2faf79565..cddda5ccc5 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/AbstractDataTreeCandidate.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/AbstractDataTreeCandidate.java @@ -13,21 +13,15 @@ import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import com.google.common.base.Preconditions; abstract class AbstractDataTreeCandidate implements DataTreeCandidate { - private final InstanceIdentifier rootPath; - private final NodeModification modificationRoot; + private final InstanceIdentifier rootPath; - protected AbstractDataTreeCandidate(final InstanceIdentifier rootPath, NodeModification modificationRoot) { - this.rootPath = Preconditions.checkNotNull(rootPath); - this.modificationRoot = Preconditions.checkNotNull(modificationRoot); - } + protected AbstractDataTreeCandidate(final InstanceIdentifier rootPath) { + this.rootPath = Preconditions.checkNotNull(rootPath); + } - @Override - public final InstanceIdentifier getRootPath() { - return rootPath; - } + @Override + public final InstanceIdentifier getRootPath() { + return rootPath; + } - @Override - public final NodeModification getModificationRoot() { - return modificationRoot; - } } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/AlwaysFailOperation.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/AlwaysFailOperation.java index 4e3aa49113..15479be462 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/AlwaysFailOperation.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/AlwaysFailOperation.java @@ -1,21 +1,27 @@ package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.Version; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; import com.google.common.base.Optional; -import com.google.common.primitives.UnsignedLong; +/** + * An implementation of apply operation which fails to do anything, + * consistently. An instance of this class is used by the data tree + * if it does not have a SchemaContext attached and hence cannot + * perform anything meaningful. + */ final class AlwaysFailOperation implements ModificationApplyOperation { - @Override - public Optional apply(final NodeModification modification, - final Optional storeMeta, final UnsignedLong subtreeVersion) { + public Optional apply(final ModifiedNode modification, + final Optional storeMeta, final Version subtreeVersion) { throw new IllegalStateException("Schema Context is not available."); } @Override - public void checkApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional storeMetadata) { + public void checkApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional storeMetadata) { throw new IllegalStateException("Schema Context is not available."); } @@ -25,7 +31,7 @@ final class AlwaysFailOperation implements ModificationApplyOperation { } @Override - public void verifyStructure(final NodeModification modification) throws IllegalArgumentException { + public void verifyStructure(final ModifiedNode modification) { throw new IllegalStateException("Schema Context is not available."); } } \ No newline at end of file diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/DataNodeContainerModificationStrategy.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/DataNodeContainerModificationStrategy.java new file mode 100644 index 0000000000..dc891482ab --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/DataNodeContainerModificationStrategy.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; + +import static com.google.common.base.Preconditions.checkArgument; + +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.ExecutionException; + +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; +import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode; +import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder; +import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableAugmentationNodeBuilder; +import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder; +import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder; +import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUnkeyedListEntryNodeBuilder; +import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.AugmentationSchemaProxy; +import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; +import org.opendaylight.yangtools.yang.model.api.AugmentationTarget; +import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; + +import com.google.common.base.Function; +import com.google.common.base.Optional; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; + +/** + * Base strategy for applying changes to a ContainerNode, irrespective of its + * actual type. + * + * @param Type of the container node + */ +abstract class DataNodeContainerModificationStrategy extends NormalizedNodeContainerModificationStrategy { + + private final T schema; + private final LoadingCache childCache = CacheBuilder.newBuilder() + .build(CacheLoader.from(new Function() { + + @Override + public ModificationApplyOperation apply(final PathArgument identifier) { + if (identifier instanceof AugmentationIdentifier && schema instanceof AugmentationTarget) { + return from(schema, (AugmentationTarget) schema, (AugmentationIdentifier) identifier); + } + + DataSchemaNode child = schema.getDataChildByName(identifier.getNodeType()); + if (child == null) { + return null; + } + return from(child); + } + })); + + protected DataNodeContainerModificationStrategy(final T schema, + final Class> nodeClass) { + super(nodeClass); + this.schema = schema; + } + + protected T getSchema() { + return schema; + } + + @Override + public Optional getChild(final PathArgument identifier) { + try { + return Optional. fromNullable(childCache.get(identifier)); + } catch (ExecutionException e) { + return Optional.absent(); + } + } + + @Override + @SuppressWarnings("rawtypes") + protected abstract DataContainerNodeBuilder createBuilder(NormalizedNode original); + + @Override + public String toString() { + return getClass().getSimpleName() + " [" + schema + "]"; + } + + public static class AugmentationModificationStrategy extends DataNodeContainerModificationStrategy { + + protected AugmentationModificationStrategy(final AugmentationSchema schema, final DataNodeContainer resolved) { + super(createAugmentProxy(schema,resolved), AugmentationNode.class); + } + + @Override + @SuppressWarnings("rawtypes") + protected DataContainerNodeBuilder createBuilder(final NormalizedNode original) { + checkArgument(original instanceof AugmentationNode); + return ImmutableAugmentationNodeBuilder.create((AugmentationNode) original); + } + + + private static AugmentationSchema createAugmentProxy(final AugmentationSchema schema, final DataNodeContainer resolved) { + Set realChildSchemas = new HashSet<>(); + for(DataSchemaNode augChild : schema.getChildNodes()) { + realChildSchemas.add(resolved.getDataChildByName(augChild.getQName())); + } + return new AugmentationSchemaProxy(schema, realChildSchemas); + } + } + + public static class ContainerModificationStrategy extends DataNodeContainerModificationStrategy { + + public ContainerModificationStrategy(final ContainerSchemaNode schemaNode) { + super(schemaNode, ContainerNode.class); + } + + @Override + @SuppressWarnings("rawtypes") + protected DataContainerNodeBuilder createBuilder(final NormalizedNode original) { + checkArgument(original instanceof ContainerNode); + return ImmutableContainerNodeBuilder.create((ContainerNode) original); + } + } + + public static class ListEntryModificationStrategy extends DataNodeContainerModificationStrategy { + + protected ListEntryModificationStrategy(final ListSchemaNode schema) { + super(schema, MapEntryNode.class); + } + + @Override + @SuppressWarnings("rawtypes") + protected final DataContainerNodeBuilder createBuilder(final NormalizedNode original) { + checkArgument(original instanceof MapEntryNode); + return ImmutableMapEntryNodeBuilder.create((MapEntryNode) original); + } + } + + public static class UnkeyedListItemModificationStrategy extends DataNodeContainerModificationStrategy { + + public UnkeyedListItemModificationStrategy(final ListSchemaNode schemaNode) { + super(schemaNode, UnkeyedListEntryNode.class); + } + + @Override + @SuppressWarnings("rawtypes") + protected DataContainerNodeBuilder createBuilder(final NormalizedNode original) { + checkArgument(original instanceof UnkeyedListEntryNode); + return ImmutableUnkeyedListEntryNodeBuilder.create((UnkeyedListEntryNode) original); + } + } +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTree.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTree.java index 5a300a071d..d3495b542a 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTree.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTree.java @@ -14,7 +14,9 @@ import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataPreconditionFa import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTree; import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeCandidate; import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeModification; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType; import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreUtils; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.slf4j.Logger; @@ -33,9 +35,9 @@ final class InMemoryDataTree implements DataTree { private final ReadWriteLock rwLock = new ReentrantReadWriteLock(true); private ModificationApplyOperation applyOper = new AlwaysFailOperation(); private SchemaContext currentSchemaContext; - private StoreMetadataNode rootNode; + private TreeNode rootNode; - public InMemoryDataTree(StoreMetadataNode rootNode, final SchemaContext schemaContext) { + public InMemoryDataTree(final TreeNode rootNode, final SchemaContext schemaContext) { this.rootNode = Preconditions.checkNotNull(rootNode); if (schemaContext != null) { @@ -79,28 +81,28 @@ final class InMemoryDataTree implements DataTree { } @Override - public void validate(DataTreeModification modification) throws DataPreconditionFailedException { + public void validate(final DataTreeModification modification) throws DataPreconditionFailedException { Preconditions.checkArgument(modification instanceof InMemoryDataTreeModification, "Invalid modification class %s", modification.getClass()); final InMemoryDataTreeModification m = (InMemoryDataTreeModification)modification; - m.getStrategy().checkApplicable(PUBLIC_ROOT_PATH, m.getRootModification(), Optional.of(rootNode)); + m.getStrategy().checkApplicable(PUBLIC_ROOT_PATH, m.getRootModification(), Optional.of(rootNode)); } @Override - public synchronized DataTreeCandidate prepare(DataTreeModification modification) { + public synchronized DataTreeCandidate prepare(final DataTreeModification modification) { Preconditions.checkArgument(modification instanceof InMemoryDataTreeModification, "Invalid modification class %s", modification.getClass()); final InMemoryDataTreeModification m = (InMemoryDataTreeModification)modification; - final NodeModification root = m.getRootModification(); + final ModifiedNode root = m.getRootModification(); - if (root.getModificationType() == ModificationType.UNMODIFIED) { + if (root.getType() == ModificationType.UNMODIFIED) { return new NoopDataTreeCandidate(PUBLIC_ROOT_PATH, root); } rwLock.writeLock().lock(); try { - // FIXME: rootNode needs to be a read-write snapshot here... - final Optional newRoot = m.getStrategy().apply(m.getRootModification(), Optional.of(rootNode), StoreUtils.increase(rootNode.getSubtreeVersion())); + final Optional newRoot = m.getStrategy().apply(m.getRootModification(), + Optional.of(rootNode), rootNode.getSubtreeVersion().next()); Preconditions.checkState(newRoot.isPresent(), "Apply strategy failed to produce root node"); return new InMemoryDataTreeCandidate(PUBLIC_ROOT_PATH, root, rootNode, newRoot.get()); } finally { @@ -109,7 +111,7 @@ final class InMemoryDataTree implements DataTree { } @Override - public synchronized void commit(DataTreeCandidate candidate) { + public synchronized void commit(final DataTreeCandidate candidate) { if (candidate instanceof NoopDataTreeCandidate) { return; } @@ -117,7 +119,7 @@ final class InMemoryDataTree implements DataTree { Preconditions.checkArgument(candidate instanceof InMemoryDataTreeCandidate, "Invalid candidate class %s", candidate.getClass()); final InMemoryDataTreeCandidate c = (InMemoryDataTreeCandidate)candidate; - LOG.debug("Updating Store snapshot version: {} with version:{}", rootNode.getSubtreeVersion(), c.getAfterRoot().getSubtreeVersion()); + LOG.debug("Updating datastore from {} to {}", rootNode, c.getAfterRoot()); if (LOG.isTraceEnabled()) { LOG.trace("Data Tree is {}", StoreUtils.toStringTree(c.getAfterRoot().getData())); @@ -127,7 +129,7 @@ final class InMemoryDataTree implements DataTree { rwLock.writeLock().lock(); try { Preconditions.checkState(c.getBeforeRoot() == rootNode, - String.format("Store snapshot %s and transaction snapshot %s differ.", rootNode, c.getBeforeRoot())); + String.format("Store tree %s and candidate base %s differ.", rootNode, c.getBeforeRoot())); this.rootNode = c.getAfterRoot(); } finally { rwLock.writeLock().unlock(); diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeCandidate.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeCandidate.java index 93719b7f53..bafea6bd97 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeCandidate.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeCandidate.java @@ -1,32 +1,125 @@ package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeCandidateNode; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import com.google.common.base.Function; +import com.google.common.base.Optional; import com.google.common.base.Preconditions; +import com.google.common.collect.Iterables; final class InMemoryDataTreeCandidate extends AbstractDataTreeCandidate { - private final StoreMetadataNode newRoot; - private final StoreMetadataNode oldRoot; - - InMemoryDataTreeCandidate(final InstanceIdentifier rootPath, final NodeModification modificationRoot, - final StoreMetadataNode oldRoot, final StoreMetadataNode newRoot) { - super(rootPath, modificationRoot); - this.newRoot = Preconditions.checkNotNull(newRoot); - this.oldRoot = Preconditions.checkNotNull(oldRoot); - } - - @Override - public void close() { - // FIXME: abort operation here :) - } - - @Override - public StoreMetadataNode getBeforeRoot() { - return oldRoot; - } - - @Override - public StoreMetadataNode getAfterRoot() { - return newRoot; - } + private static abstract class AbstractNode implements DataTreeCandidateNode { + private final ModifiedNode mod; + private final TreeNode newMeta; + private final TreeNode oldMeta; + + protected AbstractNode(final ModifiedNode mod, + final TreeNode oldMeta, final TreeNode newMeta) { + this.newMeta = newMeta; + this.oldMeta = oldMeta; + this.mod = Preconditions.checkNotNull(mod); + } + + protected final ModifiedNode getMod() { + return mod; + } + + protected final TreeNode getNewMeta() { + return newMeta; + } + + protected final TreeNode getOldMeta() { + return oldMeta; + } + + private static final TreeNode childMeta(final TreeNode parent, final PathArgument id) { + if (parent != null) { + return parent.getChild(id).orNull(); + } else { + return null; + } + } + + @Override + public Iterable getChildNodes() { + return Iterables.transform(mod.getChildren(), new Function() { + @Override + public DataTreeCandidateNode apply(final ModifiedNode input) { + final PathArgument id = input.getIdentifier(); + return new ChildNode(input, childMeta(oldMeta, id), childMeta(newMeta, id)); + } + }); + } + + @Override + public ModificationType getModificationType() { + return mod.getType(); + } + + private Optional> optionalData(final TreeNode meta) { + if (meta != null) { + return Optional.>of(meta.getData()); + } else { + return Optional.absent(); + } + } + + @Override + public Optional> getDataAfter() { + return optionalData(newMeta); + } + + @Override + public Optional> getDataBefore() { + return optionalData(oldMeta); + } + } + + private static final class ChildNode extends AbstractNode { + public ChildNode(final ModifiedNode mod, final TreeNode oldMeta, final TreeNode newMeta) { + super(mod, oldMeta, newMeta); + } + + @Override + public PathArgument getIdentifier() { + return getMod().getIdentifier(); + } + } + + private static final class RootNode extends AbstractNode { + public RootNode(final ModifiedNode mod, final TreeNode oldMeta, final TreeNode newMeta) { + super(mod, oldMeta, newMeta); + } + + @Override + public PathArgument getIdentifier() { + throw new IllegalStateException("Attempted to get identifier of the root node"); + } + } + + private final RootNode root; + + InMemoryDataTreeCandidate(final InstanceIdentifier rootPath, final ModifiedNode modificationRoot, + final TreeNode beforeRoot, final TreeNode afterRoot) { + super(rootPath); + this.root = new RootNode(modificationRoot, beforeRoot, afterRoot); + } + + TreeNode getAfterRoot() { + return root.getNewMeta(); + } + + TreeNode getBeforeRoot() { + return root.getOldMeta(); + } + + @Override + public DataTreeCandidateNode getRootNode() { + return root; + } } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeFactory.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeFactory.java index 7614611ab2..4640be43e7 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeFactory.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeFactory.java @@ -1,6 +1,8 @@ package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeFactory; +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.data.api.InstanceIdentifier.NodeIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.data.impl.schema.Builders; @@ -10,26 +12,26 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext; * A factory for creating in-memory data trees. */ public final class InMemoryDataTreeFactory implements DataTreeFactory { - private static final InMemoryDataTreeFactory INSTANCE = new InMemoryDataTreeFactory(); + private static final InMemoryDataTreeFactory INSTANCE = new InMemoryDataTreeFactory(); - private InMemoryDataTreeFactory() { - // Never instantiated externally - } + private InMemoryDataTreeFactory() { + // Never instantiated externally + } - @Override - public InMemoryDataTree create() { - final NodeIdentifier root = new NodeIdentifier(SchemaContext.NAME); - final NormalizedNode data = Builders.containerBuilder().withNodeIdentifier(root).build(); + @Override + public InMemoryDataTree create() { + final NodeIdentifier root = new NodeIdentifier(SchemaContext.NAME); + final NormalizedNode data = Builders.containerBuilder().withNodeIdentifier(root).build(); - return new InMemoryDataTree(StoreMetadataNode.createEmpty(data), null); - } + return new InMemoryDataTree(TreeNodeFactory.createTreeNode(data, Version.initial()), null); + } - /** - * Get an instance of this factory. This method cannot fail. - * - * @return Data tree factory instance. - */ - public static final InMemoryDataTreeFactory getInstance() { - return INSTANCE; - } + /** + * Get an instance of this factory. This method cannot fail. + * + * @return Data tree factory instance. + */ + public static final InMemoryDataTreeFactory getInstance() { + return INSTANCE; + } } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeModification.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeModification.java index df3ef8b7e1..c05ed4b442 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeModification.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeModification.java @@ -7,14 +7,13 @@ */ package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; -import static com.google.common.base.Preconditions.checkState; - import java.util.Map.Entry; -import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; + +import javax.annotation.concurrent.GuardedBy; import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeModification; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreUtils; import org.opendaylight.controller.md.sal.dom.store.impl.tree.TreeNodeUtils; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; @@ -28,26 +27,20 @@ import com.google.common.base.Preconditions; final class InMemoryDataTreeModification implements DataTreeModification { private static final Logger LOG = LoggerFactory.getLogger(InMemoryDataTreeModification.class); - - /* - * FIXME: the thread safety of concurrent write/delete/read/seal operations - * needs to be evaluated. - */ - private static final AtomicIntegerFieldUpdater SEALED_UPDATER = - AtomicIntegerFieldUpdater.newUpdater(InMemoryDataTreeModification.class, "sealed"); - private volatile int sealed = 0; - private final ModificationApplyOperation strategyTree; private final InMemoryDataTreeSnapshot snapshot; - private final NodeModification rootNode; + private final ModifiedNode rootNode; + + @GuardedBy("this") + private boolean sealed = false; InMemoryDataTreeModification(final InMemoryDataTreeSnapshot snapshot, final ModificationApplyOperation resolver) { this.snapshot = Preconditions.checkNotNull(snapshot); this.strategyTree = Preconditions.checkNotNull(resolver); - this.rootNode = NodeModification.createUnmodified(snapshot.getRootNode()); + this.rootNode = ModifiedNode.createUnmodified(snapshot.getRootNode()); } - NodeModification getRootModification() { + ModifiedNode getRootModification() { return rootNode; } @@ -56,13 +49,13 @@ final class InMemoryDataTreeModification implements DataTreeModification { } @Override - public void write(final InstanceIdentifier path, final NormalizedNode value) { + public synchronized void write(final InstanceIdentifier path, final NormalizedNode value) { checkSealed(); resolveModificationFor(path).write(value); } @Override - public void merge(final InstanceIdentifier path, final NormalizedNode data) { + public synchronized void merge(final InstanceIdentifier path, final NormalizedNode data) { checkSealed(); mergeImpl(resolveModificationFor(path),data); } @@ -81,39 +74,41 @@ final class InMemoryDataTreeModification implements DataTreeModification { } @Override - public void delete(final InstanceIdentifier path) { + public synchronized void delete(final InstanceIdentifier path) { checkSealed(); resolveModificationFor(path).delete(); } @Override - public Optional> readNode(final InstanceIdentifier path) { - Entry modification = TreeNodeUtils.findClosestsOrFirstMatch(rootNode, path, NodeModification.IS_TERMINAL_PREDICATE); - - Optional result = resolveSnapshot(modification); + public synchronized Optional> readNode(final InstanceIdentifier path) { + /* + * Walk the tree from the top, looking for the first node between root and + * the requested path which has been modified. If no such node exists, + * we use the node itself. + */ + final Entry entry = TreeNodeUtils.findClosestsOrFirstMatch(rootNode, path, ModifiedNode.IS_TERMINAL_PREDICATE); + final InstanceIdentifier key = entry.getKey(); + final ModifiedNode mod = entry.getValue(); + + final Optional result = resolveSnapshot(key, mod); if (result.isPresent()) { NormalizedNode data = result.get().getData(); - return NormalizedNodeUtils.findNode(modification.getKey(), data, path); + return NormalizedNodeUtils.findNode(key, data, path); + } else { + return Optional.absent(); } - return Optional.absent(); } - private Optional resolveSnapshot( - final Entry keyModification) { - InstanceIdentifier path = keyModification.getKey(); - NodeModification modification = keyModification.getValue(); - return resolveSnapshot(path, modification); - } + private Optional resolveSnapshot(final InstanceIdentifier path, + final ModifiedNode modification) { + final Optional> potentialSnapshot = modification.getSnapshotCache(); + if(potentialSnapshot.isPresent()) { + return potentialSnapshot.get(); + } - private Optional resolveSnapshot(final InstanceIdentifier path, - final NodeModification modification) { try { - Optional> potentialSnapshot = modification.getSnapshotCache(); - if(potentialSnapshot.isPresent()) { - return potentialSnapshot.get(); - } return resolveModificationStrategy(path).apply(modification, modification.getOriginal(), - StoreUtils.increase(snapshot.getRootNode().getSubtreeVersion())); + snapshot.getRootNode().getSubtreeVersion().next()); } catch (Exception e) { LOG.error("Could not create snapshot for {}:{}", path,modification,e); throw e; @@ -126,7 +121,7 @@ final class InMemoryDataTreeModification implements DataTreeModification { } private OperationWithModification resolveModificationFor(final InstanceIdentifier path) { - NodeModification modification = rootNode; + ModifiedNode modification = rootNode; // We ensure strategy is present. ModificationApplyOperation operation = resolveModificationStrategy(path); for (PathArgument pathArg : path.getPath()) { @@ -136,14 +131,15 @@ final class InMemoryDataTreeModification implements DataTreeModification { } @Override - public void seal() { - final boolean success = SEALED_UPDATER.compareAndSet(this, 0, 1); - Preconditions.checkState(success, "Attempted to seal an already-sealed Data Tree."); + public synchronized void seal() { + Preconditions.checkState(!sealed, "Attempted to seal an already-sealed Data Tree."); + sealed = true; rootNode.seal(); } + @GuardedBy("this") private void checkSealed() { - checkState(sealed == 0, "Data Tree is sealed. No further modifications allowed."); + Preconditions.checkState(!sealed, "Data Tree is sealed. No further modifications allowed."); } @Override @@ -152,7 +148,9 @@ final class InMemoryDataTreeModification implements DataTreeModification { } @Override - public DataTreeModification newModification() { + public synchronized DataTreeModification newModification() { + Preconditions.checkState(sealed, "Attempted to chain on an unsealed modification"); + // FIXME: transaction chaining throw new UnsupportedOperationException("Implement this as part of transaction chaining"); } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeSnapshot.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeSnapshot.java index ce2d8c9bd4..ee91e62518 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeSnapshot.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeSnapshot.java @@ -1,6 +1,7 @@ package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeSnapshot; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeUtils; @@ -12,16 +13,16 @@ import com.google.common.base.Preconditions; final class InMemoryDataTreeSnapshot implements DataTreeSnapshot { private final ModificationApplyOperation applyOper; private final SchemaContext schemaContext; - private final StoreMetadataNode rootNode; + private final TreeNode rootNode; - InMemoryDataTreeSnapshot(final SchemaContext schemaContext, final StoreMetadataNode rootNode, + InMemoryDataTreeSnapshot(final SchemaContext schemaContext, final TreeNode rootNode, final ModificationApplyOperation applyOper) { this.schemaContext = Preconditions.checkNotNull(schemaContext); this.rootNode = Preconditions.checkNotNull(rootNode); this.applyOper = Preconditions.checkNotNull(applyOper); } - StoreMetadataNode getRootNode() { + TreeNode getRootNode() { return rootNode; } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationApplyOperation.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationApplyOperation.java index 5b4cd565e5..10f39a8cef 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationApplyOperation.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationApplyOperation.java @@ -9,15 +9,16 @@ package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataPreconditionFailedException; import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreTreeNode; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.Version; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; import com.google.common.base.Optional; -import com.google.common.primitives.UnsignedLong; /** * - * Operation responsible for applying {@link NodeModification} on tree. + * Operation responsible for applying {@link ModifiedNode} on tree. * * Operation is composite - operation on top level node consists of * suboperations on child nodes. This allows to walk operation hierarchy and @@ -29,7 +30,7 @@ import com.google.common.primitives.UnsignedLong; * Implementations MUST expose all nested suboperations which operates on child * nodes expose via {@link #getChild(PathArgument)} method. *
  • Same suboperations SHOULD be used when invoked via - * {@link #apply(NodeModification, Optional)} if applicable. + * {@link #apply(ModifiedNode, Optional)} if applicable. * * * Hierarchical composite operation which is responsible for applying @@ -54,10 +55,10 @@ interface ModificationApplyOperation extends StoreTreeNode apply(NodeModification modification, Optional storeMeta, UnsignedLong subtreeVersion); + Optional apply(ModifiedNode modification, Optional storeMeta, Version subtreeVersion); /** * @@ -67,7 +68,7 @@ interface ModificationApplyOperation extends StoreTreeNode current) throws DataPreconditionFailedException; + void checkApplicable(InstanceIdentifier path, NodeModification modification, Optional current) throws DataPreconditionFailedException; } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModifiedNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModifiedNode.java new file mode 100644 index 0000000000..f83ea1a2de --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModifiedNode.java @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; + +import java.util.LinkedHashMap; +import java.util.Map; + +import javax.annotation.concurrent.GuardedBy; + +import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreTreeNode; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode; +import org.opendaylight.yangtools.concepts.Identifiable; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; + +import com.google.common.base.Optional; +import com.google.common.base.Predicate; + +/** + * Node Modification Node and Tree + * + * Tree which structurally resembles data tree and captures client modifications + * to the data store tree. + * + * This tree is lazily created and populated via {@link #modifyChild(PathArgument)} + * and {@link StoreMetadataNode} which represents original state {@link #getOriginal()}. + */ +final class ModifiedNode implements StoreTreeNode, Identifiable, NodeModification { + + public static final Predicate IS_TERMINAL_PREDICATE = new Predicate() { + @Override + public boolean apply(final ModifiedNode input) { + switch (input.getType()) { + case DELETE: + case MERGE: + case WRITE: + return true; + case SUBTREE_MODIFIED: + case UNMODIFIED: + return false; + } + + throw new IllegalArgumentException(String.format("Unhandled modification type %s", input.getType())); + } + }; + + private final Map children = new LinkedHashMap<>(); + private final Optional original; + private final PathArgument identifier; + private ModificationType modificationType = ModificationType.UNMODIFIED; + private Optional snapshotCache; + private NormalizedNode value; + + private ModifiedNode(final PathArgument identifier, final Optional original) { + this.identifier = identifier; + this.original = original; + } + + /** + * + * + * @return + */ + public NormalizedNode getWrittenValue() { + return value; + } + + @Override + public PathArgument getIdentifier() { + return identifier; + } + + /** + * + * Returns original store metadata + * @return original store metadata + */ + @Override + public Optional getOriginal() { + return original; + } + + /** + * Returns modification type + * + * @return modification type + */ + @Override + public ModificationType getType() { + return modificationType; + } + + /** + * + * Returns child modification if child was modified + * + * @return Child modification if direct child or it's subtree + * was modified. + * + */ + @Override + public Optional getChild(final PathArgument child) { + return Optional. fromNullable(children.get(child)); + } + + /** + * + * Returns child modification if child was modified, creates {@link ModifiedNode} + * for child otherwise. + * + * If this node's {@link ModificationType} is {@link ModificationType#UNMODIFIED} + * changes modification type to {@link ModificationType#SUBTREE_MODIFIED} + * + * @param child + * @return {@link ModifiedNode} for specified child, with {@link #getOriginal()} + * containing child metadata if child was present in original data. + */ + public ModifiedNode modifyChild(final PathArgument child) { + clearSnapshot(); + if (modificationType == ModificationType.UNMODIFIED) { + updateModificationType(ModificationType.SUBTREE_MODIFIED); + } + final ModifiedNode potential = children.get(child); + if (potential != null) { + return potential; + } + + final Optional currentMetadata; + if (original.isPresent()) { + final TreeNode orig = original.get(); + currentMetadata = orig.getChild(child); + } else { + currentMetadata = Optional.absent(); + } + + ModifiedNode newlyCreated = new ModifiedNode(child, currentMetadata); + children.put(child, newlyCreated); + return newlyCreated; + } + + /** + * + * Returns all recorded direct child modification + * + * @return all recorded direct child modifications + */ + @Override + public Iterable getChildren() { + return children.values(); + } + + /** + * + * Records a delete for associated node. + * + */ + public void delete() { + clearSnapshot(); + updateModificationType(ModificationType.DELETE); + children.clear(); + this.value = null; + } + + /** + * + * Records a write for associated node. + * + * @param value + */ + public void write(final NormalizedNode value) { + clearSnapshot(); + updateModificationType(ModificationType.WRITE); + children.clear(); + this.value = value; + } + + public void merge(final NormalizedNode data) { + clearSnapshot(); + updateModificationType(ModificationType.MERGE); + // FIXME: Probably merge with previous value. + this.value = data; + } + + void seal() { + clearSnapshot(); + for (ModifiedNode child : children.values()) { + child.seal(); + } + } + + private void clearSnapshot() { + snapshotCache = null; + } + + public Optional storeSnapshot(final Optional snapshot) { + snapshotCache = snapshot; + return snapshot; + } + + public Optional> getSnapshotCache() { + return Optional.fromNullable(snapshotCache); + } + + @GuardedBy("this") + private void updateModificationType(final ModificationType type) { + modificationType = type; + clearSnapshot(); + } + + @Override + public String toString() { + return "NodeModification [identifier=" + identifier + ", modificationType=" + + modificationType + ", childModification=" + children + "]"; + } + + public static ModifiedNode createUnmodified(final TreeNode metadataTree) { + return new ModifiedNode(metadataTree.getIdentifier(), Optional.of(metadataTree)); + } +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NodeModification.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NodeModification.java index 18179afd50..2639d050ef 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NodeModification.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NodeModification.java @@ -7,229 +7,15 @@ */ package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; -import static com.google.common.base.Preconditions.checkState; - -import java.util.LinkedHashMap; -import java.util.Map; - -import javax.annotation.concurrent.GuardedBy; - -import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreTreeNode; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode; import org.opendaylight.yangtools.concepts.Identifiable; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; -import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import com.google.common.base.Optional; -import com.google.common.base.Predicate; - -/** - * Node Modification Node and Tree - * - * Tree which structurally resembles data tree and captures client modifications - * to the data store tree. - * - * This tree is lazily created and populated via {@link #modifyChild(PathArgument)} - * and {@link StoreMetadataNode} which represents original state {@link #getOriginal()}. - * - */ -// FIXME: hide this class -public class NodeModification implements StoreTreeNode, Identifiable { - - public static final Predicate IS_TERMINAL_PREDICATE = new Predicate() { - @Override - public boolean apply(final NodeModification input) { - return input.getModificationType() == ModificationType.WRITE // - || input.getModificationType() == ModificationType.DELETE // - || input.getModificationType() == ModificationType.MERGE; - } - }; - private final PathArgument identifier; - private ModificationType modificationType = ModificationType.UNMODIFIED; - - - private final Optional original; - - private NormalizedNode value; - - private Optional snapshotCache; - - private final Map childModification; - - @GuardedBy("this") - private boolean sealed = false; - - protected NodeModification(final PathArgument identifier, final Optional original) { - this.identifier = identifier; - this.original = original; - childModification = new LinkedHashMap<>(); - } - - /** - * - * - * @return - */ - public NormalizedNode getWrittenValue() { - return value; - } - - @Override - public PathArgument getIdentifier() { - return identifier; - } - - /** - * - * Returns original store metadata - * @return original store metadata - */ - public final Optional getOriginal() { - return original; - } - - /** - * Returns modification type - * - * @return modification type - */ - public final ModificationType getModificationType() { - return modificationType; - } - - /** - * - * Returns child modification if child was modified - * - * @return Child modification if direct child or it's subtree - * was modified. - * - */ - @Override - public Optional getChild(final PathArgument child) { - return Optional. fromNullable(childModification.get(child)); - } - - /** - * - * Returns child modification if child was modified, creates {@link NodeModification} - * for child otherwise. - * - * If this node's {@link ModificationType} is {@link ModificationType#UNMODIFIED} - * changes modification type to {@link ModificationType#SUBTREE_MODIFIED} - * - * @param child - * @return {@link NodeModification} for specified child, with {@link #getOriginal()} - * containing child metadata if child was present in original data. - */ - public synchronized NodeModification modifyChild(final PathArgument child) { - checkSealed(); - clearSnapshot(); - if(modificationType == ModificationType.UNMODIFIED) { - updateModificationType(ModificationType.SUBTREE_MODIFIED); - } - final NodeModification potential = childModification.get(child); - if (potential != null) { - return potential; - } - Optional currentMetadata = Optional.absent(); - if(original.isPresent()) { - currentMetadata = original.get().getChild(child); - } - NodeModification newlyCreated = new NodeModification(child,currentMetadata); - childModification.put(child, newlyCreated); - return newlyCreated; - } - - /** - * - * Returns all recorded direct child modification - * - * @return all recorded direct child modifications - */ - public Iterable getModifications() { - return childModification.values(); - } - - - /** - * - * Records a delete for associated node. - * - */ - public synchronized void delete() { - checkSealed(); - clearSnapshot(); - updateModificationType(ModificationType.DELETE); - childModification.clear(); - this.value = null; - } - - /** - * - * Records a write for associated node. - * - * @param value - */ - public synchronized void write(final NormalizedNode value) { - checkSealed(); - clearSnapshot(); - updateModificationType(ModificationType.WRITE); - childModification.clear(); - this.value = value; - } - - public synchronized void merge(final NormalizedNode data) { - checkSealed(); - clearSnapshot(); - updateModificationType(ModificationType.MERGE); - // FIXME: Probably merge with previous value. - this.value = data; - } - - @GuardedBy("this") - private void checkSealed() { - checkState(!sealed, "Node Modification is sealed. No further changes allowed."); - } - - public synchronized void seal() { - sealed = true; - clearSnapshot(); - for(NodeModification child : childModification.values()) { - child.seal(); - } - } - - private void clearSnapshot() { - snapshotCache = null; - } - - public Optional storeSnapshot(final Optional snapshot) { - snapshotCache = snapshot; - return snapshot; - } - - public Optional> getSnapshotCache() { - return Optional.fromNullable(snapshotCache); - } - - public boolean hasAdditionalModifications() { - return !childModification.isEmpty(); - } - - @GuardedBy("this") - private void updateModificationType(final ModificationType type) { - modificationType = type; - clearSnapshot(); - } - - @Override - public String toString() { - return "NodeModification [identifier=" + identifier + ", modificationType=" - + modificationType + ", childModification=" + childModification + "]"; - } - - public static NodeModification createUnmodified(final StoreMetadataNode metadataTree) { - return new NodeModification(metadataTree.getIdentifier(), Optional.of(metadataTree)); - } +interface NodeModification extends Identifiable { + ModificationType getType(); + Optional getOriginal(); + Iterable getChildren(); } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NoopDataTreeCandidate.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NoopDataTreeCandidate.java index 1782da2835..2ef85cbcb7 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NoopDataTreeCandidate.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NoopDataTreeCandidate.java @@ -7,25 +7,52 @@ */ package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; +import java.util.Collections; + +import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeCandidateNode; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; + +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; final class NoopDataTreeCandidate extends AbstractDataTreeCandidate { - protected NoopDataTreeCandidate(final InstanceIdentifier rootPath, final NodeModification modificationRoot) { - super(rootPath, modificationRoot); - } - - @Override - public void close() { - // NO-OP - } - - @Override - public StoreMetadataNode getBeforeRoot() { - return null; - } - - @Override - public StoreMetadataNode getAfterRoot() { - return null; - } + private static final DataTreeCandidateNode ROOT = new DataTreeCandidateNode() { + @Override + public ModificationType getModificationType() { + return ModificationType.UNMODIFIED; + } + + @Override + public Iterable getChildNodes() { + return Collections.emptyList(); + } + + @Override + public PathArgument getIdentifier() { + throw new IllegalStateException("Attempted to read identifier of the no-operation change"); + } + + @Override + public Optional> getDataAfter() { + return Optional.absent(); + } + + @Override + public Optional> getDataBefore() { + return Optional.absent(); + } + }; + + protected NoopDataTreeCandidate(final InstanceIdentifier rootPath, final ModifiedNode modificationRoot) { + super(rootPath); + Preconditions.checkArgument(modificationRoot.getType() == ModificationType.UNMODIFIED); + } + + @Override + public DataTreeCandidateNode getRootNode() { + return ROOT; + } } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NormalizedNodeContainerModificationStrategy.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NormalizedNodeContainerModificationStrategy.java new file mode 100644 index 0000000000..3a3af5ecab --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NormalizedNodeContainerModificationStrategy.java @@ -0,0 +1,348 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; + +import static com.google.common.base.Preconditions.checkArgument; + +import java.util.Map; + +import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataPreconditionFailedException; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreUtils; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.DataNodeContainerModificationStrategy.ListEntryModificationStrategy; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.ValueNodeModificationStrategy.LeafSetEntryModificationStrategy; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.MutableTreeNode; +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.data.api.InstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeWithValue; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode; +import org.opendaylight.yangtools.yang.data.api.schema.MapNode; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer; +import org.opendaylight.yangtools.yang.data.api.schema.OrderedLeafSetNode; +import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode; +import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder; +import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder; +import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableChoiceNodeBuilder; +import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder; +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.model.api.ChoiceCaseNode; +import org.opendaylight.yangtools.yang.model.api.ChoiceNode; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; + +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Iterables; + +abstract class NormalizedNodeContainerModificationStrategy extends SchemaAwareApplyOperation { + + private final Class> nodeClass; + + protected NormalizedNodeContainerModificationStrategy(final Class> nodeClass) { + this.nodeClass = nodeClass; + } + + @Override + public void verifyStructure(final ModifiedNode modification) throws IllegalArgumentException { + if (modification.getType() == ModificationType.WRITE) { + + } + for (ModifiedNode childModification : modification.getChildren()) { + resolveChildOperation(childModification.getIdentifier()).verifyStructure(childModification); + } + } + + @Override + protected void checkWriteApplicable(final InstanceIdentifier path, final NodeModification modification, + final Optional current) throws DataPreconditionFailedException { + // FIXME: Implement proper write check for replacement of node container + // prerequisite is to have transaction chain available for clients + // otherwise this will break chained writes to same node. + } + + @SuppressWarnings("rawtypes") + @Override + protected void verifyWrittenStructure(final NormalizedNode writtenValue) { + checkArgument(nodeClass.isInstance(writtenValue), "Node should must be of type %s", nodeClass); + checkArgument(writtenValue instanceof NormalizedNodeContainer); + + NormalizedNodeContainer container = (NormalizedNodeContainer) writtenValue; + for (Object child : container.getValue()) { + checkArgument(child instanceof NormalizedNode); + + /* + * FIXME: fail-fast semantics: + * + * We can validate the data structure here, aborting the commit + * before it ever progresses to being committed. + */ + } + } + + @Override + protected TreeNode applyWrite(final ModifiedNode modification, + final Optional currentMeta, final Version subtreeVersion) { + final Version nodeVersion; + if (currentMeta.isPresent()) { + nodeVersion = currentMeta.get().getVersion().next(); + } else { + nodeVersion = subtreeVersion; + } + + final NormalizedNode newValue = modification.getWrittenValue(); + final TreeNode newValueMeta = TreeNodeFactory.createTreeNode(newValue, nodeVersion); + + if (Iterables.isEmpty(modification.getChildren())) { + return newValueMeta; + } + + /* + * This is where things get interesting. The user has performed a write and + * then she applied some more modifications to it. So we need to make sense + * of that an apply the operations on top of the written value. We could have + * done it during the write, but this operation is potentially expensive, so + * we have left it out of the fast path. + * + * As it turns out, once we materialize the written data, we can share the + * code path with the subtree change. So let's create an unsealed TreeNode + * and run the common parts on it -- which end with the node being sealed. + */ + final MutableTreeNode mutable = newValueMeta.mutable(); + mutable.setSubtreeVersion(subtreeVersion); + + @SuppressWarnings("rawtypes") + final NormalizedNodeContainerBuilder dataBuilder = createBuilder(newValue); + + return mutateChildren(mutable, dataBuilder, nodeVersion, modification.getChildren()); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + private TreeNode mutateChildren(final MutableTreeNode meta, final NormalizedNodeContainerBuilder data, + final Version nodeVersion, final Iterable modifications) { + + for (ModifiedNode mod : modifications) { + final PathArgument id = mod.getIdentifier(); + final Optional cm = meta.getChild(id); + + Optional result = resolveChildOperation(id).apply(mod, cm, nodeVersion); + if (result.isPresent()) { + final TreeNode tn = result.get(); + meta.addChild(tn); + data.addChild(tn.getData()); + } else { + meta.removeChild(id); + data.removeChild(id); + } + } + + meta.setData(data.build()); + return meta.seal(); + } + + @Override + protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta, + final Version subtreeVersion) { + // For Node Containers - merge is same as subtree change - we only replace children. + return applySubtreeChange(modification, currentMeta, subtreeVersion); + } + + @Override + public TreeNode applySubtreeChange(final ModifiedNode modification, + final TreeNode currentMeta, final Version subtreeVersion) { + // Bump subtree version to its new target + final Version updatedSubtreeVersion = currentMeta.getSubtreeVersion().next(); + + final MutableTreeNode newMeta = currentMeta.mutable(); + newMeta.setSubtreeVersion(updatedSubtreeVersion); + + @SuppressWarnings("rawtypes") + NormalizedNodeContainerBuilder dataBuilder = createBuilder(currentMeta.getData()); + + return mutateChildren(newMeta, dataBuilder, updatedSubtreeVersion, modification.getChildren()); + } + + @Override + protected void checkSubtreeModificationApplicable(final InstanceIdentifier path, final NodeModification modification, + final Optional current) throws DataPreconditionFailedException { + checkDataPrecondition(path, current.isPresent(), "Node was deleted by other transaction."); + checkChildPreconditions(path, modification, current); + } + + private void checkChildPreconditions(final InstanceIdentifier path, final NodeModification modification, final Optional current) throws DataPreconditionFailedException { + final TreeNode currentMeta = current.get(); + for (NodeModification childMod : modification.getChildren()) { + final PathArgument childId = childMod.getIdentifier(); + final Optional childMeta = currentMeta.getChild(childId); + + InstanceIdentifier childPath = StoreUtils.append(path, childId); + resolveChildOperation(childId).checkApplicable(childPath, childMod, childMeta); + } + } + + @Override + protected void checkMergeApplicable(final InstanceIdentifier path, final NodeModification modification, + final Optional current) throws DataPreconditionFailedException { + if(current.isPresent()) { + checkChildPreconditions(path, modification,current); + } + } + + @SuppressWarnings("rawtypes") + protected abstract NormalizedNodeContainerBuilder createBuilder(NormalizedNode original); + + public static class ChoiceModificationStrategy extends NormalizedNodeContainerModificationStrategy { + + private final Map childNodes; + + public ChoiceModificationStrategy(final ChoiceNode schemaNode) { + super(org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode.class); + ImmutableMap.Builder child = ImmutableMap.builder(); + + for (ChoiceCaseNode caze : schemaNode.getCases()) { + for (DataSchemaNode cazeChild : caze.getChildNodes()) { + SchemaAwareApplyOperation childNode = from(cazeChild); + child.put(new NodeIdentifier(cazeChild.getQName()), childNode); + } + } + childNodes = child.build(); + } + + @Override + public Optional getChild(final PathArgument child) { + return Optional.fromNullable(childNodes.get(child)); + } + + @Override + @SuppressWarnings("rawtypes") + protected DataContainerNodeBuilder createBuilder(final NormalizedNode original) { + checkArgument(original instanceof org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode); + return ImmutableChoiceNodeBuilder.create((org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode) original); + } + } + + public static class OrderedLeafSetModificationStrategy extends NormalizedNodeContainerModificationStrategy { + + private final Optional entryStrategy; + + @SuppressWarnings({ "unchecked", "rawtypes" }) + protected OrderedLeafSetModificationStrategy(final LeafListSchemaNode schema) { + super((Class) LeafSetNode.class); + entryStrategy = Optional. of(new LeafSetEntryModificationStrategy(schema)); + } + + @SuppressWarnings("rawtypes") + @Override + protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode original) { + checkArgument(original instanceof OrderedLeafSetNode); + return ImmutableOrderedLeafSetNodeBuilder.create((OrderedLeafSetNode) original); + } + + @Override + public Optional getChild(final PathArgument identifier) { + if (identifier instanceof NodeWithValue) { + return entryStrategy; + } + return Optional.absent(); + } + } + + public static class OrderedMapModificationStrategy extends NormalizedNodeContainerModificationStrategy { + + private final Optional entryStrategy; + + protected OrderedMapModificationStrategy(final ListSchemaNode schema) { + super(OrderedMapNode.class); + entryStrategy = Optional. of(new ListEntryModificationStrategy(schema)); + } + + @SuppressWarnings("rawtypes") + @Override + protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode original) { + checkArgument(original instanceof OrderedMapNode); + return ImmutableOrderedMapNodeBuilder.create((OrderedMapNode) original); + } + + @Override + public Optional getChild(final PathArgument identifier) { + if (identifier instanceof NodeIdentifierWithPredicates) { + return entryStrategy; + } + return Optional.absent(); + } + + @Override + public String toString() { + return "OrderedMapModificationStrategy [entry=" + entryStrategy + "]"; + } + } + + public static class UnorderedLeafSetModificationStrategy extends NormalizedNodeContainerModificationStrategy { + + private final Optional entryStrategy; + + @SuppressWarnings({ "unchecked", "rawtypes" }) + protected UnorderedLeafSetModificationStrategy(final LeafListSchemaNode schema) { + super((Class) LeafSetNode.class); + entryStrategy = Optional. of(new LeafSetEntryModificationStrategy(schema)); + } + + @SuppressWarnings("rawtypes") + @Override + protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode original) { + checkArgument(original instanceof LeafSetNode); + return ImmutableLeafSetNodeBuilder.create((LeafSetNode) original); + } + + @Override + public Optional getChild(final PathArgument identifier) { + if (identifier instanceof NodeWithValue) { + return entryStrategy; + } + return Optional.absent(); + } + } + + public static class UnorderedMapModificationStrategy extends NormalizedNodeContainerModificationStrategy { + + private final Optional entryStrategy; + + protected UnorderedMapModificationStrategy(final ListSchemaNode schema) { + super(MapNode.class); + entryStrategy = Optional. of(new ListEntryModificationStrategy(schema)); + } + + @SuppressWarnings("rawtypes") + @Override + protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode original) { + checkArgument(original instanceof MapNode); + return ImmutableMapNodeBuilder.create((MapNode) original); + } + + @Override + public Optional getChild(final PathArgument identifier) { + if (identifier instanceof NodeIdentifierWithPredicates) { + return entryStrategy; + } + return Optional.absent(); + } + + @Override + public String toString() { + return "UnorderedMapModificationStrategy [entry=" + entryStrategy + "]"; + } + } +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/OperationWithModification.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/OperationWithModification.java index fda8407a95..ff90d57f49 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/OperationWithModification.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/OperationWithModification.java @@ -7,19 +7,20 @@ */ package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.Version; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import com.google.common.base.Optional; -import com.google.common.primitives.UnsignedLong; final class OperationWithModification { - private final NodeModification modification; + private final ModifiedNode modification; private final ModificationApplyOperation applyOperation; - private OperationWithModification(final ModificationApplyOperation op, final NodeModification mod) { + private OperationWithModification(final ModificationApplyOperation op, final ModifiedNode mod) { this.modification = mod; this.applyOperation = op; } @@ -35,7 +36,7 @@ final class OperationWithModification { return this; } - public NodeModification getModification() { + public ModifiedNode getModification() { return modification; } @@ -43,12 +44,12 @@ final class OperationWithModification { return applyOperation; } - public Optional apply(final Optional data, final UnsignedLong subtreeVersion) { + public Optional apply(final Optional data, final Version subtreeVersion) { return applyOperation.apply(modification, data, subtreeVersion); } public static OperationWithModification from(final ModificationApplyOperation operation, - final NodeModification modification) { + final ModifiedNode modification) { return new OperationWithModification(operation, modification); } @@ -60,7 +61,7 @@ final class OperationWithModification { } public OperationWithModification forChild(final PathArgument childId) { - NodeModification childMod = modification.modifyChild(childId); + ModifiedNode childMod = modification.modifyChild(childId); Optional childOp = applyOperation.getChild(childId); return from(childOp.get(),childMod); } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperation.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperation.java index 02244d9f98..bdf5667b67 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperation.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperation.java @@ -9,48 +9,28 @@ package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; import static com.google.common.base.Preconditions.checkArgument; -import java.util.HashSet; import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ExecutionException; import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataPreconditionFailedException; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreUtils; +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.ChoiceModificationStrategy; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.NormalizedNodeContainerModificationStrategy.OrderedLeafSetModificationStrategy; +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 org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier; -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates; -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeWithValue; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; -import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode; -import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; -import org.opendaylight.yangtools.yang.data.api.schema.LeafNode; -import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode; -import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode; -import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; -import org.opendaylight.yangtools.yang.data.api.schema.MapNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; -import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer; -import org.opendaylight.yangtools.yang.data.api.schema.OrderedLeafSetNode; -import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode; -import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode; -import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder; -import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder; -import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableAugmentationNodeBuilder; -import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableChoiceNodeBuilder; -import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder; -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.data.impl.schema.transform.base.AugmentationSchemaProxy; import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; import org.opendaylight.yangtools.yang.model.api.AugmentationTarget; -import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode; import org.opendaylight.yangtools.yang.model.api.ChoiceNode; import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; @@ -58,17 +38,14 @@ import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import com.google.common.base.Function; import com.google.common.base.Optional; import com.google.common.base.Preconditions; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; -import com.google.common.collect.ImmutableMap; -import com.google.common.primitives.UnsignedLong; abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { + private static final Logger LOG = LoggerFactory.getLogger(SchemaAwareApplyOperation.class); public static SchemaAwareApplyOperation from(final DataSchemaNode schemaNode) { if (schemaNode instanceof ContainerSchemaNode) { @@ -85,6 +62,33 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { throw new IllegalArgumentException("Not supported schema node type for " + schemaNode.getClass()); } + public static SchemaAwareApplyOperation from(final DataNodeContainer resolvedTree, + final AugmentationTarget augSchemas, final AugmentationIdentifier identifier) { + AugmentationSchema augSchema = null; + + allAugments: + for (AugmentationSchema potential : augSchemas.getAvailableAugmentations()) { + for (DataSchemaNode child : potential.getChildNodes()) { + if (identifier.getPossibleChildNames().contains(child.getQName())) { + augSchema = potential; + break allAugments; + } + } + } + + if (augSchema != null) { + return new DataNodeContainerModificationStrategy.AugmentationModificationStrategy(augSchema, resolvedTree); + } + return null; + } + + public static boolean checkDataPrecondition(final InstanceIdentifier path, final boolean condition, final String message) throws DataPreconditionFailedException { + if(!condition) { + throw new DataPreconditionFailedException(path, message); + } + return condition; + } + private static SchemaAwareApplyOperation fromListSchemaNode(final ListSchemaNode schemaNode) { List keyDefinition = schemaNode.getKeyDefinition(); if (keyDefinition == null || keyDefinition.isEmpty()) { @@ -94,7 +98,7 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { return new OrderedMapModificationStrategy(schemaNode); } - return new UnorderedMapModificationStrategy(schemaNode); + return new NormalizedNodeContainerModificationStrategy.UnorderedMapModificationStrategy(schemaNode); } private static SchemaAwareApplyOperation fromLeafListSchemaNode(final LeafListSchemaNode schemaNode) { @@ -105,25 +109,11 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { } } - - public static SchemaAwareApplyOperation from(final DataNodeContainer resolvedTree, - final AugmentationTarget augSchemas, final AugmentationIdentifier identifier) { - AugmentationSchema augSchema = null; - - allAugments: - for (AugmentationSchema potential : augSchemas.getAvailableAugmentations()) { - for (DataSchemaNode child : potential.getChildNodes()) { - if (identifier.getPossibleChildNames().contains(child.getQName())) { - augSchema = potential; - break allAugments; - } - } - } - - if (augSchema != null) { - return new AugmentationModificationStrategy(augSchema, resolvedTree); - } - return null; + private static final void checkNotConflicting(final InstanceIdentifier path, final TreeNode original, final TreeNode current) throws DataPreconditionFailedException { + checkDataPrecondition(path, original.getVersion().equals(current.getVersion()), + "Node was replaced by other transaction."); + checkDataPrecondition(path, original.getSubtreeVersion().equals(current.getSubtreeVersion()), + "Node children was modified by other transaction"); } protected final ModificationApplyOperation resolveChildOperation(final PathArgument child) { @@ -133,38 +123,36 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { } @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()); } } - protected abstract void verifyWrittenStructure(NormalizedNode writtenValue); - @Override - public void checkApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional current) throws DataPreconditionFailedException { - switch (modification.getModificationType()) { + public final void checkApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional current) throws DataPreconditionFailedException { + 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 current) throws DataPreconditionFailedException { - Optional original = modification.getOriginal(); + protected void checkMergeApplicable(final InstanceIdentifier path, final NodeModification modification, final Optional current) throws DataPreconditionFailedException { + Optional original = modification.getOriginal(); if (original.isPresent() && current.isPresent()) { /* * We need to do conflict detection only and only if the value of leaf changed @@ -173,39 +161,34 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { * 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 current) throws DataPreconditionFailedException { - Optional original = modification.getOriginal(); + protected void checkWriteApplicable(final InstanceIdentifier path, final NodeModification modification, final Optional current) throws DataPreconditionFailedException { + Optional 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."); } } - protected 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"); - } - - protected abstract void checkSubtreeModificationApplicable(InstanceIdentifier path,final NodeModification modification, - final Optional current) throws DataPreconditionFailedException; - - private void checkDeleteApplicable(final NodeModification modification, final Optional current) { + private void checkDeleteApplicable(final NodeModification modification, final Optional 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 apply(final NodeModification modification, - final Optional currentMeta, final UnsignedLong subtreeVersion) { + public final Optional apply(final ModifiedNode modification, + final Optional currentMeta, final Version subtreeVersion) { - switch (modification.getModificationType()) { + switch (modification.getType()) { case DELETE: - return modification.storeSnapshot(Optional. absent()); + return modification.storeSnapshot(Optional. absent()); case SUBTREE_MODIFIED: Preconditions.checkArgument(currentMeta.isPresent(), "Metadata not available for modification", modification); @@ -224,411 +207,19 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { } } - protected abstract StoreMetadataNode applyMerge(NodeModification modification, - StoreMetadataNode currentMeta, UnsignedLong subtreeVersion); - - protected abstract StoreMetadataNode applyWrite(NodeModification modification, - Optional currentMeta, UnsignedLong subtreeVersion); - - protected abstract StoreMetadataNode applySubtreeChange(NodeModification modification, - StoreMetadataNode currentMeta, UnsignedLong subtreeVersion); - - public static abstract class ValueNodeModificationStrategy extends SchemaAwareApplyOperation { + protected abstract TreeNode applyMerge(ModifiedNode modification, + TreeNode currentMeta, Version subtreeVersion); - private final T schema; - private final Class> nodeClass; - - protected ValueNodeModificationStrategy(final T schema, final Class> nodeClass) { - super(); - this.schema = schema; - this.nodeClass = nodeClass; - } - - @Override - protected void verifyWrittenStructure(final NormalizedNode writtenValue) { - checkArgument(nodeClass.isInstance(writtenValue), "Node should must be of type %s", nodeClass); - } - - @Override - public Optional getChild(final PathArgument child) { - throw new UnsupportedOperationException("Node " + schema.getPath() - + "is leaf type node. Child nodes not allowed"); - } - - @Override - protected StoreMetadataNode applySubtreeChange(final NodeModification modification, - final StoreMetadataNode currentMeta, final UnsignedLong subtreeVersion) { - throw new UnsupportedOperationException("Node " + schema.getPath() - + "is leaf type node. Subtree change is not allowed."); - } - - @Override - protected StoreMetadataNode applyMerge(final NodeModification modification, final StoreMetadataNode currentMeta, - final UnsignedLong subtreeVersion) { - return applyWrite(modification, Optional.of(currentMeta), subtreeVersion); - } + protected abstract TreeNode applyWrite(ModifiedNode modification, + Optional currentMeta, Version subtreeVersion); - @Override - protected StoreMetadataNode applyWrite(final NodeModification modification, - final Optional currentMeta, final UnsignedLong subtreeVersion) { - UnsignedLong nodeVersion = subtreeVersion; - return StoreMetadataNode.builder().setNodeVersion(nodeVersion).setSubtreeVersion(subtreeVersion) - .setData(modification.getWrittenValue()).build(); - } - - @Override - protected void checkSubtreeModificationApplicable(final InstanceIdentifier path,final NodeModification modification, - final Optional current) throws DataPreconditionFailedException { - throw new DataPreconditionFailedException(path, "Subtree modification is not allowed."); - } - - } - - public static class LeafSetEntryModificationStrategy extends ValueNodeModificationStrategy { - - @SuppressWarnings({ "unchecked", "rawtypes" }) - protected LeafSetEntryModificationStrategy(final LeafListSchemaNode schema) { - super(schema, (Class) LeafSetEntryNode.class); - } - } - - public static class LeafModificationStrategy extends ValueNodeModificationStrategy { - - @SuppressWarnings({ "unchecked", "rawtypes" }) - protected LeafModificationStrategy(final LeafSchemaNode schema) { - super(schema, (Class) LeafNode.class); - } - } - - public static abstract class NormalizedNodeContainerModificationStrategy extends SchemaAwareApplyOperation { - - private final Class> nodeClass; - - protected NormalizedNodeContainerModificationStrategy(final Class> nodeClass) { - this.nodeClass = nodeClass; - } - - @Override - public void verifyStructure(final NodeModification modification) throws IllegalArgumentException { - if (modification.getModificationType() == ModificationType.WRITE) { - - } - for (NodeModification childModification : modification.getModifications()) { - resolveChildOperation(childModification.getIdentifier()).verifyStructure(childModification); - } - } - - @Override - protected void checkWriteApplicable(final InstanceIdentifier path, final NodeModification modification, - final Optional current) throws DataPreconditionFailedException { - // FIXME: Implement proper write check for replacement of node container - // prerequisite is to have transaction chain available for clients - // otherwise this will break chained writes to same node. - } - - @SuppressWarnings("rawtypes") - @Override - protected void verifyWrittenStructure(final NormalizedNode writtenValue) { - checkArgument(nodeClass.isInstance(writtenValue), "Node should must be of type %s", nodeClass); - checkArgument(writtenValue instanceof NormalizedNodeContainer); - - NormalizedNodeContainer container = (NormalizedNodeContainer) writtenValue; - for (Object child : container.getValue()) { - checkArgument(child instanceof NormalizedNode); - - /* - * FIXME: fail-fast semantics: - * - * We can validate the data structure here, aborting the commit - * before it ever progresses to being committed. - */ - } - } - - @Override - protected StoreMetadataNode applyWrite(final NodeModification modification, - final Optional currentMeta, final UnsignedLong subtreeVersion) { - - NormalizedNode newValue = modification.getWrittenValue(); - - final UnsignedLong nodeVersion; - if (currentMeta.isPresent()) { - nodeVersion = StoreUtils.increase(currentMeta.get().getNodeVersion()); - } else { - nodeVersion = subtreeVersion; - } - - final StoreMetadataNode newValueMeta = StoreMetadataNode.createRecursively(newValue, nodeVersion, nodeVersion); - if (!modification.hasAdditionalModifications()) { - return newValueMeta; - } - - @SuppressWarnings("rawtypes") - NormalizedNodeContainerBuilder dataBuilder = createBuilder(newValue); - StoreNodeCompositeBuilder builder = StoreNodeCompositeBuilder.from(dataBuilder) // - .setNodeVersion(nodeVersion) // - .setSubtreeVersion(subtreeVersion); - - return mutateChildren(modification.getModifications(), newValueMeta, builder, nodeVersion); - } - - @Override - protected StoreMetadataNode applyMerge(final NodeModification modification, final StoreMetadataNode currentMeta, - final UnsignedLong subtreeVersion) { - // For Node Containers - merge is same as subtree change - we only replace children. - return applySubtreeChange(modification, currentMeta, subtreeVersion); - } - - @Override - public StoreMetadataNode applySubtreeChange(final NodeModification modification, - final StoreMetadataNode currentMeta, final UnsignedLong subtreeVersion) { - // Bump subtree version to its new target - final UnsignedLong updatedSubtreeVersion = StoreUtils.increase(currentMeta.getSubtreeVersion()); - - @SuppressWarnings("rawtypes") - NormalizedNodeContainerBuilder dataBuilder = createBuilder(currentMeta.getData()); - StoreNodeCompositeBuilder builder = StoreNodeCompositeBuilder.from(dataBuilder, currentMeta) - .setIdentifier(modification.getIdentifier()).setNodeVersion(currentMeta.getNodeVersion()) - .setSubtreeVersion(updatedSubtreeVersion); - - return mutateChildren(modification.getModifications(), currentMeta, builder, updatedSubtreeVersion); - } - - private StoreMetadataNode mutateChildren(final Iterable modifications, final StoreMetadataNode meta, - final StoreNodeCompositeBuilder builder, final UnsignedLong nodeVersion) { - - for (NodeModification mod : modifications) { - final PathArgument id = mod.getIdentifier(); - final Optional cm = meta.getChild(id); - - Optional result = resolveChildOperation(id).apply(mod, cm, nodeVersion); - if (result.isPresent()) { - builder.add(result.get()); - } else { - builder.remove(id); - } - } - - return builder.build(); - } - - @Override - protected void checkSubtreeModificationApplicable(final InstanceIdentifier path,final NodeModification modification, - final Optional current) throws DataPreconditionFailedException { - checkDataPrecondition(path, current.isPresent(), "Node was deleted by other transaction."); - checkChildPreconditions(path,modification,current); - - } - - private void checkChildPreconditions(final InstanceIdentifier path, final NodeModification modification, final Optional current) throws DataPreconditionFailedException { - StoreMetadataNode currentMeta = current.get(); - for (NodeModification childMod : modification.getModifications()) { - PathArgument childId = childMod.getIdentifier(); - Optional childMeta = currentMeta.getChild(childId); - InstanceIdentifier childPath = StoreUtils.append(path, childId); - resolveChildOperation(childId).checkApplicable(childPath,childMod, childMeta); - } - } - - @Override - protected void checkMergeApplicable(final InstanceIdentifier path, final NodeModification modification, - final Optional current) throws DataPreconditionFailedException { - if(current.isPresent()) { - checkChildPreconditions(path,modification,current); - } - } - - @SuppressWarnings("rawtypes") - protected abstract NormalizedNodeContainerBuilder createBuilder(NormalizedNode original); - } + protected abstract TreeNode applySubtreeChange(ModifiedNode modification, + TreeNode currentMeta, Version subtreeVersion); - public static abstract class DataNodeContainerModificationStrategy extends NormalizedNodeContainerModificationStrategy { + protected abstract void checkSubtreeModificationApplicable(InstanceIdentifier path, final NodeModification modification, + final Optional current) throws DataPreconditionFailedException; - private final T schema; - private final LoadingCache childCache = CacheBuilder.newBuilder() - .build(CacheLoader.from(new Function() { - - @Override - public ModificationApplyOperation apply(final PathArgument identifier) { - if (identifier instanceof AugmentationIdentifier && schema instanceof AugmentationTarget) { - return from(schema, (AugmentationTarget) schema, (AugmentationIdentifier) identifier); - } - - DataSchemaNode child = schema.getDataChildByName(identifier.getNodeType()); - if (child == null) { - return null; - } - return from(child); - } - })); - - protected DataNodeContainerModificationStrategy(final T schema, - final Class> nodeClass) { - super(nodeClass); - this.schema = schema; - } - - protected T getSchema() { - return schema; - } - - @Override - public Optional getChild(final PathArgument identifier) { - try { - return Optional. fromNullable(childCache.get(identifier)); - } catch (ExecutionException e) { - return Optional.absent(); - } - } - - @Override - @SuppressWarnings("rawtypes") - protected abstract DataContainerNodeBuilder createBuilder(NormalizedNode original); - - @Override - public String toString() { - return getClass().getSimpleName() + " [" + schema + "]"; - } - - } - - public static class ContainerModificationStrategy extends DataNodeContainerModificationStrategy { - - public ContainerModificationStrategy(final ContainerSchemaNode schemaNode) { - super(schemaNode, ContainerNode.class); - } - - @Override - @SuppressWarnings("rawtypes") - protected DataContainerNodeBuilder createBuilder(final NormalizedNode original) { - checkArgument(original instanceof ContainerNode); - return ImmutableContainerNodeBuilder.create((ContainerNode) original); - } - } - - public static class UnkeyedListItemModificationStrategy extends DataNodeContainerModificationStrategy { - - public UnkeyedListItemModificationStrategy(final ListSchemaNode schemaNode) { - super(schemaNode, UnkeyedListEntryNode.class); - } - - @Override - @SuppressWarnings("rawtypes") - protected DataContainerNodeBuilder createBuilder(final NormalizedNode original) { - checkArgument(original instanceof UnkeyedListEntryNode); - return ImmutableUnkeyedListEntryNodeBuilder.create((UnkeyedListEntryNode) original); - } - } - - public static class AugmentationModificationStrategy extends DataNodeContainerModificationStrategy { - - protected AugmentationModificationStrategy(final AugmentationSchema schema, final DataNodeContainer resolved) { - super(createAugmentProxy(schema,resolved), AugmentationNode.class); - } - - @Override - @SuppressWarnings("rawtypes") - protected DataContainerNodeBuilder createBuilder(final NormalizedNode original) { - checkArgument(original instanceof AugmentationNode); - return ImmutableAugmentationNodeBuilder.create((AugmentationNode) original); - } - } - - public static class ChoiceModificationStrategy extends NormalizedNodeContainerModificationStrategy { - - private final Map childNodes; - - public ChoiceModificationStrategy(final ChoiceNode schemaNode) { - super(org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode.class); - ImmutableMap.Builder child = ImmutableMap.builder(); - - for (ChoiceCaseNode caze : schemaNode.getCases()) { - for (DataSchemaNode cazeChild : caze.getChildNodes()) { - SchemaAwareApplyOperation childNode = from(cazeChild); - child.put(new NodeIdentifier(cazeChild.getQName()), childNode); - } - } - childNodes = child.build(); - } - - @Override - public Optional getChild(final PathArgument child) { - return Optional.fromNullable(childNodes.get(child)); - } - - @Override - @SuppressWarnings("rawtypes") - protected DataContainerNodeBuilder createBuilder(final NormalizedNode original) { - checkArgument(original instanceof org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode); - return ImmutableChoiceNodeBuilder.create((org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode) original); - } - } - - public static class ListEntryModificationStrategy extends DataNodeContainerModificationStrategy { - - protected ListEntryModificationStrategy(final ListSchemaNode schema) { - super(schema, MapEntryNode.class); - } - - @Override - @SuppressWarnings("rawtypes") - protected final DataContainerNodeBuilder createBuilder(final NormalizedNode original) { - checkArgument(original instanceof MapEntryNode); - return ImmutableMapEntryNodeBuilder.create((MapEntryNode) original); - } - } - - public static class UnorderedLeafSetModificationStrategy extends NormalizedNodeContainerModificationStrategy { - - private final Optional entryStrategy; - - @SuppressWarnings({ "unchecked", "rawtypes" }) - protected UnorderedLeafSetModificationStrategy(final LeafListSchemaNode schema) { - super((Class) LeafSetNode.class); - entryStrategy = Optional. of(new LeafSetEntryModificationStrategy(schema)); - } - - @SuppressWarnings("rawtypes") - @Override - protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode original) { - checkArgument(original instanceof LeafSetNode); - return ImmutableLeafSetNodeBuilder.create((LeafSetNode) original); - } - - @Override - public Optional getChild(final PathArgument identifier) { - if (identifier instanceof NodeWithValue) { - return entryStrategy; - } - return Optional.absent(); - } - } - - public static class OrderedLeafSetModificationStrategy extends NormalizedNodeContainerModificationStrategy { - - private final Optional entryStrategy; - - @SuppressWarnings({ "unchecked", "rawtypes" }) - protected OrderedLeafSetModificationStrategy(final LeafListSchemaNode schema) { - super((Class) LeafSetNode.class); - entryStrategy = Optional. of(new LeafSetEntryModificationStrategy(schema)); - } - - @SuppressWarnings("rawtypes") - @Override - protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode original) { - checkArgument(original instanceof OrderedLeafSetNode); - return ImmutableOrderedLeafSetNodeBuilder.create((OrderedLeafSetNode) original); - } - - @Override - public Optional getChild(final PathArgument identifier) { - if (identifier instanceof NodeWithValue) { - return entryStrategy; - } - return Optional.absent(); - } - } + protected abstract void verifyWrittenStructure(NormalizedNode writtenValue); public static class UnkeyedListModificationStrategy extends SchemaAwareApplyOperation { @@ -639,21 +230,21 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { } @Override - protected StoreMetadataNode applyMerge(final NodeModification modification, final StoreMetadataNode currentMeta, - final UnsignedLong subtreeVersion) { + protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta, + final Version subtreeVersion) { return applyWrite(modification, Optional.of(currentMeta), subtreeVersion); } @Override - protected StoreMetadataNode applySubtreeChange(final NodeModification modification, - final StoreMetadataNode currentMeta, final UnsignedLong subtreeVersion) { + protected TreeNode applySubtreeChange(final ModifiedNode modification, + final TreeNode currentMeta, final Version subtreeVersion) { throw new UnsupportedOperationException("UnkeyedList does not support subtree change."); } @Override - protected StoreMetadataNode applyWrite(final NodeModification modification, - final Optional currentMeta, final UnsignedLong subtreeVersion) { - return StoreMetadataNode.createRecursively(modification.getWrittenValue(), subtreeVersion); + protected TreeNode applyWrite(final ModifiedNode modification, + final Optional currentMeta, final Version subtreeVersion) { + return TreeNodeFactory.createTreeNode(modification.getWrittenValue(), subtreeVersion); } @Override @@ -670,86 +261,9 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { } @Override - protected void checkSubtreeModificationApplicable(final InstanceIdentifier path,final NodeModification modification, - final Optional current) throws DataPreconditionFailedException { + protected void checkSubtreeModificationApplicable(final InstanceIdentifier path, final NodeModification modification, + final Optional current) throws DataPreconditionFailedException { throw new DataPreconditionFailedException(path, "Subtree modification is not allowed."); } - - } - - public static class UnorderedMapModificationStrategy extends NormalizedNodeContainerModificationStrategy { - - private final Optional entryStrategy; - - protected UnorderedMapModificationStrategy(final ListSchemaNode schema) { - super(MapNode.class); - entryStrategy = Optional. of(new ListEntryModificationStrategy(schema)); - } - - @SuppressWarnings("rawtypes") - @Override - protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode original) { - checkArgument(original instanceof MapNode); - return ImmutableMapNodeBuilder.create((MapNode) original); - } - - @Override - public Optional getChild(final PathArgument identifier) { - if (identifier instanceof NodeIdentifierWithPredicates) { - return entryStrategy; - } - return Optional.absent(); - } - - @Override - public String toString() { - return "UnorderedMapModificationStrategy [entry=" + entryStrategy + "]"; - } } - - public static class OrderedMapModificationStrategy extends NormalizedNodeContainerModificationStrategy { - - private final Optional entryStrategy; - - protected OrderedMapModificationStrategy(final ListSchemaNode schema) { - super(OrderedMapNode.class); - entryStrategy = Optional. of(new ListEntryModificationStrategy(schema)); - } - - @SuppressWarnings("rawtypes") - @Override - protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode original) { - checkArgument(original instanceof OrderedMapNode); - return ImmutableOrderedMapNodeBuilder.create((OrderedMapNode) original); - } - - @Override - public Optional getChild(final PathArgument identifier) { - if (identifier instanceof NodeIdentifierWithPredicates) { - return entryStrategy; - } - return Optional.absent(); - } - - @Override - public String toString() { - return "OrderedMapModificationStrategy [entry=" + entryStrategy + "]"; - } - } - - public static AugmentationSchema createAugmentProxy(final AugmentationSchema schema, final DataNodeContainer resolved) { - Set realChildSchemas = new HashSet<>(); - for(DataSchemaNode augChild : schema.getChildNodes()) { - realChildSchemas.add(resolved.getDataChildByName(augChild.getQName())); - } - return new AugmentationSchemaProxy(schema, realChildSchemas); - } - - public static boolean checkDataPrecondition(final InstanceIdentifier path, final boolean condition, final String message) throws DataPreconditionFailedException { - if(!condition) { - throw new DataPreconditionFailedException(path, message); - } - return condition; - } - } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/StoreMetadataNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/StoreMetadataNode.java deleted file mode 100644 index 8addb89bd1..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/StoreMetadataNode.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; - -import static com.google.common.base.Preconditions.checkState; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreTreeNode; -import org.opendaylight.yangtools.concepts.Identifiable; -import org.opendaylight.yangtools.concepts.Immutable; -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; -import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; -import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer; - -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.primitives.UnsignedLong; - -// FIXME: this should not be public -public class StoreMetadataNode implements Immutable, Identifiable, StoreTreeNode { - - private final UnsignedLong nodeVersion; - private final UnsignedLong subtreeVersion; - private final NormalizedNode data; - - private final Map children; - - /** - * - * @param data - * @param nodeVersion - * @param subtreeVersion - * @param children Map of children, must not be modified externally - */ - protected StoreMetadataNode(final NormalizedNode data, final UnsignedLong nodeVersion, - final UnsignedLong subtreeVersion, final Map children) { - this.nodeVersion = nodeVersion; - this.subtreeVersion = subtreeVersion; - this.data = data; - this.children = Preconditions.checkNotNull(children); - } - - public static StoreMetadataNode createEmpty(final NormalizedNode data) { - return new StoreMetadataNode(data, UnsignedLong.ZERO, UnsignedLong.ZERO, - Collections.emptyMap()); - } - - public StoreMetadataNode(final NormalizedNode data, final UnsignedLong nodeVersion, - final UnsignedLong subtreeVersion) { - this(data, nodeVersion, subtreeVersion, Collections.emptyMap()); - } - - public static Builder builder() { - return new Builder(); - } - - public static Builder builder(StoreMetadataNode node) { - return new Builder(node); - } - - public UnsignedLong getNodeVersion() { - return this.nodeVersion; - } - - @Override - public PathArgument getIdentifier() { - return data.getIdentifier(); - } - - public UnsignedLong getSubtreeVersion() { - return subtreeVersion; - } - - public NormalizedNode getData() { - return this.data; - } - - @Override - public Optional getChild(final PathArgument key) { - return Optional.fromNullable(children.get(key)); - } - - @Override - public String toString() { - return "StoreMetadataNode [identifier=" + getIdentifier() + ", nodeVersion=" + nodeVersion + "]"; - } - - public static Optional getVersion(final Optional currentMetadata) { - if (currentMetadata.isPresent()) { - return Optional.of(currentMetadata.get().getNodeVersion()); - } - return Optional.absent(); - } - - public static Optional getChild(final Optional parent, - final PathArgument child) { - if (parent.isPresent()) { - return parent.get().getChild(child); - } - return Optional.absent(); - } - - public static final StoreMetadataNode createRecursively(final NormalizedNode node, - final UnsignedLong nodeVersion, final UnsignedLong subtreeVersion) { - Builder builder = builder() // - .setNodeVersion(nodeVersion) // - .setSubtreeVersion(subtreeVersion) // - .setData(node); - if (node instanceof NormalizedNodeContainer) { - - @SuppressWarnings("unchecked") - NormalizedNodeContainer> nodeContainer = (NormalizedNodeContainer>) node; - for (NormalizedNode subNode : nodeContainer.getValue()) { - builder.add(createRecursively(subNode, nodeVersion, subtreeVersion)); - } - } - return builder.build(); - } - - public static class Builder { - - private UnsignedLong nodeVersion; - private UnsignedLong subtreeVersion; - private NormalizedNode data; - private Map children; - private boolean dirty = false; - - private Builder() { - children = new HashMap<>(); - } - - public Builder(StoreMetadataNode node) { - children = new HashMap<>(node.children); - } - - public UnsignedLong getVersion() { - return nodeVersion; - - } - - public Builder setNodeVersion(final UnsignedLong version) { - this.nodeVersion = version; - return this; - } - - public Builder setSubtreeVersion(final UnsignedLong version) { - this.subtreeVersion = version; - return this; - } - - public Builder setData(final NormalizedNode data) { - this.data = data; - return this; - } - - public Builder add(final StoreMetadataNode node) { - if (dirty) { - children = new HashMap<>(children); - dirty = false; - } - children.put(node.getIdentifier(), node); - return this; - } - - public Builder remove(final PathArgument id) { - if (dirty) { - children = new HashMap<>(children); - dirty = false; - } - children.remove(id); - return this; - } - - public StoreMetadataNode build() { - checkState(data != null, "Data node should not be null."); - checkState(subtreeVersion.compareTo(nodeVersion) >= 0, - "Subtree version must be equals or greater than node version."); - dirty = true; - return new StoreMetadataNode(data, nodeVersion, subtreeVersion, children); - } - } - - public static StoreMetadataNode createRecursively(final NormalizedNode node, final UnsignedLong version) { - return createRecursively(node, version, version); - } -} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/StoreNodeCompositeBuilder.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/StoreNodeCompositeBuilder.java deleted file mode 100644 index 6bce4fff0c..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/StoreNodeCompositeBuilder.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; - -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; -import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder; - -import com.google.common.base.Preconditions; -import com.google.common.primitives.UnsignedLong; - -/** - * - * Helper builder - * - * - */ -@SuppressWarnings("rawtypes") -class StoreNodeCompositeBuilder { - - private final StoreMetadataNode.Builder metadata; - - private final NormalizedNodeContainerBuilder data; - - private StoreNodeCompositeBuilder(final NormalizedNodeContainerBuilder nodeBuilder) { - this.metadata = StoreMetadataNode.builder(); - this.data = Preconditions.checkNotNull(nodeBuilder); - } - - public StoreNodeCompositeBuilder(NormalizedNodeContainerBuilder nodeBuilder, StoreMetadataNode currentMeta) { - this.metadata = StoreMetadataNode.builder(currentMeta); - this.data = Preconditions.checkNotNull(nodeBuilder); - } - - @SuppressWarnings("unchecked") - public StoreNodeCompositeBuilder add(final StoreMetadataNode node) { - metadata.add(node); - data.addChild(node.getData()); - return this; - } - - @SuppressWarnings("unchecked") - public StoreNodeCompositeBuilder remove(PathArgument id) { - metadata.remove(id); - data.removeChild(id); - return this; - } - - public StoreMetadataNode build() { - return metadata.setData(data.build()).build(); - } - - public static StoreNodeCompositeBuilder from(final NormalizedNodeContainerBuilder nodeBuilder) { - return new StoreNodeCompositeBuilder(nodeBuilder); - } - - public static StoreNodeCompositeBuilder from(final NormalizedNodeContainerBuilder nodeBuilder, StoreMetadataNode currentMeta) { - return new StoreNodeCompositeBuilder(nodeBuilder, currentMeta); - } - - @SuppressWarnings("unchecked") - public StoreNodeCompositeBuilder setIdentifier(final PathArgument identifier) { - data.withNodeIdentifier(identifier); - return this; - } - - public StoreNodeCompositeBuilder setNodeVersion(final UnsignedLong nodeVersion) { - metadata.setNodeVersion(nodeVersion); - return this; - } - - public StoreNodeCompositeBuilder setSubtreeVersion(final UnsignedLong updatedSubtreeVersion) { - metadata.setSubtreeVersion(updatedSubtreeVersion); - return this; - } -} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ValueNodeModificationStrategy.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ValueNodeModificationStrategy.java new file mode 100644 index 0000000000..5f68782a2e --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ValueNodeModificationStrategy.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; + +import static com.google.common.base.Preconditions.checkArgument; + +import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataPreconditionFailedException; +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.data.api.InstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.LeafNode; +import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; + +import com.google.common.base.Optional; + +abstract class ValueNodeModificationStrategy extends SchemaAwareApplyOperation { + + private final T schema; + private final Class> nodeClass; + + protected ValueNodeModificationStrategy(final T schema, final Class> nodeClass) { + super(); + this.schema = schema; + this.nodeClass = nodeClass; + } + + @Override + protected void verifyWrittenStructure(final NormalizedNode writtenValue) { + checkArgument(nodeClass.isInstance(writtenValue), "Node should must be of type %s", nodeClass); + } + + @Override + public Optional getChild(final PathArgument child) { + throw new UnsupportedOperationException("Node " + schema.getPath() + + "is leaf type node. Child nodes not allowed"); + } + + @Override + protected TreeNode applySubtreeChange(final ModifiedNode modification, + final TreeNode currentMeta, final Version subtreeVersion) { + throw new UnsupportedOperationException("Node " + schema.getPath() + + "is leaf type node. Subtree change is not allowed."); + } + + @Override + protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta, + final Version subtreeVersion) { + // Just overwrite whatever was there + return applyWrite(modification, null, subtreeVersion); + } + + @Override + protected TreeNode applyWrite(final ModifiedNode modification, + final Optional currentMeta, final Version subtreeVersion) { + return TreeNodeFactory.createTreeNode(modification.getWrittenValue(), subtreeVersion); + } + + @Override + protected void checkSubtreeModificationApplicable(final InstanceIdentifier path, final NodeModification modification, + final Optional current) throws DataPreconditionFailedException { + throw new DataPreconditionFailedException(path, "Subtree modification is not allowed."); + } + + public static class LeafSetEntryModificationStrategy extends ValueNodeModificationStrategy { + @SuppressWarnings({ "unchecked", "rawtypes" }) + protected LeafSetEntryModificationStrategy(final LeafListSchemaNode schema) { + super(schema, (Class) LeafSetEntryNode.class); + } + } + + public static class LeafModificationStrategy extends ValueNodeModificationStrategy { + @SuppressWarnings({ "unchecked", "rawtypes" }) + protected LeafModificationStrategy(final LeafSchemaNode schema) { + super(schema, (Class) LeafNode.class); + } + } +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/AbstractTreeNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/AbstractTreeNode.java new file mode 100644 index 0000000000..1444f0c6a8 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/AbstractTreeNode.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.md.sal.dom.store.impl.tree.spi; + +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; + +import com.google.common.base.Preconditions; + +/* + * A very basic data tree node. + */ +abstract class AbstractTreeNode implements TreeNode { + private final NormalizedNode data; + private final Version version; + + protected AbstractTreeNode(final NormalizedNode data, final Version version) { + this.data = Preconditions.checkNotNull(data); + this.version = Preconditions.checkNotNull(version); + } + + @Override + public PathArgument getIdentifier() { + return data.getIdentifier(); + } + + @Override + public final Version getVersion() { + return version; + } + + @Override + public final NormalizedNode getData() { + return data; + } +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/ContainerNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/ContainerNode.java new file mode 100644 index 0000000000..8f74f60498 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/ContainerNode.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.md.sal.dom.store.impl.tree.spi; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer; +import org.opendaylight.yangtools.yang.data.api.schema.OrderedNodeContainer; + +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; + +/** + * A TreeNode capable of holding child nodes. The fact that any of the children + * changed is tracked by the subtree version. + */ +final class ContainerNode extends AbstractTreeNode { + private final Map children; + private final Version subtreeVersion; + + protected ContainerNode(final NormalizedNode data, final Version version, + final Map children, final Version subtreeVersion) { + super(data, version); + this.children = Preconditions.checkNotNull(children); + this.subtreeVersion = Preconditions.checkNotNull(subtreeVersion); + } + + @Override + public Version getSubtreeVersion() { + return subtreeVersion; + } + + @Override + public Optional getChild(final PathArgument key) { + return Optional.fromNullable(children.get(key)); + } + + @Override + public MutableTreeNode mutable() { + return new Mutable(this); + } + + private static final class Mutable implements MutableTreeNode { + private final Map children; + private final Version version; + private NormalizedNode data; + private Version subtreeVersion; + + private Mutable(final ContainerNode parent) { + this.data = parent.getData(); + this.children = new HashMap<>(parent.children); + this.subtreeVersion = parent.getSubtreeVersion(); + this.version = parent.getVersion(); + } + + @Override + public Optional getChild(final PathArgument child) { + return Optional.fromNullable(children.get(child)); + } + + @Override + public void setSubtreeVersion(final Version subtreeVersion) { + this.subtreeVersion = Preconditions.checkNotNull(subtreeVersion); + } + + @Override + public void addChild(final TreeNode child) { + children.put(child.getIdentifier(), child); + } + + @Override + public void removeChild(final PathArgument id) { + children.remove(id); + } + + @Override + public TreeNode seal() { + final Map realChildren; + + if (children.isEmpty()) { + realChildren = Collections.emptyMap(); + } else { + realChildren = children; + } + + return new ContainerNode(data, version, realChildren, subtreeVersion); + } + + @Override + public void setData(final NormalizedNode data) { + this.data = Preconditions.checkNotNull(data); + } + } + + private static ContainerNode create(final Version version, final NormalizedNode data, + final Iterable> children) { + final Map map = new HashMap<>(); + + for (NormalizedNode child : children) { + map.put(child.getIdentifier(), TreeNodeFactory.createTreeNode(child, version)); + } + + return new ContainerNode(data, version, map, version); + } + + public static ContainerNode create(final Version version, final NormalizedNodeContainer> container) { + return create(version, container, container.getValue()); + } + + public static ContainerNode create(final Version version, final OrderedNodeContainer> container) { + return create(version, container, container.getValue()); + } +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/MutableTreeNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/MutableTreeNode.java new file mode 100644 index 0000000000..dd3672cf11 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/MutableTreeNode.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.md.sal.dom.store.impl.tree.spi; + +import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreTreeNode; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; + +public interface MutableTreeNode extends StoreTreeNode { + void setData(NormalizedNode data); + void setSubtreeVersion(Version subtreeVersion); + void addChild(TreeNode child); + void removeChild(PathArgument id); + TreeNode seal(); +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/TreeNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/TreeNode.java new file mode 100644 index 0000000000..b0beb8168b --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/TreeNode.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.md.sal.dom.store.impl.tree.spi; + +import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreTreeNode; +import org.opendaylight.yangtools.concepts.Identifiable; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; + +/* + * A very basic data tree node. It has a version (when it was last modified), + * a subtree version (when any of its children were modified) and some read-only + * data. + */ +public interface TreeNode extends Identifiable, StoreTreeNode { + /** + * Get the data node version. + * + * @return Current data node version. + */ + Version getVersion(); + + /** + * Get the subtree version. + * + * @return Current subtree version. + */ + Version getSubtreeVersion(); + + /** + * Get a read-only view of the underlying data. + * + * @return Unmodifiable view of the underlying data. + */ + NormalizedNode getData(); + + /** + * Get a mutable, isolated copy of the node. + * + * @return Mutable copy + */ + MutableTreeNode mutable(); +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/TreeNodeFactory.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/TreeNodeFactory.java new file mode 100644 index 0000000000..c5d174caad --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/TreeNodeFactory.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.md.sal.dom.store.impl.tree.spi; + +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer; +import org.opendaylight.yangtools.yang.data.api.schema.OrderedNodeContainer; + +public final class TreeNodeFactory { + private TreeNodeFactory() { + throw new UnsupportedOperationException("Utility class should not be instantiated"); + } + + /** + * Create a new AbstractTreeNode from a data node, descending recursively as needed. + * This method should only ever be used for new data. + * + * @param data data node + * @param version data node version + * @return new AbstractTreeNode instance, covering the data tree provided + */ + public static final TreeNode createTreeNode(final NormalizedNode data, final Version version) { + if (data instanceof NormalizedNodeContainer) { + @SuppressWarnings("unchecked") + NormalizedNodeContainer> container = (NormalizedNodeContainer>) data; + return ContainerNode.create(version, container); + + } + if (data instanceof OrderedNodeContainer) { + @SuppressWarnings("unchecked") + OrderedNodeContainer> container = (OrderedNodeContainer>) data; + return ContainerNode.create(version, container); + } + + return new ValueNode(data, version); + } +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/ValueNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/ValueNode.java new file mode 100644 index 0000000000..7194faadf6 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/ValueNode.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.md.sal.dom.store.impl.tree.spi; + +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Optional; + +final class ValueNode extends AbstractTreeNode { + private static final Logger LOG = LoggerFactory.getLogger(ValueNode.class); + + protected ValueNode(final NormalizedNode data, final Version version) { + super(data, version); + } + + @Override + public Optional getChild(final PathArgument childId) { + LOG.warn("Attempted to access child {} of value-node {}", childId, this); + return Optional.absent(); + } + + @Override + public Version getSubtreeVersion() { + return getVersion(); + } + + @Override + public MutableTreeNode mutable() { + /** + * Value nodes can only we read/written/delete, which does a straight + * replace. That means they don't haver need to be made mutable. + */ + throw new UnsupportedOperationException(String.format("Attempted to mutate value-node %s", this)); + } +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/Version.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/Version.java new file mode 100644 index 0000000000..09a35d3b1a --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/Version.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.md.sal.dom.store.impl.tree.spi; + +/** + * The concept of a version, either node version, or a subtree version. The + * only interface contract this class has is that no two versions are the + * same. + */ +public final class Version { + private Version() { + + } + + /** + * Create a new version, distinct from any other version. + * + * @return a new version. + */ + public Version next() { + return new Version(); + } + + /** + * Create an initial version. + * + * @return a new version. + */ + public static final Version initial() { + return new Version(); + } +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaAwareDataStoreAdapter.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaAwareDataStoreAdapter.java index d8315568be..1a572d157d 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaAwareDataStoreAdapter.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaAwareDataStoreAdapter.java @@ -45,9 +45,9 @@ import com.google.common.collect.FluentIterable; import com.google.common.collect.ImmutableSet; public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator implements // - DataStore, // - SchemaContextListener, // - AutoCloseable { +DataStore, // +SchemaContextListener, // +AutoCloseable { private final static Logger LOG = LoggerFactory.getLogger(SchemaAwareDataStoreAdapter.class); @@ -56,7 +56,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator reader = new MergeFirstLevelReader(); @Override - public boolean containsConfigurationPath(InstanceIdentifier path) { + public boolean containsConfigurationPath(final InstanceIdentifier path) { try { getDelegateReadLock().lock(); return getDelegate().containsConfigurationPath(path); @@ -67,7 +67,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator requestCommit( - DataModification modification) { + final DataModification modification) { validateAgainstSchema(modification); NormalizedDataModification cleanedUp = prepareMergedTransaction(modification); cleanedUp.status = TransactionStatus.SUBMITED; @@ -122,11 +122,11 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator modification) { + private void validateAgainstSchema(final DataModification modification) { if (!validationEnabled) { return; } @@ -138,12 +138,12 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator original) { + final DataModification original) { NormalizedDataModification normalized = new NormalizedDataModification(original); LOG.trace("Transaction: {} Removed Configuration {}, Removed Operational {}", original.getIdentifier(), original.getRemovedConfigurationData(), original.getRemovedConfigurationData()); @@ -194,7 +194,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator getConfigurationSubpaths(InstanceIdentifier entry) { + private Iterable getConfigurationSubpaths(final InstanceIdentifier entry) { // FIXME: This should be replaced by index Iterable paths = getStoredConfigurationPaths(); @@ -202,15 +202,15 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator getOperationalSubpaths(InstanceIdentifier entry) { + public Iterable getOperationalSubpaths(final InstanceIdentifier entry) { // FIXME: This should be indexed Iterable paths = getStoredOperationalPaths(); return getChildrenPaths(entry, paths); } - private static final Iterable getChildrenPaths(InstanceIdentifier entry, - Iterable paths) { + private static final Iterable getChildrenPaths(final InstanceIdentifier entry, + final Iterable paths) { ImmutableSet.Builder children = ImmutableSet.builder(); for (InstanceIdentifier potential : paths) { if (entry.contains(potential)) { @@ -222,7 +222,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator> preparationComparator = new Comparator>() { @Override - public int compare(Entry o1, Entry o2) { + public int compare(final Entry o1, final Entry o2) { InstanceIdentifier o1Key = o1.getKey(); InstanceIdentifier o2Key = o2.getKey(); return Integer.compare(o1Key.getPath().size(), o2Key.getPath().size()); @@ -242,7 +242,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator> childNodes = new ArrayList>(); if (original != null) { - childNodes.addAll(original.getChildren()); + childNodes.addAll(original.getValue()); qname = original.getNodeType(); } else { qname = path.getPath().get(path.getPath().size() - 1).getNodeType(); @@ -251,7 +251,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator directChildren = FluentIterable.from(getStoredConfigurationPaths()) .filter(new Predicate() { @Override - public boolean apply(InstanceIdentifier input) { + public boolean apply(final InstanceIdentifier input) { if (path.contains(input)) { int nesting = input.getPath().size() - path.getPath().size(); if (nesting == 1) { @@ -285,7 +285,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator> childNodes = new ArrayList>(); if (original != null) { - childNodes.addAll(original.getChildren()); + childNodes.addAll(original.getValue()); qname = original.getNodeType(); } else { qname = path.getPath().get(path.getPath().size() - 1).getNodeType(); @@ -294,7 +294,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator directChildren = FluentIterable.from(getStoredOperationalPaths()) .filter(new Predicate() { @Override - public boolean apply(InstanceIdentifier input) { + public boolean apply(final InstanceIdentifier input) { if (path.contains(input)) { int nesting = input.getPath().size() - path.getPath().size(); if (nesting == 1) { @@ -326,7 +326,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator original) { + public NormalizedDataModification(final DataModification original) { super(getDelegate()); identifier = original; status = TransactionStatus.NEW; @@ -339,7 +339,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator paths = getOperationalSubpaths(entry); removeOperationalData(entry); for (InstanceIdentifier potential : paths) { @@ -347,7 +347,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator paths = getConfigurationSubpaths(entry); removeConfigurationData(entry); for (InstanceIdentifier potential : paths) { @@ -355,11 +355,11 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator child : entryData.getChildren()) { + for (Node child : entryData.getValue()) { InstanceIdentifier subEntryId = InstanceIdentifier.builder(entryKey).node(child.getNodeType()) .toInstance(); if (child instanceof CompositeNode) { @@ -438,7 +438,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator getValuesFromListSchema(ListSchemaNode listSchema, CompositeNode entryData) { + private Map getValuesFromListSchema(final ListSchemaNode listSchema, final CompositeNode entryData) { List keyDef = listSchema.getKeyDefinition(); if (keyDef != null && !keyDef.isEmpty()) { Map map = new HashMap(); diff --git a/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationMetadataTreeTest.java b/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationMetadataTreeTest.java index 8940e55d32..4fb190fc82 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationMetadataTreeTest.java +++ b/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationMetadataTreeTest.java @@ -29,6 +29,8 @@ import org.junit.Test; import org.opendaylight.controller.md.sal.dom.store.impl.TestModel; import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTree; import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeModification; +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.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; @@ -40,7 +42,6 @@ import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableCo import org.opendaylight.yangtools.yang.model.api.SchemaContext; import com.google.common.base.Optional; -import com.google.common.primitives.UnsignedLong; /** * @@ -149,7 +150,7 @@ public class ModificationMetadataTreeTest { @Test public void basicReadWrites() { DataTreeModification modificationTree = new InMemoryDataTreeModification(new InMemoryDataTreeSnapshot(schemaContext, - StoreMetadataNode.createRecursively(createDocumentOne(), UnsignedLong.valueOf(5)), applyOper), + TreeNodeFactory.createTreeNode(createDocumentOne(), Version.initial()), applyOper), new SchemaAwareApplyOperationRoot(schemaContext)); Optional> originalBarNode = modificationTree.readNode(OUTER_LIST_2_PATH); assertTrue(originalBarNode.isPresent()); diff --git a/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperationRoot.java b/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperationRoot.java index f2cc533207..03ece2f5e0 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperationRoot.java +++ b/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperationRoot.java @@ -14,7 +14,7 @@ import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableCo import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; import org.opendaylight.yangtools.yang.model.api.SchemaContext; -public class SchemaAwareApplyOperationRoot extends SchemaAwareApplyOperation.DataNodeContainerModificationStrategy { +public class SchemaAwareApplyOperationRoot extends DataNodeContainerModificationStrategy { private final SchemaContext context; public SchemaAwareApplyOperationRoot(final SchemaContext context) { diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTwoPhaseCommitTransaction.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTwoPhaseCommitTransaction.java index 8a74b17ac4..34cd9aa47b 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTwoPhaseCommitTransaction.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTwoPhaseCommitTransaction.java @@ -35,7 +35,6 @@ import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifie import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.Node; import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode; -import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl; import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,9 +51,9 @@ class NetconfDeviceTwoPhaseCommitTransaction implements DataCommitTransaction modification, - boolean candidateSupported, boolean rollbackOnErrorSupported) { + public NetconfDeviceTwoPhaseCommitTransaction(final NetconfDevice device, + final DataModification modification, + final boolean candidateSupported, final boolean rollbackOnErrorSupported) { this.device = Preconditions.checkNotNull(device); this.modification = Preconditions.checkNotNull(modification); this.candidateSupported = candidateSupported; @@ -70,15 +69,15 @@ class NetconfDeviceTwoPhaseCommitTransaction implements DataCommitTransactionabsent(), Optional.of(value))); } - private void sendDelete(InstanceIdentifier toDelete) throws InterruptedException, ExecutionException { + private void sendDelete(final InstanceIdentifier toDelete) throws InterruptedException, ExecutionException { sendEditRpc(createEditStructure(toDelete, Optional.of("delete"), Optional. absent())); } - private void sendEditRpc(CompositeNode editStructure) throws InterruptedException, ExecutionException { + private void sendEditRpc(final CompositeNode editStructure) throws InterruptedException, ExecutionException { CompositeNodeBuilder builder = configurationRpcBuilder(); builder.setQName(NETCONF_EDIT_CONFIG_QNAME); builder.add(editStructure); @@ -108,8 +107,8 @@ class NetconfDeviceTwoPhaseCommitTransaction implements DataCommitTransaction operation, - Optional lastChildOverride) { + private CompositeNode createEditStructure(final InstanceIdentifier dataPath, final Optional operation, + final Optional lastChildOverride) { List path = dataPath.getPath(); List reversed = Lists.reverse(path); CompositeNode previous = null; @@ -130,7 +129,7 @@ class NetconfDeviceTwoPhaseCommitTransaction implements DataCommitTransaction> children = lastChildOverride.get().getChildren(); + List> children = lastChildOverride.get().getValue(); for(Node child : children) { if(!predicates.containsKey(child.getKey())) { builder.add(child); diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.java index f76ec28624..2b3a992fc1 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.java @@ -7,12 +7,6 @@ */ package org.opendaylight.controller.sal.connect.netconf; -import com.google.common.base.Optional; -import com.google.common.base.Predicate; -import com.google.common.collect.Collections2; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; import java.net.URI; import java.util.ArrayList; import java.util.Collections; @@ -20,8 +14,10 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; + import javax.activation.UnsupportedDataTypeException; import javax.annotation.Nullable; + import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.api.NetconfMessage; import org.opendaylight.controller.netconf.util.messages.NetconfMessageUtil; @@ -41,11 +37,16 @@ import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl; import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlDocumentUtils; import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder; import org.opendaylight.yangtools.yang.model.api.NotificationDefinition; -import org.opendaylight.yangtools.yang.model.api.RpcDefinition; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.w3c.dom.Document; import org.w3c.dom.Element; +import com.google.common.base.Optional; +import com.google.common.base.Predicate; +import com.google.common.collect.Collections2; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; + public class NetconfMapping { public static URI NETCONF_URI = URI.create("urn:ietf:params:xml:ns:netconf:base:1.0"); @@ -91,7 +92,7 @@ public class NetconfMapping { static AtomicInteger messageId = new AtomicInteger(0); - static Node toFilterStructure(InstanceIdentifier identifier) { + static Node toFilterStructure(final InstanceIdentifier identifier) { Node previous = null; if (identifier.getPath().isEmpty()) { return null; @@ -108,7 +109,7 @@ public class NetconfMapping { return filter("subtree", previous); } - static Node toNode(NodeIdentifierWithPredicates argument, Node node) { + static Node toNode(final NodeIdentifierWithPredicates argument, final Node node) { List> list = new ArrayList<>(); for (Map.Entry arg : argument.getKeyValues().entrySet()) { list.add(new SimpleNodeTOImpl(arg.getKey(), null, arg.getValue())); @@ -119,7 +120,7 @@ public class NetconfMapping { return new CompositeNodeTOImpl(argument.getNodeType(), null, list); } - static Node toNode(PathArgument argument, Node node) { + static Node toNode(final PathArgument argument, final Node node) { if (node != null) { return new CompositeNodeTOImpl(argument.getNodeType(), null, Collections.> singletonList(node)); } else { @@ -127,14 +128,14 @@ public class NetconfMapping { } } - static CompositeNode toCompositeNode(NetconfMessage message, Optional ctx) { + static CompositeNode toCompositeNode(final NetconfMessage message, final Optional ctx) { // TODO: implement general normalization to normalize incoming Netconf // Message // for Schema Context counterpart return null; } - static CompositeNode toNotificationNode(NetconfMessage message, Optional ctx) { + static CompositeNode toNotificationNode(final NetconfMessage message, final Optional ctx) { if (ctx.isPresent()) { SchemaContext schemaContext = ctx.get(); Set notifications = schemaContext.getNotifications(); @@ -144,7 +145,7 @@ public class NetconfMapping { return null; } - static NetconfMessage toRpcMessage(QName rpc, CompositeNode node, Optional ctx) { + static NetconfMessage toRpcMessage(final QName rpc, final CompositeNode node, final Optional ctx) { CompositeNodeTOImpl rpcPayload = wrap(NETCONF_RPC_QNAME, flattenInput(node)); Document w3cPayload = null; try { @@ -164,8 +165,8 @@ public class NetconfMapping { if (input instanceof CompositeNode) { List> nodes = ImmutableList.> builder() // - .addAll(input.getChildren()) // - .addAll(Collections2.filter(node.getChildren(), new Predicate>() { + .addAll(input.getValue()) // + .addAll(Collections2.filter(node.getValue(), new Predicate>() { @Override public boolean apply(@Nullable final Node input) { return input.getNodeType() != inputQName; @@ -179,7 +180,7 @@ public class NetconfMapping { return input; } - static RpcResult toRpcResult(NetconfMessage message, final QName rpc, Optional context) { + static RpcResult toRpcResult(final NetconfMessage message, final QName rpc, final Optional context) { CompositeNode rawRpc; if (context.isPresent()) if (isDataRetrieQNameReply(rpc)) { @@ -196,7 +197,7 @@ public class NetconfMapping { rawRpc = it.toInstance(); // sys(xmlData) } else { - rawRpc = (CompositeNode) toCompositeNode(message, context); + rawRpc = toCompositeNode(message, context); } else { rawRpc = (CompositeNode) toCompositeNode(message.getDocument()); @@ -205,17 +206,17 @@ public class NetconfMapping { return Rpcs.getRpcResult(true, rawRpc, Collections. emptySet()); } - static Element getDataSubtree(Document doc) { + static Element getDataSubtree(final Document doc) { return (Element) doc.getElementsByTagNameNS(NETCONF_URI.toString(), "data").item(0); } - static boolean isDataRetrieQNameReply(QName it) { + static boolean isDataRetrieQNameReply(final QName it) { return NETCONF_URI == it.getNamespace() && (it.getLocalName() == NETCONF_GET_CONFIG_QNAME.getLocalName() || it.getLocalName() == NETCONF_GET_QNAME - .getLocalName()); + .getLocalName()); } - static CompositeNodeTOImpl wrap(QName name, Node node) { + static CompositeNodeTOImpl wrap(final QName name, final Node node) { if (node != null) { return new CompositeNodeTOImpl(name, null, Collections.> singletonList(node)); } else { @@ -223,7 +224,7 @@ public class NetconfMapping { } } - static CompositeNodeTOImpl wrap(QName name, Node additional, Node node) { + static CompositeNodeTOImpl wrap(final QName name, final Node additional, final Node node) { if (node != null) { return new CompositeNodeTOImpl(name, null, ImmutableList.of(additional, node)); } else { @@ -231,7 +232,7 @@ public class NetconfMapping { } } - static ImmutableCompositeNode filter(String type, Node node) { + static ImmutableCompositeNode filter(final String type, final Node node) { CompositeNodeBuilder it = ImmutableCompositeNode.builder(); // it.setQName(NETCONF_FILTER_QNAME); it.setAttribute(NETCONF_TYPE_QNAME, type); @@ -242,11 +243,11 @@ public class NetconfMapping { } } - public static Node toCompositeNode(Document document) { + public static Node toCompositeNode(final Document document) { return XmlDocumentUtils.toDomNode(document); } - public static void checkValidReply(NetconfMessage input, NetconfMessage output) { + public static void checkValidReply(final NetconfMessage input, final NetconfMessage output) { String inputMsgId = input.getDocument().getDocumentElement().getAttribute("message-id"); String outputMsgId = output.getDocument().getDocumentElement().getAttribute("message-id"); @@ -257,7 +258,7 @@ public class NetconfMapping { } } - public static void checkSuccessReply(NetconfMessage output) throws NetconfDocumentedException { + public static void checkSuccessReply(final NetconfMessage output) throws NetconfDocumentedException { if(NetconfMessageUtil.isErrorMessage(output)) { throw new IllegalStateException(String.format("Response contains error: %s", XmlUtil.toString(output.getDocument()))); } diff --git a/opendaylight/md-sal/sal-rest-connector/pom.xml b/opendaylight/md-sal/sal-rest-connector/pom.xml index c17a4b70cc..e4c7c0c647 100644 --- a/opendaylight/md-sal/sal-rest-connector/pom.xml +++ b/opendaylight/md-sal/sal-rest-connector/pom.xml @@ -47,6 +47,14 @@ org.opendaylight.yangtools yang-parser-impl + + org.opendaylight.yangtools.model + ietf-restconf + + + org.opendaylight.yangtools.model + ietf-yang-types-20130715 + org.slf4j slf4j-api diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java index d1441d7b9d..ea0f149d29 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java @@ -57,7 +57,7 @@ class JsonMapper { private MountInstance mountPoint; private final Logger logger = LoggerFactory.getLogger(JsonMapper.class); - public void write(JsonWriter writer, CompositeNode data, DataNodeContainer schema, MountInstance mountPoint) + public void write(final JsonWriter writer, final CompositeNode data, final DataNodeContainer schema, final MountInstance mountPoint) throws IOException { Preconditions.checkNotNull(writer); Preconditions.checkNotNull(data); @@ -81,12 +81,12 @@ class JsonMapper { foundLists.clear(); } - private void writeChildrenOfParent(JsonWriter writer, CompositeNode parent, DataNodeContainer parentSchema) + private void writeChildrenOfParent(final JsonWriter writer, final CompositeNode parent, final DataNodeContainer parentSchema) throws IOException { checkNotNull(parent); checkNotNull(parentSchema); - for (Node child : parent.getChildren()) { + for (Node child : parent.getValue()) { DataSchemaNode childSchema = findFirstSchemaForNode(child, parentSchema.getChildNodes()); if (childSchema == null) { @@ -122,17 +122,17 @@ class JsonMapper { } } - for (Node child : parent.getChildren()) { + for (Node child : parent.getValue()) { DataSchemaNode childSchema = findFirstSchemaForNode(child, parentSchema.getChildNodes()); if (childSchema instanceof LeafListSchemaNode) { - foundLeafLists.remove((LeafListSchemaNode) childSchema); + foundLeafLists.remove(childSchema); } else if (childSchema instanceof ListSchemaNode) { - foundLists.remove((ListSchemaNode) childSchema); + foundLists.remove(childSchema); } } } - private DataSchemaNode findFirstSchemaForNode(Node node, Set dataSchemaNode) { + private DataSchemaNode findFirstSchemaForNode(final Node node, final Set dataSchemaNode) { for (DataSchemaNode dsn : dataSchemaNode) { if (node.getNodeType().equals(dsn.getQName())) { return dsn; @@ -148,14 +148,14 @@ class JsonMapper { return null; } - private void writeContainer(JsonWriter writer, CompositeNode node, ContainerSchemaNode schema) throws IOException { + private void writeContainer(final JsonWriter writer, final CompositeNode node, final ContainerSchemaNode schema) throws IOException { writeName(node, schema, writer); writer.beginObject(); writeChildrenOfParent(writer, node, schema); writer.endObject(); } - private void writeList(JsonWriter writer, CompositeNode nodeParent, CompositeNode node, ListSchemaNode schema) + private void writeList(final JsonWriter writer, final CompositeNode nodeParent, final CompositeNode node, final ListSchemaNode schema) throws IOException { writeName(node, schema, writer); writer.beginArray(); @@ -176,8 +176,8 @@ class JsonMapper { writer.endArray(); } - private void writeLeafList(JsonWriter writer, CompositeNode nodeParent, SimpleNode node, - LeafListSchemaNode schema) throws IOException { + private void writeLeafList(final JsonWriter writer, final CompositeNode nodeParent, final SimpleNode node, + final LeafListSchemaNode schema) throws IOException { writeName(node, schema, writer); writer.beginArray(); @@ -188,13 +188,13 @@ class JsonMapper { writer.endArray(); } - private void writeLeaf(JsonWriter writer, SimpleNode node, LeafSchemaNode schema) throws IOException { + private void writeLeaf(final JsonWriter writer, final SimpleNode node, final LeafSchemaNode schema) throws IOException { writeName(node, schema, writer); writeValueOfNodeByType(writer, node, schema.getType(), schema); } - private void writeValueOfNodeByType(JsonWriter writer, SimpleNode node, TypeDefinition type, - DataSchemaNode schema) throws IOException { + private void writeValueOfNodeByType(final JsonWriter writer, final SimpleNode node, final TypeDefinition type, + final DataSchemaNode schema) throws IOException { TypeDefinition baseType = RestUtil.resolveBaseTypeFrom(type); @@ -245,7 +245,7 @@ class JsonMapper { } } - private void writeIdentityValuesDTOToJson(JsonWriter writer, IdentityValuesDTO valueDTO) throws IOException { + private void writeIdentityValuesDTOToJson(final JsonWriter writer, final IdentityValuesDTO valueDTO) throws IOException { StringBuilder result = new StringBuilder(); for (IdentityValue identityValue : valueDTO.getValuesWithNamespaces()) { result.append("/"); @@ -271,7 +271,7 @@ class JsonMapper { writer.value(result.toString()); } - private void writeModuleNameAndIdentifier(StringBuilder result, IdentityValue identityValue) { + private void writeModuleNameAndIdentifier(final StringBuilder result, final IdentityValue identityValue) { String moduleName = ControllerContext.getInstance().findModuleNameByNamespace( URI.create(identityValue.getNamespace())); if (moduleName != null && !moduleName.isEmpty()) { @@ -281,8 +281,8 @@ class JsonMapper { result.append(identityValue.getValue()); } - private void writeStringRepresentation(JsonWriter writer, SimpleNode node, TypeDefinition baseType, - Class requiredType) throws IOException { + private void writeStringRepresentation(final JsonWriter writer, final SimpleNode node, final TypeDefinition baseType, + final Class requiredType) throws IOException { Object value = node.getValue(); logger.debug("Value of " + baseType.getQName().getNamespace() + ":" + baseType.getQName().getLocalName() + " is not instance of " + requiredType.getClass() + " but is " + node.getValue().getClass()); @@ -293,13 +293,13 @@ class JsonMapper { } } - private void writeEmptyDataTypeToJson(JsonWriter writer) throws IOException { + private void writeEmptyDataTypeToJson(final JsonWriter writer) throws IOException { writer.beginArray(); writer.nullValue(); writer.endArray(); } - private void writeName(Node node, DataSchemaNode schema, JsonWriter writer) throws IOException { + private void writeName(final Node node, final DataSchemaNode schema, final JsonWriter writer) throws IOException { String nameForOutput = node.getNodeType().getLocalName(); if (schema.isAugmenting()) { ControllerContext contContext = ControllerContext.getInstance(); @@ -323,7 +323,7 @@ class JsonMapper { private static final long serialVersionUID = -3147729419814417666L; private final String value; - public NumberForJsonWriter(String value) { + public NumberForJsonWriter(final String value) { this.value = value; } diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProvider.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProvider.java index 1870bdf0bf..2abd4b6a3a 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProvider.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProvider.java @@ -34,7 +34,6 @@ public class RestconfProvider implements BundleActivator, Provider, ServiceTrack private ListenerRegistration listenerRegistration; private ServiceTracker brokerServiceTrancker; private BundleContext bundleContext; - private ProviderSession session; private Thread webSocketServerThread; @Override @@ -70,7 +69,6 @@ public class RestconfProvider implements BundleActivator, Provider, ServiceTrack } } webSocketServerThread.interrupt(); - session.close(); brokerServiceTrancker.close(); } diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/CompositeNodeWrapper.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/CompositeNodeWrapper.java index e0ae788703..96ad528a0d 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/CompositeNodeWrapper.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/CompositeNodeWrapper.java @@ -34,21 +34,21 @@ public final class CompositeNodeWrapper implements NodeWrapper, C private QName name; private List> values = new ArrayList<>(); - public CompositeNodeWrapper(String localName) { + public CompositeNodeWrapper(final String localName) { this.localName = Preconditions.checkNotNull(localName); } - public CompositeNodeWrapper(URI namespace, String localName) { + public CompositeNodeWrapper(final URI namespace, final String localName) { this(localName); this.namespace = namespace; } - + @Override - public void setQname(QName name) { + public void setQname(final QName name) { Preconditions.checkState(compositeNode == null, "Cannot change the object, due to data inconsistencies."); this.name = name; } - + @Override public QName getQname() { return name; @@ -71,26 +71,26 @@ public final class CompositeNodeWrapper implements NodeWrapper, C } @Override - public void setNamespace(URI namespace) { + public void setNamespace(final URI namespace) { Preconditions.checkState(compositeNode == null, "Cannot change the object, due to data inconsistencies."); this.namespace = namespace; } - public void addValue(NodeWrapper value) { + public void addValue(final NodeWrapper value) { Preconditions.checkState(compositeNode == null, "Cannot change the object, due to data inconsistencies."); values.add(value); } - public void removeValue(NodeWrapper value) { + public void removeValue(final NodeWrapper value) { Preconditions.checkState(compositeNode == null, "Cannot change the object, due to data inconsistencies."); values.remove(value); } - + public List> getValues() { Preconditions.checkState(compositeNode == null, "Data can be inconsistent."); return Collections.unmodifiableList(values); } - + @Override public boolean isChangeAllowed() { return compositeNode == null ? true : false; @@ -103,13 +103,13 @@ public final class CompositeNodeWrapper implements NodeWrapper, C Preconditions.checkNotNull(namespace); name = new QName(namespace, localName); } - + List> nodeValues = new ArrayList<>(); for (NodeWrapper nodeWrapper : values) { nodeValues.add(nodeWrapper.unwrap()); } compositeNode = NodeFactory.createMutableCompositeNode(name, null, nodeValues, null, null); - + values = null; namespace = null; localName = null; @@ -123,6 +123,7 @@ public final class CompositeNodeWrapper implements NodeWrapper, C return unwrap().getNodeType(); } + @Deprecated @Override public CompositeNode getParent() { return unwrap().getParent(); @@ -138,38 +139,42 @@ public final class CompositeNodeWrapper implements NodeWrapper, C return unwrap().getModificationAction(); } + /** + * @deprecated Use {@link #getValue()} instead. + */ + @Deprecated @Override public List> getChildren() { - return unwrap().getChildren(); + return unwrap().getValue(); } @Override - public List getCompositesByName(QName children) { + public List getCompositesByName(final QName children) { return unwrap().getCompositesByName(children); } @Override - public List getCompositesByName(String children) { + public List getCompositesByName(final String children) { return unwrap().getCompositesByName(children); } @Override - public List> getSimpleNodesByName(QName children) { + public List> getSimpleNodesByName(final QName children) { return unwrap().getSimpleNodesByName(children); } @Override - public List> getSimpleNodesByName(String children) { + public List> getSimpleNodesByName(final String children) { return unwrap().getSimpleNodesByName(children); } @Override - public CompositeNode getFirstCompositeByName(QName container) { + public CompositeNode getFirstCompositeByName(final QName container) { return unwrap().getFirstCompositeByName(container); } @Override - public SimpleNode getFirstSimpleByName(QName leaf) { + public SimpleNode getFirstSimpleByName(final QName leaf) { return unwrap().getFirstSimpleByName(leaf); } @@ -184,7 +189,7 @@ public final class CompositeNodeWrapper implements NodeWrapper, C } @Override - public List> setValue(List> value) { + public List> setValue(final List> value) { return unwrap().setValue(value); } @@ -199,32 +204,32 @@ public final class CompositeNodeWrapper implements NodeWrapper, C } @Override - public boolean containsKey(Object key) { + public boolean containsKey(final Object key) { return unwrap().containsKey(key); } @Override - public boolean containsValue(Object value) { + public boolean containsValue(final Object value) { return unwrap().containsValue(value); } @Override - public List> get(Object key) { + public List> get(final Object key) { return unwrap().get(key); } @Override - public List> put(QName key, List> value) { + public List> put(final QName key, final List> value) { return unwrap().put(key, value); } @Override - public List> remove(Object key) { + public List> remove(final Object key) { return unwrap().remove(key); } @Override - public void putAll(Map>> m) { + public void putAll(final Map>> m) { unwrap().putAll(m); } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonBasicYangTypesTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonBasicYangTypesTest.java index 874e8b0d1f..d978a2f0de 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonBasicYangTypesTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonBasicYangTypesTest.java @@ -85,7 +85,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { verifyJsonOutput(jsonOutput); } - private void verifyJsonOutputForEmptyData(String jsonOutput) { + private void verifyJsonOutputForEmptyData(final String jsonOutput) { assertNotNull(jsonOutput); StringReader strReader = new StringReader(jsonOutput); JsonReader jReader = new JsonReader(strReader); @@ -104,7 +104,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { assertNull("Error during reading Json output: " + exception, exception); } - private void verifyJsonOutput(String jsonOutput) { + private void verifyJsonOutput(final String jsonOutput) { assertNotNull(jsonOutput); StringReader strReader = new StringReader(jsonOutput); JsonReader jReader = new JsonReader(strReader); @@ -123,7 +123,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { assertNull("Error during reading Json output: " + exception, exception); } - private Cont jsonReadCont1(JsonReader jReader) throws IOException { + private Cont jsonReadCont1(final JsonReader jReader) throws IOException { jReader.beginObject(); assertNotNull("cont1 is missing.", jReader.hasNext()); @@ -136,7 +136,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { } - private Cont jsonReadCont1Elements(JsonReader jReader, Cont redData) throws IOException { + private Cont jsonReadCont1Elements(final JsonReader jReader, final Cont redData) throws IOException { jReader.beginObject(); while (jReader.hasNext()) { String keyName = jReader.nextName(); @@ -163,7 +163,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { } - private Lst jsonReadLst11(JsonReader jReader, Lst lst) throws IOException { + private Lst jsonReadLst11(final JsonReader jReader, final Lst lst) throws IOException { jReader.beginArray(); while (jReader.hasNext()) { @@ -174,7 +174,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { return lst; } - private LstItem jsonReadLst11Elements(JsonReader jReader) throws IOException { + private LstItem jsonReadLst11Elements(final JsonReader jReader) throws IOException { LstItem lstItem = new LstItem(); jReader.beginObject(); while (jReader.hasNext()) { @@ -203,7 +203,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { return lstItem; } - private Lst jsonReadLst112(JsonReader jReader, Lst lst) throws IOException { + private Lst jsonReadLst112(final JsonReader jReader, final Lst lst) throws IOException { jReader.beginArray(); while (jReader.hasNext()) { LstItem lstItem = jsonReadLst112Elements(jReader); @@ -213,7 +213,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { return lst; } - private LstItem jsonReadLst112Elements(JsonReader jReader) throws IOException { + private LstItem jsonReadLst112Elements(final JsonReader jReader) throws IOException { LstItem lstItem = new LstItem(); jReader.beginObject(); if (jReader.hasNext()) { @@ -227,7 +227,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { } - private Lst jsonReadLst111(JsonReader jReader, Lst lst) throws IOException { + private Lst jsonReadLst111(final JsonReader jReader, final Lst lst) throws IOException { jReader.beginArray(); while (jReader.hasNext()) { LstItem lstItem = jsonReadLst111Elements(jReader); @@ -237,7 +237,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { return lst; } - private LstItem jsonReadLst111Elements(JsonReader jReader) throws IOException { + private LstItem jsonReadLst111Elements(final JsonReader jReader) throws IOException { LstItem lstItem = new LstItem(); jReader.beginObject(); if (jReader.hasNext()) { @@ -250,7 +250,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { return lstItem; } - private Object nextValue(JsonReader jReader) throws IOException { + private Object nextValue(final JsonReader jReader) throws IOException { if (jReader.peek().equals(JsonToken.NULL)) { jReader.nextNull(); return null; @@ -261,14 +261,14 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { } } - private Cont jsonReadCont111(JsonReader jReader, Cont cont) throws IOException { + private Cont jsonReadCont111(final JsonReader jReader, Cont cont) throws IOException { jReader.beginObject(); cont = jsonReadCont111Elements(jReader, cont); jReader.endObject(); return cont; } - private Cont jsonReadCont111Elements(JsonReader jReader, Cont cont) throws IOException { + private Cont jsonReadCont111Elements(final JsonReader jReader, final Cont cont) throws IOException { while (jReader.hasNext()) { String keyName = jReader.nextName(); if (keyName.equals("lf1111")) { @@ -289,7 +289,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { } - private Lst jsonReadLst1111(JsonReader jReader, Lst lst) throws IOException { + private Lst jsonReadLst1111(final JsonReader jReader, final Lst lst) throws IOException { jReader.beginArray(); while (jReader.hasNext()) { LstItem lstItem = jsonReadLst1111Elements(jReader); @@ -299,7 +299,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { return lst; } - private LstItem jsonReadLst1111Elements(JsonReader jReader) throws IOException { + private LstItem jsonReadLst1111Elements(final JsonReader jReader) throws IOException { jReader.beginObject(); LstItem lstItem = new LstItem(); while (jReader.hasNext()) { @@ -312,7 +312,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { return lstItem; } - private LfLst jsonReadLflstValues(JsonReader jReader, LfLst lfLst) throws IOException { + private LfLst jsonReadLflstValues(final JsonReader jReader, final LfLst lfLst) throws IOException { jReader.beginArray(); while (jReader.hasNext()) { lfLst.addLf(new Lf(nextValue(jReader))); @@ -321,7 +321,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { return lfLst; } - private void checkDataFromJsonEmpty(Cont dataFromJson) { + private void checkDataFromJsonEmpty(final Cont dataFromJson) { assertTrue(dataFromJson.getLfs().isEmpty()); assertTrue(dataFromJson.getLfLsts().isEmpty()); assertTrue(dataFromJson.getConts().isEmpty()); @@ -357,9 +357,9 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { assertEquals(1, lst11_1.getLsts().size()); assertEquals( lst11_1.getLsts().get("lst111"), - new Lst("lst111").addLstItem(new LstItem().addLf("lf1111", (int) 35)) - .addLstItem(new LstItem().addLf("lf1111", (int) 34)).addLstItem(new LstItem()) - .addLstItem(new LstItem())); + new Lst("lst111").addLstItem(new LstItem().addLf("lf1111", 35)) + .addLstItem(new LstItem().addLf("lf1111", 34)).addLstItem(new LstItem()) + .addLstItem(new LstItem())); assertEquals(lst11_1.getConts().get("cont111"), new Cont("cont111")); // : lst11_1 @@ -378,10 +378,10 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { assertEquals(1, lst11_2_cont111.getLsts().size()); assertTrue(lst11_2_cont111.getConts().isEmpty()); - assertEquals(new LfLst("lflst1111").addLf((int) 1024).addLf((int) 4096), + assertEquals(new LfLst("lflst1111").addLf(1024).addLf(4096), lst11_2_cont111.getLfLsts().get("lflst1111")); assertEquals( - new Lst("lst1111").addLstItem(new LstItem().addLf("lf1111B", (int) 4)).addLstItem( + new Lst("lst1111").addLstItem(new LstItem().addLf("lf1111B", 4)).addLstItem( new LstItem().addLf("lf1111A", "lf1111A str12")), lst11_2_cont111.getLsts().get("lst1111")); // :-cont111 assertEquals(lst11_2.getLsts().get("lst112"), new Lst("lst112").addLstItem(new LstItem())); @@ -407,7 +407,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { } - private void checkDataFromJson(Cont dataFromJson) { + private void checkDataFromJson(final Cont dataFromJson) { assertNotNull(dataFromJson.getLfs().get("lf11")); assertEquals(dataFromJson.getLfs().get("lf11"), new Lf("lf11", "lf")); @@ -450,7 +450,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { checkLst11_2(lst11_2); } - private void checkLst11_2(LstItem lst11_2) { + private void checkLst11_2(final LstItem lst11_2) { assertNotNull(lst11_2); assertEquals(2, lst11_2.getLfs().size()); assertEquals(1, lst11_2.getConts().size()); @@ -479,7 +479,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { new LstItem().addLf(new Lf("lf1121", "lf1121 str21"))); } - private void checkLst11_1(LstItem lst11_1) { + private void checkLst11_1(final LstItem lst11_1) { assertNotNull(lst11_1); assertEquals(2, lst11_1.getLfs().size()); @@ -507,7 +507,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { checkLst11x(lst11_1.getLsts().get("lst112"), new LstItem().addLf(new Lf("lf1121", "lf1121 str11"))); } - private void checkLst11x(Lst lst, LstItem... lstItems) { + private void checkLst11x(final Lst lst, final LstItem... lstItems) { assertNotNull(lst); Lst requiredLst = new Lst(lst.getName()); @@ -519,7 +519,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { } - private void checkLst1111(Set lstItems, Lf lf11, Lf lf12, Lf lf21, Lf lf22) { + private void checkLst1111(final Set lstItems, final Lf lf11, final Lf lf12, final Lf lf21, final Lf lf22) { LstItem lst11_1_cont_lst1111_1 = null; LstItem lst11_1_cont_lst1111_2 = null; for (LstItem lstItem : lstItems) { @@ -541,49 +541,49 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { // lst11_1 MutableCompositeNode lst11_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst11","simple:yang:types","2013-11-5"), cont1, null, ModifyAction.CREATE, null); - cont1.getChildren().add(lst11_1); + cont1.getValue().add(lst11_1); MutableSimpleNode lf111_1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111","simple:yang:types","2013-11-5"), lst11_1, (short) 1, ModifyAction.CREATE, null); - lst11_1.getChildren().add(lf111_1); + lst11_1.getValue().add(lf111_1); // lst111_1_1 MutableCompositeNode lst111_1_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst111","simple:yang:types","2013-11-5"), lst11_1, null, ModifyAction.CREATE, null); - lst11_1.getChildren().add(lst111_1_1); + lst11_1.getValue().add(lst111_1_1); MutableSimpleNode lf1111_1_1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111","simple:yang:types","2013-11-5"), - lst111_1_1, (int) 34, ModifyAction.CREATE, null); - lst111_1_1.getChildren().add(lf1111_1_1); + lst111_1_1, 34, ModifyAction.CREATE, null); + lst111_1_1.getValue().add(lf1111_1_1); lst111_1_1.init(); // :lst111_1_1 // lst111_1_2 MutableCompositeNode lst111_1_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst111","simple:yang:types","2013-11-5"), lst11_1, null, ModifyAction.CREATE, null); - lst11_1.getChildren().add(lst111_1_2); + lst11_1.getValue().add(lst111_1_2); MutableSimpleNode lf1111_1_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111","simple:yang:types","2013-11-5"), - lst111_1_2, (int) 35, ModifyAction.CREATE, null); - lst111_1_2.getChildren().add(lf1111_1_2); + lst111_1_2, 35, ModifyAction.CREATE, null); + lst111_1_2.getValue().add(lf1111_1_2); lst111_1_2.init(); // :lst111_1_2 // lst111_1_3 MutableCompositeNode lst111_1_3 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst111","simple:yang:types","2013-11-5"), lst11_1, null, ModifyAction.CREATE, null); - lst11_1.getChildren().add(lst111_1_3); + lst11_1.getValue().add(lst111_1_3); lst111_1_2.init(); // :lst111_1_3 // lst111_1_4 MutableCompositeNode lst111_1_4 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst111","simple:yang:types","2013-11-5"), lst11_1, null, ModifyAction.CREATE, null); - lst11_1.getChildren().add(lst111_1_4); + lst11_1.getValue().add(lst111_1_4); lst111_1_2.init(); // :lst111_1_4 MutableCompositeNode cont111_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont111","simple:yang:types","2013-11-5"), lst11_1, null, ModifyAction.CREATE, null); - lst11_1.getChildren().add(cont111_1); + lst11_1.getValue().add(cont111_1); lst11_1.init(); // :lst11_1 @@ -591,39 +591,39 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { // lst11_2 MutableCompositeNode lst11_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst11","simple:yang:types","2013-11-5"), cont1, null, ModifyAction.CREATE, null); - cont1.getChildren().add(lst11_2); + cont1.getValue().add(lst11_2); MutableSimpleNode lf111_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111","simple:yang:types","2013-11-5"), lst11_2, (short) 2, ModifyAction.CREATE, null); - lst11_2.getChildren().add(lf111_2); + lst11_2.getValue().add(lf111_2); // cont111_2 MutableCompositeNode cont111_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont111","simple:yang:types","2013-11-5"), lst11_2, null, ModifyAction.CREATE, null); - lst11_2.getChildren().add(cont111_2); + lst11_2.getValue().add(cont111_2); MutableSimpleNode lflst1111_2_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lflst1111","simple:yang:types","2013-11-5"), - cont111_2, (int) 1024, ModifyAction.CREATE, null); - cont111_2.getChildren().add(lflst1111_2_2); + cont111_2, 1024, ModifyAction.CREATE, null); + cont111_2.getValue().add(lflst1111_2_2); MutableSimpleNode lflst1111_2_3 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lflst1111","simple:yang:types","2013-11-5"), - cont111_2, (int) 4096, ModifyAction.CREATE, null); - cont111_2.getChildren().add(lflst1111_2_3); + cont111_2, 4096, ModifyAction.CREATE, null); + cont111_2.getValue().add(lflst1111_2_3); // lst1111_2 MutableCompositeNode lst1111_2_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst1111","simple:yang:types","2013-11-5"), cont111_2, null, ModifyAction.CREATE, null); - cont111_2.getChildren().add(lst1111_2_1); + cont111_2.getValue().add(lst1111_2_1); MutableSimpleNode lf1111B_2_1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111B","simple:yang:types","2013-11-5"), lst1111_2_1, (short) 4, ModifyAction.CREATE, null); - lst1111_2_1.getChildren().add(lf1111B_2_1); + lst1111_2_1.getValue().add(lf1111B_2_1); lst1111_2_1.init(); MutableCompositeNode lst1111_2_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst1111","simple:yang:types","2013-11-5"), cont111_2, null, ModifyAction.CREATE, null); - cont111_2.getChildren().add(lst1111_2_2); + cont111_2.getValue().add(lst1111_2_2); MutableSimpleNode lf1111A_2_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111A","simple:yang:types","2013-11-5"), lst1111_2_2, "lf1111A str12", ModifyAction.CREATE, null); - lst1111_2_2.getChildren().add(lf1111A_2_2); + lst1111_2_2.getValue().add(lf1111A_2_2); lst1111_2_2.init(); // :lst1111_2 @@ -632,7 +632,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { MutableCompositeNode lst112_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst112","simple:yang:types","2013-11-5"), lst11_2, null, ModifyAction.CREATE, null); - lst11_2.getChildren().add(lst112_2); + lst11_2.getValue().add(lst112_2); lst112_2.init(); lst11_2.init(); @@ -641,25 +641,25 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { // lst11_3 MutableCompositeNode lst11_3 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst11","simple:yang:types","2013-11-5"), cont1, null, ModifyAction.CREATE, null); - cont1.getChildren().add(lst11_3); + cont1.getValue().add(lst11_3); MutableSimpleNode lf111_3 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111","simple:yang:types","2013-11-5"), lst11_3, (short) 3, ModifyAction.CREATE, null); - lst11_3.getChildren().add(lf111_3); + lst11_3.getValue().add(lf111_3); // cont111_3 MutableCompositeNode cont111_3 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont111","simple:yang:types","2013-11-5"), lst11_3, null, ModifyAction.CREATE, null); - lst11_3.getChildren().add(cont111_3); + lst11_3.getValue().add(cont111_3); MutableCompositeNode lst1111_3_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst1111","simple:yang:types","2013-11-5"), cont111_3, null, ModifyAction.CREATE, null); - cont111_3.getChildren().add(lst1111_3_1); + cont111_3.getValue().add(lst1111_3_1); lst1111_3_1.init(); MutableCompositeNode lst1111_3_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst1111","simple:yang:types","2013-11-5"), cont111_3, null, ModifyAction.CREATE, null); - cont111_3.getChildren().add(lst1111_3_2); + cont111_3.getValue().add(lst1111_3_2); lst1111_3_2.init(); cont111_3.init(); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIdentityrefTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIdentityrefTest.java index 745f11c210..fdd3aa6684 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIdentityrefTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIdentityrefTest.java @@ -73,17 +73,17 @@ public class CnSnToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader { assertTrue(mtch.matches()); } - private CompositeNode prepareCompositeNode(Object value) { + private CompositeNode prepareCompositeNode(final Object value) { MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont","identityref:module","2013-12-2"), null, null, ModifyAction.CREATE, null); MutableCompositeNode cont1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont1","identityref:module","2013-12-2"), cont, null, ModifyAction.CREATE, null); - cont.getChildren().add(cont1); + cont.getValue().add(cont1); MutableSimpleNode lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1","identityref:module","2013-12-2"), cont1, value, ModifyAction.CREATE, null); - cont1.getChildren().add(lf1); + cont1.getValue().add(lf1); cont1.init(); cont.init(); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonNotExistingLeafTypeTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonNotExistingLeafTypeTest.java index dd1502ba79..42e1e3f739 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonNotExistingLeafTypeTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonNotExistingLeafTypeTest.java @@ -27,6 +27,7 @@ import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode; import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode; import org.opendaylight.yangtools.yang.data.impl.NodeFactory; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder; import org.opendaylight.yangtools.yang.parser.builder.impl.LeafSchemaNodeBuilder; import org.slf4j.Logger; @@ -46,7 +47,7 @@ public class CnSnToJsonNotExistingLeafTypeTest extends YangAndXmlAndDataSchemaLo String jsonOutput = null; jsonOutput = TestUtils .writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(), - Collections.EMPTY_SET, prepareDataSchemaNode(), + Collections.emptySet(), prepareDataSchemaNode(), StructuredDataToJsonProvider.INSTANCE); assertNotNull(jsonOutput); assertTrue(jsonOutput.contains("\"lf1\": \"\"")); @@ -57,7 +58,7 @@ public class CnSnToJsonNotExistingLeafTypeTest extends YangAndXmlAndDataSchemaLo TestUtils.buildQName("cont", "simple:uri", "2012-12-17"), null, null, ModifyAction.CREATE, null); MutableSimpleNode lf1 = NodeFactory.createMutableSimpleNode( TestUtils.buildQName("lf1", "simple:uri", "2012-12-17"), cont, "any value", ModifyAction.CREATE, null); - cont.getChildren().add(lf1); + cont.getValue().add(lf1); cont.init(); return cont; } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithDataFromSeveralModulesTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithDataFromSeveralModulesTest.java index 348edbd294..052bb1a2be 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithDataFromSeveralModulesTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithDataFromSeveralModulesTest.java @@ -99,32 +99,32 @@ public class CnSnToJsonWithDataFromSeveralModulesTest extends YangAndXmlAndDataS MutableCompositeNode cont_m1 = NodeFactory.createMutableCompositeNode( TestUtils.buildQName("cont_m1", uri1, rev1), data, null, null, null); - data.getChildren().add(cont_m1); + data.getValue().add(cont_m1); MutableSimpleNode lf1_m1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1_m1", uri1, rev1), cont_m1, "lf1 m1 value", null, null); - cont_m1.getChildren().add(lf1_m1); + cont_m1.getValue().add(lf1_m1); cont_m1.init(); MutableCompositeNode contB_m1 = NodeFactory.createMutableCompositeNode( TestUtils.buildQName("contB_m1", uri1, rev1), data, null, null, null); - data.getChildren().add(contB_m1); + data.getValue().add(contB_m1); contB_m1.init(); String uri2 = "module:two"; String rev2 = "2014-01-17"; MutableCompositeNode cont_m2 = NodeFactory.createMutableCompositeNode( TestUtils.buildQName("cont_m2", uri2, rev2), data, null, null, null); - data.getChildren().add(cont_m2); + data.getValue().add(cont_m2); MutableSimpleNode lf1_m2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1_m2", uri2, rev2), cont_m1, "lf1 m2 value", null, null); - cont_m2.getChildren().add(lf1_m2); + cont_m2.getValue().add(lf1_m2); cont_m2.init(); MutableCompositeNode contB_m2 = NodeFactory.createMutableCompositeNode( TestUtils.buildQName("contB_m2", uri2, rev2), data, null, null, null); - data.getChildren().add(contB_m2); + data.getValue().add(contB_m2); contB_m2.init(); data.init(); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlNotExistingLeafTypeTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlNotExistingLeafTypeTest.java index f81c1d63f5..2ada6e13e9 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlNotExistingLeafTypeTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlNotExistingLeafTypeTest.java @@ -25,6 +25,7 @@ import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode; import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode; import org.opendaylight.yangtools.yang.data.impl.NodeFactory; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder; import org.opendaylight.yangtools.yang.parser.builder.impl.LeafSchemaNodeBuilder; import org.slf4j.Logger; @@ -41,7 +42,7 @@ public class CnSnToXmlNotExistingLeafTypeTest { boolean nullPointerExceptionRaised = false; try { TestUtils.writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(), - Collections.EMPTY_SET, prepareDataSchemaNode(), StructuredDataToXmlProvider.INSTANCE); + Collections.emptySet(), prepareDataSchemaNode(), StructuredDataToXmlProvider.INSTANCE); } catch (WebApplicationException | IOException e) { LOG.error("WebApplicationException or IOException was raised"); } catch (NullPointerException e) { @@ -56,7 +57,7 @@ public class CnSnToXmlNotExistingLeafTypeTest { TestUtils.buildQName("cont", "simple:uri", "2012-12-17"), null, null, ModifyAction.CREATE, null); MutableSimpleNode lf1 = NodeFactory.createMutableSimpleNode( TestUtils.buildQName("lf1", "simple:uri", "2012-12-17"), cont, "any value", ModifyAction.CREATE, null); - cont.getChildren().add(lf1); + cont.getValue().add(lf1); cont.init(); return cont; } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlTest.java index 6b4b153252..fc54795fcc 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlTest.java @@ -28,11 +28,11 @@ import org.opendaylight.yangtools.yang.data.impl.NodeFactory; import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec; /** - * + * * CnSn = Composite node and Simple node data structure Class contains test of * serializing simple nodes data values according data types from YANG schema to * XML file - * + * */ public class CnSnToXmlTest extends YangAndXmlAndDataSchemaLoader { @BeforeClass @@ -139,9 +139,9 @@ public class CnSnToXmlTest extends YangAndXmlAndDataSchemaLoader { serializeToXml( prepareCnStructForYangData( TypeDefinitionAwareCodec.BINARY_DEFAULT_CODEC - .deserialize("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567"), + .deserialize("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567"), elName), "<" + elName + ">ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567"); + + elName + ">"); } @Test @@ -198,7 +198,7 @@ public class CnSnToXmlTest extends YangAndXmlAndDataSchemaLoader { + elName + ">str"); } - private void serializeToXml(CompositeNode compositeNode, String... xmlRepresentation) + private void serializeToXml(final CompositeNode compositeNode, final String... xmlRepresentation) throws TransformerFactoryConfigurationError { String xmlString = ""; try { @@ -220,12 +220,12 @@ public class CnSnToXmlTest extends YangAndXmlAndDataSchemaLoader { } - private CompositeNode prepareIdentityrefData(String prefix, boolean valueAsQName) { + private CompositeNode prepareIdentityrefData(final String prefix, final boolean valueAsQName) { MutableCompositeNode cont = NodeFactory.createMutableCompositeNode( TestUtils.buildQName("cont", "basic:module", "2013-12-2"), null, null, ModifyAction.CREATE, null); MutableCompositeNode cont1 = NodeFactory.createMutableCompositeNode( TestUtils.buildQName("cont1", "basic:module", "2013-12-2"), cont, null, ModifyAction.CREATE, null); - cont.getChildren().add(cont1); + cont.getValue().add(cont1); Object value = null; if (valueAsQName) { @@ -235,20 +235,20 @@ public class CnSnToXmlTest extends YangAndXmlAndDataSchemaLoader { } MutableSimpleNode lf11 = NodeFactory.createMutableSimpleNode( TestUtils.buildQName("lf11", "basic:module", "2013-12-2"), cont1, value, ModifyAction.CREATE, null); - cont1.getChildren().add(lf11); + cont1.getValue().add(lf11); cont1.init(); cont.init(); return cont; } - private CompositeNode prepareCnStructForYangData(Object data, String leafName) { + private CompositeNode prepareCnStructForYangData(final Object data, final String leafName) { MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null, ModifyAction.CREATE, null); MutableSimpleNode lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName(leafName), cont, data, ModifyAction.CREATE, null); - cont.getChildren().add(lf1); + cont.getValue().add(lf1); cont.init(); return cont; @@ -262,8 +262,8 @@ public class CnSnToXmlTest extends YangAndXmlAndDataSchemaLoader { cont, Boolean.TRUE, ModifyAction.CREATE, null); MutableSimpleNode lfLfref = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfLfref"), cont, "true", ModifyAction.CREATE, null); - cont.getChildren().add(lfBoolean); - cont.getChildren().add(lfLfref); + cont.getValue().add(lfBoolean); + cont.getValue().add(lfLfref); cont.init(); return cont; diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithChoiceTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithChoiceTest.java index a3e33ce30b..ac7fe20818 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithChoiceTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithChoiceTest.java @@ -18,15 +18,18 @@ import org.junit.Test; import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider; import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; -import org.opendaylight.yangtools.yang.data.api.*; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.ModifyAction; +import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode; +import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode; import org.opendaylight.yangtools.yang.data.impl.NodeFactory; /** - * + * * CnSn = Composite node and Simple node data structure Class contains test of * serializing simple nodes data values according data types from YANG schema to * XML file - * + * */ public class CnSnToXmlWithChoiceTest extends YangAndXmlAndDataSchemaLoader { @BeforeClass @@ -56,13 +59,13 @@ public class CnSnToXmlWithChoiceTest extends YangAndXmlAndDataSchemaLoader { } - private CompositeNode prepareCnStructForYangData(String lfName, Object data) { + private CompositeNode prepareCnStructForYangData(final String lfName, final Object data) { MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null, ModifyAction.CREATE, null); MutableSimpleNode lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName(lfName), cont, data, ModifyAction.CREATE, null); - cont.getChildren().add(lf1); + cont.getValue().add(lf1); cont.init(); return cont; diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonIdentityrefToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonIdentityrefToCnSnTest.java index 9e726baf55..0c9e95173f 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonIdentityrefToCnSnTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonIdentityrefToCnSnTest.java @@ -7,7 +7,9 @@ */ package org.opendaylight.controller.sal.restconf.impl.json.to.cnsn.test; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import java.util.List; @@ -17,7 +19,9 @@ import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider; import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.data.api.*; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.Node; +import org.opendaylight.yangtools.yang.data.api.SimpleNode; public class JsonIdentityrefToCnSnTest extends YangAndXmlAndDataSchemaLoader { @@ -36,13 +40,13 @@ public class JsonIdentityrefToCnSnTest extends YangAndXmlAndDataSchemaLoader { assertEquals("cont", compositeNode.getNodeType().getLocalName()); - List> childs = compositeNode.getChildren(); + List> childs = compositeNode.getValue(); assertEquals(1, childs.size()); Node nd = childs.iterator().next(); assertTrue(nd instanceof CompositeNode); assertEquals("cont1", nd.getNodeType().getLocalName()); - childs = ((CompositeNode) nd).getChildren(); + childs = ((CompositeNode) nd).getValue(); assertEquals(4, childs.size()); SimpleNode lf11 = null; SimpleNode lf12 = null; diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonLeafrefToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonLeafrefToCnSnTest.java index 2030d9125a..79dd026fd0 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonLeafrefToCnSnTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonLeafrefToCnSnTest.java @@ -7,14 +7,18 @@ */ package org.opendaylight.controller.sal.restconf.impl.json.to.cnsn.test; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import org.junit.BeforeClass; import org.junit.Test; import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider; import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; -import org.opendaylight.yangtools.yang.data.api.*; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.Node; +import org.opendaylight.yangtools.yang.data.api.SimpleNode; public class JsonLeafrefToCnSnTest extends YangAndXmlAndDataSchemaLoader { @@ -37,7 +41,7 @@ public class JsonLeafrefToCnSnTest extends YangAndXmlAndDataSchemaLoader { assertEquals("cont", compositeNode.getNodeType().getLocalName()); SimpleNode lf2 = null; - for (Node childNode : compositeNode.getChildren()) { + for (Node childNode : compositeNode.getValue()) { if (childNode instanceof SimpleNode) { if (childNode.getNodeType().getLocalName().equals("lf2")) { lf2 = (SimpleNode) childNode; @@ -48,7 +52,7 @@ public class JsonLeafrefToCnSnTest extends YangAndXmlAndDataSchemaLoader { assertNotNull(lf2); assertTrue(lf2.getValue() instanceof String); - assertEquals("121", (String) lf2.getValue()); + assertEquals("121", lf2.getValue()); } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonToCnSnTest.java index 8b1dc3475f..415d58e53d 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonToCnSnTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonToCnSnTest.java @@ -58,13 +58,13 @@ public class JsonToCnSnTest { CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/multiple-leaflist-items.json", true, JsonToCompositeNodeProvider.INSTANCE); assertNotNull(compositeNode); - assertEquals(3, compositeNode.getChildren().size()); + assertEquals(3, compositeNode.getValue().size()); boolean lflst1_1 = false; boolean lflst1_2 = false; boolean lflst1_3 = false; - for (Node node : compositeNode.getChildren()) { + for (Node node : compositeNode.getValue()) { assertEquals("lflst1", node.getNodeType().getLocalName()); assertTrue(node instanceof SimpleNode); SimpleNode simpleNode = (SimpleNode) node; @@ -105,9 +105,9 @@ public class JsonToCnSnTest { assertNotNull(compositeNode); assertEquals("cont", compositeNode.getNodeType().getLocalName()); - assertNotNull(compositeNode.getChildren()); - assertEquals(1, compositeNode.getChildren().size()); - Node lfNode = compositeNode.getChildren().iterator().next(); + assertNotNull(compositeNode.getValue()); + assertEquals(1, compositeNode.getValue().size()); + Node lfNode = compositeNode.getValue().iterator().next(); assertTrue(lfNode instanceof SimpleNode); assertEquals(null, ((SimpleNode) lfNode).getValue()); @@ -119,7 +119,7 @@ public class JsonToCnSnTest { Throwable cause1 = null; try { TestUtils - .readInputToCnSn("/json-to-cnsn/wrong-top-level1.json", true, JsonToCompositeNodeProvider.INSTANCE); + .readInputToCnSn("/json-to-cnsn/wrong-top-level1.json", true, JsonToCompositeNodeProvider.INSTANCE); } catch (WebApplicationException e) { cause1 = e; } @@ -134,7 +134,7 @@ public class JsonToCnSnTest { Throwable cause2 = null; try { TestUtils - .readInputToCnSn("/json-to-cnsn/wrong-top-level2.json", true, JsonToCompositeNodeProvider.INSTANCE); + .readInputToCnSn("/json-to-cnsn/wrong-top-level2.json", true, JsonToCompositeNodeProvider.INSTANCE); } catch (WebApplicationException e) { cause2 = e; } @@ -144,7 +144,7 @@ public class JsonToCnSnTest { Throwable cause3 = null; try { TestUtils - .readInputToCnSn("/json-to-cnsn/wrong-top-level3.json", true, JsonToCompositeNodeProvider.INSTANCE); + .readInputToCnSn("/json-to-cnsn/wrong-top-level3.json", true, JsonToCompositeNodeProvider.INSTANCE); } catch (WebApplicationException e) { cause3 = e; } @@ -170,7 +170,7 @@ public class JsonToCnSnTest { assertEquals("cont", compositeNode.getNodeType().getLocalName()); assertTrue(compositeNode instanceof CompositeNode); - List> children = ((CompositeNode) compositeNode).getChildren(); + List> children = compositeNode.getValue(); assertEquals(1, children.size()); assertEquals("lflst2", children.get(0).getNodeType().getLocalName()); assertEquals("45", children.get(0).getValue()); @@ -190,7 +190,7 @@ public class JsonToCnSnTest { * Tests whether namespace stay unchanged if concrete values are * present in composite or simple node and if the method for update is * called. - * + * */ @Test public void notSupplyNamespaceIfAlreadySupplied() { @@ -233,13 +233,13 @@ public class JsonToCnSnTest { assertEquals("cont", compositeNode.getNodeType().getLocalName()); - List> childs = compositeNode.getChildren(); + List> childs = compositeNode.getValue(); assertEquals(1, childs.size()); Node nd = childs.iterator().next(); assertTrue(nd instanceof CompositeNode); assertEquals("cont1", nd.getNodeType().getLocalName()); - childs = ((CompositeNode) nd).getChildren(); + childs = ((CompositeNode) nd).getValue(); assertEquals(4, childs.size()); SimpleNode lf11 = null; SimpleNode lf12 = null; @@ -274,7 +274,7 @@ public class JsonToCnSnTest { assertEquals("iden_local", ((QName) lf14.getValue()).getLocalName()); assertEquals("identity:module", ((QName) lf14.getValue()).getNamespace().toString()); } - + @Ignore @Test public void loadDataAugmentedSchemaMoreEqualNamesTest() { @@ -285,17 +285,17 @@ public class JsonToCnSnTest { } catch (ResponseException e) { exceptionCaught = true; } - + assertFalse(exceptionCaught); } - private void simpleTest(String jsonPath, String yangPath, String topLevelElementName, String namespace, - String moduleName) { + private void simpleTest(final String jsonPath, final String yangPath, final String topLevelElementName, final String namespace, + final String moduleName) { CompositeNode compNode = loadAndNormalizeData(jsonPath, yangPath, topLevelElementName, moduleName); verifyCompositeNode(compNode, namespace); } - private CompositeNode loadAndNormalizeData(String jsonPath, String yangPath, String topLevelElementName, String moduleName) { + private CompositeNode loadAndNormalizeData(final String jsonPath, final String yangPath, final String topLevelElementName, final String moduleName) { CompositeNode compositeNode = TestUtils.readInputToCnSn(jsonPath, false, JsonToCompositeNodeProvider.INSTANCE); assertNotNull(compositeNode); @@ -312,8 +312,8 @@ public class JsonToCnSnTest { return compNode; } - private void verityMultipleItemsInList(CompositeNode compositeNode) { - List> childrenNodes = compositeNode.getChildren(); + private void verityMultipleItemsInList(final CompositeNode compositeNode) { + List> childrenNodes = compositeNode.getValue(); assertEquals(4, childrenNodes.size()); boolean lf11Found = false; boolean cont11Found = false; @@ -322,7 +322,7 @@ public class JsonToCnSnTest { assertEquals("lst1", lst1Item.getNodeType().getLocalName()); assertTrue(lst1Item instanceof CompositeNode); - List> childrenLst1 = ((CompositeNode) lst1Item).getChildren(); + List> childrenLst1 = ((CompositeNode) lst1Item).getValue(); assertEquals(1, childrenLst1.size()); String localName = childrenLst1.get(0).getNodeType().getLocalName(); if (localName.equals("lf11")) { @@ -338,7 +338,7 @@ public class JsonToCnSnTest { } else if (localName.equals("lst11")) { lst11Found = true; assertTrue(childrenLst1.get(0) instanceof CompositeNode); - assertEquals(0, ((CompositeNode) childrenLst1.get(0)).getChildren().size()); + assertEquals(0, ((CompositeNode) childrenLst1.get(0)).getValue().size()); } } @@ -347,7 +347,7 @@ public class JsonToCnSnTest { assertTrue(lst11Found); } - private void verifyCompositeNode(CompositeNode compositeNode, String namespace) { + private void verifyCompositeNode(final CompositeNode compositeNode, final String namespace) { boolean cont1Found = false; boolean lst1Found = false; boolean lflst1_1Found = false; @@ -357,16 +357,16 @@ public class JsonToCnSnTest { // assertEquals(namespace, // compositeNode.getNodeType().getNamespace().toString()); - for (Node node : compositeNode.getChildren()) { + for (Node node : compositeNode.getValue()) { if (node.getNodeType().getLocalName().equals("cont1")) { if (node instanceof CompositeNode) { cont1Found = true; - assertEquals(0, ((CompositeNode) node).getChildren().size()); + assertEquals(0, ((CompositeNode) node).getValue().size()); } } else if (node.getNodeType().getLocalName().equals("lst1")) { if (node instanceof CompositeNode) { lst1Found = true; - assertEquals(0, ((CompositeNode) node).getChildren().size()); + assertEquals(0, ((CompositeNode) node).getValue().size()); } } else if (node.getNodeType().getLocalName().equals("lflst1")) { if (node instanceof SimpleNode) { diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/CnSnToXmlAndJsonInstanceIdentifierTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/CnSnToXmlAndJsonInstanceIdentifierTest.java index 0492b3efd4..07d781028b 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/CnSnToXmlAndJsonInstanceIdentifierTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/CnSnToXmlAndJsonInstanceIdentifierTest.java @@ -64,7 +64,7 @@ public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSch @Ignore @Test public void saveCnSnWithLeafListInstIdentifierToXmlTest() throws WebApplicationException, IOException, - URISyntaxException, XMLStreamException { + URISyntaxException, XMLStreamException { CompositeNode cnSn = prepareCnSn(createInstanceIdentifierWithLeafList()); String output = TestUtils.writeCompNodeWithSchemaContextToOutput(cnSn, modules, dataSchemaNode, StructuredDataToXmlProvider.INSTANCE); @@ -94,7 +94,7 @@ public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSch @Test public void saveCnSnWithLeafListInstIdentifierToJsonTest() throws WebApplicationException, IOException, - URISyntaxException { + URISyntaxException { CompositeNode cnSn = prepareCnSn(createInstanceIdentifierWithLeafList()); String output = TestUtils.writeCompNodeWithSchemaContextToOutput(cnSn, modules, dataSchemaNode, StructuredDataToJsonProvider.INSTANCE); @@ -111,7 +111,7 @@ public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSch assertTrue(strInOutput); } - private void validateXmlOutput(String xml) throws XMLStreamException { + private void validateXmlOutput(final String xml) throws XMLStreamException { XMLInputFactory xmlInFactory = XMLInputFactory.newInstance(); XMLEventReader eventReader; @@ -152,7 +152,7 @@ public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSch } - private void validateXmlOutputWithLeafList(String xml) throws XMLStreamException { + private void validateXmlOutputWithLeafList(final String xml) throws XMLStreamException { XMLInputFactory xmlInFactory = XMLInputFactory.newInstance(); XMLEventReader eventReader; @@ -188,7 +188,7 @@ public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSch } - private CompositeNode prepareCnSn(InstanceIdentifier instanceIdentifier) throws URISyntaxException { + private CompositeNode prepareCnSn(final InstanceIdentifier instanceIdentifier) throws URISyntaxException { MutableCompositeNode cont = NodeFactory.createMutableCompositeNode( TestUtils.buildQName("cont", "instance:identifier:module", "2014-01-17"), null, null,null,null); MutableCompositeNode cont1 = NodeFactory.createMutableCompositeNode( @@ -200,13 +200,13 @@ public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSch lst11, instanceIdentifier,null,null); - lst11.getChildren().add(lf111); + lst11.getValue().add(lf111); lst11.init(); - cont1.getChildren().add(lst11); + cont1.getValue().add(lst11); cont1.init(); - cont.getChildren().add(cont1); + cont.getValue().add(cont1); cont.init(); return cont; diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java index b42178a9c6..018a235718 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java @@ -63,7 +63,7 @@ public class InvokeRpcMethodTest { private class AnswerImpl implements Answer> { @Override - public RpcResult answer(InvocationOnMock invocation) throws Throwable { + public RpcResult answer(final InvocationOnMock invocation) throws Throwable { CompositeNode compNode = (CompositeNode) invocation.getArguments()[1]; return new DummyRpcResult.Builder().result(compNode).isSuccessful(true).build(); } @@ -123,7 +123,7 @@ public class InvokeRpcMethodTest { TestUtils.buildQName("cont", "nmspc", "2013-12-04"), null, null, ModifyAction.CREATE, null); MutableSimpleNode lf = NodeFactory.createMutableSimpleNode( TestUtils.buildQName("lf", "nmspc", "2013-12-04"), cont, "any value", ModifyAction.CREATE, null); - cont.getChildren().add(lf); + cont.getValue().add(lf); cont.init(); return cont; @@ -150,7 +150,7 @@ public class InvokeRpcMethodTest { } catch (ResponseException e) { assertEquals(e.getMessage(), Status.INTERNAL_SERVER_ERROR.getStatusCode(), e - .getResponse().getStatus()); + .getResponse().getStatus()); } } @@ -216,7 +216,7 @@ public class InvokeRpcMethodTest { } catch (ResponseException e) { assertEquals(e.getMessage(), Status.UNSUPPORTED_MEDIA_TYPE.getStatusCode(), e - .getResponse().getStatus()); + .getResponse().getStatus()); } } @@ -273,8 +273,8 @@ public class InvokeRpcMethodTest { BrokerFacade brokerFacade = mock(BrokerFacade.class); when( brokerFacade.invokeRpc( - eq(QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)testOutput")), - any( CompositeNode.class ))).thenReturn(rpcResult); + eq(QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)testOutput")), + any( CompositeNode.class ))).thenReturn(rpcResult); restconfImpl.setBroker(brokerFacade); @@ -301,7 +301,7 @@ public class InvokeRpcMethodTest { MountInstance mockMountPoint = mock( MountInstance.class ); when( mockMountPoint.rpc( eq( cancelToastQName ), any( CompositeNode.class ) ) ) - .thenReturn( mockListener ); + .thenReturn( mockListener ); InstanceIdWithSchemaNode mockedInstanceId = mock( InstanceIdWithSchemaNode.class ); when( mockedInstanceId.getMountPoint() ).thenReturn( mockMountPoint ); @@ -315,8 +315,8 @@ public class InvokeRpcMethodTest { restconfImpl.setControllerContext( mockedContext ); StructuredData output = restconfImpl.invokeRpc( - "opendaylight-inventory:nodes/node/REMOTE_HOST/yang-ext:mount/toaster:cancel-toast", - ""); + "opendaylight-inventory:nodes/node/REMOTE_HOST/yang-ext:mount/toaster:cancel-toast", + ""); assertEquals(null, output); //additional validation in the fact that the restconfImpl does not throw an exception. diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlLeafrefToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlLeafrefToCnSnTest.java index 7a949b8f2d..e5b0bf507d 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlLeafrefToCnSnTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlLeafrefToCnSnTest.java @@ -50,13 +50,13 @@ public class XmlLeafrefToCnSnTest { verifyCommonPartAOfXml(compNode, "", nameSpace); } - private void verifyNullAndEmptyStringSingleNode(CompositeNode compNode, String nameSpace) { + private void verifyNullAndEmptyStringSingleNode(final CompositeNode compNode, final String nameSpace) { assertEquals("cont", compNode.getNodeType().getLocalName()); SimpleNode lf2 = null; SimpleNode lf3 = null; int found = 0; - for (Node child : compNode.getChildren()) { + for (Node child : compNode.getValue()) { if (found == 0x3) break; if (child instanceof SimpleNode) { @@ -91,11 +91,11 @@ public class XmlLeafrefToCnSnTest { String nameSpaceCont = "data:container:yang"; assertEquals(nameSpaceCont, compNode.getNodeType().getNamespace().toString()); assertEquals("cont", compNode.getNodeType().getLocalName()); - assertEquals(3, compNode.getChildren().size()); + assertEquals(3, compNode.getValue().size()); CompositeNode lst1_1 = null; CompositeNode lst1_2 = null; int loopCount = 0; - for (Node node : compNode.getChildren()) { + for (Node node : compNode.getValue()) { if (node.getNodeType().getLocalName().equals("lf1")) { assertEquals(nameSpaceList, node.getNodeType().getNamespace().toString()); assertTrue(node instanceof SimpleNode); @@ -120,7 +120,7 @@ public class XmlLeafrefToCnSnTest { // lst1_2 SimpleNode lflst11 = null; CompositeNode cont11 = null; - for (Node node : lst1_2.getChildren()) { + for (Node node : lst1_2.getValue()) { String nodeName = node.getNodeType().getLocalName(); if (nodeName.equals("lflst11")) { assertTrue(node instanceof SimpleNode); @@ -134,9 +134,9 @@ public class XmlLeafrefToCnSnTest { } assertEquals("221", lflst11.getValue()); - assertEquals(1, cont11.getChildren().size()); - assertTrue(cont11.getChildren().get(0) instanceof SimpleNode); - SimpleNode cont11_lf111 = (SimpleNode) cont11.getChildren().get(0); + assertEquals(1, cont11.getValue().size()); + assertTrue(cont11.getValue().get(0) instanceof SimpleNode); + SimpleNode cont11_lf111 = (SimpleNode) cont11.getValue().get(0); assertEquals(nameSpaceCont, cont11_lf111.getNodeType().getNamespace().toString()); assertEquals("lf111", cont11_lf111.getNodeType().getLocalName()); assertEquals((short) 100, cont11_lf111.getValue()); @@ -154,7 +154,7 @@ public class XmlLeafrefToCnSnTest { SimpleNode lflst1_2 = null; CompositeNode lst1 = null; int lflst1Count = 0; - for (Node node : compNode.getChildren()) { + for (Node node : compNode.getValue()) { if (node.getNodeType().getLocalName().equals("lf1")) { assertTrue(node instanceof SimpleNode); lf1 = (SimpleNode) node; @@ -183,11 +183,11 @@ public class XmlLeafrefToCnSnTest { assertEquals("", lf1.getValue()); assertEquals("", lflst1_1.getValue()); assertEquals("", lflst1_2.getValue()); - assertEquals(1, lst1.getChildren().size()); - assertEquals("lf11", lst1.getChildren().get(0).getNodeType().getLocalName()); + assertEquals(1, lst1.getValue().size()); + assertEquals("lf11", lst1.getValue().get(0).getNodeType().getLocalName()); - assertTrue(lst1.getChildren().get(0) instanceof SimpleNode); - assertEquals("", lst1.getChildren().get(0).getValue()); + assertTrue(lst1.getValue().get(0) instanceof SimpleNode); + assertEquals("", lst1.getValue().get(0).getValue()); } @@ -201,7 +201,7 @@ public class XmlLeafrefToCnSnTest { } /** - * + * * Test case like identity */ @@ -213,7 +213,7 @@ public class XmlLeafrefToCnSnTest { } /** - * + * * Test case like identity */ @@ -224,7 +224,7 @@ public class XmlLeafrefToCnSnTest { } /** - * + * * Test case like * x:identity */ @@ -236,7 +236,7 @@ public class XmlLeafrefToCnSnTest { } /** - * + * * Test case like (without namespace in xml) x:identity * */ @@ -247,7 +247,7 @@ public class XmlLeafrefToCnSnTest { } /** - * + * * Test case like (without namespace in xml) identity * */ @@ -257,7 +257,7 @@ public class XmlLeafrefToCnSnTest { "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "identityref:module"); } - private void verifyCommonPartAOfXml(CompositeNode compNode, String suf, String nameSpace) { + private void verifyCommonPartAOfXml(final CompositeNode compNode, final String suf, final String nameSpace) { SimpleNode lf1suf = null; SimpleNode lflst1suf_1 = null; SimpleNode lflst1suf_2 = null; @@ -267,7 +267,7 @@ public class XmlLeafrefToCnSnTest { int lflstCount = 0; - for (Node node : compNode.getChildren()) { + for (Node node : compNode.getValue()) { String localName = node.getNodeType().getLocalName(); if (localName.equals("lf1" + suf)) { assertTrue(node instanceof SimpleNode); @@ -307,23 +307,23 @@ public class XmlLeafrefToCnSnTest { assertEquals("131", lflst1suf_2.getValue()); assertEquals("str1", lflst1suf_3.getValue()); - assertEquals(1, lst1suf.getChildren().size()); + assertEquals(1, lst1suf.getValue().size()); - assertTrue(lst1suf.getChildren().get(0) instanceof SimpleNode); - SimpleNode lst11_lf11 = (SimpleNode) lst1suf.getChildren().get(0); + assertTrue(lst1suf.getValue().get(0) instanceof SimpleNode); + SimpleNode lst11_lf11 = (SimpleNode) lst1suf.getValue().get(0); assertEquals(nameSpace, lst11_lf11.getNodeType().getNamespace().toString()); assertEquals("lf11" + suf, lst11_lf11.getNodeType().getLocalName()); assertEquals("str2", lst11_lf11.getValue()); - assertTrue(cont1suf.getChildren().get(0) instanceof SimpleNode); - SimpleNode cont1_lf11 = (SimpleNode) cont1suf.getChildren().get(0); + assertTrue(cont1suf.getValue().get(0) instanceof SimpleNode); + SimpleNode cont1_lf11 = (SimpleNode) cont1suf.getValue().get(0); assertEquals(nameSpace, cont1_lf11.getNodeType().getNamespace().toString()); assertEquals("lf11" + suf, cont1_lf11.getNodeType().getLocalName()); assertEquals((short) 100, cont1_lf11.getValue()); } - private void testIdentityrefToCnSn(String xmlPath, String yangPath, String moduleName, String schemaName, - int moduleCount, String resultLocalName, String resultNamespace) { + private void testIdentityrefToCnSn(final String xmlPath, final String yangPath, final String moduleName, final String schemaName, + final int moduleCount, final String resultLocalName, final String resultNamespace) { CompositeNode compositeNode = TestUtils.readInputToCnSn(xmlPath, false, XmlToCompositeNodeProvider.INSTANCE); assertNotNull(compositeNode); @@ -339,16 +339,16 @@ public class XmlLeafrefToCnSnTest { assertEquals(resultNamespace, qName.getNamespace().toString()); } - private SimpleNode getLf11(CompositeNode compositeNode) { + private SimpleNode getLf11(final CompositeNode compositeNode) { assertEquals("cont", compositeNode.getNodeType().getLocalName()); - List> childs = compositeNode.getChildren(); + List> childs = compositeNode.getValue(); assertEquals(1, childs.size()); Node nd = childs.iterator().next(); assertTrue(nd instanceof CompositeNode); assertEquals("cont1", nd.getNodeType().getLocalName()); - childs = ((CompositeNode) nd).getChildren(); + childs = ((CompositeNode) nd).getValue(); SimpleNode lf11 = null; for (Node child : childs) { assertTrue(child instanceof SimpleNode); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlToCnSnTest.java index f1a18d56a8..5008d28bbf 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlToCnSnTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlToCnSnTest.java @@ -7,14 +7,18 @@ */ package org.opendaylight.controller.sal.restconf.impl.xml.to.cnsn.test; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import org.junit.BeforeClass; import org.junit.Test; import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider; import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; -import org.opendaylight.yangtools.yang.data.api.*; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.Node; +import org.opendaylight.yangtools.yang.data.api.SimpleNode; public class XmlToCnSnTest extends YangAndXmlAndDataSchemaLoader { @@ -34,7 +38,7 @@ public class XmlToCnSnTest extends YangAndXmlAndDataSchemaLoader { assertEquals("cont", compositeNode.getNodeType().getLocalName()); SimpleNode lf2 = null; - for (Node childNode : compositeNode.getChildren()) { + for (Node childNode : compositeNode.getValue()) { if (childNode instanceof SimpleNode) { if (childNode.getNodeType().getLocalName().equals("lf2")) { lf2 = (SimpleNode) childNode; @@ -45,7 +49,7 @@ public class XmlToCnSnTest extends YangAndXmlAndDataSchemaLoader { assertNotNull(lf2); assertTrue(lf2.getValue() instanceof String); - assertEquals("121", (String) lf2.getValue()); + assertEquals("121", lf2.getValue()); } } diff --git a/opendaylight/md-sal/sal-rest-docgen/pom.xml b/opendaylight/md-sal/sal-rest-docgen/pom.xml index 423d2e48ce..8954c05811 100644 --- a/opendaylight/md-sal/sal-rest-docgen/pom.xml +++ b/opendaylight/md-sal/sal-rest-docgen/pom.xml @@ -7,7 +7,6 @@ 1.1-SNAPSHOT - org.opendaylight.controller sal-rest-docgen bundle @@ -94,7 +93,6 @@ org.apache.felix maven-bundle-plugin - 2.4.0 true diff --git a/opendaylight/md-sal/samples/l2switch/implementation/src/main/java/org/opendaylight/controller/sample/l2switch/md/util/InstanceIdentifierUtils.java b/opendaylight/md-sal/samples/l2switch/implementation/src/main/java/org/opendaylight/controller/sample/l2switch/md/util/InstanceIdentifierUtils.java index ea08f94ebc..c2be488d93 100644 --- a/opendaylight/md-sal/samples/l2switch/implementation/src/main/java/org/opendaylight/controller/sample/l2switch/md/util/InstanceIdentifierUtils.java +++ b/opendaylight/md-sal/samples/l2switch/implementation/src/main/java/org/opendaylight/controller/sample/l2switch/md/util/InstanceIdentifierUtils.java @@ -28,130 +28,129 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; /* InstanceIdentifierUtils provides utility functions related to InstanceIdentifiers. */ -public class InstanceIdentifierUtils { - - /** - * Creates an Instance Identifier (path) for node with specified id - * - * @param nodeId - * @return - */ - public static final InstanceIdentifier createNodePath(NodeId nodeId) { - return InstanceIdentifier.builder(Nodes.class) // - .child(Node.class, new NodeKey(nodeId)) // - .build(); - } - - /** - * Shorten's node child path to node path. - * - * @param nodeChild child of node, from which we want node path. - * @return - */ - public static final InstanceIdentifier getNodePath(InstanceIdentifier nodeChild) { - return nodeChild.firstIdentifierOf(Node.class); - } - - - /** - * Creates a table path by appending table specific location to node path - * - * @param nodePath - * @param tableKey - * @return - */ - public static final InstanceIdentifier createTablePath(InstanceIdentifier nodePath, TableKey tableKey) { - return InstanceIdentifier.builder(nodePath) - .augmentation(FlowCapableNode.class) - .child(Table.class, tableKey) - .build(); - } - - /** - * Creates a path for particular flow, by appending flow-specific information - * to table path. - * - * @param table - * @param flowKey - * @return - */ - public static InstanceIdentifier createFlowPath(InstanceIdentifier
    table, FlowKey flowKey) { - return InstanceIdentifier.builder(table) - .child(Flow.class, flowKey) - .build(); - } - - /** - * Extract table id from table path. - * - * @param tablePath - * @return - */ - public static Short getTableId(InstanceIdentifier
    tablePath) { - return tablePath.firstKeyOf(Table.class, TableKey.class).getId(); - } - - /** - * Extracts NodeConnectorKey from node connector path. - */ - public static NodeConnectorKey getNodeConnectorKey(InstanceIdentifier nodeConnectorPath) { - return nodeConnectorPath.firstKeyOf(NodeConnector.class, NodeConnectorKey.class); - } - - /** - * Extracts NodeKey from node path. - */ - public static NodeKey getNodeKey(InstanceIdentifier nodePath) { - return nodePath.firstKeyOf(Node.class, NodeKey.class); - } - - - // - public static final InstanceIdentifier createNodeConnectorIdentifier(String nodeIdValue, - String nodeConnectorIdValue) { - return InstanceIdentifier.builder(createNodePath(new NodeId(nodeIdValue))) // - .child(NodeConnector.class, new NodeConnectorKey(new NodeConnectorId(nodeConnectorIdValue))) // - .build(); - } - - /** - * @param nodeConnectorRef - * @return - */ - public static InstanceIdentifier generateNodeInstanceIdentifier(NodeConnectorRef nodeConnectorRef) { - return nodeConnectorRef.getValue().firstIdentifierOf(Node.class); - } - - /** - * @param nodeConnectorRef - * @param flowTableKey - * @return - */ - public static InstanceIdentifier
    generateFlowTableInstanceIdentifier(NodeConnectorRef nodeConnectorRef, TableKey flowTableKey) { - return InstanceIdentifier.builder(generateNodeInstanceIdentifier(nodeConnectorRef)) - .augmentation(FlowCapableNode.class) - .child(Table.class, flowTableKey) - .build(); - } - - /** - * @param nodeConnectorRef - * @param flowTableKey - * @param flowKey - * @return - */ - public static InstanceIdentifier generateFlowInstanceIdentifier(NodeConnectorRef nodeConnectorRef, - TableKey flowTableKey, - FlowKey flowKey) { - return InstanceIdentifier.builder(generateFlowTableInstanceIdentifier(nodeConnectorRef, flowTableKey)) - .child(Flow.class, flowKey) - .build(); - } - - public static InstanceIdentifier generateTopologyInstanceIdentifier(String topologyId) { - return InstanceIdentifier.builder(NetworkTopology.class) - .child(Topology.class, new TopologyKey(new TopologyId(topologyId))) - .build(); - } +public final class InstanceIdentifierUtils { + + private InstanceIdentifierUtils() { + throw new UnsupportedOperationException("Utility class should never be instantiated"); + } + + /** + * Creates an Instance Identifier (path) for node with specified id + * + * @param nodeId + * @return + */ + public static final InstanceIdentifier createNodePath(final NodeId nodeId) { + return InstanceIdentifier.builder(Nodes.class) // + .child(Node.class, new NodeKey(nodeId)) // + .build(); + } + + /** + * Shorten's node child path to node path. + * + * @param nodeChild child of node, from which we want node path. + * @return + */ + public static final InstanceIdentifier getNodePath(final InstanceIdentifier nodeChild) { + return nodeChild.firstIdentifierOf(Node.class); + } + + + /** + * Creates a table path by appending table specific location to node path + * + * @param nodePath + * @param tableKey + * @return + */ + public static final InstanceIdentifier
    createTablePath(final InstanceIdentifier nodePath, final TableKey tableKey) { + return nodePath.builder() + .augmentation(FlowCapableNode.class) + .child(Table.class, tableKey) + .build(); + } + + /** + * Creates a path for particular flow, by appending flow-specific information + * to table path. + * + * @param table + * @param flowKey + * @return + */ + public static InstanceIdentifier createFlowPath(final InstanceIdentifier
    table, final FlowKey flowKey) { + return table.child(Flow.class, flowKey); + } + + /** + * Extract table id from table path. + * + * @param tablePath + * @return + */ + public static Short getTableId(final InstanceIdentifier
    tablePath) { + return tablePath.firstKeyOf(Table.class, TableKey.class).getId(); + } + + /** + * Extracts NodeConnectorKey from node connector path. + */ + public static NodeConnectorKey getNodeConnectorKey(final InstanceIdentifier nodeConnectorPath) { + return nodeConnectorPath.firstKeyOf(NodeConnector.class, NodeConnectorKey.class); + } + + /** + * Extracts NodeKey from node path. + */ + public static NodeKey getNodeKey(final InstanceIdentifier nodePath) { + return nodePath.firstKeyOf(Node.class, NodeKey.class); + } + + + // + public static final InstanceIdentifier createNodeConnectorIdentifier(final String nodeIdValue, + final String nodeConnectorIdValue) { + return createNodePath(new NodeId(nodeIdValue)) + .child(NodeConnector.class, new NodeConnectorKey(new NodeConnectorId(nodeConnectorIdValue))); + } + + /** + * @param nodeConnectorRef + * @return + */ + public static InstanceIdentifier generateNodeInstanceIdentifier(final NodeConnectorRef nodeConnectorRef) { + return nodeConnectorRef.getValue().firstIdentifierOf(Node.class); + } + + /** + * @param nodeConnectorRef + * @param flowTableKey + * @return + */ + public static InstanceIdentifier
    generateFlowTableInstanceIdentifier(final NodeConnectorRef nodeConnectorRef, final TableKey flowTableKey) { + return generateNodeInstanceIdentifier(nodeConnectorRef).builder() + .augmentation(FlowCapableNode.class) + .child(Table.class, flowTableKey) + .build(); + } + + /** + * @param nodeConnectorRef + * @param flowTableKey + * @param flowKey + * @return + */ + public static InstanceIdentifier generateFlowInstanceIdentifier(final NodeConnectorRef nodeConnectorRef, + final TableKey flowTableKey, + final FlowKey flowKey) { + return generateFlowTableInstanceIdentifier(nodeConnectorRef, flowTableKey).child(Flow.class, flowKey); + } + + public static InstanceIdentifier generateTopologyInstanceIdentifier(final String topologyId) { + return InstanceIdentifier.builder(NetworkTopology.class) + .child(Topology.class, new TopologyKey(new TopologyId(topologyId))) + .build(); + } } diff --git a/opendaylight/md-sal/samples/l2switch/implementation/src/test/java/org/opendaylight/controller/sample/l2switch/md/flow/FlowWriterServiceImplTest.java b/opendaylight/md-sal/samples/l2switch/implementation/src/test/java/org/opendaylight/controller/sample/l2switch/md/flow/FlowWriterServiceImplTest.java index 3520d812d7..50f74cc33f 100644 --- a/opendaylight/md-sal/samples/l2switch/implementation/src/test/java/org/opendaylight/controller/sample/l2switch/md/flow/FlowWriterServiceImplTest.java +++ b/opendaylight/md-sal/samples/l2switch/implementation/src/test/java/org/opendaylight/controller/sample/l2switch/md/flow/FlowWriterServiceImplTest.java @@ -7,11 +7,19 @@ */ package org.opendaylight.controller.sample.l2switch.md.flow; +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import org.junit.Before; import org.junit.Test; -import org.opendaylight.controller.sample.l2switch.md.topology.NetworkGraphService; import org.opendaylight.controller.sal.binding.api.data.DataBrokerService; import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; +import org.opendaylight.controller.sample.l2switch.md.topology.NetworkGraphService; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef; @@ -23,128 +31,110 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.N import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.fail; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - /** */ public class FlowWriterServiceImplTest { - private DataBrokerService dataBrokerService; - private NodeConnectorRef srcNodeConnectorRef; - private NodeConnectorRef destNodeConnectorRef; - private MacAddress destMacAddress; - private MacAddress srcMacAddress; - private DataModificationTransaction dataModificationTransaction; - private NetworkGraphService networkGraphService; + private DataBrokerService dataBrokerService; + private NodeConnectorRef srcNodeConnectorRef; + private NodeConnectorRef destNodeConnectorRef; + private MacAddress destMacAddress; + private MacAddress srcMacAddress; + private DataModificationTransaction dataModificationTransaction; + private NetworkGraphService networkGraphService; - @Before - public void init() { - dataBrokerService = mock(DataBrokerService.class); - networkGraphService = mock(NetworkGraphService.class); - //build source node connector ref - InstanceIdentifier srcNodesInstanceIdentifier - = InstanceIdentifier.builder(Nodes.class) - .build(); - InstanceIdentifier srcNodeInstanceIdentifier - = InstanceIdentifier.builder(srcNodesInstanceIdentifier) - .child(Node.class, new NodeKey(new NodeId("openflow:1"))) - .build(); - InstanceIdentifier srcNodeConnectorInstanceIdentifier - = InstanceIdentifier.builder(srcNodeInstanceIdentifier) - .child(NodeConnector.class, new NodeConnectorKey(new NodeConnectorId("openflow:1:2"))) - .build(); - srcNodeConnectorRef = new NodeConnectorRef(srcNodeConnectorInstanceIdentifier); + @Before + public void init() { + dataBrokerService = mock(DataBrokerService.class); + networkGraphService = mock(NetworkGraphService.class); + //build source node connector ref + InstanceIdentifier srcNodesInstanceIdentifier = InstanceIdentifier.create(Nodes.class); + InstanceIdentifier srcNodeInstanceIdentifier = srcNodesInstanceIdentifier + .child(Node.class, new NodeKey(new NodeId("openflow:1"))); + InstanceIdentifier srcNodeConnectorInstanceIdentifier = srcNodeInstanceIdentifier + .child(NodeConnector.class, new NodeConnectorKey(new NodeConnectorId("openflow:1:2"))); + srcNodeConnectorRef = new NodeConnectorRef(srcNodeConnectorInstanceIdentifier); - //build dest node connector ref - InstanceIdentifier nodesInstanceIdentifier + //build dest node connector ref + InstanceIdentifier nodesInstanceIdentifier = InstanceIdentifier.builder(Nodes.class) .build(); - InstanceIdentifier nodeInstanceIdentifier - = InstanceIdentifier.builder(nodesInstanceIdentifier) - .child(Node.class, new NodeKey(new NodeId("openflow:2"))) - .build(); - InstanceIdentifier nodeConnectorInstanceIdentifier - = InstanceIdentifier.builder(nodeInstanceIdentifier) - .child(NodeConnector.class, new NodeConnectorKey(new NodeConnectorId("openflow:2:2"))) - .build(); - destNodeConnectorRef = new NodeConnectorRef(nodeConnectorInstanceIdentifier); - destMacAddress = new MacAddress("00:0a:95:9d:68:16"); - srcMacAddress = new MacAddress("00:0a:95:8c:97:24"); - dataModificationTransaction = mock(DataModificationTransaction.class); - when(dataBrokerService.beginTransaction()).thenReturn(dataModificationTransaction); - } + InstanceIdentifier nodeInstanceIdentifier = + nodesInstanceIdentifier.child(Node.class, new NodeKey(new NodeId("openflow:2"))); + InstanceIdentifier nodeConnectorInstanceIdentifier = + nodeInstanceIdentifier.child(NodeConnector.class, new NodeConnectorKey(new NodeConnectorId("openflow:2:2"))); + destNodeConnectorRef = new NodeConnectorRef(nodeConnectorInstanceIdentifier); + destMacAddress = new MacAddress("00:0a:95:9d:68:16"); + srcMacAddress = new MacAddress("00:0a:95:8c:97:24"); + dataModificationTransaction = mock(DataModificationTransaction.class); + when(dataBrokerService.beginTransaction()).thenReturn(dataModificationTransaction); + } - @Test - public void testFlowWriterServiceImpl_NPEWhenDataBrokerServiceIsNull() throws Exception { - try { - new FlowWriterServiceImpl(null, networkGraphService); - fail("Expected null pointer exception."); - } catch(NullPointerException npe) { - assertEquals("dataBrokerService should not be null.", npe.getMessage()); + @Test + public void testFlowWriterServiceImpl_NPEWhenDataBrokerServiceIsNull() throws Exception { + try { + new FlowWriterServiceImpl(null, networkGraphService); + fail("Expected null pointer exception."); + } catch(NullPointerException npe) { + assertEquals("dataBrokerService should not be null.", npe.getMessage()); + } } - } - @Test - public void testAddMacToMacFlow_NPEWhenNullSourceMacDestMacAndNodeConnectorRef() throws Exception { - FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService); - try { - flowWriterService.addMacToMacFlow(null, null, null); - fail("Expected null pointer exception."); - } catch(NullPointerException npe) { - assertEquals("Destination mac address should not be null.", npe.getMessage()); + @Test + public void testAddMacToMacFlow_NPEWhenNullSourceMacDestMacAndNodeConnectorRef() throws Exception { + FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService); + try { + flowWriterService.addMacToMacFlow(null, null, null); + fail("Expected null pointer exception."); + } catch(NullPointerException npe) { + assertEquals("Destination mac address should not be null.", npe.getMessage()); + } } - } - @Test - public void testAddMacToMacFlow_NPEWhenSourceMacNullMac() throws Exception { - FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService); - try { - flowWriterService.addMacToMacFlow(null, null, destNodeConnectorRef); - fail("Expected null pointer exception."); - } catch(NullPointerException npe) { - assertEquals("Destination mac address should not be null.", npe.getMessage()); + @Test + public void testAddMacToMacFlow_NPEWhenSourceMacNullMac() throws Exception { + FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService); + try { + flowWriterService.addMacToMacFlow(null, null, destNodeConnectorRef); + fail("Expected null pointer exception."); + } catch(NullPointerException npe) { + assertEquals("Destination mac address should not be null.", npe.getMessage()); + } } - } - @Test - public void testAddMacToMacFlow_NPEWhenNullSourceMacNodeConnectorRef() throws Exception { - FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService); - try { - flowWriterService.addMacToMacFlow(null, destMacAddress, null); - fail("Expected null pointer exception."); - } catch(NullPointerException npe) { - assertEquals("Destination port should not be null.", npe.getMessage()); + @Test + public void testAddMacToMacFlow_NPEWhenNullSourceMacNodeConnectorRef() throws Exception { + FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService); + try { + flowWriterService.addMacToMacFlow(null, destMacAddress, null); + fail("Expected null pointer exception."); + } catch(NullPointerException npe) { + assertEquals("Destination port should not be null.", npe.getMessage()); + } } - } - @Test - public void testAddMacToMacFlow_WhenNullSourceMac() throws Exception { - FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService); - flowWriterService.addMacToMacFlow(null, destMacAddress, destNodeConnectorRef); - verify(dataBrokerService, times(1)).beginTransaction(); - verify(dataModificationTransaction, times(1)).commit(); - } + @Test + public void testAddMacToMacFlow_WhenNullSourceMac() throws Exception { + FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService); + flowWriterService.addMacToMacFlow(null, destMacAddress, destNodeConnectorRef); + verify(dataBrokerService, times(1)).beginTransaction(); + verify(dataModificationTransaction, times(1)).commit(); + } - @Test - public void testAddMacToMacFlow_WhenSrcAndDestMacAreSame() throws Exception { - FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService); - flowWriterService.addMacToMacFlow(new MacAddress(destMacAddress.getValue()), destMacAddress, destNodeConnectorRef); - verify(dataBrokerService, never()).beginTransaction(); - verify(dataModificationTransaction, never()).commit(); + @Test + public void testAddMacToMacFlow_WhenSrcAndDestMacAreSame() throws Exception { + FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService); + flowWriterService.addMacToMacFlow(new MacAddress(destMacAddress.getValue()), destMacAddress, destNodeConnectorRef); + verify(dataBrokerService, never()).beginTransaction(); + verify(dataModificationTransaction, never()).commit(); - } + } - @Test - public void testAddMacToMacFlow_SunnyDay() throws Exception { - FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService); - flowWriterService.addMacToMacFlow(srcMacAddress, destMacAddress, destNodeConnectorRef); - verify(dataBrokerService, times(1)).beginTransaction(); - verify(dataModificationTransaction, times(1)).commit(); - } + @Test + public void testAddMacToMacFlow_SunnyDay() throws Exception { + FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService); + flowWriterService.addMacToMacFlow(srcMacAddress, destMacAddress, destNodeConnectorRef); + verify(dataBrokerService, times(1)).beginTransaction(); + verify(dataModificationTransaction, times(1)).commit(); + } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleAttributeReadingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleAttributeReadingStrategy.java index cb8f66081b..8f6a7cd1e4 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleAttributeReadingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleAttributeReadingStrategy.java @@ -12,13 +12,8 @@ import com.google.common.base.Preconditions; import java.util.List; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.util.xml.XmlElement; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public class SimpleAttributeReadingStrategy extends AbstractAttributeReadingStrategy { - private static final Logger logger = LoggerFactory.getLogger(SimpleAttributeReadingStrategy.class); - - public SimpleAttributeReadingStrategy(String nullableDefault) { super(nullableDefault); } @@ -29,20 +24,7 @@ public class SimpleAttributeReadingStrategy extends AbstractAttributeReadingStra Preconditions.checkState(configNodes.size() == 1, "This element should be present only once " + xmlElement + " but was " + configNodes.size()); - String textContent = ""; - try{ - textContent = readElementContent(xmlElement); - }catch(IllegalStateException | NullPointerException e) { - // yuma sends for empty value instead of - logger.warn("Ignoring exception caused by failure to read text element", e); - } - - if (null == textContent){ - throw new NetconfDocumentedException(String.format("This element should contain text %s", xmlElement), - NetconfDocumentedException.ErrorType.application, - NetconfDocumentedException.ErrorTag.invalid_value, - NetconfDocumentedException.ErrorSeverity.error); - } + String textContent = readElementContent(xmlElement); return AttributeConfigElement.create(postprocessNullableDefault(getNullableDefault()), postprocessParsedValue(textContent)); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectNameAttributeWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectNameAttributeWritingStrategy.java index 66b945d14b..68c8c6fce3 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectNameAttributeWritingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectNameAttributeWritingStrategy.java @@ -40,8 +40,9 @@ public class ObjectNameAttributeWritingStrategy implements AttributeWritingStrat String refName = ((ObjectNameAttributeMappingStrategy.MappedDependency) value).getRefName(); String namespaceForType = ((ObjectNameAttributeMappingStrategy.MappedDependency) value).getNamespace(); - Element typeElement = XmlUtil.createPrefixedTextElement(document, XmlUtil.createPrefixedValue(XmlNetconfConstants.PREFIX, XmlNetconfConstants.TYPE_KEY), XmlNetconfConstants.PREFIX, - moduleName, Optional.of(namespaceForType)); + Element typeElement = XmlUtil.createTextElementWithNamespacedContent(document, XmlNetconfConstants.TYPE_KEY, XmlNetconfConstants.PREFIX, + namespaceForType, moduleName); + innerNode.appendChild(typeElement); final Element nameElement = XmlUtil.createTextElement(document, XmlNetconfConstants.NAME_KEY, refName, Optional.absent()); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleIdentityRefAttributeWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleIdentityRefAttributeWritingStrategy.java index ed3bb2a9d9..a2b8e0bfdf 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleIdentityRefAttributeWritingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleIdentityRefAttributeWritingStrategy.java @@ -43,9 +43,8 @@ public class SimpleIdentityRefAttributeWritingStrategy extends SimpleAttributeWr @Override protected Element createElement(Document doc, String key, String value, Optional namespace) { QName qName = QName.create(value); - String identity = qName.getLocalName(); + String identityValue = qName.getLocalName(); String identityNamespace = qName.getNamespace().toString(); - Element element = XmlUtil.createPrefixedTextElement(doc, XmlUtil.createPrefixedValue(PREFIX, key), PREFIX, identity, Optional.of(identityNamespace)); - return element; + return XmlUtil.createTextElementWithNamespacedContent(doc, key, PREFIX, identityNamespace, identityValue); } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java index a5a625a2d6..6a17e97350 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java @@ -60,19 +60,17 @@ public class ModuleConfig { public Element toXml(ObjectName instanceON, ServiceRegistryWrapper depTracker, Document document, String namespace) { Element root = XmlUtil.createElement(document, XmlNetconfConstants.MODULE_KEY, Optional.absent()); - // Xml.addNamespaceAttr(document, root, namespace); - final String prefix = getPrefix(); - Element typeElement = XmlUtil.createPrefixedTextElement(document, XmlUtil.createPrefixedValue(prefix, XmlNetconfConstants.TYPE_KEY), prefix, - moduleName, Optional.of(namespace)); - // Xml.addNamespaceAttr(document, typeElement, - // XMLUtil.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); + // type belongs to config.yang namespace, but needs to be prefix:moduleName + + Element typeElement = XmlUtil.createTextElementWithNamespacedContent(document, XmlNetconfConstants.TYPE_KEY, + XmlNetconfConstants.PREFIX, namespace, moduleName); + root.appendChild(typeElement); + // name belongs to config.yang namespace + String instanceName = ObjectNameUtil.getInstanceName(instanceON); + Element nameElement = XmlUtil.createTextElement(document, XmlNetconfConstants.NAME_KEY, instanceName, Optional.absent()); - Element nameElement = XmlUtil.createTextElement(document, XmlUtil.createPrefixedValue(prefix, XmlNetconfConstants.NAME_KEY), - ObjectNameUtil.getInstanceName(instanceON), Optional.of(namespace)); - // Xml.addNamespaceAttr(document, nameElement, - // XMLUtil.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); root.appendChild(nameElement); root = instanceConfig.toXml(instanceON, depTracker, namespace, document, root); @@ -80,10 +78,6 @@ public class ModuleConfig { return root; } - private String getPrefix() { - return XmlNetconfConstants.PREFIX; - } - public ModuleElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper depTracker, String instanceName, String moduleNamespace, EditStrategyType defaultStrategy, Map> identityMap) throws NetconfDocumentedException { diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java index eb5c018cf3..559de7a756 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java @@ -131,11 +131,15 @@ public final class Services { for (String namespace : mappedServices.keySet()) { for (Entry> serviceEntry : mappedServices.get(namespace).entrySet()) { + // service belongs to config.yang namespace Element serviceElement = XmlUtil.createElement(document, SERVICE_KEY, Optional.absent()); root.appendChild(serviceElement); - Element typeElement = XmlUtil.createPrefixedTextElement(document, XmlUtil.createPrefixedValue(XmlNetconfConstants.PREFIX, TYPE_KEY), XmlNetconfConstants.PREFIX, - serviceEntry.getKey(), Optional.of(namespace)); + // type belongs to config.yang namespace + String serviceType = serviceEntry.getKey(); + Element typeElement = XmlUtil.createTextElementWithNamespacedContent(document, XmlNetconfConstants.TYPE_KEY, + XmlNetconfConstants.PREFIX, namespace, serviceType); + serviceElement.appendChild(typeElement); for (Entry instanceEntry : serviceEntry.getValue().entrySet()) { diff --git a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java index 2e8d1f64ab..f8d21e401c 100644 --- a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java +++ b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java @@ -8,11 +8,42 @@ package org.opendaylight.controller.netconf.confignetconfconnector; +import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElement; +import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElementWithText; +import static org.opendaylight.controller.netconf.util.xml.XmlUtil.readXmlToElement; + import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.math.BigInteger; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import javax.management.InstanceAlreadyExistsException; +import javax.management.InstanceNotFoundException; +import javax.management.ObjectName; +import javax.xml.parsers.ParserConfigurationException; import org.custommonkey.xmlunit.AbstractNodeTester; import org.custommonkey.xmlunit.NodeTest; import org.custommonkey.xmlunit.NodeTestException; @@ -83,38 +114,6 @@ import org.w3c.dom.Text; import org.w3c.dom.traversal.DocumentTraversal; import org.xml.sax.SAXException; -import javax.management.InstanceAlreadyExistsException; -import javax.management.InstanceNotFoundException; -import javax.management.ObjectName; -import javax.xml.parsers.ParserConfigurationException; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.math.BigInteger; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElement; -import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElementWithText; -import static org.opendaylight.controller.netconf.util.xml.XmlUtil.readXmlToElement; - public class NetconfMappingTest extends AbstractConfigTest { private static final Logger logger = LoggerFactory.getLogger(NetconfMappingTest.class); @@ -573,7 +572,7 @@ public class NetconfMappingTest extends AbstractConfigTest { String enumContent = "TWO"; for (XmlElement moduleElement : modulesElement.getChildElements("module")) { - String name = moduleElement.getOnlyChildElement("prefix:name").getTextContent(); + String name = moduleElement.getOnlyChildElement("name").getTextContent(); if(name.equals(INSTANCE_NAME)) { XmlElement enumAttr = moduleElement.getOnlyChildElement(enumName); assertEquals(enumContent, enumAttr.getTextContent()); @@ -599,7 +598,7 @@ public class NetconfMappingTest extends AbstractConfigTest { for (XmlElement moduleElement : modulesElement.getChildElements("module")) { for (XmlElement type : moduleElement.getChildElements("type")) { - if (type.getNamespace() != null) { + if (type.getNamespaceOptionally().isPresent()) { configAttributeType.add(type.getTextContent()); } } diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java index cd53995bce..fd43f67c05 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java @@ -386,10 +386,10 @@ public class NetconfITTest extends AbstractNetconfConfigTest { NetconfMessage response = netconfClient.sendMessage(getConfig); - assertThat(XmlUtil.toString(response.getDocument()), JUnitMatchers.containsString("prefix:test-identity1")); - assertThat(XmlUtil.toString(response.getDocument()), JUnitMatchers.containsString("prefix:test-identity2")); - assertThat(XmlUtil.toString(response.getDocument()), JUnitMatchers.containsString("prefix:test-identity2")); - assertThat(XmlUtil.toString(response.getDocument()), JUnitMatchers.containsString("prefix:test-identity1")); + assertThat(XmlUtil.toString(response.getDocument()), JUnitMatchers.containsString("prefix:test-identity1")); + assertThat(XmlUtil.toString(response.getDocument()), JUnitMatchers.containsString("prefix:test-identity2")); + assertThat(XmlUtil.toString(response.getDocument()), JUnitMatchers.containsString("prefix:test-identity2")); + assertThat(XmlUtil.toString(response.getDocument()), JUnitMatchers.containsString("prefix:test-identity1")); } catch (Exception e) { fail(Throwables.getStackTraceAsString(e)); diff --git a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/NetconfSSHServer.java b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/NetconfSSHServer.java index ff950e95e9..c6974d4982 100644 --- a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/NetconfSSHServer.java +++ b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/NetconfSSHServer.java @@ -27,7 +27,7 @@ public final class NetconfSSHServer implements Runnable { private static final AtomicLong sesssionId = new AtomicLong(); private final InetSocketAddress clientAddress; private final AuthProvider authProvider; - private boolean up = false; + private volatile boolean up = false; private NetconfSSHServer(int serverPort,InetSocketAddress clientAddress, AuthProvider authProvider) throws IllegalStateException, IOException { @@ -68,9 +68,17 @@ public final class NetconfSSHServer implements Runnable { while (up) { logger.trace("Starting new socket thread."); try { - SocketThread.start(ss.accept(), clientAddress, sesssionId.incrementAndGet(), authProvider); - } catch (IOException e) { - logger.error("Exception occurred during socket thread initialization {}", e); + SocketThread.start(ss.accept(), clientAddress, sesssionId.incrementAndGet(), authProvider); + } + catch (IOException e) { + if( up ) { + logger.error("Exception occurred during socket thread initialization", e); + } + else { + // We're shutting down so an exception is expected as the socket's been closed. + // Log to debug. + logger.debug("Shutting down - got expected exception: " + e); + } } } } diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java index 66603fb6c2..ac200a0aa6 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java @@ -10,9 +10,17 @@ package org.opendaylight.controller.netconf.util.xml; import com.google.common.base.Optional; import com.google.common.base.Predicate; +import com.google.common.base.Strings; import com.google.common.collect.Collections2; import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.annotation.Nullable; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException; import org.opendaylight.controller.netconf.util.exception.UnexpectedElementException; @@ -28,14 +36,6 @@ import org.w3c.dom.NodeList; import org.w3c.dom.Text; import org.xml.sax.SAXException; -import javax.annotation.Nullable; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - public final class XmlElement { private final Element element; @@ -111,7 +111,7 @@ public final class XmlElement { public void checkNamespaceAttribute(String expectedNamespace) throws UnexpectedNamespaceException, MissingNameSpaceException { if (!getNamespaceAttribute().equals(expectedNamespace)) { - throw new UnexpectedNamespaceException(String.format("Unexpected namespace %s for element %s, should be %s", + throw new UnexpectedNamespaceException(String.format("Unexpected namespace %s should be %s", getNamespaceAttribute(), expectedNamespace), NetconfDocumentedException.ErrorType.application, @@ -123,7 +123,7 @@ public final class XmlElement { public void checkNamespace(String expectedNamespace) throws UnexpectedNamespaceException, MissingNameSpaceException { if (!getNamespace().equals(expectedNamespace)) { - throw new UnexpectedNamespaceException(String.format("Unexpected namespace %s for element %s, should be %s", + throw new UnexpectedNamespaceException(String.format("Unexpected namespace %s should be %s", getNamespace(), expectedNamespace), NetconfDocumentedException.ErrorType.application, @@ -320,23 +320,22 @@ public final class XmlElement { } public String getTextContent() throws NetconfDocumentedException { - Node textChild = element.getFirstChild(); - if (null == textChild){ - throw new NetconfDocumentedException(String.format( "Child node expected, got null for " + getName() + " : " + element), - NetconfDocumentedException.ErrorType.application, - NetconfDocumentedException.ErrorTag.invalid_value, - NetconfDocumentedException.ErrorSeverity.error); + NodeList childNodes = element.getChildNodes(); + if (childNodes.getLength() == 0) { + return ""; } - if (!(textChild instanceof Text)){ - throw new NetconfDocumentedException(String.format(getName() + " should contain text." + - Text.class.getName() + " expected, got " + textChild), - NetconfDocumentedException.ErrorType.application, - NetconfDocumentedException.ErrorTag.invalid_value, - NetconfDocumentedException.ErrorSeverity.error); + for(int i = 0; i < childNodes.getLength(); i++) { + Node textChild = childNodes.item(i); + if (textChild instanceof Text) { + String content = textChild.getTextContent(); + return content.trim(); + } } - String content = textChild.getTextContent(); - // Trim needed - return content.trim(); + throw new NetconfDocumentedException(getName() + " should contain text.", + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.invalid_value, + NetconfDocumentedException.ErrorSeverity.error + ); } public String getNamespaceAttribute() throws MissingNameSpaceException { @@ -351,15 +350,24 @@ public final class XmlElement { return attribute; } - public String getNamespace() throws MissingNameSpaceException { + public Optional getNamespaceOptionally() { String namespaceURI = element.getNamespaceURI(); - if (namespaceURI == null || namespaceURI.equals("")){ + if (Strings.isNullOrEmpty(namespaceURI)) { + return Optional.absent(); + } else { + return Optional.of(namespaceURI); + } + } + + public String getNamespace() throws MissingNameSpaceException { + Optional namespaceURI = getNamespaceOptionally(); + if (namespaceURI.isPresent() == false){ throw new MissingNameSpaceException(String.format("No namespace defined for %s", this), NetconfDocumentedException.ErrorType.application, NetconfDocumentedException.ErrorTag.operation_failed, NetconfDocumentedException.ErrorSeverity.error); } - return namespaceURI; + return namespaceURI.get(); } @Override diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlUtil.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlUtil.java index 1f81117ca3..b2b202b69e 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlUtil.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlUtil.java @@ -10,11 +10,12 @@ package org.opendaylight.controller.netconf.util.xml; import com.google.common.base.Charsets; import com.google.common.base.Optional; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.xml.sax.SAXException; - +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; import javax.xml.XMLConstants; import javax.xml.namespace.QName; import javax.xml.parsers.DocumentBuilder; @@ -32,17 +33,15 @@ import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathExpressionException; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.StringWriter; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xml.sax.SAXException; public final class XmlUtil { public static final String XMLNS_ATTRIBUTE_KEY = "xmlns"; - private static final String XMLNS_URI = "http://www.w3.org/2000/xmlns/"; + public static final String XMLNS_URI = "http://www.w3.org/2000/xmlns/"; private static final DocumentBuilderFactory BUILDERFACTORY; static { @@ -118,8 +117,14 @@ public final class XmlUtil { return typeElement; } - public static Element createPrefixedTextElement(Document document, String qName, String prefix, String content, Optional namespace) { - return createTextElement(document, qName, createPrefixedValue(prefix, content), namespace); + public static Element createTextElementWithNamespacedContent(Document document, String qName, String prefix, + String namespace, String contentWithoutPrefix) { + + String content = createPrefixedValue(XmlNetconfConstants.PREFIX, contentWithoutPrefix); + Element element = createTextElement(document, qName, content, Optional.absent()); + String prefixedNamespaceAttr = createPrefixedValue(XMLNS_ATTRIBUTE_KEY, prefix); + element.setAttributeNS(XMLNS_URI, prefixedNamespaceAttr, namespace); + return element; } public static String createPrefixedValue(String prefix, String value) { diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortsNorthbound.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortsNorthbound.java index 9f24e79ea0..1a2512fde3 100644 --- a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortsNorthbound.java +++ b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortsNorthbound.java @@ -218,16 +218,6 @@ public class NeutronPortsNorthbound { if (portInterface.macInUse(singleton.getMacAddress())) { throw new ResourceConflictException("MAC Address is in use."); } - Object[] instances = ServiceHelper.getGlobalInstances(INeutronPortAware.class, this, null); - if (instances != null) { - for (Object instance : instances) { - INeutronPortAware service = (INeutronPortAware) instance; - int status = service.canCreatePort(singleton); - if (status < 200 || status > 299) { - return Response.status(status).build(); - } - } - } /* * if fixed IPs are specified, each one has to have an existing subnet ID * that is in the same scoping network as the port. In addition, if an IP @@ -260,6 +250,18 @@ public class NeutronPortsNorthbound { } } + Object[] instances = ServiceHelper.getGlobalInstances(INeutronPortAware.class, this, null); + if (instances != null) { + for (Object instance : instances) { + INeutronPortAware service = (INeutronPortAware) instance; + int status = service.canCreatePort(singleton); + if (status < 200 || status > 299) { + return Response.status(status).build(); + } + } + } + + // add the port to the cache portInterface.addPort(singleton); if (instances != null) { @@ -309,15 +311,7 @@ public class NeutronPortsNorthbound { if (portInterface.macInUse(test.getMacAddress())) { throw new ResourceConflictException("MAC address in use"); } - if (instances != null) { - for (Object instance : instances) { - INeutronPortAware service = (INeutronPortAware) instance; - int status = service.canCreatePort(test); - if (status < 200 || status > 299) { - return Response.status(status).build(); - } - } - } + /* * if fixed IPs are specified, each one has to have an existing subnet ID * that is in the same scoping network as the port. In addition, if an IP @@ -351,6 +345,15 @@ public class NeutronPortsNorthbound { } } } + if (instances != null) { + for (Object instance : instances) { + INeutronPortAware service = (INeutronPortAware) instance; + int status = service.canCreatePort(test); + if (status < 200 || status > 299) { + return Response.status(status).build(); + } + } + } } //once everything has passed, then we can add to the cache