Add session-id to the operational datastore
[netconf.git] / apps / netconf-topology-singleton / src / main / java / org / opendaylight / netconf / topology / singleton / impl / ProxyNetconfDataTreeService.java
1 /*
2  * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.netconf.topology.singleton.impl;
9
10 import akka.actor.ActorRef;
11 import akka.pattern.Patterns;
12 import akka.util.Timeout;
13 import com.google.common.base.Preconditions;
14 import com.google.common.util.concurrent.ListenableFuture;
15 import java.util.List;
16 import java.util.Optional;
17 import org.eclipse.jdt.annotation.NonNull;
18 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
19 import org.opendaylight.mdsal.dom.api.DOMRpcResult;
20 import org.opendaylight.netconf.api.EffectiveOperation;
21 import org.opendaylight.netconf.dom.api.NetconfDataTreeService;
22 import org.opendaylight.netconf.sal.connect.api.RemoteDeviceId;
23 import org.opendaylight.netconf.topology.singleton.impl.netconf.ProxyNetconfService;
24 import org.opendaylight.netconf.topology.singleton.messages.netconf.NetconfDataTreeServiceRequest;
25 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
26 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
27 import scala.concurrent.ExecutionContext;
28 import scala.concurrent.Future;
29
30 public class ProxyNetconfDataTreeService implements NetconfDataTreeService {
31     private final Timeout askTimeout;
32     private final RemoteDeviceId id;
33     private final ActorRef masterNode;
34     private final ExecutionContext executionContext;
35
36     private volatile ProxyNetconfService proxyNetconfService;
37
38     /**
39      * Constructor for {@code ProxyNetconfDataTreeService}.
40      *
41      * @param id               id
42      * @param masterNode       {@link org.opendaylight.netconf.topology.singleton.impl.actors.NetconfNodeActor} ref
43      * @param executionContext ExecutionContext
44      * @param askTimeout       ask timeout
45      */
46     public ProxyNetconfDataTreeService(final RemoteDeviceId id, final ActorRef masterNode,
47                                        final ExecutionContext executionContext, final Timeout askTimeout) {
48         this.id = id;
49         this.masterNode = masterNode;
50         this.executionContext = executionContext;
51         this.askTimeout = askTimeout;
52     }
53
54     @Override
55     public synchronized ListenableFuture<DOMRpcResult> lock() {
56         final Future<Object> masterActor = Patterns.ask(masterNode, new NetconfDataTreeServiceRequest(), askTimeout);
57         proxyNetconfService = new ProxyNetconfService(id, masterActor, executionContext, askTimeout);
58         return proxyNetconfService.lock();
59     }
60
61     @Override
62     public ListenableFuture<DOMRpcResult> unlock() {
63         isLocked();
64         return proxyNetconfService.unlock();
65     }
66
67     @Override
68     public ListenableFuture<DOMRpcResult> discardChanges() {
69         isLocked();
70         return proxyNetconfService.discardChanges();
71     }
72
73     @Override
74     public ListenableFuture<Optional<NormalizedNode>> get(final YangInstanceIdentifier path) {
75         final Future<Object> masterActor = Patterns.ask(masterNode, new NetconfDataTreeServiceRequest(), askTimeout);
76         ProxyNetconfService netconfService = new ProxyNetconfService(id, masterActor, executionContext, askTimeout);
77         return netconfService.get(path);
78     }
79
80     @Override
81     public ListenableFuture<Optional<NormalizedNode>> get(final YangInstanceIdentifier path,
82             final List<YangInstanceIdentifier> fields) {
83         final Future<Object> masterActor = Patterns.ask(masterNode, new NetconfDataTreeServiceRequest(), askTimeout);
84         ProxyNetconfService netconfService = new ProxyNetconfService(id, masterActor, executionContext, askTimeout);
85         return netconfService.get(path, fields);
86     }
87
88     @Override
89     public ListenableFuture<Optional<NormalizedNode>> getConfig(final YangInstanceIdentifier path) {
90         final Future<Object> masterActor = Patterns.ask(masterNode, new NetconfDataTreeServiceRequest(), askTimeout);
91         ProxyNetconfService netconfService = new ProxyNetconfService(id, masterActor, executionContext, askTimeout);
92         return netconfService.getConfig(path);
93     }
94
95     @Override
96     public ListenableFuture<Optional<NormalizedNode>> getConfig(final YangInstanceIdentifier path,
97             final List<YangInstanceIdentifier> fields) {
98         final Future<Object> masterActor = Patterns.ask(masterNode, new NetconfDataTreeServiceRequest(), askTimeout);
99         ProxyNetconfService netconfService = new ProxyNetconfService(id, masterActor, executionContext, askTimeout);
100         return netconfService.getConfig(path, fields);
101     }
102
103     @Override
104     public ListenableFuture<? extends DOMRpcResult> merge(final LogicalDatastoreType store,
105             final YangInstanceIdentifier path, final NormalizedNode data,
106             final Optional<EffectiveOperation> defaultOperation) {
107         isLocked();
108         return proxyNetconfService.merge(store, path, data, defaultOperation);
109     }
110
111     @Override
112     public ListenableFuture<? extends DOMRpcResult> replace(final LogicalDatastoreType store,
113             final YangInstanceIdentifier path, final NormalizedNode data,
114             final Optional<EffectiveOperation> defaultOperation) {
115         isLocked();
116         return proxyNetconfService.replace(store, path, data, defaultOperation);
117     }
118
119     @Override
120     public ListenableFuture<? extends DOMRpcResult> create(final LogicalDatastoreType store,
121             final YangInstanceIdentifier path, final NormalizedNode data,
122             final Optional<EffectiveOperation> defaultOperation) {
123         isLocked();
124         return proxyNetconfService.create(store, path, data, defaultOperation);
125     }
126
127     @Override
128     public ListenableFuture<? extends DOMRpcResult> delete(final LogicalDatastoreType store,
129             final YangInstanceIdentifier path) {
130         isLocked();
131         return proxyNetconfService.delete(store, path);
132     }
133
134     @Override
135     public ListenableFuture<? extends DOMRpcResult> remove(final LogicalDatastoreType store,
136             final YangInstanceIdentifier path) {
137         isLocked();
138         return proxyNetconfService.remove(store, path);
139     }
140
141     @Override
142     public ListenableFuture<? extends DOMRpcResult> commit() {
143         isLocked();
144         return proxyNetconfService.commit();
145     }
146
147     @Override
148     public @NonNull Object getDeviceId() {
149         return id;
150     }
151
152     private void isLocked() {
153         Preconditions.checkState(proxyNetconfService != null,
154             "%s: Device's datastore must be locked first", id);
155     }
156 }