blob: 206da0450e27b8bf3b4f263ee4d1acabd57afaff [file] [log] [blame]
Jordan Halterman00e92da2018-05-22 23:05:52 -07001/*
2 * Copyright 2018-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Thomas Vachuskab6d31672018-07-27 17:03:46 -070016package org.onosproject.store.atomix.primitives.impl;
Jordan Halterman00e92da2018-05-22 23:05:52 -070017
Jordan Halterman6aca84c2018-07-31 13:33:13 -070018import java.util.List;
Jordan Halterman00e92da2018-05-22 23:05:52 -070019import java.util.Map;
20import java.util.concurrent.CompletableFuture;
21import java.util.stream.Collectors;
22
Jordan Halterman6aca84c2018-07-31 13:33:13 -070023import com.google.common.collect.Lists;
Jordan Halterman00e92da2018-05-22 23:05:52 -070024import com.google.common.collect.Maps;
25import org.onosproject.store.primitives.NodeUpdate;
26import org.onosproject.store.primitives.TransactionId;
27import org.onosproject.store.service.AsyncDocumentTree;
28import org.onosproject.store.service.DocumentPath;
29import org.onosproject.store.service.DocumentTreeEvent;
30import org.onosproject.store.service.DocumentTreeListener;
31import org.onosproject.store.service.TransactionLog;
32import org.onosproject.store.service.Version;
33import org.onosproject.store.service.Versioned;
34
Jordan Halterman6cf60c32018-08-15 01:22:51 -070035import static org.onosproject.store.atomix.primitives.impl.AtomixFutures.adaptTreeFuture;
36
Jordan Halterman00e92da2018-05-22 23:05:52 -070037/**
38 * Atomix document tree.
39 */
40public class AtomixDocumentTree<V> implements AsyncDocumentTree<V> {
41 private final io.atomix.core.tree.AsyncAtomicDocumentTree<V> atomixTree;
42 private final Map<DocumentTreeListener<V>, io.atomix.core.tree.DocumentTreeEventListener<V>> listenerMap =
43 Maps.newIdentityHashMap();
44
45 public AtomixDocumentTree(io.atomix.core.tree.AsyncAtomicDocumentTree<V> atomixTree) {
46 this.atomixTree = atomixTree;
47 }
48
49 @Override
50 public String name() {
51 return atomixTree.name();
52 }
53
54 @Override
55 public DocumentPath root() {
56 return toOnosPath(atomixTree.root());
57 }
58
59 @Override
60 public CompletableFuture<Map<String, Versioned<V>>> getChildren(DocumentPath path) {
Jordan Halterman6cf60c32018-08-15 01:22:51 -070061 return adaptTreeFuture(atomixTree.getChildren(toAtomixPath(path)))
Jordan Halterman00e92da2018-05-22 23:05:52 -070062 .thenApply(map -> map.entrySet().stream()
63 .collect(Collectors.toMap(e -> e.getKey(),
64 e -> toVersioned(e.getValue()))));
65 }
66
67 @Override
68 public CompletableFuture<Versioned<V>> get(DocumentPath path) {
Jordan Halterman6cf60c32018-08-15 01:22:51 -070069 return adaptTreeFuture(atomixTree.get(toAtomixPath(path))).thenApply(this::toVersioned);
Jordan Halterman00e92da2018-05-22 23:05:52 -070070 }
71
72 @Override
73 public CompletableFuture<Versioned<V>> set(DocumentPath path, V value) {
Jordan Halterman6cf60c32018-08-15 01:22:51 -070074 return adaptTreeFuture(atomixTree.set(toAtomixPath(path), value)).thenApply(this::toVersioned);
Jordan Halterman00e92da2018-05-22 23:05:52 -070075 }
76
77 @Override
78 public CompletableFuture<Boolean> create(DocumentPath path, V value) {
Jordan Halterman6cf60c32018-08-15 01:22:51 -070079 return adaptTreeFuture(atomixTree.create(toAtomixPath(path), value));
Jordan Halterman00e92da2018-05-22 23:05:52 -070080 }
81
82 @Override
83 public CompletableFuture<Boolean> createRecursive(DocumentPath path, V value) {
Jordan Halterman6cf60c32018-08-15 01:22:51 -070084 return adaptTreeFuture(atomixTree.createRecursive(toAtomixPath(path), value));
Jordan Halterman00e92da2018-05-22 23:05:52 -070085 }
86
87 @Override
88 public CompletableFuture<Boolean> replace(DocumentPath path, V newValue, long version) {
Jordan Halterman6cf60c32018-08-15 01:22:51 -070089 return adaptTreeFuture(atomixTree.replace(toAtomixPath(path), newValue, version));
Jordan Halterman00e92da2018-05-22 23:05:52 -070090 }
91
92 @Override
93 public CompletableFuture<Boolean> replace(DocumentPath path, V newValue, V currentValue) {
Jordan Halterman6cf60c32018-08-15 01:22:51 -070094 return adaptTreeFuture(atomixTree.replace(toAtomixPath(path), newValue, currentValue));
Jordan Halterman00e92da2018-05-22 23:05:52 -070095 }
96
97 @Override
98 public CompletableFuture<Versioned<V>> removeNode(DocumentPath path) {
Jordan Halterman6cf60c32018-08-15 01:22:51 -070099 return adaptTreeFuture(atomixTree.remove(toAtomixPath(path))).thenApply(this::toVersioned);
Jordan Halterman00e92da2018-05-22 23:05:52 -0700100 }
101
102 @Override
103 public synchronized CompletableFuture<Void> addListener(DocumentPath path, DocumentTreeListener<V> listener) {
104 io.atomix.core.tree.DocumentTreeEventListener<V> atomixListener = event ->
105 listener.event(new DocumentTreeEvent<V>(
106 DocumentPath.from(event.path().pathElements()),
107 DocumentTreeEvent.Type.valueOf(event.type().name()),
108 event.newValue().map(this::toVersioned),
109 event.oldValue().map(this::toVersioned)));
110 listenerMap.put(listener, atomixListener);
Jordan Halterman6cf60c32018-08-15 01:22:51 -0700111 return adaptTreeFuture(atomixTree.addListener(toAtomixPath(path), atomixListener));
Jordan Halterman00e92da2018-05-22 23:05:52 -0700112 }
113
114 @Override
115 public CompletableFuture<Void> removeListener(DocumentTreeListener<V> listener) {
116 io.atomix.core.tree.DocumentTreeEventListener<V> atomixListener = listenerMap.remove(listener);
117 if (atomixListener != null) {
Jordan Halterman6cf60c32018-08-15 01:22:51 -0700118 return adaptTreeFuture(atomixTree.removeListener(atomixListener));
Jordan Halterman00e92da2018-05-22 23:05:52 -0700119 }
120 return CompletableFuture.completedFuture(null);
121 }
122
123 @Override
124 public CompletableFuture<Version> begin(TransactionId transactionId) {
125 throw new UnsupportedOperationException();
126 }
127
128 @Override
129 public CompletableFuture<Boolean> prepare(TransactionLog<NodeUpdate<V>> transactionLog) {
130 throw new UnsupportedOperationException();
131 }
132
133 @Override
134 public CompletableFuture<Boolean> prepareAndCommit(TransactionLog<NodeUpdate<V>> transactionLog) {
135 throw new UnsupportedOperationException();
136 }
137
138 @Override
139 public CompletableFuture<Void> commit(TransactionId transactionId) {
140 throw new UnsupportedOperationException();
141 }
142
143 @Override
144 public CompletableFuture<Void> rollback(TransactionId transactionId) {
145 throw new UnsupportedOperationException();
146 }
147
148 private DocumentPath toOnosPath(io.atomix.core.tree.DocumentPath path) {
Jordan Halterman6aca84c2018-07-31 13:33:13 -0700149 List<String> pathElements = Lists.newArrayList(path.pathElements());
150 pathElements.set(0, DocumentPath.ROOT.pathElements().get(0));
151 return DocumentPath.from(pathElements);
Jordan Halterman00e92da2018-05-22 23:05:52 -0700152 }
153
154 private io.atomix.core.tree.DocumentPath toAtomixPath(DocumentPath path) {
Jordan Halterman6aca84c2018-07-31 13:33:13 -0700155 List<String> pathElements = Lists.newArrayList(path.pathElements());
156 pathElements.set(0, "");
157 return io.atomix.core.tree.DocumentPath.from(pathElements);
Jordan Halterman00e92da2018-05-22 23:05:52 -0700158 }
159
160 private Versioned<V> toVersioned(io.atomix.utils.time.Versioned<V> versioned) {
161 return versioned != null
162 ? new Versioned<>(versioned.value(), versioned.version(), versioned.creationTime())
163 : null;
164 }
165}