From: Basheeruddin Ahmed Date: Fri, 20 Jun 2014 06:34:15 +0000 (-0700) Subject: Having InMemoryDOMDatastore in its own bundle.To make it configurable X-Git-Tag: release/helium~604^2 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=cc36277f18d3efaa5635e4a64fb22490c8223ef9 Having InMemoryDOMDatastore in its own bundle.To make it configurable using the config subystem. patch 5 changes: md-sal/pom.xml correction patch 4 changes: Moved data tree api and impl to yang-tools based on earlier comment Patch 3 changes: 1. Included sal-inmemory-datastore dependency in TestHelper.java for PaxExam integration test cases [Weird that it was working earlier and my local controller full build were passing] Patch 2 changes: 1. Keeping schema service as part of opendaylight-dom-broker-impl for backward comptability scenario 2. Initializing InMemoryDOMDataStore by default if config-dom-datastore and operation-dom-datastore are not found 3. Updated 01-md-sal.xml based on 1. 4. Regarding the comment of moving data tree in yangtools. It shall be done in separate patch. This is done to replace InMemoryDOMDatastore with distributed-datastore The changes done are: 1. Created a new sal-inmemory-datastore bundle and moved the store/impl source files from sal-dom-broker and the corresponding InMemoryDOMDatastore test cases. 2. Created two yang config models in sal-dom-spi that represent the configurable config-dom-datastore and operational-dom-datastore, that are of service type DOMStore 3. In opendaylight-dom-broker-impl.yang of sal-dom-broker, in the augment of dom-inmemory-data-broker added two container config-data-store and operational-data-store that refer the service implementations of service defined in sal-dom-spi 4.In sal-inmemory-datastore bundle, created a yang model opendaylight-inmemory-datastore that provide the implementation of the sal-dom-spi service definitions mentioned in 2 -- The implementaions are augmented to have schema-service container required by InMemoryDOMDatastore for registering itself for scheam changes 5. Updated the 01-md-sal.xml with the above changes 6. Update the distribution pom.xml to include sal-inmemory-datastore. Change-Id: Ib2f0f0556869981e7e60b3eeae9b1e5e6cc96a0f Signed-off-by: Basheeruddin Ahmed --- diff --git a/opendaylight/distribution/opendaylight/pom.xml b/opendaylight/distribution/opendaylight/pom.xml index 7160acba81..149154334d 100644 --- a/opendaylight/distribution/opendaylight/pom.xml +++ b/opendaylight/distribution/opendaylight/pom.xml @@ -994,6 +994,11 @@ org.opendaylight.controller sal-core-spi + + org.opendaylight.controller + sal-inmemory-datastore + 1.1-SNAPSHOT + org.opendaylight.controller sal-netconf-connector diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.xml b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.xml index 8b07ce3a33..7b1df98247 100644 --- a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.xml +++ b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.xml @@ -15,6 +15,7 @@ prefix:schema-service-singleton yang-schema-service + prefix:runtime-generated-mapping runtime-mapping-singleton @@ -36,6 +37,25 @@ + + + prefix:inmemory-config-datastore-provider + config-store-service + + dom:schema-service + yang-schema-service + + + + + prefix:inmemory-operational-datastore-provider + operational-store-service + + dom:schema-service + yang-schema-service + + + remoterpc-routingtable/implementation sal-remoterpc-connector/implementation - sal-rest-docgen + + sal-inmemory-datastore + sal-protocolbuffer-encoding diff --git a/opendaylight/md-sal/sal-binding-it/src/main/java/org/opendaylight/controller/test/sal/binding/it/TestHelper.java b/opendaylight/md-sal/sal-binding-it/src/main/java/org/opendaylight/controller/test/sal/binding/it/TestHelper.java index a15c711e2d..5ede600d97 100644 --- a/opendaylight/md-sal/sal-binding-it/src/main/java/org/opendaylight/controller/test/sal/binding/it/TestHelper.java +++ b/opendaylight/md-sal/sal-binding-it/src/main/java/org/opendaylight/controller/test/sal/binding/it/TestHelper.java @@ -119,7 +119,7 @@ public class TestHelper { mavenBundle(CONTROLLER, "sal-common-util").versionAsInProject(), // // - + mavenBundle(CONTROLLER, "sal-inmemory-datastore").versionAsInProject(), // / mavenBundle(CONTROLLER, "sal-broker-impl").versionAsInProject(), // // mavenBundle(CONTROLLER, "sal-core-spi").versionAsInProject().update(), // diff --git a/opendaylight/md-sal/sal-dom-broker/pom.xml b/opendaylight/md-sal/sal-dom-broker/pom.xml index bac9146bf5..022882fceb 100644 --- a/opendaylight/md-sal/sal-dom-broker/pom.xml +++ b/opendaylight/md-sal/sal-dom-broker/pom.xml @@ -42,6 +42,12 @@ org.opendaylight.controller sal-core-spi + + org.opendaylight.controller + sal-inmemory-datastore + 1.1-SNAPSHOT + + org.opendaylight.yangtools util @@ -88,8 +94,6 @@ org.opendaylight.controller.config.yang.md.sal.dom.statistics, org.opendaylight.controller.md.sal.dom.broker.impl, org.opendaylight.controller.md.sal.dom.broker.impl.*, - org.opendaylight.controller.md.sal.dom.store.impl, - org.opendaylight.controller.md.sal.dom.store.impl.*, org.opendaylight.yangtools.yang.util, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.dom.impl.rev131028.* * diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/DomInmemoryDataBrokerModule.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/DomInmemoryDataBrokerModule.java index ad0de54bc0..d3852d28c5 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/DomInmemoryDataBrokerModule.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/DomInmemoryDataBrokerModule.java @@ -7,9 +7,9 @@ */ package org.opendaylight.controller.config.yang.md.sal.dom.impl; -import java.util.Hashtable; -import java.util.concurrent.Executors; - +import com.google.common.collect.ImmutableMap; +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker; import org.opendaylight.controller.md.sal.dom.broker.impl.DOMDataBrokerImpl; @@ -17,9 +17,8 @@ import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore; import org.opendaylight.controller.sal.core.spi.data.DOMStore; import org.osgi.framework.BundleContext; -import com.google.common.collect.ImmutableMap; -import com.google.common.util.concurrent.ListeningExecutorService; -import com.google.common.util.concurrent.MoreExecutors; +import java.util.Hashtable; +import java.util.concurrent.Executors; /** * @@ -49,8 +48,22 @@ public final class DomInmemoryDataBrokerModule extends @Override public java.lang.AutoCloseable createInstance() { ListeningExecutorService storeExecutor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(2)); - InMemoryDOMDataStore operStore = new InMemoryDOMDataStore("DOM-OPER", storeExecutor); - InMemoryDOMDataStore configStore = new InMemoryDOMDataStore("DOM-CFG", storeExecutor); + //Initializing Operational DOM DataStore defaulting to InMemoryDOMDataStore if one is not configured + DOMStore operStore = getOperationalDataStoreDependency(); + if(operStore == null){ + //we will default to InMemoryDOMDataStore creation + operStore = new InMemoryDOMDataStore("DOM-OPER", storeExecutor); + //here we will register the SchemaContext listener + getSchemaServiceDependency().registerSchemaServiceListener((InMemoryDOMDataStore)operStore); + } + + DOMStore configStore = getConfigDataStoreDependency(); + if(configStore == null){ + //we will default to InMemoryDOMDataStore creation + configStore = new InMemoryDOMDataStore("DOM-CFG", storeExecutor); + //here we will register the SchemaContext listener + getSchemaServiceDependency().registerSchemaServiceListener((InMemoryDOMDataStore)configStore); + } ImmutableMap datastores = ImmutableMap . builder().put(LogicalDatastoreType.OPERATIONAL, operStore) .put(LogicalDatastoreType.CONFIGURATION, configStore).build(); @@ -59,8 +72,6 @@ public final class DomInmemoryDataBrokerModule extends getBundleContext().registerService(DOMDataBroker.class, newDataBroker, new Hashtable()); - getSchemaServiceDependency().registerSchemaServiceListener(operStore); - getSchemaServiceDependency().registerSchemaServiceListener(configStore); return newDataBroker; } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ConflictingModificationAppliedException.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ConflictingModificationAppliedException.java deleted file mode 100644 index 3625d3356a..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ConflictingModificationAppliedException.java +++ /dev/null @@ -1,33 +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; - -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; - -/** - * Exception thrown when a proposed change fails validation before being - * applied into the Data Tree because the Data Tree has been modified - * in way that a conflicting - * node is present. - */ -public class ConflictingModificationAppliedException extends DataValidationFailedException { - - /** - * - */ - private static final long serialVersionUID = 1L; - - public ConflictingModificationAppliedException(final InstanceIdentifier path, final String message, final Throwable cause) { - super(path, message, cause); - } - - public ConflictingModificationAppliedException(final InstanceIdentifier path, final String message) { - super(path, message); - } - -} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTree.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTree.java deleted file mode 100644 index 4807e15653..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTree.java +++ /dev/null @@ -1,51 +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; - -import org.opendaylight.yangtools.yang.model.api.SchemaContext; - -/** - * Interface representing a data tree which can be modified in an MVCC fashion. - */ -public interface DataTree { - /** - * Take a read-only point-in-time snapshot of the tree. - * - * @return Data tree snapshot. - */ - DataTreeSnapshot takeSnapshot(); - - /** - * Make the data tree use a new schema context. The context will be used - * only by subsequent operations. - * - * @param newSchemaContext new SchemaContext - * @throws IllegalArgumentException if the new context is incompatible - */ - void setSchemaContext(SchemaContext newSchemaContext); - - /** - * Validate whether a particular modification can be applied to the data tree. - */ - void validate(DataTreeModification modification) throws DataValidationFailedException; - - /** - * Prepare a modification for commit. - * - * @param modification - * @return candidate data tree - */ - DataTreeCandidate prepare(DataTreeModification modification); - - /** - * Commit a data tree candidate. - * - * @param candidate data tree candidate - */ - void commit(DataTreeCandidate candidate); -} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeCandidate.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeCandidate.java deleted file mode 100644 index d860dfc064..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeCandidate.java +++ /dev/null @@ -1,35 +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; - -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; - -/** - * An encapsulation of a validated data tree modification. This candidate - * is ready for atomic commit to the datastore. It allows access to before- - * and after-state as it will be seen in to subsequent commit. This capture - * can be accessed for reference, but cannot be modified and the content - * is limited to nodes which were affected by the modification from which - * this instance originated. - */ -public interface DataTreeCandidate { - /** - * Get the candidate tree root node. - * - * @return Candidate tree root node - */ - DataTreeCandidateNode getRootNode(); - - /** - * Get the candidate tree root path. This is the path of the root node - * relative to the root of InstanceIdentifier namespace. - * - * @return Relative path of the root node - */ - InstanceIdentifier getRootPath(); -} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeCandidateNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeCandidateNode.java deleted file mode 100644 index 528419d235..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeCandidateNode.java +++ /dev/null @@ -1,58 +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; - -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; -import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; - -import com.google.common.base.Optional; - -/** - * A single node within a {@link DataTreeCandidate}. The nodes are organized - * in tree hierarchy, reflecting the modification from which this candidate - * was created. The node itself exposes the before- and after-image of the - * tree restricted to the modified nodes. - */ -public interface DataTreeCandidateNode { - /** - * Get the node identifier. - * - * @return The node identifier. - */ - PathArgument getIdentifier(); - - /** - * Get an unmodifiable iterable of modified child nodes. - * - * @return Unmodifiable iterable of modified child nodes. - */ - Iterable getChildNodes(); - - /** - * Return the type of modification this node is undergoing. - * - * @return Node modification type. - */ - ModificationType getModificationType(); - - /** - * Return the before-image of data corresponding to the node. - * - * @return Node data as they were present in the tree before - * the modification was applied. - */ - Optional> getDataAfter(); - - /** - * Return the after-image of data corresponding to the node. - * - * @return Node data as they will be present in the tree after - * the modification is applied. - */ - Optional> getDataBefore(); -} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeFactory.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeFactory.java deleted file mode 100644 index c6dd25c76b..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeFactory.java +++ /dev/null @@ -1,20 +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; - -/** - * Factory interface for creating data trees. - */ -public interface DataTreeFactory { - /** - * Create a new data tree. - * - * @return A data tree instance. - */ - DataTree create(); -} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeModification.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeModification.java deleted file mode 100644 index e4370c46a0..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeModification.java +++ /dev/null @@ -1,50 +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; - -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; -import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; - -/** - * Class encapsulation of set of modifications to a base tree. This tree is backed - * by a read-only snapshot and tracks modifications on top of that. The modification - * has the ability to rebase itself to a new snapshot. - */ -public interface DataTreeModification extends DataTreeSnapshot { - /** - * Delete the node at specified path. - * - * @param path Node path - */ - void delete(InstanceIdentifier path); - - /** - * Merge the specified data with the currently-present data - * at specified path. - * - * @param path Node path - * @param data Data to be merged - */ - void merge(InstanceIdentifier path, NormalizedNode data); - - /** - * Replace the data at specified path with supplied data. - * - * @param path Node path - * @param data New node data - */ - void write(InstanceIdentifier path, NormalizedNode data); - - /** - * Finish creation of a modification, making it ready for application - * to the data tree. Any calls to this object's methods will result - * in undefined behavior, possibly with an - * {@link IllegalStateException} being thrown. - */ - void ready(); -} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeSnapshot.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeSnapshot.java deleted file mode 100644 index a94acc5658..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeSnapshot.java +++ /dev/null @@ -1,37 +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; - -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; -import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; - -import com.google.common.base.Optional; - -/** - * Read-only snapshot of a {@link DataTree}. The snapshot is stable and isolated, - * e.g. data tree changes occurring after the snapshot has been taken are not - * visible through the snapshot. - */ -public interface DataTreeSnapshot { - /** - * Read a particular node from the snapshot. - * - * @param path Path of the node - * @return Optional result encapsulating the presence and value of the node - */ - Optional> readNode(InstanceIdentifier path); - - /** - * Create a new data tree modification based on this snapshot, using the - * specified data application strategy. - * - * @param strategy data modification strategy - * @return A new data tree modification - */ - DataTreeModification newModification(); -} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataValidationFailedException.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataValidationFailedException.java deleted file mode 100644 index 3683240f57..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataValidationFailedException.java +++ /dev/null @@ -1,53 +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; - -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; - -import com.google.common.base.Preconditions; - -/** - * Exception thrown when a proposed change fails validation before being - * applied into the datastore. This can have multiple reasons, for example - * the datastore has been concurrently modified such that a conflicting - * node is present, or the modification is structurally incorrect. - */ -public class DataValidationFailedException extends Exception { - private static final long serialVersionUID = 1L; - private final InstanceIdentifier path; - - /** - * Create a new instance. - * - * @param path Object path which caused this exception - * @param message Specific message describing the failure - */ - public DataValidationFailedException(final InstanceIdentifier path, final String message) { - this(path, message, null); - } - /** - * Create a new instance, initializing - * - * @param path Object path which caused this exception - * @param message Specific message describing the failure - * @param cause Exception which triggered this failure, may be null - */ - public DataValidationFailedException(final InstanceIdentifier path, final String message, final Throwable cause) { - super(message, cause); - this.path = Preconditions.checkNotNull(path); - } - - /** - * Returns the offending object path. - * - * @return Path of the offending object - */ - public InstanceIdentifier getPath() { - return path; - } -} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/IncorrectDataStructureException.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/IncorrectDataStructureException.java deleted file mode 100644 index 87482a9156..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/IncorrectDataStructureException.java +++ /dev/null @@ -1,33 +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; - -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; - -/** - * Exception thrown when a proposed change fails validation before being - * applied into the datastore because of incorrect structure of user supplied - * data. - * - */ -public class IncorrectDataStructureException extends DataValidationFailedException { - - /** - * - */ - private static final long serialVersionUID = 1L; - - public IncorrectDataStructureException(final InstanceIdentifier path, final String message, final Throwable cause) { - super(path, message, cause); - } - - public IncorrectDataStructureException(final InstanceIdentifier path, final String message) { - super(path, message); - } - -} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ModificationType.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ModificationType.java deleted file mode 100644 index b9a26f5c00..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ModificationType.java +++ /dev/null @@ -1,45 +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; - -/** - * Enumeration of all possible node modification states. These are used in - * data tree modification context to quickly assess what sort of modification - * the node is undergoing. - */ -public enum ModificationType { - /** - * Node is currently unmodified. - */ - UNMODIFIED, - - /** - * A child node, either direct or indirect, has been modified. This means - * that the data representation of this node has potentially changed. - */ - SUBTREE_MODIFIED, - - /** - * This node has been placed into the tree, potentially completely replacing - * pre-existing contents. - */ - WRITE, - - /** - * This node has been deleted along with any of its child nodes. - */ - DELETE, - - /** - * Node has been written into the tree, but instead of replacing pre-existing - * contents, it has been merged. This means that any incoming nodes which - * were present in the tree have been replaced, but their child nodes have - * been retained. - */ - MERGE, -} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreTreeNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreTreeNode.java deleted file mode 100644 index d714f1cc85..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreTreeNode.java +++ /dev/null @@ -1,29 +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; - -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; - -import com.google.common.base.Optional; - -/** - * A tree node which has references to its child leaves. This are typically - * internal non-data leaves, such as containers, lists, etc. - * - * @param Final node type - */ -public interface StoreTreeNode> { - - /** - * Returns a direct child of the node - * - * @param child Identifier of child - * @return Optional with node if the child is existing, {@link Optional#absent()} otherwise. - */ - Optional getChild(PathArgument child); -} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreUtils.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreUtils.java deleted file mode 100644 index b634866856..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreUtils.java +++ /dev/null @@ -1,70 +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; - -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier; -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates; -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.Strings; - -/** - * Data store tree manipulation utilities. - */ -public final class StoreUtils { - private static final int STRINGTREE_INDENT = 4; - - private StoreUtils() { - throw new UnsupportedOperationException("Utility class should not be instantiated"); - } - - /** - * Convert a data subtree under a node into a human-readable string format. - * - * @param node Data subtree root - * @return String containing a human-readable form of the subtree. - */ - public static String toStringTree(final NormalizedNode node) { - final StringBuilder builder = new StringBuilder(); - toStringTree(builder, node, 0); - return builder.toString(); - } - - private static void toStringTree(final StringBuilder builder, final NormalizedNode node, final int offset) { - final String prefix = Strings.repeat(" ", offset); - - builder.append(prefix).append(toStringTree(node.getIdentifier())); - if (node instanceof NormalizedNodeContainer) { - final NormalizedNodeContainer container = (NormalizedNodeContainer) node; - - builder.append(" {\n"); - for (NormalizedNode child : container.getValue()) { - toStringTree(builder, child, offset + STRINGTREE_INDENT); - } - - builder.append(prefix).append('}'); - } else { - builder.append(' ').append(node.getValue()); - } - builder.append('\n'); - } - - private static String toStringTree(final PathArgument identifier) { - if (identifier instanceof NodeIdentifierWithPredicates) { - StringBuilder builder = new StringBuilder(); - builder.append(identifier.getNodeType().getLocalName()); - builder.append(((NodeIdentifierWithPredicates) identifier).getKeyValues().values()); - return builder.toString(); - } else if (identifier instanceof AugmentationIdentifier) { - return "augmentation"; - } - return identifier.getNodeType().getLocalName(); - } -} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/TreeNodeUtils.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/TreeNodeUtils.java deleted file mode 100644 index fe98468b5c..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/TreeNodeUtils.java +++ /dev/null @@ -1,107 +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; - -import java.util.AbstractMap.SimpleEntry; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -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.base.Preconditions; -import com.google.common.base.Predicate; -import com.google.common.base.Predicates; - -/** - * A set of utility methods for interacting with {@link org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode} objects. - */ -public final class TreeNodeUtils { - private TreeNodeUtils() { - throw new UnsupportedOperationException("Utility class should not be instantiated"); - } - - /** - * Finds a node in tree - * - * @param tree Data Tree - * @param path Path to the node - * @return Optional with node if the node is present in tree, {@link Optional#absent()} otherwise. - */ - public static > Optional findNode(final T tree, final InstanceIdentifier path) { - Optional current = Optional. of(tree); - Iterator pathIter = path.getPath().iterator(); - while (current.isPresent() && pathIter.hasNext()) { - current = current.get().getChild(pathIter.next()); - } - return current; - } - - public static > T findNodeChecked(final T tree, final InstanceIdentifier path) { - T current = tree; - List nested = new ArrayList<>(path.getPath().size()); - for(PathArgument pathArg : path.getPath()) { - Optional potential = current.getChild(pathArg); - nested.add(pathArg); - Preconditions.checkArgument(potential.isPresent(),"Child %s is not present in tree.",nested); - current = potential.get(); - } - return current; - } - - /** - * Finds a node or closest parent in the tree - * - * @param tree Data Tree - * @param path Path to the node - * @return Map.Entry Entry with key which is path to closest parent and value is parent node. - * - */ - public static > Map.Entry findClosest(final T tree, final InstanceIdentifier path) { - return findClosestsOrFirstMatch(tree, path, Predicates.alwaysFalse()); - } - - public static > Map.Entry findClosestsOrFirstMatch(final T tree, final InstanceIdentifier path, final Predicate predicate) { - Optional parent = Optional.of(tree); - Optional current = Optional. of(tree); - - int nesting = 0; - Iterator pathIter = path.getPath().iterator(); - while (current.isPresent() && pathIter.hasNext() && !predicate.apply(current.get())) { - parent = current; - current = current.get().getChild(pathIter.next()); - nesting++; - } - if(current.isPresent()) { - final InstanceIdentifier currentPath = new InstanceIdentifier(path.getPath().subList(0, nesting)); - return new SimpleEntry(currentPath,current.get()); - } - - /* - * Subtracting 1 from nesting level at this point is safe, because we - * cannot reach here with nesting == 0: that would mean the above check - * for current.isPresent() failed, which it cannot, as current is always - * present. At any rate we check state just to be on the safe side. - */ - Preconditions.checkState(nesting > 0); - final InstanceIdentifier parentPath = new InstanceIdentifier(path.getPath().subList(0, nesting - 1)); - - return new SimpleEntry(parentPath,parent.get()); - } - - public static > Optional getChild(final Optional parent,final PathArgument child) { - if(parent.isPresent()) { - return parent.get().getChild(child); - } - return Optional.absent(); - } - -} 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 deleted file mode 100644 index cddda5ccc5..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/AbstractDataTreeCandidate.java +++ /dev/null @@ -1,27 +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.controller.md.sal.dom.store.impl.tree.DataTreeCandidate; -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; - -import com.google.common.base.Preconditions; - -abstract class AbstractDataTreeCandidate implements DataTreeCandidate { - private final InstanceIdentifier rootPath; - - protected AbstractDataTreeCandidate(final InstanceIdentifier rootPath) { - this.rootPath = Preconditions.checkNotNull(rootPath); - } - - @Override - public final InstanceIdentifier getRootPath() { - return rootPath; - } - -} 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 deleted file mode 100644 index c09a1a38b5..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/AlwaysFailOperation.java +++ /dev/null @@ -1,37 +0,0 @@ -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; - -/** - * 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 ModifiedNode modification, - final Optional storeMeta, final Version version) { - throw new IllegalStateException("Schema Context is not available."); - } - - @Override - public void checkApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional storeMetadata) { - throw new IllegalStateException("Schema Context is not available."); - } - - @Override - public Optional getChild(final PathArgument child) { - throw new IllegalStateException("Schema Context is not available."); - } - - @Override - 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 deleted file mode 100644 index dc891482ab..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/DataNodeContainerModificationStrategy.java +++ /dev/null @@ -1,160 +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.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 deleted file mode 100644 index 803105f264..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTree.java +++ /dev/null @@ -1,137 +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 com.google.common.base.Optional; -import com.google.common.base.Preconditions; -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.DataValidationFailedException; -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; -import org.slf4j.LoggerFactory; - -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -/** - * Read-only snapshot of the data tree. - */ -final class InMemoryDataTree implements DataTree { - private static final Logger LOG = LoggerFactory.getLogger(InMemoryDataTree.class); - private static final InstanceIdentifier PUBLIC_ROOT_PATH = InstanceIdentifier.builder().build(); - - private final ReadWriteLock rwLock = new ReentrantReadWriteLock(true); - private ModificationApplyOperation applyOper = new AlwaysFailOperation(); - private SchemaContext currentSchemaContext; - private TreeNode rootNode; - - public InMemoryDataTree(final TreeNode rootNode, final SchemaContext schemaContext) { - this.rootNode = Preconditions.checkNotNull(rootNode); - - if (schemaContext != null) { - // Also sets applyOper - setSchemaContext(schemaContext); - } - } - - @Override - public synchronized void setSchemaContext(final SchemaContext newSchemaContext) { - Preconditions.checkNotNull(newSchemaContext); - - LOG.info("Attepting to install schema context {}", newSchemaContext); - - /* - * FIXME: we should walk the schema contexts, both current and new and see - * whether they are compatible here. Reject incompatible changes. - */ - - // Instantiate new apply operation, this still may fail - final ModificationApplyOperation newApplyOper = SchemaAwareApplyOperation.from(newSchemaContext); - - // Ready to change the context now, make sure no operations are running - rwLock.writeLock().lock(); - try { - this.applyOper = newApplyOper; - this.currentSchemaContext = newSchemaContext; - } finally { - rwLock.writeLock().unlock(); - } - } - - @Override - public InMemoryDataTreeSnapshot takeSnapshot() { - rwLock.readLock().lock(); - try { - return new InMemoryDataTreeSnapshot(currentSchemaContext, rootNode, applyOper); - } finally { - rwLock.readLock().unlock(); - } - } - - @Override - public void validate(final DataTreeModification modification) throws DataValidationFailedException { - 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)); - } - - @Override - public synchronized DataTreeCandidate prepare(final DataTreeModification modification) { - Preconditions.checkArgument(modification instanceof InMemoryDataTreeModification, "Invalid modification class %s", modification.getClass()); - - final InMemoryDataTreeModification m = (InMemoryDataTreeModification)modification; - final ModifiedNode root = m.getRootModification(); - - if (root.getType() == ModificationType.UNMODIFIED) { - return new NoopDataTreeCandidate(PUBLIC_ROOT_PATH, root); - } - - rwLock.writeLock().lock(); - try { - 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 { - rwLock.writeLock().unlock(); - } - } - - @Override - public synchronized void commit(final DataTreeCandidate candidate) { - if (candidate instanceof NoopDataTreeCandidate) { - return; - } - - Preconditions.checkArgument(candidate instanceof InMemoryDataTreeCandidate, "Invalid candidate class %s", candidate.getClass()); - final InMemoryDataTreeCandidate c = (InMemoryDataTreeCandidate)candidate; - - LOG.debug("Updating datastore from {} to {}", rootNode, c.getAfterRoot()); - - if (LOG.isTraceEnabled()) { - LOG.trace("Data Tree is {}", StoreUtils.toStringTree(c.getAfterRoot().getData())); - } - - // Ready to change the context now, make sure no operations are running - rwLock.writeLock().lock(); - try { - Preconditions.checkState(c.getBeforeRoot() == rootNode, - 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 deleted file mode 100644 index bafea6bd97..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeCandidate.java +++ /dev/null @@ -1,125 +0,0 @@ -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 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 deleted file mode 100644 index 4640be43e7..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeFactory.java +++ /dev/null @@ -1,37 +0,0 @@ -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; -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 InMemoryDataTreeFactory() { - // Never instantiated externally - } - - @Override - public InMemoryDataTree create() { - final NodeIdentifier root = new NodeIdentifier(SchemaContext.NAME); - final NormalizedNode data = Builders.containerBuilder().withNodeIdentifier(root).build(); - - 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; - } -} 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 deleted file mode 100644 index 39ff4f0aa0..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeModification.java +++ /dev/null @@ -1,178 +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 java.util.Map.Entry; - -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.ModificationType; -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; -import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer; -import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; - -final class InMemoryDataTreeModification implements DataTreeModification { - private static final Logger LOG = LoggerFactory.getLogger(InMemoryDataTreeModification.class); - private final ModificationApplyOperation strategyTree; - private final InMemoryDataTreeSnapshot snapshot; - 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 = ModifiedNode.createUnmodified(snapshot.getRootNode()); - } - - ModifiedNode getRootModification() { - return rootNode; - } - - ModificationApplyOperation getStrategy() { - return strategyTree; - } - - @Override - public synchronized void write(final InstanceIdentifier path, final NormalizedNode value) { - checkSealed(); - resolveModificationFor(path).write(value); - } - - @Override - public synchronized void merge(final InstanceIdentifier path, final NormalizedNode data) { - checkSealed(); - mergeImpl(resolveModificationFor(path),data); - } - - private void mergeImpl(final OperationWithModification op,final NormalizedNode data) { - - if(data instanceof NormalizedNodeContainer) { - @SuppressWarnings({ "rawtypes", "unchecked" }) - NormalizedNodeContainer> dataContainer = (NormalizedNodeContainer) data; - for(NormalizedNode child : dataContainer.getValue()) { - PathArgument childId = child.getIdentifier(); - mergeImpl(op.forChild(childId), child); - } - } - op.merge(data); - } - - @Override - public synchronized void delete(final InstanceIdentifier path) { - checkSealed(); - resolveModificationFor(path).delete(); - } - - @Override - 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(key, data, path); - } else { - return Optional.absent(); - } - } - - private Optional resolveSnapshot(final InstanceIdentifier path, - final ModifiedNode modification) { - final Optional> potentialSnapshot = modification.getSnapshotCache(); - if(potentialSnapshot.isPresent()) { - return potentialSnapshot.get(); - } - - try { - return resolveModificationStrategy(path).apply(modification, modification.getOriginal(), - snapshot.getRootNode().getSubtreeVersion().next()); - } catch (Exception e) { - LOG.error("Could not create snapshot for {}:{}", path,modification,e); - throw e; - } - } - - private ModificationApplyOperation resolveModificationStrategy(final InstanceIdentifier path) { - LOG.trace("Resolving modification apply strategy for {}", path); - return TreeNodeUtils.findNodeChecked(strategyTree, path); - } - - private OperationWithModification resolveModificationFor(final InstanceIdentifier path) { - ModifiedNode modification = rootNode; - // We ensure strategy is present. - ModificationApplyOperation operation = resolveModificationStrategy(path); - for (PathArgument pathArg : path.getPath()) { - modification = modification.modifyChild(pathArg); - } - return OperationWithModification.from(operation, modification); - } - - @Override - public synchronized void ready() { - Preconditions.checkState(!sealed, "Attempted to seal an already-sealed Data Tree."); - sealed = true; - rootNode.seal(); - } - - @GuardedBy("this") - private void checkSealed() { - Preconditions.checkState(!sealed, "Data Tree is sealed. No further modifications allowed."); - } - - @Override - public String toString() { - return "MutableDataTree [modification=" + rootNode + "]"; - } - - @Override - public synchronized DataTreeModification newModification() { - Preconditions.checkState(sealed, "Attempted to chain on an unsealed modification"); - - if(rootNode.getType() == ModificationType.UNMODIFIED) { - return snapshot.newModification(); - } - - /* - * FIXME: Add advanced transaction chaining for modification of not rebased - * modification. - * - * Current computation of tempRoot may yeld incorrect subtree versions - * if there are multiple concurrent transactions, which may break - * versioning preconditions for modification of previously occured write, - * directly nested under parent node, since node version is derived from - * subtree version. - * - * For deeper nodes subtree version is derived from their respective metadata - * nodes, so this incorrect root subtree version is not affecting us. - */ - TreeNode originalSnapshotRoot = snapshot.getRootNode(); - Optional tempRoot = strategyTree.apply(rootNode, Optional.of(originalSnapshotRoot), originalSnapshotRoot.getSubtreeVersion().next()); - - InMemoryDataTreeSnapshot tempTree = new InMemoryDataTreeSnapshot(snapshot.getSchemaContext(), tempRoot.get(), strategyTree); - return tempTree.newModification(); - } -} 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 deleted file mode 100644 index ee91e62518..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeSnapshot.java +++ /dev/null @@ -1,48 +0,0 @@ -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; -import org.opendaylight.yangtools.yang.model.api.SchemaContext; - -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; - -final class InMemoryDataTreeSnapshot implements DataTreeSnapshot { - private final ModificationApplyOperation applyOper; - private final SchemaContext schemaContext; - private final TreeNode 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); - } - - TreeNode getRootNode() { - return rootNode; - } - - SchemaContext getSchemaContext() { - return schemaContext; - } - - @Override - public Optional> readNode(final InstanceIdentifier path) { - return NormalizedNodeUtils.findNode(rootNode.getData(), path); - } - - @Override - public InMemoryDataTreeModification newModification() { - return new InMemoryDataTreeModification(this, applyOper); - } - - @Override - public String toString() { - return rootNode.getSubtreeVersion().toString(); - } - -} \ 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/ModificationApplyOperation.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationApplyOperation.java deleted file mode 100644 index f72d575194..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationApplyOperation.java +++ /dev/null @@ -1,93 +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.controller.md.sal.dom.store.impl.tree.DataValidationFailedException; -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; - -/** - * - * 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 - * invoke suboperations independently. - * - * Implementation notes - *
    - *
  • - * 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(ModifiedNode, Optional)} if applicable. - * - * - * Hierarchical composite operation which is responsible for applying - * modification on particular subtree and creating updated subtree - * - * - */ -interface ModificationApplyOperation extends StoreTreeNode { - - /** - * - * Implementation of this operation must be stateless and must not change - * state of this object. - * - * @param modification - * NodeModification to be applied - * @param storeMeta - * Store Metadata Node on which NodeModification should be - * applied - * @param version New subtree version of parent node - * @throws IllegalArgumentException - * If it is not possible to apply Operation on provided Metadata - * node - * @return new {@link StoreMetadataNode} if operation resulted in updating - * node, {@link Optional#absent()} if {@link ModifiedNode} - * resulted in deletion of this node. - */ - Optional apply(ModifiedNode modification, Optional storeMeta, Version version); - - /** - * - * Performs structural verification of NodeModification, such as writen values / types - * uses right structural elements. - * - * @param modification to be verified. - * @throws IllegalArgumentException If provided NodeModification does not adhere to the structure. - */ - void verifyStructure(ModifiedNode modification) throws IllegalArgumentException; - - /** - * Returns a suboperation for specified tree node - * - * @return Reference to suboperation for specified tree node, {@link Optional#absent()} - * if suboperation is not supported for specified tree node. - */ - @Override - Optional getChild(PathArgument child); - - /** - * - * Checks if provided node modification could be applied to current metadata node. - * - * @param modification Modification - * @param current Metadata Node to which modification should be applied - * @return true if modification is applicable - * false if modification is no applicable - * @throws DataValidationFailedException - */ - void checkApplicable(InstanceIdentifier path, NodeModification modification, Optional current) throws DataValidationFailedException; -} 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 deleted file mode 100644 index f83ea1a2de..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModifiedNode.java +++ /dev/null @@ -1,225 +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 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 deleted file mode 100644 index e7e79f8916..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NodeModification.java +++ /dev/null @@ -1,44 +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.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 com.google.common.base.Optional; - -/** - * Internal interface representing a modification action of a particular node. - * It is used by the validation code to allow for a read-only view of the - * modification tree as we should never modify that during validation. - */ -interface NodeModification extends Identifiable { - /** - * Get the type of modification. - * - * @return Modification type. - */ - ModificationType getType(); - - /** - * Get the original tree node to which the modification is to be applied. - * - * @return The original node, or {@link Optional#absent()} if the node is - * a new node. - */ - Optional getOriginal(); - - /** - * Get a read-only view of children nodes. - * - * @return Iterable of all children nodes. - */ - 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 deleted file mode 100644 index 227684ae35..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NoopDataTreeCandidate.java +++ /dev/null @@ -1,63 +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 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; - -/** - * Internal utility class for an empty candidate. We instantiate this class - * for empty modifications, saving memory and processing speed. Instances - * of this class are explicitly recognized and processing of them is skipped. - */ -final class NoopDataTreeCandidate extends AbstractDataTreeCandidate { - 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 deleted file mode 100644 index 1d10ab6ea5..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NormalizedNodeContainerModificationStrategy.java +++ /dev/null @@ -1,337 +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.checkArgument; - -import java.util.Map; - -import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataValidationFailedException; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType; -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 DataValidationFailedException { - // 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 version) { - final NormalizedNode newValue = modification.getWrittenValue(); - final TreeNode newValueMeta = TreeNodeFactory.createTreeNode(newValue, version); - - 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(version); - - @SuppressWarnings("rawtypes") - final NormalizedNodeContainerBuilder dataBuilder = createBuilder(newValue); - - return mutateChildren(mutable, dataBuilder, version, 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 version) { - // For Node Containers - merge is same as subtree change - we only replace children. - return applySubtreeChange(modification, currentMeta, version); - } - - @Override - public TreeNode applySubtreeChange(final ModifiedNode modification, - final TreeNode currentMeta, final Version version) { - final MutableTreeNode newMeta = currentMeta.mutable(); - newMeta.setSubtreeVersion(version); - - @SuppressWarnings("rawtypes") - NormalizedNodeContainerBuilder dataBuilder = createBuilder(currentMeta.getData()); - - return mutateChildren(newMeta, dataBuilder, version, modification.getChildren()); - } - - @Override - protected void checkSubtreeModificationApplicable(final InstanceIdentifier path, final NodeModification modification, - final Optional current) throws DataValidationFailedException { - checkConflicting(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 DataValidationFailedException { - final TreeNode currentMeta = current.get(); - for (NodeModification childMod : modification.getChildren()) { - final PathArgument childId = childMod.getIdentifier(); - final Optional childMeta = currentMeta.getChild(childId); - - InstanceIdentifier childPath = path.node(childId); - resolveChildOperation(childId).checkApplicable(childPath, childMod, childMeta); - } - } - - @Override - protected void checkMergeApplicable(final InstanceIdentifier path, final NodeModification modification, - final Optional current) throws DataValidationFailedException { - 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 deleted file mode 100644 index e1cc1a17e5..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/OperationWithModification.java +++ /dev/null @@ -1,68 +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.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; - -final class OperationWithModification { - - private final ModifiedNode modification; - - private final ModificationApplyOperation applyOperation; - - private OperationWithModification(final ModificationApplyOperation op, final ModifiedNode mod) { - this.modification = mod; - this.applyOperation = op; - } - - public OperationWithModification write(final NormalizedNode value) { - modification.write(value); - applyOperation.verifyStructure(modification); - return this; - } - - public OperationWithModification delete() { - modification.delete(); - return this; - } - - public ModifiedNode getModification() { - return modification; - } - - public ModificationApplyOperation getApplyOperation() { - return applyOperation; - } - - public Optional apply(final Optional data, final Version version) { - return applyOperation.apply(modification, data, version); - } - - public static OperationWithModification from(final ModificationApplyOperation operation, - final ModifiedNode modification) { - return new OperationWithModification(operation, modification); - - } - - public void merge(final NormalizedNode data) { - modification.merge(data); - applyOperation.verifyStructure(modification); - - } - - public OperationWithModification forChild(final PathArgument 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 deleted file mode 100644 index f6006359af..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperation.java +++ /dev/null @@ -1,281 +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.checkArgument; - -import java.util.List; - -import org.opendaylight.controller.md.sal.dom.store.impl.tree.ConflictingModificationAppliedException; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataValidationFailedException; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.IncorrectDataStructureException; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.DataNodeContainerModificationStrategy.ContainerModificationStrategy; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.DataNodeContainerModificationStrategy.UnkeyedListItemModificationStrategy; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.NormalizedNodeContainerModificationStrategy.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.PathArgument; -import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; -import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; -import org.opendaylight.yangtools.yang.model.api.AugmentationTarget; -import org.opendaylight.yangtools.yang.model.api.ChoiceNode; -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.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.Optional; -import com.google.common.base.Preconditions; - -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) { - return new ContainerModificationStrategy((ContainerSchemaNode) schemaNode); - } else if (schemaNode instanceof ListSchemaNode) { - return fromListSchemaNode((ListSchemaNode) schemaNode); - } else if (schemaNode instanceof ChoiceNode) { - return new ChoiceModificationStrategy((ChoiceNode) schemaNode); - } else if (schemaNode instanceof LeafListSchemaNode) { - return fromLeafListSchemaNode((LeafListSchemaNode) schemaNode); - } else if (schemaNode instanceof LeafSchemaNode) { - return new LeafModificationStrategy((LeafSchemaNode) schemaNode); - } - 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 checkConflicting(final InstanceIdentifier path, final boolean condition, final String message) throws ConflictingModificationAppliedException { - if(!condition) { - throw new ConflictingModificationAppliedException(path, message); - } - return condition; - } - - private static SchemaAwareApplyOperation fromListSchemaNode(final ListSchemaNode schemaNode) { - List keyDefinition = schemaNode.getKeyDefinition(); - if (keyDefinition == null || keyDefinition.isEmpty()) { - return new UnkeyedListModificationStrategy(schemaNode); - } - if (schemaNode.isUserOrdered()) { - return new OrderedMapModificationStrategy(schemaNode); - } - - return new NormalizedNodeContainerModificationStrategy.UnorderedMapModificationStrategy(schemaNode); - } - - private static SchemaAwareApplyOperation fromLeafListSchemaNode(final LeafListSchemaNode schemaNode) { - if(schemaNode.isUserOrdered()) { - return new OrderedLeafSetModificationStrategy(schemaNode); - } else { - return new UnorderedLeafSetModificationStrategy(schemaNode); - } - } - - private static final void checkNotConflicting(final InstanceIdentifier path, final TreeNode original, final TreeNode current) throws ConflictingModificationAppliedException { - checkConflicting(path, original.getVersion().equals(current.getVersion()), - "Node was replaced by other transaction."); - checkConflicting(path, original.getSubtreeVersion().equals(current.getSubtreeVersion()), - "Node children was modified by other transaction"); - } - - protected final ModificationApplyOperation resolveChildOperation(final PathArgument child) { - Optional potential = getChild(child); - checkArgument(potential.isPresent(), "Operation for child %s is not defined.", child); - return potential.get(); - } - - @Override - public void verifyStructure(final ModifiedNode modification) throws IllegalArgumentException { - if (modification.getType() == ModificationType.WRITE) { - verifyWrittenStructure(modification.getWrittenValue()); - } - } - - @Override - public final void checkApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional current) throws DataValidationFailedException { - switch (modification.getType()) { - case DELETE: - checkDeleteApplicable(modification, current); - case SUBTREE_MODIFIED: - checkSubtreeModificationApplicable(path, modification, current); - return; - case WRITE: - checkWriteApplicable(path, modification, current); - return; - case MERGE: - checkMergeApplicable(path, modification, current); - return; - case UNMODIFIED: - return; - default: - throw new UnsupportedOperationException("Suplied modification type "+ modification.getType()+ "is not supported."); - } - - } - - protected void checkMergeApplicable(final InstanceIdentifier path, final NodeModification modification, final Optional current) throws DataValidationFailedException { - Optional original = modification.getOriginal(); - if (original.isPresent() && current.isPresent()) { - /* - * We need to do conflict detection only and only if the value of leaf changed - * before two transactions. If value of leaf is unchanged between two transactions - * it should not cause transaction to fail, since result of this merge - * leads to same data. - */ - if(!original.get().getData().equals(current.get().getData())) { - checkNotConflicting(path, original.get(), current.get()); - } - } - } - - protected void checkWriteApplicable(final InstanceIdentifier path, final NodeModification modification, final Optional current) throws DataValidationFailedException { - Optional original = modification.getOriginal(); - if (original.isPresent() && current.isPresent()) { - checkNotConflicting(path, original.get(), current.get()); - } else if(original.isPresent()) { - throw new ConflictingModificationAppliedException(path,"Node was deleted by other transaction."); - } - } - - 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 ModifiedNode modification, - final Optional currentMeta, final Version version) { - - switch (modification.getType()) { - case DELETE: - return modification.storeSnapshot(Optional. absent()); - case SUBTREE_MODIFIED: - Preconditions.checkArgument(currentMeta.isPresent(), "Metadata not available for modification", - modification); - return modification.storeSnapshot(Optional.of(applySubtreeChange(modification, currentMeta.get(), - version))); - case MERGE: - if(currentMeta.isPresent()) { - return modification.storeSnapshot(Optional.of(applyMerge(modification,currentMeta.get(), version))); - } // Fallback to write is intentional - if node is not preexisting merge is same as write - case WRITE: - return modification.storeSnapshot(Optional.of(applyWrite(modification, currentMeta, version))); - case UNMODIFIED: - return currentMeta; - default: - throw new IllegalArgumentException("Provided modification type is not supported."); - } - } - - protected abstract TreeNode applyMerge(ModifiedNode modification, - TreeNode currentMeta, Version version); - - protected abstract TreeNode applyWrite(ModifiedNode modification, - Optional currentMeta, Version version); - - protected abstract TreeNode applySubtreeChange(ModifiedNode modification, - TreeNode currentMeta, Version version); - - /** - * - * Checks is supplied {@link NodeModification} is applicable for Subtree Modification. - * - * @param path Path to current node - * @param modification Node modification which should be applied. - * @param current Current state of data tree - * @throws ConflictingModificationAppliedException If subtree was changed in conflicting way - * @throws IncorrectDataStructureException If subtree modification is not applicable (e.g. leaf node). - */ - protected abstract void checkSubtreeModificationApplicable(InstanceIdentifier path, final NodeModification modification, - final Optional current) throws DataValidationFailedException; - - protected abstract void verifyWrittenStructure(NormalizedNode writtenValue); - - public static class UnkeyedListModificationStrategy extends SchemaAwareApplyOperation { - - private final Optional entryStrategy; - - protected UnkeyedListModificationStrategy(final ListSchemaNode schema) { - entryStrategy = Optional. of(new UnkeyedListItemModificationStrategy(schema)); - } - - @Override - protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta, - final Version version) { - return applyWrite(modification, Optional.of(currentMeta), version); - } - - @Override - protected TreeNode applySubtreeChange(final ModifiedNode modification, - final TreeNode currentMeta, final Version version) { - throw new UnsupportedOperationException("UnkeyedList does not support subtree change."); - } - - @Override - protected TreeNode applyWrite(final ModifiedNode modification, - final Optional currentMeta, final Version version) { - return TreeNodeFactory.createTreeNode(modification.getWrittenValue(), version); - } - - @Override - public Optional getChild(final PathArgument child) { - if (child instanceof NodeIdentifier) { - return entryStrategy; - } - return Optional.absent(); - } - - @Override - protected void verifyWrittenStructure(final NormalizedNode writtenValue) { - - } - - @Override - protected void checkSubtreeModificationApplicable(final InstanceIdentifier path, final NodeModification modification, - final Optional current) throws IncorrectDataStructureException { - throw new IncorrectDataStructureException(path, "Subtree modification is not allowed."); - } - } -} 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 deleted file mode 100644 index 900fa320a1..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ValueNodeModificationStrategy.java +++ /dev/null @@ -1,88 +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.checkArgument; - -import org.opendaylight.controller.md.sal.dom.store.impl.tree.IncorrectDataStructureException; -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 version) { - 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 version) { - // Just overwrite whatever was there - return applyWrite(modification, null, version); - } - - @Override - protected TreeNode applyWrite(final ModifiedNode modification, - final Optional currentMeta, final Version version) { - return TreeNodeFactory.createTreeNode(modification.getWrittenValue(), version); - } - - @Override - protected void checkSubtreeModificationApplicable(final InstanceIdentifier path, final NodeModification modification, - final Optional current) throws IncorrectDataStructureException { - throw new IncorrectDataStructureException(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 deleted file mode 100644 index 522bf3c84d..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/AbstractTreeNode.java +++ /dev/null @@ -1,41 +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.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 deleted file mode 100644 index 3ca8db2405..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/ContainerNode.java +++ /dev/null @@ -1,118 +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.spi; - -import java.util.HashMap; -import java.util.Map; - -import org.opendaylight.yangtools.util.MapAdaptor; -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 Version version; - private Map children; - private NormalizedNode data; - private Version subtreeVersion; - - private Mutable(final ContainerNode parent) { - this.data = parent.getData(); - this.children = MapAdaptor.getDefaultInstance().takeSnapshot(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 TreeNode ret = new ContainerNode(data, version, MapAdaptor.getDefaultInstance().optimize(children), subtreeVersion); - - // This forces a NPE if this class is accessed again. Better than corruption. - children = null; - return ret; - } - - @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 deleted file mode 100644 index 087f4de666..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/MutableTreeNode.java +++ /dev/null @@ -1,59 +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.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; - -/** - * A mutable tree node. This is a transient view materialized from a pre-existing - * node. Modifications are isolated. Once this object is {@link #seal()}-ed, - * any interactions with it will result in undefined behavior. - */ -public interface MutableTreeNode extends StoreTreeNode { - /** - * Set the data component of the node. - * - * @param data New data component, may not be null. - */ - void setData(NormalizedNode data); - - /** - * Set the new subtree version. This is typically invoked when the user - * has modified some of this node's children. - * - * @param subtreeVersion New subtree version. - */ - void setSubtreeVersion(Version subtreeVersion); - - /** - * Add a new child node. This acts as add-or-replace operation, e.g. it - * succeeds even if a conflicting child is already present. - * - * @param child New child node. - */ - void addChild(TreeNode child); - - /** - * Remove a child node. This acts as delete-or-nothing operation, e.g. it - * succeeds even if the corresponding child is not present. - * - * @param id Child identificator. - */ - void removeChild(PathArgument id); - - /** - * Finish node modification and return a read-only view of this node. After - * this method is invoked, any further calls to this object's method result - * in undefined behavior. - * - * @return Read-only view of this node. - */ - 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 deleted file mode 100644 index def1958123..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/TreeNode.java +++ /dev/null @@ -1,48 +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.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 deleted file mode 100644 index 9547628ae9..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/TreeNodeFactory.java +++ /dev/null @@ -1,46 +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.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 entrypoint for other packages. Allows instantiating a tree node - * with specified version. - */ -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 deleted file mode 100644 index d89928b51e..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/ValueNode.java +++ /dev/null @@ -1,48 +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.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; - -/** - * Concretization of AbstractTreeNode for leaf nodes which only contain data. - * Instances of this class report all children as absent, subtree version - * equal to this node's version and do not support mutable view. - */ -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 deleted file mode 100644 index 09a35d3b1a..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/Version.java +++ /dev/null @@ -1,37 +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.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/yang/opendaylight-dom-broker-impl.yang b/opendaylight/md-sal/sal-dom-broker/src/main/yang/opendaylight-dom-broker-impl.yang index 3c29fe5885..82897b0198 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/yang/opendaylight-dom-broker-impl.yang +++ b/opendaylight/md-sal/sal-dom-broker/src/main/yang/opendaylight-dom-broker-impl.yang @@ -6,9 +6,14 @@ module opendaylight-sal-dom-broker-impl { import config { prefix config; revision-date 2013-04-05; } import opendaylight-md-sal-dom {prefix sal;} import opendaylight-md-sal-common {prefix common;} + import opendaylight-config-dom-datastore {prefix config-dom-store-spi;} + import opendaylight-operational-dom-datastore {prefix operational-dom-store-spi;} description - "Service definition for Binding Aware MD-SAL."; + "Service definition for Binding Aware MD-SAL. + Note: The dom-inmemory-data-broker utilizes configurable config-dom-datastore + and operation-dom-datastore. If configuration is not done for this stores + then it defaults to InMemoryDOMDataStore"; revision "2013-10-28" { description @@ -66,7 +71,8 @@ module opendaylight-sal-dom-broker-impl { augment "/config:modules/config:module/config:configuration" { case dom-inmemory-data-broker { when "/config:modules/config:module/config:type = 'dom-inmemory-data-broker'"; - + + container schema-service { uses config:service-ref { refine type { @@ -74,7 +80,25 @@ module opendaylight-sal-dom-broker-impl { config:required-identity sal:schema-service; } } - + + } + + container config-data-store{ + uses config:service-ref { + refine type { + mandatory false; + config:required-identity config-dom-store-spi:config-dom-datastore; + } + } + } + + container operational-data-store{ + uses config:service-ref { + refine type { + mandatory false; + config:required-identity operational-dom-store-spi:operational-dom-datastore; + } + } } } } diff --git a/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMBrokerPerformanceTest.java b/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMBrokerPerformanceTest.java index 66d57f9f87..29e078918e 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMBrokerPerformanceTest.java +++ b/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMBrokerPerformanceTest.java @@ -63,8 +63,8 @@ public class DOMBrokerPerformanceTest { @Before public void setupStore() { - InMemoryDOMDataStore operStore = new InMemoryDOMDataStore("OPER", MoreExecutors.sameThreadExecutor()); - InMemoryDOMDataStore configStore = new InMemoryDOMDataStore("CFG", MoreExecutors.sameThreadExecutor()); + InMemoryDOMDataStore operStore = new InMemoryDOMDataStore("OPER", MoreExecutors.sameThreadExecutor()); + InMemoryDOMDataStore configStore = new InMemoryDOMDataStore("CFG", MoreExecutors.sameThreadExecutor()); schemaContext = TestModel.createTestContext(); operStore.onGlobalContextUpdated(schemaContext); diff --git a/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDataStoreTest.java b/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDataStoreTest.java deleted file mode 100644 index 413d81d029..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDataStoreTest.java +++ /dev/null @@ -1,250 +0,0 @@ -package org.opendaylight.controller.md.sal.dom.store.impl; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.util.concurrent.ExecutionException; - -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadTransaction; -import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction; -import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort; -import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransactionChain; -import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; -import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes; -import org.opendaylight.yangtools.yang.model.api.SchemaContext; - -import com.google.common.base.Optional; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.MoreExecutors; - -public class InMemoryDataStoreTest { - - private SchemaContext schemaContext; - private InMemoryDOMDataStore domStore; - - @Before - public void setupStore() { - domStore = new InMemoryDOMDataStore("TEST", MoreExecutors.sameThreadExecutor()); - schemaContext = TestModel.createTestContext(); - domStore.onGlobalContextUpdated(schemaContext); - - } - - @Test - public void testTransactionIsolation() throws InterruptedException, ExecutionException { - - assertNotNull(domStore); - - DOMStoreReadTransaction readTx = domStore.newReadOnlyTransaction(); - assertNotNull(readTx); - - DOMStoreReadWriteTransaction writeTx = domStore.newReadWriteTransaction(); - assertNotNull(writeTx); - /** - * - * Writes /test in writeTx - * - */ - writeTx.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME)); - - /** - * - * Reads /test from writeTx Read should return container. - * - */ - ListenableFuture>> writeTxContainer = writeTx.read(TestModel.TEST_PATH); - assertTrue(writeTxContainer.get().isPresent()); - - /** - * - * Reads /test from readTx Read should return Absent. - * - */ - ListenableFuture>> readTxContainer = readTx.read(TestModel.TEST_PATH); - assertFalse(readTxContainer.get().isPresent()); - } - - @Test - public void testTransactionCommit() throws InterruptedException, ExecutionException { - - DOMStoreReadWriteTransaction writeTx = domStore.newReadWriteTransaction(); - assertNotNull(writeTx); - /** - * - * Writes /test in writeTx - * - */ - writeTx.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME)); - - /** - * - * Reads /test from writeTx Read should return container. - * - */ - ListenableFuture>> writeTxContainer = writeTx.read(TestModel.TEST_PATH); - assertTrue(writeTxContainer.get().isPresent()); - - DOMStoreThreePhaseCommitCohort cohort = writeTx.ready(); - - assertThreePhaseCommit(cohort); - - Optional> afterCommitRead = domStore.newReadOnlyTransaction().read(TestModel.TEST_PATH) - .get(); - assertTrue(afterCommitRead.isPresent()); - } - - @Test - public void testTransactionAbort() throws InterruptedException, ExecutionException { - - DOMStoreReadWriteTransaction writeTx = domStore.newReadWriteTransaction(); - assertNotNull(writeTx); - - assertTestContainerWrite(writeTx); - - DOMStoreThreePhaseCommitCohort cohort = writeTx.ready(); - - assertTrue(cohort.canCommit().get().booleanValue()); - cohort.preCommit().get(); - cohort.abort().get(); - - Optional> afterCommitRead = domStore.newReadOnlyTransaction().read(TestModel.TEST_PATH) - .get(); - assertFalse(afterCommitRead.isPresent()); - } - - @Test - public void testTransactionChain() throws InterruptedException, ExecutionException { - DOMStoreTransactionChain txChain = domStore.createTransactionChain(); - assertNotNull(txChain); - - /** - * We alocate new read-write transaction and write /test - * - * - */ - DOMStoreReadWriteTransaction firstTx = txChain.newReadWriteTransaction(); - assertTestContainerWrite(firstTx); - - /** - * First transaction is marked as ready, we are able to allocate chained - * transactions - */ - DOMStoreThreePhaseCommitCohort firstWriteTxCohort = firstTx.ready(); - - /** - * We alocate chained transaction - read transaction, note first one is - * still not commited to datastore. - */ - DOMStoreReadTransaction secondReadTx = txChain.newReadOnlyTransaction(); - - /** - * - * We test if we are able to read data from tx, read should not fail - * since we are using chained transaction. - * - * - */ - assertTestContainerExists(secondReadTx); - - /** - * - * We alocate next transaction, which is still based on first one, but - * is read-write. - * - */ - DOMStoreReadWriteTransaction thirdDeleteTx = txChain.newReadWriteTransaction(); - - /** - * We test existence of /test in third transaction container should - * still be visible from first one (which is still uncommmited). - * - * - */ - assertTestContainerExists(thirdDeleteTx); - - /** - * We delete node in third transaction - */ - thirdDeleteTx.delete(TestModel.TEST_PATH); - - /** - * third transaction is sealed. - */ - DOMStoreThreePhaseCommitCohort thirdDeleteTxCohort = thirdDeleteTx.ready(); - - /** - * We commit first transaction - * - */ - assertThreePhaseCommit(firstWriteTxCohort); - - // Alocates store transacion - DOMStoreReadTransaction storeReadTx = domStore.newReadOnlyTransaction(); - /** - * We verify transaction is commited to store, container should exists - * in datastore. - */ - assertTestContainerExists(storeReadTx); - /** - * We commit third transaction - * - */ - assertThreePhaseCommit(thirdDeleteTxCohort); - } - - @Test - @Ignore - public void testTransactionConflict() throws InterruptedException, ExecutionException { - DOMStoreReadWriteTransaction txOne = domStore.newReadWriteTransaction(); - DOMStoreReadWriteTransaction txTwo = domStore.newReadWriteTransaction(); - assertTestContainerWrite(txOne); - assertTestContainerWrite(txTwo); - - /** - * Commits transaction - */ - assertThreePhaseCommit(txOne.ready()); - - /** - * Asserts that txTwo could not be commited - */ - assertFalse(txTwo.ready().canCommit().get()); - } - - private static void assertThreePhaseCommit(final DOMStoreThreePhaseCommitCohort cohort) - throws InterruptedException, ExecutionException { - assertTrue(cohort.canCommit().get().booleanValue()); - cohort.preCommit().get(); - cohort.commit().get(); - } - - private static Optional> assertTestContainerWrite(final DOMStoreReadWriteTransaction writeTx) - throws InterruptedException, ExecutionException { - /** - * - * Writes /test in writeTx - * - */ - writeTx.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME)); - - return assertTestContainerExists(writeTx); - } - - /** - * - * Reads /test from readTx Read should return container. - * - */ - private static Optional> assertTestContainerExists(DOMStoreReadTransaction readTx) - throws InterruptedException, ExecutionException { - - ListenableFuture>> writeTxContainer = readTx.read(TestModel.TEST_PATH); - assertTrue(writeTxContainer.get().isPresent()); - return writeTxContainer.get(); - } - -} diff --git a/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/TestModel.java b/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/TestModel.java index 2c965047db..91aa57c259 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/TestModel.java +++ b/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/TestModel.java @@ -7,16 +7,16 @@ */ package org.opendaylight.controller.md.sal.dom.store.impl; -import java.io.InputStream; -import java.util.Collections; -import java.util.Set; - import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl; +import java.io.InputStream; +import java.util.Collections; +import java.util.Set; + public class TestModel { public static final QName TEST_QNAME = QName.create("urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test", "2014-03-13", 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 deleted file mode 100644 index 4fb190fc82..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationMetadataTreeTest.java +++ /dev/null @@ -1,259 +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 org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.opendaylight.controller.md.sal.dom.store.impl.TestModel.ID_QNAME; -import static org.opendaylight.controller.md.sal.dom.store.impl.TestModel.INNER_LIST_QNAME; -import static org.opendaylight.controller.md.sal.dom.store.impl.TestModel.NAME_QNAME; -import static org.opendaylight.controller.md.sal.dom.store.impl.TestModel.OUTER_LIST_PATH; -import static org.opendaylight.controller.md.sal.dom.store.impl.TestModel.OUTER_LIST_QNAME; -import static org.opendaylight.controller.md.sal.dom.store.impl.TestModel.TEST_PATH; -import static org.opendaylight.controller.md.sal.dom.store.impl.TestModel.TEST_QNAME; -import static org.opendaylight.controller.md.sal.dom.store.impl.TestModel.VALUE_QNAME; -import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntry; -import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntryBuilder; -import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapNodeBuilder; - -import org.junit.Before; -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; -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.impl.schema.ImmutableNodes; -import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder; -import org.opendaylight.yangtools.yang.model.api.SchemaContext; - -import com.google.common.base.Optional; - -/** - * - * Schema structure of document is - * - *
    - * container root { 
    - *      list list-a {
    - *              key leaf-a;
    - *              leaf leaf-a;
    - *              choice choice-a {
    - *                      case one {
    - *                              leaf one;
    - *                      }
    - *                      case two-three {
    - *                              leaf two;
    - *                              leaf three;
    - *                      }
    - *              }
    - *              list list-b {
    - *                      key leaf-b;
    - *                      leaf leaf-b;
    - *              }
    - *      }
    - * }
    - * 
    - * - */ -public class ModificationMetadataTreeTest { - - private static final Short ONE_ID = 1; - private static final Short TWO_ID = 2; - private static final String TWO_ONE_NAME = "one"; - private static final String TWO_TWO_NAME = "two"; - - private static final InstanceIdentifier OUTER_LIST_1_PATH = InstanceIdentifier.builder(OUTER_LIST_PATH) - .nodeWithKey(OUTER_LIST_QNAME, ID_QNAME, ONE_ID) // - .build(); - - private static final InstanceIdentifier OUTER_LIST_2_PATH = InstanceIdentifier.builder(OUTER_LIST_PATH) - .nodeWithKey(OUTER_LIST_QNAME, ID_QNAME, TWO_ID) // - .build(); - - private static final InstanceIdentifier TWO_TWO_PATH = InstanceIdentifier.builder(OUTER_LIST_2_PATH) - .node(INNER_LIST_QNAME) // - .nodeWithKey(INNER_LIST_QNAME, NAME_QNAME, TWO_TWO_NAME) // - .build(); - - private static final InstanceIdentifier TWO_TWO_VALUE_PATH = InstanceIdentifier.builder(TWO_TWO_PATH) - .node(VALUE_QNAME) // - .build(); - - private static final MapEntryNode BAR_NODE = mapEntryBuilder(OUTER_LIST_QNAME, ID_QNAME, TWO_ID) // - .withChild(mapNodeBuilder(INNER_LIST_QNAME) // - .withChild(mapEntry(INNER_LIST_QNAME, NAME_QNAME, TWO_ONE_NAME)) // - .withChild(mapEntry(INNER_LIST_QNAME, NAME_QNAME, TWO_TWO_NAME)) // - .build()) // - .build(); - - private SchemaContext schemaContext; - private ModificationApplyOperation applyOper; - - @Before - public void prepare() { - schemaContext = TestModel.createTestContext(); - assertNotNull("Schema context must not be null.", schemaContext); - applyOper = SchemaAwareApplyOperation.from(schemaContext); - } - - /** - * Returns a test document - * - *
    -     * test
    -     *     outer-list
    -     *          id 1
    -     *     outer-list
    -     *          id 2
    -     *          inner-list
    -     *                  name "one"
    -     *          inner-list
    -     *                  name "two"
    -     *
    -     * 
    - * - * @return - */ - public NormalizedNode createDocumentOne() { - return ImmutableContainerNodeBuilder - .create() - .withNodeIdentifier(new NodeIdentifier(schemaContext.getQName())) - .withChild(createTestContainer()).build(); - - } - - private ContainerNode createTestContainer() { - return ImmutableContainerNodeBuilder - .create() - .withNodeIdentifier(new NodeIdentifier(TEST_QNAME)) - .withChild( - mapNodeBuilder(OUTER_LIST_QNAME) - .withChild(mapEntry(OUTER_LIST_QNAME, ID_QNAME, ONE_ID)) - .withChild(BAR_NODE).build()).build(); - } - - @Test - public void basicReadWrites() { - DataTreeModification modificationTree = new InMemoryDataTreeModification(new InMemoryDataTreeSnapshot(schemaContext, - TreeNodeFactory.createTreeNode(createDocumentOne(), Version.initial()), applyOper), - new SchemaAwareApplyOperationRoot(schemaContext)); - Optional> originalBarNode = modificationTree.readNode(OUTER_LIST_2_PATH); - assertTrue(originalBarNode.isPresent()); - assertSame(BAR_NODE, originalBarNode.get()); - - // writes node to /outer-list/1/inner_list/two/value - modificationTree.write(TWO_TWO_VALUE_PATH, ImmutableNodes.leafNode(VALUE_QNAME, "test")); - - // reads node to /outer-list/1/inner_list/two/value - // and checks if node is already present - Optional> barTwoCModified = modificationTree.readNode(TWO_TWO_VALUE_PATH); - assertTrue(barTwoCModified.isPresent()); - assertEquals(ImmutableNodes.leafNode(VALUE_QNAME, "test"), barTwoCModified.get()); - - // delete node to /outer-list/1/inner_list/two/value - modificationTree.delete(TWO_TWO_VALUE_PATH); - Optional> barTwoCAfterDelete = modificationTree.readNode(TWO_TWO_VALUE_PATH); - assertFalse(barTwoCAfterDelete.isPresent()); - } - - - public DataTreeModification createEmptyModificationTree() { - /** - * Creates empty Snapshot with associated schema context. - */ - DataTree t = InMemoryDataTreeFactory.getInstance().create(); - t.setSchemaContext(schemaContext); - - /** - * - * Creates Mutable Data Tree based on provided snapshot and schema - * context. - * - */ - return t.takeSnapshot().newModification(); - } - - @Test - public void createFromEmptyState() { - - DataTreeModification modificationTree = createEmptyModificationTree(); - /** - * Writes empty container node to /test - * - */ - modificationTree.write(TEST_PATH, ImmutableNodes.containerNode(TEST_QNAME)); - - /** - * Writes empty list node to /test/outer-list - */ - modificationTree.write(OUTER_LIST_PATH, ImmutableNodes.mapNodeBuilder(OUTER_LIST_QNAME).build()); - - /** - * Reads list node from /test/outer-list - */ - Optional> potentialOuterList = modificationTree.readNode(OUTER_LIST_PATH); - assertTrue(potentialOuterList.isPresent()); - - /** - * Reads container node from /test and verifies that it contains test - * node - */ - Optional> potentialTest = modificationTree.readNode(TEST_PATH); - ContainerNode containerTest = assertPresentAndType(potentialTest, ContainerNode.class); - - /** - * - * Gets list from returned snapshot of /test and verifies it contains - * outer-list - * - */ - assertPresentAndType(containerTest.getChild(new NodeIdentifier(OUTER_LIST_QNAME)), MapNode.class); - - } - - @Test - public void writeSubtreeReadChildren() { - DataTreeModification modificationTree = createEmptyModificationTree(); - modificationTree.write(TEST_PATH, createTestContainer()); - Optional> potential = modificationTree.readNode(TWO_TWO_PATH); - assertPresentAndType(potential, MapEntryNode.class); - } - - @Test - public void writeSubtreeDeleteChildren() { - DataTreeModification modificationTree = createEmptyModificationTree(); - modificationTree.write(TEST_PATH, createTestContainer()); - - // We verify data are present - Optional> potentialBeforeDelete = modificationTree.readNode(TWO_TWO_PATH); - assertPresentAndType(potentialBeforeDelete, MapEntryNode.class); - - modificationTree.delete(TWO_TWO_PATH); - Optional> potentialAfterDelete = modificationTree.readNode(TWO_TWO_PATH); - assertFalse(potentialAfterDelete.isPresent()); - - } - - private static T assertPresentAndType(final Optional potential, final Class type) { - assertNotNull(potential); - assertTrue(potential.isPresent()); - assertTrue(type.isInstance(potential.get())); - return type.cast(potential.get()); - } - -} 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 deleted file mode 100644 index 03ece2f5e0..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperationRoot.java +++ /dev/null @@ -1,39 +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.schema.ContainerNode; -import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; -import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder; -import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder; -import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; -import org.opendaylight.yangtools.yang.model.api.SchemaContext; - -public class SchemaAwareApplyOperationRoot extends DataNodeContainerModificationStrategy { - private final SchemaContext context; - - public SchemaAwareApplyOperationRoot(final SchemaContext context) { - super(context,ContainerNode.class); - this.context = context; - } - - public SchemaContext getContext() { - return context; - } - - @Override - public String toString() { - return "SchemaAwareApplyOperationRoot [context=" + context + "]"; - } - - @Override - @SuppressWarnings("rawtypes") - protected DataContainerNodeBuilder createBuilder(NormalizedNode original) { - return ImmutableContainerNodeBuilder.create((ContainerNode) original); - } -} diff --git a/opendaylight/md-sal/sal-dom-spi/pom.xml b/opendaylight/md-sal/sal-dom-spi/pom.xml index 660a67923f..88ac86a45e 100644 --- a/opendaylight/md-sal/sal-dom-spi/pom.xml +++ b/opendaylight/md-sal/sal-dom-spi/pom.xml @@ -15,6 +15,39 @@ sal-core-api + + + + org.opendaylight.yangtools + yang-maven-plugin + + + config + + generate-sources + + + + + org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator + ${jmxGeneratorPath} + + urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang + + + + org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl + ${salGeneratorPath} + + + true + + + + + + + scm:git:ssh://git.opendaylight.org:29418/controller.git scm:git:ssh://git.opendaylight.org:29418/controller.git diff --git a/opendaylight/md-sal/sal-dom-spi/src/main/yang/opendaylight-config-dom-datastore.yang b/opendaylight/md-sal/sal-dom-spi/src/main/yang/opendaylight-config-dom-datastore.yang new file mode 100644 index 0000000000..9a3ab181e0 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-spi/src/main/yang/opendaylight-config-dom-datastore.yang @@ -0,0 +1,22 @@ +module opendaylight-config-dom-datastore { + yang-version 1; + namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:config-dom-store"; + prefix "config-dom-store-spi"; + + import config { prefix config; revision-date 2013-04-05; } + + description + "DOM Service Provider Interface definition for MD-SAL config store"; + + revision "2014-06-17" { + description + "Initial revision"; + } + + identity config-dom-datastore { + base "config:service-type"; + config:java-class "org.opendaylight.controller.sal.core.spi.data.DOMStore"; + + } + +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-dom-spi/src/main/yang/opendaylight-operational-dom-datastore.yang b/opendaylight/md-sal/sal-dom-spi/src/main/yang/opendaylight-operational-dom-datastore.yang new file mode 100644 index 0000000000..fd408840bb --- /dev/null +++ b/opendaylight/md-sal/sal-dom-spi/src/main/yang/opendaylight-operational-dom-datastore.yang @@ -0,0 +1,22 @@ +module opendaylight-operational-dom-datastore { + yang-version 1; + namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:operational-dom-store"; + prefix "operational-dom-store-spi"; + + import config { prefix config; revision-date 2013-04-05; } + + description + "DOM Service Provider Interface definition for MD-SAL operational store"; + + revision "2014-06-17" { + description + "Initial revision"; + } + + identity operational-dom-datastore { + base "config:service-type"; + config:java-class "org.opendaylight.controller.sal.core.spi.data.DOMStore"; + + } + +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-inmemory-datastore/pom.xml b/opendaylight/md-sal/sal-inmemory-datastore/pom.xml new file mode 100644 index 0000000000..dadef821eb --- /dev/null +++ b/opendaylight/md-sal/sal-inmemory-datastore/pom.xml @@ -0,0 +1,191 @@ + + + 4.0.0 + + org.opendaylight.controller + sal-parent + 1.1-SNAPSHOT + + + sal-inmemory-datastore + + bundle + + + + com.google.guava + guava + + + + + + org.opendaylight.controller + config-api + + + + org.opendaylight.controller + sal-binding-api + + + + org.opendaylight.controller + sal-binding-config + + + + org.opendaylight.controller + sal-common-api + + + + org.opendaylight.controller + sal-common-util + + + + org.opendaylight.controller + sal-core-api + + + org.opendaylight.controller + sal-core-spi + + + + org.opendaylight.yangtools + concepts + + + + org.opendaylight.yangtools + util + + + + org.opendaylight.yangtools + yang-binding + + + + org.opendaylight.yangtools + yang-common + + + + org.opendaylight.yangtools + yang-data-api + + + org.opendaylight.yangtools + yang-data-impl + + + org.opendaylight.yangtools + yang-parser-impl + + + + org.osgi + org.osgi.core + + + + org.slf4j + slf4j-api + + + + + junit + junit + test + + + org.slf4j + slf4j-simple + ${slf4j.version} + test + + + + + + + org.apache.felix + maven-bundle-plugin + true + + + ${project.groupId}.${project.artifactId} + + org.opendaylight.controller.md.sal.dom.store.impl.* + + * + + + + + org.jacoco + jacoco-maven-plugin + + + org.opendaylight.controller.* + + false + + + + pre-test + + prepare-agent + + + + post-test + + report + + test + + + + + org.opendaylight.yangtools + yang-maven-plugin + + + config + + generate-sources + + + + + org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator + ${jmxGeneratorPath} + + urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang + + + + org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl + ${salGeneratorPath} + + + true + + + + + + + + scm:git:ssh://git.opendaylight.org:29418/controller.git + scm:git:ssh://git.opendaylight.org:29418/controller.git + HEAD + https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Architecture:Clustering + + + diff --git a/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/config/yang/inmemory_datastore_provider/InMemoryConfigDataStoreProviderModule.java b/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/config/yang/inmemory_datastore_provider/InMemoryConfigDataStoreProviderModule.java new file mode 100644 index 0000000000..3ed02dfb41 --- /dev/null +++ b/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/config/yang/inmemory_datastore_provider/InMemoryConfigDataStoreProviderModule.java @@ -0,0 +1,27 @@ +package org.opendaylight.controller.config.yang.inmemory_datastore_provider; + +import com.google.common.util.concurrent.MoreExecutors; +import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore; + +public class InMemoryConfigDataStoreProviderModule extends org.opendaylight.controller.config.yang.inmemory_datastore_provider.AbstractInMemoryConfigDataStoreProviderModule { + public InMemoryConfigDataStoreProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { + super(identifier, dependencyResolver); + } + + public InMemoryConfigDataStoreProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.inmemory_datastore_provider.InMemoryConfigDataStoreProviderModule oldModule, java.lang.AutoCloseable oldInstance) { + super(identifier, dependencyResolver, oldModule, oldInstance); + } + + @Override + public void customValidation() { + // add custom validation form module attributes here. + } + + @Override + public java.lang.AutoCloseable createInstance() { + InMemoryDOMDataStore ids = new InMemoryDOMDataStore("DOM-CFG", MoreExecutors.sameThreadExecutor()); + getSchemaServiceDependency().registerSchemaServiceListener(ids); + return ids; + } + +} diff --git a/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/config/yang/inmemory_datastore_provider/InMemoryConfigDataStoreProviderModuleFactory.java b/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/config/yang/inmemory_datastore_provider/InMemoryConfigDataStoreProviderModuleFactory.java new file mode 100644 index 0000000000..1931c14347 --- /dev/null +++ b/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/config/yang/inmemory_datastore_provider/InMemoryConfigDataStoreProviderModuleFactory.java @@ -0,0 +1,13 @@ +/* +* Generated file +* +* Generated from: yang module name: opendaylight-inmemory-datastore-provider yang module local name: inmemory-config-datastore-provider +* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator +* Generated at: Thu Jun 19 17:10:42 PDT 2014 +* +* Do not modify this file unless it is present under src/main directory +*/ +package org.opendaylight.controller.config.yang.inmemory_datastore_provider; +public class InMemoryConfigDataStoreProviderModuleFactory extends org.opendaylight.controller.config.yang.inmemory_datastore_provider.AbstractInMemoryConfigDataStoreProviderModuleFactory { + +} diff --git a/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/config/yang/inmemory_datastore_provider/InMemoryOperationalDataStoreProviderModule.java b/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/config/yang/inmemory_datastore_provider/InMemoryOperationalDataStoreProviderModule.java new file mode 100644 index 0000000000..eea95990a1 --- /dev/null +++ b/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/config/yang/inmemory_datastore_provider/InMemoryOperationalDataStoreProviderModule.java @@ -0,0 +1,27 @@ +package org.opendaylight.controller.config.yang.inmemory_datastore_provider; + +import com.google.common.util.concurrent.MoreExecutors; +import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore; + +public class InMemoryOperationalDataStoreProviderModule extends org.opendaylight.controller.config.yang.inmemory_datastore_provider.AbstractInMemoryOperationalDataStoreProviderModule { + public InMemoryOperationalDataStoreProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { + super(identifier, dependencyResolver); + } + + public InMemoryOperationalDataStoreProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.inmemory_datastore_provider.InMemoryOperationalDataStoreProviderModule oldModule, java.lang.AutoCloseable oldInstance) { + super(identifier, dependencyResolver, oldModule, oldInstance); + } + + @Override + public void customValidation() { + // add custom validation form module attributes here. + } + + @Override + public java.lang.AutoCloseable createInstance() { + InMemoryDOMDataStore ids = new InMemoryDOMDataStore("DOM-OPER", MoreExecutors.sameThreadExecutor()); + getSchemaServiceDependency().registerSchemaServiceListener(ids); + return ids; + } + +} diff --git a/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/config/yang/inmemory_datastore_provider/InMemoryOperationalDataStoreProviderModuleFactory.java b/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/config/yang/inmemory_datastore_provider/InMemoryOperationalDataStoreProviderModuleFactory.java new file mode 100644 index 0000000000..49bc6a2064 --- /dev/null +++ b/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/config/yang/inmemory_datastore_provider/InMemoryOperationalDataStoreProviderModuleFactory.java @@ -0,0 +1,13 @@ +/* +* Generated file +* +* Generated from: yang module name: opendaylight-inmemory-datastore-provider yang module local name: inmemory-operational-datastore-provider +* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator +* Generated at: Thu Jun 19 17:10:42 PDT 2014 +* +* Do not modify this file unless it is present under src/main directory +*/ +package org.opendaylight.controller.config.yang.inmemory_datastore_provider; +public class InMemoryOperationalDataStoreProviderModuleFactory extends org.opendaylight.controller.config.yang.inmemory_datastore_provider.AbstractInMemoryOperationalDataStoreProviderModuleFactory { + +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/AbstractDOMStoreTransaction.java b/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/AbstractDOMStoreTransaction.java similarity index 100% rename from opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/AbstractDOMStoreTransaction.java rename to opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/AbstractDOMStoreTransaction.java diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ChangeListenerNotifyTask.java b/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ChangeListenerNotifyTask.java similarity index 100% rename from opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ChangeListenerNotifyTask.java rename to opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ChangeListenerNotifyTask.java diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DOMImmutableDataChangeEvent.java b/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DOMImmutableDataChangeEvent.java similarity index 100% rename from opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DOMImmutableDataChangeEvent.java rename to opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DOMImmutableDataChangeEvent.java diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DataChangeListenerRegistration.java b/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DataChangeListenerRegistration.java similarity index 100% rename from opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DataChangeListenerRegistration.java rename to opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DataChangeListenerRegistration.java 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-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMDataStore.java similarity index 95% rename from opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMDataStore.java rename to opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMDataStore.java index b0c4274fa5..bef37980e5 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-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMDataStore.java @@ -7,27 +7,25 @@ */ package org.opendaylight.controller.md.sal.dom.store.impl; -import static com.google.common.base.Preconditions.checkState; - -import java.util.Collections; -import java.util.concurrent.Callable; -import java.util.concurrent.atomic.AtomicLong; - -import javax.annotation.concurrent.GuardedBy; - +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope; import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener; import org.opendaylight.controller.md.sal.common.api.data.OptimisticLockFailedException; import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; import org.opendaylight.controller.md.sal.dom.store.impl.SnapshotBackedWriteTransaction.TransactionReadyPrototype; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.ConflictingModificationAppliedException; -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.DataTreeSnapshot; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataValidationFailedException; +import org.opendaylight.yangtools.yang.data.api.schema.tree.ConflictingModificationAppliedException; +import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree; +import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate; +import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification; +import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot; +import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException; import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerTree; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.InMemoryDataTreeFactory; +import org.opendaylight.yangtools.yang.data.impl.schema.tree.InMemoryDataTreeFactory; import org.opendaylight.controller.sal.core.spi.data.DOMStore; import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadTransaction; import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction; @@ -44,12 +42,12 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContextListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.ListeningExecutorService; +import javax.annotation.concurrent.GuardedBy; +import java.util.Collections; +import java.util.concurrent.Callable; +import java.util.concurrent.atomic.AtomicLong; + +import static com.google.common.base.Preconditions.checkState; /** * In-memory DOM Data Store @@ -61,12 +59,13 @@ import com.google.common.util.concurrent.ListeningExecutorService; * */ public class InMemoryDOMDataStore implements DOMStore, Identifiable, SchemaContextListener, - TransactionReadyPrototype { + TransactionReadyPrototype,AutoCloseable { private static final Logger LOG = LoggerFactory.getLogger(InMemoryDOMDataStore.class); private final DataTree dataTree = InMemoryDataTreeFactory.getInstance().create(); private final ListenerTree listenerTree = ListenerTree.create(); private final AtomicLong txCounter = new AtomicLong(0); private final ListeningExecutorService executor; + private final String name; public InMemoryDOMDataStore(final String name, final ListeningExecutorService executor) { @@ -104,6 +103,10 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable, Sch dataTree.setSchemaContext(ctx); } + @Override + public void close(){ + executor.shutdownNow(); + } @Override public >> ListenerRegistration registerChangeListener( final InstanceIdentifier path, final L listener, final DataChangeScope scope) { @@ -218,6 +221,8 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable, Sch @Override public void close() { + executor.shutdownNow(); + } protected synchronized void onTransactionFailed(final SnapshotBackedWriteTransaction transaction, 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-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java similarity index 98% rename from opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java rename to opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java index 5021d070e1..71a3534c81 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-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java @@ -7,26 +7,18 @@ */ package org.opendaylight.controller.md.sal.dom.store.impl; -import static org.opendaylight.controller.md.sal.dom.store.impl.DOMImmutableDataChangeEvent.builder; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map.Entry; -import java.util.Set; -import java.util.concurrent.Callable; - +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; +import com.google.common.collect.Multimap; import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope; 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.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; @@ -34,15 +26,22 @@ 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.NormalizedNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer; +import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate; +import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode; +import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; -import com.google.common.collect.Multimap; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map.Entry; +import java.util.Set; +import java.util.concurrent.Callable; + +import static org.opendaylight.controller.md.sal.dom.store.impl.DOMImmutableDataChangeEvent.builder; /** * Resolve Data Change Events based on modifications and listeners @@ -94,7 +93,7 @@ final class ResolveDataChangeEventsTask implements Callable, Identifiable { diff --git a/opendaylight/md-sal/sal-inmemory-datastore/src/main/yang/opendaylight-inmemory-datastore-provider.yang b/opendaylight/md-sal/sal-inmemory-datastore/src/main/yang/opendaylight-inmemory-datastore-provider.yang new file mode 100644 index 0000000000..03220a3e5d --- /dev/null +++ b/opendaylight/md-sal/sal-inmemory-datastore/src/main/yang/opendaylight-inmemory-datastore-provider.yang @@ -0,0 +1,71 @@ + +module opendaylight-inmemory-datastore-provider { + + yang-version 1; + namespace "urn:opendaylight:params:xml:ns:yang:controller:inmemory-datastore-provider"; + prefix "inmemory-datastore-provider"; + + import config { prefix config; revision-date 2013-04-05; } + import rpc-context { prefix rpcx; revision-date 2013-06-17; } + import opendaylight-config-dom-datastore {prefix config-dom-store-spi;} + import opendaylight-operational-dom-datastore {prefix operational-dom-store-spi;} + import opendaylight-md-sal-dom {prefix sal;} + + description + "InMemory datastore provider implementation for config & operational datastore"; + + revision "2014-06-17" { + description + "Initial revision."; + } + + // This is the definition of the service implementation as a module identity. + identity inmemory-config-datastore-provider { + base config:module-type; + config:provided-service config-dom-store-spi:config-dom-datastore; + config:java-name-prefix InMemoryConfigDataStoreProvider; + } + + // This is the definition of the service implementation as a module identity. + + identity inmemory-operational-datastore-provider { + base config:module-type; + config:provided-service operational-dom-store-spi:operational-dom-datastore; + config:java-name-prefix InMemoryOperationalDataStoreProvider; + } + + + // Augments the 'configuration' choice node under modules/module. + augment "/config:modules/config:module/config:configuration" { + case inmemory-config-datastore-provider { + when "/config:modules/config:module/config:type = 'inmemory-config-datastore-provider'"; + + container schema-service { + uses config:service-ref { + refine type { + mandatory false; + config:required-identity sal:schema-service; + } + } + } + } + } + + + + // Augments the 'configuration' choice node under modules/module. + augment "/config:modules/config:module/config:configuration" { + case inmemory-operational-datastore-provider { + when "/config:modules/config:module/config:type = 'inmemory-operational-datastore-provider'"; + + container schema-service { + uses config:service-ref { + refine type { + mandatory false; + config:required-identity sal:schema-service; + } + } + } + } + } +} diff --git a/opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDataStoreTest.java b/opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDataStoreTest.java new file mode 100644 index 0000000000..369a7da138 --- /dev/null +++ b/opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDataStoreTest.java @@ -0,0 +1,248 @@ +package org.opendaylight.controller.md.sal.dom.store.impl; + +import com.google.common.base.Optional; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.MoreExecutors; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadTransaction; +import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction; +import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort; +import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransactionChain; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; + +import java.util.concurrent.ExecutionException; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + + +public class InMemoryDataStoreTest { + + private SchemaContext schemaContext; + private InMemoryDOMDataStore domStore; + + @Before + public void setupStore() { + domStore = new InMemoryDOMDataStore("TEST", MoreExecutors.sameThreadExecutor()); + schemaContext = TestModel.createTestContext(); + domStore.onGlobalContextUpdated(schemaContext); + + } + + @Test + public void testTransactionIsolation() throws InterruptedException, ExecutionException { + + assertNotNull(domStore); + + DOMStoreReadTransaction readTx = domStore.newReadOnlyTransaction(); + assertNotNull(readTx); + + DOMStoreReadWriteTransaction writeTx = domStore.newReadWriteTransaction(); + assertNotNull(writeTx); + /** + * + * Writes /test in writeTx + * + */ + writeTx.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME)); + + /** + * + * Reads /test from writeTx Read should return container. + * + */ + ListenableFuture>> writeTxContainer = writeTx.read(TestModel.TEST_PATH); + assertTrue(writeTxContainer.get().isPresent()); + + /** + * + * Reads /test from readTx Read should return Absent. + * + */ + ListenableFuture>> readTxContainer = readTx.read(TestModel.TEST_PATH); + assertFalse(readTxContainer.get().isPresent()); + } + + @Test + public void testTransactionCommit() throws InterruptedException, ExecutionException { + + DOMStoreReadWriteTransaction writeTx = domStore.newReadWriteTransaction(); + assertNotNull(writeTx); + /** + * + * Writes /test in writeTx + * + */ + writeTx.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME)); + + /** + * + * Reads /test from writeTx Read should return container. + * + */ + ListenableFuture>> writeTxContainer = writeTx.read(TestModel.TEST_PATH); + assertTrue(writeTxContainer.get().isPresent()); + + DOMStoreThreePhaseCommitCohort cohort = writeTx.ready(); + + assertThreePhaseCommit(cohort); + + Optional> afterCommitRead = domStore.newReadOnlyTransaction().read(TestModel.TEST_PATH) + .get(); + assertTrue(afterCommitRead.isPresent()); + } + + @Test + public void testTransactionAbort() throws InterruptedException, ExecutionException { + + DOMStoreReadWriteTransaction writeTx = domStore.newReadWriteTransaction(); + assertNotNull(writeTx); + + assertTestContainerWrite(writeTx); + + DOMStoreThreePhaseCommitCohort cohort = writeTx.ready(); + + assertTrue(cohort.canCommit().get().booleanValue()); + cohort.preCommit().get(); + cohort.abort().get(); + + Optional> afterCommitRead = domStore.newReadOnlyTransaction().read(TestModel.TEST_PATH) + .get(); + assertFalse(afterCommitRead.isPresent()); + } + + @Test + public void testTransactionChain() throws InterruptedException, ExecutionException { + DOMStoreTransactionChain txChain = domStore.createTransactionChain(); + assertNotNull(txChain); + + /** + * We alocate new read-write transaction and write /test + * + * + */ + DOMStoreReadWriteTransaction firstTx = txChain.newReadWriteTransaction(); + assertTestContainerWrite(firstTx); + + /** + * First transaction is marked as ready, we are able to allocate chained + * transactions + */ + DOMStoreThreePhaseCommitCohort firstWriteTxCohort = firstTx.ready(); + + /** + * We alocate chained transaction - read transaction, note first one is + * still not commited to datastore. + */ + DOMStoreReadTransaction secondReadTx = txChain.newReadOnlyTransaction(); + + /** + * + * We test if we are able to read data from tx, read should not fail + * since we are using chained transaction. + * + * + */ + assertTestContainerExists(secondReadTx); + + /** + * + * We alocate next transaction, which is still based on first one, but + * is read-write. + * + */ + DOMStoreReadWriteTransaction thirdDeleteTx = txChain.newReadWriteTransaction(); + + /** + * We test existence of /test in third transaction container should + * still be visible from first one (which is still uncommmited). + * + * + */ + assertTestContainerExists(thirdDeleteTx); + + /** + * We delete node in third transaction + */ + thirdDeleteTx.delete(TestModel.TEST_PATH); + + /** + * third transaction is sealed. + */ + DOMStoreThreePhaseCommitCohort thirdDeleteTxCohort = thirdDeleteTx.ready(); + + /** + * We commit first transaction + * + */ + assertThreePhaseCommit(firstWriteTxCohort); + + // Alocates store transacion + DOMStoreReadTransaction storeReadTx = domStore.newReadOnlyTransaction(); + /** + * We verify transaction is commited to store, container should exists + * in datastore. + */ + assertTestContainerExists(storeReadTx); + /** + * We commit third transaction + * + */ + assertThreePhaseCommit(thirdDeleteTxCohort); + } + + @Test + @Ignore + public void testTransactionConflict() throws InterruptedException, ExecutionException { + DOMStoreReadWriteTransaction txOne = domStore.newReadWriteTransaction(); + DOMStoreReadWriteTransaction txTwo = domStore.newReadWriteTransaction(); + assertTestContainerWrite(txOne); + assertTestContainerWrite(txTwo); + + /** + * Commits transaction + */ + assertThreePhaseCommit(txOne.ready()); + + /** + * Asserts that txTwo could not be commited + */ + assertFalse(txTwo.ready().canCommit().get()); + } + + private static void assertThreePhaseCommit(final DOMStoreThreePhaseCommitCohort cohort) + throws InterruptedException, ExecutionException { + assertTrue(cohort.canCommit().get().booleanValue()); + cohort.preCommit().get(); + cohort.commit().get(); + } + + private static Optional> assertTestContainerWrite(final DOMStoreReadWriteTransaction writeTx) + throws InterruptedException, ExecutionException { + /** + * + * Writes /test in writeTx + * + */ + writeTx.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME)); + + return assertTestContainerExists(writeTx); + } + + /** + * Reads /test from readTx Read should return container. + */ + private static Optional> assertTestContainerExists(DOMStoreReadTransaction readTx) + throws InterruptedException, ExecutionException { + + ListenableFuture>> writeTxContainer = readTx.read(TestModel.TEST_PATH); + assertTrue(writeTxContainer.get().isPresent()); + return writeTxContainer.get(); + } + +} diff --git a/opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/TestModel.java b/opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/TestModel.java new file mode 100644 index 0000000000..3feeb29672 --- /dev/null +++ b/opendaylight/md-sal/sal-inmemory-datastore/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/TestModel.java @@ -0,0 +1,51 @@ +/* + * 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; + +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl; + +import java.io.InputStream; +import java.util.Collections; +import java.util.Set; + +public class TestModel { + + public static final QName TEST_QNAME = QName.create("urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test", "2014-03-13", + "test"); + public static final QName OUTER_LIST_QNAME = QName.create(TEST_QNAME, "outer-list"); + public static final QName INNER_LIST_QNAME = QName.create(TEST_QNAME, "inner-list"); + public static final QName OUTER_CHOICE_QNAME = QName.create(TEST_QNAME, "outer-choice"); + public static final QName ID_QNAME = QName.create(TEST_QNAME, "id"); + public static final QName NAME_QNAME = QName.create(TEST_QNAME, "name"); + public static final QName VALUE_QNAME = QName.create(TEST_QNAME, "value"); + private static final String DATASTORE_TEST_YANG = "/odl-datastore-test.yang"; + + public static final InstanceIdentifier TEST_PATH = InstanceIdentifier.of(TEST_QNAME); + public static final InstanceIdentifier OUTER_LIST_PATH = InstanceIdentifier.builder(TEST_PATH).node(OUTER_LIST_QNAME).build(); + public static final QName TWO_QNAME = QName.create(TEST_QNAME, "two"); + public static final QName THREE_QNAME = QName.create(TEST_QNAME, "three"); + + + public static final InputStream getDatastoreTestInputStream() { + return getInputStream(DATASTORE_TEST_YANG); + } + + private static InputStream getInputStream(final String resourceName) { + return TestModel.class.getResourceAsStream(DATASTORE_TEST_YANG); + } + + public static SchemaContext createTestContext() { + YangParserImpl parser = new YangParserImpl(); + Set modules = parser.parseYangModelsFromStreams(Collections.singletonList(getDatastoreTestInputStream())); + return parser.resolveSchemaContext(modules); + } +} diff --git a/opendaylight/md-sal/sal-inmemory-datastore/src/test/resources/odl-datastore-test.yang b/opendaylight/md-sal/sal-inmemory-datastore/src/test/resources/odl-datastore-test.yang new file mode 100644 index 0000000000..17541fecab --- /dev/null +++ b/opendaylight/md-sal/sal-inmemory-datastore/src/test/resources/odl-datastore-test.yang @@ -0,0 +1,42 @@ +module odl-datastore-test { + yang-version 1; + namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test"; + prefix "store-test"; + + revision "2014-03-13" { + description "Initial revision."; + } + + container test { + list outer-list { + key id; + leaf id { + type uint16; + } + choice outer-choice { + case one { + leaf one { + type string; + } + } + case two-three { + leaf two { + type string; + } + leaf three { + type string; + } + } + } + list inner-list { + key name; + leaf name { + type string; + } + leaf value { + type string; + } + } + } + } +} \ No newline at end of file