2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.md.sal.dom.store.impl;
10 import java.util.concurrent.locks.ReadWriteLock;
11 import java.util.concurrent.locks.ReentrantReadWriteLock;
13 import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode;
14 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
15 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
16 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
17 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
18 import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeUtils;
19 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
23 import com.google.common.annotations.VisibleForTesting;
24 import com.google.common.base.Optional;
25 import com.google.common.base.Preconditions;
28 * Read-only snapshot of the data tree.
30 final class DataTree {
31 public static final class Snapshot {
32 private final SchemaContext schemaContext;
33 private final StoreMetadataNode rootNode;
36 Snapshot(final SchemaContext schemaContext, final StoreMetadataNode rootNode) {
37 this.schemaContext = Preconditions.checkNotNull(schemaContext);
38 this.rootNode = Preconditions.checkNotNull(rootNode);
41 public SchemaContext getSchemaContext() {
45 public Optional<NormalizedNode<?, ?>> readNode(final InstanceIdentifier path) {
46 return NormalizedNodeUtils.findNode(rootNode.getData(), path);
49 // FIXME: this is a leak of information
51 StoreMetadataNode getRootNode() {
56 public String toString() {
57 return rootNode.getSubtreeVersion().toString();
61 private static final Logger LOG = LoggerFactory.getLogger(DataTree.class);
62 private final ReadWriteLock rwLock = new ReentrantReadWriteLock(true);
63 private StoreMetadataNode rootNode;
64 private SchemaContext currentSchemaContext;
66 private DataTree(StoreMetadataNode rootNode, final SchemaContext schemaContext) {
67 this.rootNode = Preconditions.checkNotNull(rootNode);
68 this.currentSchemaContext = schemaContext;
71 public synchronized void setSchemaContext(final SchemaContext newSchemaContext) {
72 Preconditions.checkNotNull(newSchemaContext);
74 LOG.info("Attepting to install schema context {}", newSchemaContext);
77 * FIXME: we should walk the schema contexts, both current and new and see
78 * whether they are compatible here. Reject incompatible changes.
81 // Ready to change the context now, make sure no operations are running
82 rwLock.writeLock().lock();
84 this.currentSchemaContext = newSchemaContext;
86 rwLock.writeLock().unlock();
90 public static DataTree create(final SchemaContext schemaContext) {
91 final NodeIdentifier root = new NodeIdentifier(SchemaContext.NAME);
92 final NormalizedNode<?, ?> data = Builders.containerBuilder().withNodeIdentifier(root).build();
94 return new DataTree(StoreMetadataNode.createEmpty(data), schemaContext);
97 public Snapshot takeSnapshot() {
98 rwLock.readLock().lock();
101 return new Snapshot(currentSchemaContext, rootNode);
103 rwLock.readLock().unlock();
107 public void commitSnapshot(Snapshot currentSnapshot, StoreMetadataNode newDataTree) {
108 // Ready to change the context now, make sure no operations are running
109 rwLock.writeLock().lock();
111 Preconditions.checkState(currentSnapshot.rootNode == rootNode,
112 String.format("Store snapshot %s and transaction snapshot %s differ.",
113 rootNode, currentSnapshot.rootNode));
115 this.rootNode = newDataTree;
117 rwLock.writeLock().unlock();